rublon-ssh/PAM/ssh/include/rublon/error.hpp
rublon-bwi 8ffa20fffa
Bwi/sms link (#8)
* generate user enrolement message

* cleanup

* Fix bugs found during testing

* Add yotp message [not verified]

* smsLink implementation

* implement SMS Link

* YOTP fixes

* Add SMS link
2024-02-13 16:50:45 +01:00

181 lines
5.0 KiB
C++

#pragma once
#include <rublon/non_owning_ptr.hpp>
#include <tl/expected.hpp>
#include <string>
#include <variant>
namespace rublon {
#define names constexpr static inline const char * errorClassPrettyName[]
class ConnectionError {
public:
enum ErrorClass { Timeout, HttpError };
names = {"Timeout", "Error"};
constexpr static inline auto prettyName = "Connection Error";
constexpr ConnectionError() : errorClass{Timeout}, httpCode(200) {}
constexpr ConnectionError(ErrorClass e, long httpCode) : errorClass{e}, httpCode(httpCode) {}
constexpr const char * what() const {
return errorClassPrettyName[static_cast< int >(errorClass)];
}
ErrorClass errorClass;
long httpCode;
};
class CoreHandlerError {
public:
enum ErrorClass { BadSigature, RublonCoreException, BrokenData };
names = {"BadSigature", "RublonCoreException", "BrokenData"};
constexpr static inline auto prettyName = "Core Handler Error";
CoreHandlerError(ErrorClass e = BadSigature) : errorClass{e} {}
CoreHandlerError(ErrorClass e, std::string r) : errorClass{e}, reson{std::move(r)} {}
constexpr const char * what() const {
return errorClassPrettyName[static_cast< int >(errorClass)];
}
ErrorClass errorClass;
std::string reson;
};
class MethodError {
public:
enum ErrorClass { BadMethod, BadUserInput, NoMethodAvailable };
names = {"BadMethod", "BadUserInput", "NoMethodAvailable"};
constexpr static inline auto prettyName = "Method Error";
constexpr MethodError(ErrorClass e = BadMethod) : errorClass{e} {}
constexpr const char * what() const {
return errorClassPrettyName[static_cast< int >(errorClass)];
}
ErrorClass errorClass;
};
class WerificationError {
public:
enum ErrorClass { WrongCode };
names = {"WrongCode"};
constexpr static inline auto prettyName = "Werification Error";
constexpr WerificationError(ErrorClass e = WrongCode) : errorClass{e} {}
constexpr const char * what() const {
return errorClassPrettyName[static_cast< int >(errorClass)];
}
ErrorClass errorClass;
};
class RublonAuthenticationInterrupt {
public:
enum ErrorClass { UserBaypass, UserDenied, UserPending };
names = {"UserBaypass", "UserDenied", "UserPending"};
constexpr static inline auto prettyName = "Rublon Authentication Interrupt";
RublonAuthenticationInterrupt(ErrorClass e = UserBaypass) : errorClass{e} {}
constexpr const char * what() const {
return errorClassPrettyName[static_cast< int >(errorClass)];
}
ErrorClass errorClass;
};
class Error {
using Error_t =
std::variant< CoreHandlerError, ConnectionError, WerificationError, MethodError, RublonAuthenticationInterrupt >;
Error_t _error;
public:
enum Category { k_CoreHandlerError, k_ConnectionError, k_WerificationError, k_MethodError, k_RublonAuthenticationInterrupt };
Error() = default;
Error(CoreHandlerError error) : _error{error} {}
Error(ConnectionError error) : _error{error} {}
Error(MethodError error) : _error{error} {}
Error(WerificationError error) : _error{error} {}
Error(RublonAuthenticationInterrupt error) : _error{error} {}
Error(const Error &) = default;
Error(Error &&) = default;
Error & operator=(const Error &) = default;
Error & operator=(Error &&) = default;
public:
constexpr bool coreError() const {
return _error.index() == 1;
}
constexpr bool sockerError() const {
return _error.index() == 2;
}
constexpr Category category() const noexcept {
return static_cast< Category >(_error.index());
}
constexpr const char * categoryName() const noexcept {
return std::visit([](const auto & e) { return e.what(); }, _error);
}
constexpr int errorClass() const noexcept {
return std::visit([](const auto & e) { return static_cast< int >(e.errorClass); }, _error);
}
constexpr const char * errorClassName() const noexcept {
return std::visit([](const auto & e) { return e.prettyName; }, _error);
}
template < typename E >
constexpr bool is() const {
return category() == Error{E{}}.category();
}
template < typename E >
constexpr bool isSameCategoryAs(const E & e) const {
return category() == Error{e}.category();
}
constexpr bool hasClass(int _class) const {
return errorClass() == _class;
}
template < typename E >
constexpr bool hasSameErrorClassAs(E e) const {
assert(isSameCategoryAs(e));
return errorClass() == Error{e}.errorClass();
}
template < typename E >
constexpr const E & get() const {
return std::get< E >(_error);
}
};
constexpr bool operator==(const Error & e, const ConnectionError & socket) {
return e.sockerError() && e.errorClass() == socket.errorClass;
}
template < typename T >
constexpr bool operator==(const Error & lhs, const T & rhs) {
return lhs.isSameCategoryAs(rhs) && lhs.hasSameErrorClassAs(rhs);
}
} // namespace rublon