#pragma once #include "rublon/bits.hpp" #include "rublon/configuration.hpp" #include #include #include namespace rublon { class ErrorHandler { public: const Pam_t & pam; const Configuration & config; AuthenticationStatus printErrorDetails(const Error & error) { log(LogLevel::Error, "Process interrupted by {%s::%s}", error.errorClassName(), error.categoryName()); if(error.is< RublonAuthenticationInterrupt >()) { switch(error.get< RublonAuthenticationInterrupt >().errorClass) { case RublonAuthenticationInterrupt::ErrorClass::UserBaypass: return AuthenticationStatus::Action::Bypass; case RublonAuthenticationInterrupt::ErrorClass::UserDenied: pam.print("Access denied! Contact your administrator for more information"); return AuthenticationStatus::Action::Denied; case RublonAuthenticationInterrupt::ErrorClass::UserWaiting: case RublonAuthenticationInterrupt::ErrorClass::UserPending: pam.print( "Your account is awaiting administrator's approval.\n" "Contact your administrator and ask them to approve your account"); return AuthenticationStatus::Action::Denied; case RublonAuthenticationInterrupt::ErrorClass::UserNotFound: return AuthenticationStatus::Action::Bypass; } } if(error.is< MethodError >()) { switch(error.get< MethodError >().errorClass) { case MethodError::ErrorClass::BadMethod: return AuthenticationStatus::Action::Denied; case MethodError::ErrorClass::BadUserInput: return AuthenticationStatus::Action::Denied; case MethodError::ErrorClass::NoMethodAvailable: return AuthenticationStatus::Action::Denied; } } if(error.is< ConnectionError >()) { if(config.failMode == FailMode::bypass) { pam.print("Incorrect response from the Rublon API, user bypassed"); return AuthenticationStatus::Action::Bypass; } else { pam.print("Incorrect response from the Rublon API, user access denied"); return AuthenticationStatus::Action::Denied; } } if(error.is< CoreHandlerError >()) { pam.print("Something went wrong and authentication could not be completed, contact your administrator"); return AuthenticationStatus::Action::Denied; } if(error.is< WerificationError >()) { switch(error.get< WerificationError >().errorClass) { case WerificationError::ErrorClass::PasscodeException: pam.print(R"(Incorrect passcode)"); return AuthenticationStatus::Action::Denied; case WerificationError::ErrorClass::BadInput: pam.print(R"(Ensure that the Secret Key is correct.)"); return AuthenticationStatus::Action::Denied; case WerificationError::SecurityKeyException: pam.print(R"(Ensure that the Secret Key is correct.)"); return AuthenticationStatus::Action::Denied; case WerificationError::TooManyRequestsException: pam.print(R"(Too many attempts.)"); return AuthenticationStatus::Action::Denied; case WerificationError::SendPushException: pam.print(R"(Rublon failed to reach authenticator app)"); break; } } if(error.is< RublonCheckApplicationException >()) { switch(error.get< RublonCheckApplicationException >().errorClass) { case RublonCheckApplicationException::ErrorClass::ApplicationNotFoundException: log(LogLevel::Error, R"(Could not find the application in the Rublon Admin Console.)"); log(LogLevel::Error, R"(Ensure that the application exists and the SystemToken is correct.)"); return AuthenticationStatus::Action::Denied; case RublonCheckApplicationException::ErrorClass::InvalidSignatureException: log(LogLevel::Error, R"(Could not verify the signature.)"); log(LogLevel::Error, R"(Ensure that the Secret Key is correct.)"); return AuthenticationStatus::Action::Denied; case RublonCheckApplicationException::ErrorClass::UnsupportedVersionException: log(LogLevel::Error, R"(The provided version of the app is unsupported.)"); log(LogLevel::Error, R"(Try changing the app version.)"); return AuthenticationStatus::Action::Denied; case RublonCheckApplicationException::MissingFieldException: log(LogLevel::Error, R"(The provided version of the app is unsupported.)"); log(LogLevel::Error, R"(Try changing the app version.)"); return AuthenticationStatus::Action::Denied; } } return AuthenticationStatus::Action::Denied; } }; } // namespace rublon