refactor
This commit is contained in:
parent
fa748d0a2c
commit
700845e17a
@ -15,9 +15,10 @@ if(${CMAKE_VERSION} VERSION_GREATER "3.19.0")
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/error.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/init.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/json.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/method/method_factory.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/method/method_select.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/method/OTP.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/method/SMS.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/method/passcode_based_auth.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/pam_action.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/pam.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rublon/rublon.hpp
|
||||
|
||||
@ -39,7 +39,7 @@ class AuthenticationStep {
|
||||
}
|
||||
|
||||
template < typename HandlerReturn_t >
|
||||
Error coreErrorHandler(const HandlerReturn_t & coreResponse) const {
|
||||
Error coreErrorHandler(const HandlerReturn_t & /*coreResponse*/) const {
|
||||
// switch(coreResponse.error().errorClass) {
|
||||
// case CoreHandlerError::ErrorClass::BadSigature:
|
||||
// log(LogLevel::Error, "ErrorClass::BadSigature");
|
||||
|
||||
@ -40,7 +40,7 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
|
||||
HttpHandler http{};
|
||||
|
||||
public:
|
||||
CoreHandler(const rublon::Configuration & config)
|
||||
CoreHandler(const Configuration & config)
|
||||
: secretKey{config.parameters.secretKey}, url{config.parameters.apiServer}, http{[]() { return Response{}; }} {}
|
||||
|
||||
tl::expected< Response, Error > validateSignature(const Response & response) const {
|
||||
@ -52,8 +52,8 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
|
||||
}
|
||||
|
||||
tl::expected< Document, Error > validateResponse(const Response & response) const {
|
||||
rublon::RapidJSONPMRStackAlloc< 4 * 1024 > alloc{};
|
||||
rublon::Document resp{&alloc};
|
||||
RapidJSONPMRStackAlloc< 4 * 1024 > alloc{};
|
||||
Document resp{&alloc};
|
||||
resp.Parse(response.body.c_str());
|
||||
|
||||
if(resp.HasParseError() or not resp.HasMember("result")) {
|
||||
@ -70,19 +70,16 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
|
||||
return resp;
|
||||
}
|
||||
|
||||
Request generateRequest(std::string_view path, const rublon::Document & body){
|
||||
tl::expected< Document, Error > request(std::string_view path, const Document & body) const {
|
||||
const auto validateSignature = [this](const auto & arg) { return this->validateSignature(arg); };
|
||||
const auto validateResponse = [this](const auto & arg) { return this->validateResponse(arg); };
|
||||
|
||||
}
|
||||
|
||||
tl::expected< Document, Error > request(std::string_view path, const rublon::Document & body) const {
|
||||
auto bind_this = [this](auto memfn) { return [&](const auto & arg) { return (*this.*memfn)(arg); }; };
|
||||
|
||||
rublon::RapidJSONPMRStackAlloc< 4 * 1024 > alloc{};
|
||||
rublon::StringBuffer jsonStr{&alloc};
|
||||
rublon::Writer writer{jsonStr, &alloc};
|
||||
RapidJSONPMRStackAlloc< 1 * 1024 > alloc{};
|
||||
StringBuffer jsonStr{&alloc};
|
||||
Writer writer{jsonStr, &alloc};
|
||||
body.Accept(writer);
|
||||
|
||||
std::byte _buffer[8 * 1024];
|
||||
std::byte _buffer[2 * 1024];
|
||||
std::pmr::monotonic_buffer_resource mr{_buffer, sizeof(_buffer)};
|
||||
|
||||
Request request{mr};
|
||||
@ -95,8 +92,8 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
|
||||
std::pmr::string uri{url + path.data(), &mr};
|
||||
|
||||
return http.request(uri, request)
|
||||
.and_then(bind_this(&CoreHandler::validateSignature))
|
||||
.and_then(bind_this(&CoreHandler::validateResponse))
|
||||
.and_then(validateSignature)
|
||||
.and_then(validateResponse)
|
||||
.or_else([](const Error & e) -> tl::expected< Document, Error > { return tl::unexpected{e}; });
|
||||
}
|
||||
};
|
||||
|
||||
@ -22,10 +22,8 @@ namespace rublon {
|
||||
|
||||
namespace {
|
||||
size_t WriteMemoryCallback(void * contents, size_t size, size_t nmemb, void * userp) {
|
||||
log(LogLevel::Debug, "got %d/%d content : %s", size, nmemb, ( const char * ) contents);
|
||||
|
||||
size_t realsize = size * nmemb;
|
||||
reinterpret_cast< std::string * >(userp)->append(static_cast< const char * >(contents), realsize);
|
||||
const size_t realsize = size * nmemb;
|
||||
reinterpret_cast< std::pmr::string * >(userp)->append(static_cast< const char * >(contents), realsize);
|
||||
return realsize;
|
||||
}
|
||||
} // namespace
|
||||
@ -55,7 +53,7 @@ class CURL {
|
||||
std::array< char, 16 * 1024 > buffer = {};
|
||||
std::pmr::monotonic_buffer_resource mr{buffer.data(), buffer.size()};
|
||||
|
||||
std::pmr::string response_data;
|
||||
std::pmr::string response_data{&mr};
|
||||
response_data.reserve(15000);
|
||||
|
||||
/// TODO this can be done on stack using pmr
|
||||
@ -81,13 +79,13 @@ class CURL {
|
||||
log(LogLevel::Error, "%s No response from Rublon server err:{%s}", "CURL", curl_easy_strerror(res));
|
||||
return tl::unexpected{Error{SocketError{SocketError::Timeout}}};
|
||||
}
|
||||
|
||||
log(LogLevel::Debug, "Response:\n%s\n", response_data.c_str());
|
||||
Response response;
|
||||
|
||||
long size;
|
||||
curl_easy_getinfo(curl.get(), CURLINFO_HEADER_SIZE, &size);
|
||||
|
||||
/// TODO ogarnąć alokację pamięci
|
||||
response.headers = details::headers({response_data.data(), static_cast< std::size_t >(size)});
|
||||
response.body = response_data.substr(size);
|
||||
|
||||
|
||||
@ -16,7 +16,6 @@ class SocketError {
|
||||
|
||||
ErrorClass errorClass;
|
||||
std::string reson;
|
||||
std::error_code d;
|
||||
|
||||
// error_category interface
|
||||
public:
|
||||
@ -24,7 +23,7 @@ class SocketError {
|
||||
return "SockerError";
|
||||
}
|
||||
std::string message(int) const {
|
||||
return reson;
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
@ -41,16 +40,33 @@ class CoreHandlerError {
|
||||
return "CoreHandlerError";
|
||||
}
|
||||
std::string message(int) const {
|
||||
return reson;
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
class MethodError {
|
||||
public:
|
||||
enum ErrorClass { BadMethod };
|
||||
|
||||
MethodError(ErrorClass e) : errorClass{e} {}
|
||||
MethodError(ErrorClass e, std::string r) : errorClass{e}, reson{std::move(r)} {}
|
||||
|
||||
ErrorClass errorClass;
|
||||
std::string reson;
|
||||
const char * name() const noexcept {
|
||||
return "MethodError";
|
||||
}
|
||||
std::string message(int) const {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
class Critical {};
|
||||
|
||||
class Error {
|
||||
std::variant< std::monostate, CoreHandlerError, SocketError, Critical > _error;
|
||||
std::variant< std::monostate, CoreHandlerError, SocketError, Critical, MethodError > _error;
|
||||
|
||||
enum class Category { None, CoreHandlerError, SockerError, Criticat };
|
||||
enum class Category { None, CoreHandlerError, SockerError, Criticat, MethodError };
|
||||
|
||||
public:
|
||||
Error() = default;
|
||||
@ -58,6 +74,7 @@ class Error {
|
||||
Error(CoreHandlerError error) : _error{error} {}
|
||||
Error(SocketError error) : _error{error} {}
|
||||
Error(Critical error) : _error{error} {}
|
||||
Error(MethodError error) : _error{error} {}
|
||||
|
||||
Error(const Error &) = default;
|
||||
Error(Error &&) = default;
|
||||
@ -73,7 +90,7 @@ class Error {
|
||||
return _error.index() == 2;
|
||||
}
|
||||
|
||||
Category category()const noexcept{
|
||||
Category category() const noexcept {
|
||||
return static_cast< Category >(_error.index());
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include <rublon/authentication_step_interface.hpp>
|
||||
#include <rublon/configuration.hpp>
|
||||
|
||||
#include <rublon/method/method_factory.hpp>
|
||||
#include <rublon/method/method_select.hpp>
|
||||
|
||||
namespace rublon {
|
||||
class Verify {};
|
||||
|
||||
@ -6,40 +6,14 @@
|
||||
#include <rublon/pam.hpp>
|
||||
#include <rublon/pam_action.hpp>
|
||||
|
||||
#include <rublon/method/passcode_based_auth.hpp>
|
||||
|
||||
namespace rublon::method {
|
||||
|
||||
class OTP : public AuthenticationStep< OTP > {
|
||||
using base_t = AuthenticationStep< OTP >;
|
||||
const char * uri = "/api/transaction/confirmCode";
|
||||
|
||||
class OTP:public PasscodeBasedAuth{
|
||||
public:
|
||||
const char * name = "TOTP";
|
||||
OTP(std::string systemToken, std::string tid) : PasscodeBasedAuth(std::move(systemToken), std::move(tid), "OTP", "Mobile TOTP from Rublon Authenticator:") {}
|
||||
|
||||
OTP(std::string systemToken, std::string tid) : base_t(std::move(systemToken), std::move(tid)) {}
|
||||
|
||||
template < typename Hander_t, typename PamInfo_t = LinuxPam >
|
||||
tl::expected< AuthenticationStatus, Error > handle(const CoreHandlerInterface< Hander_t > & coreHandler, const PamInfo_t & pam) const {
|
||||
RapidJSONPMRStackAlloc< 1024 > alloc{};
|
||||
Document body{rapidjson::kObjectType, &alloc};
|
||||
|
||||
this->addSystemToken(body, alloc);
|
||||
this->addTid(body, alloc);
|
||||
|
||||
const auto passcode =
|
||||
pam.scan([](const char * userInput) { return std::string{userInput}; }, "Mobile TOTP from Rublon Authenticator:");
|
||||
|
||||
body.AddMember("vericode", Value{passcode.value().c_str(), alloc}, alloc); /// TODO proper username
|
||||
|
||||
auto coreResponse = coreHandler.request(uri, body);
|
||||
|
||||
if(coreResponse.has_value()) {
|
||||
// const auto & rublonResponse = coreResponse.value()["result"];
|
||||
// {"status":"OK","result":true}
|
||||
return AuthenticationStatus{AuthenticationStatus::Action::Confirmed};
|
||||
} else {
|
||||
return tl::unexpected{this->coreErrorHandler(coreResponse)};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace rublon::method
|
||||
|
||||
@ -6,39 +6,14 @@
|
||||
#include <rublon/pam.hpp>
|
||||
#include <rublon/pam_action.hpp>
|
||||
|
||||
#include <rublon/method/passcode_based_auth.hpp>
|
||||
|
||||
namespace rublon::method {
|
||||
|
||||
class SMS : public AuthenticationStep< SMS > {
|
||||
using base_t = AuthenticationStep< SMS >;
|
||||
const char * uri = "/api/transaction/confirmCode";
|
||||
|
||||
class SMS:public PasscodeBasedAuth{
|
||||
public:
|
||||
const char * name = "SMS";
|
||||
SMS(std::string systemToken, std::string tid) : PasscodeBasedAuth(std::move(systemToken), std::move(tid), "SMS", "SMS passcode:") {}
|
||||
|
||||
SMS(std::string systemToken, std::string tid) : base_t(std::move(systemToken), std::move(tid)) {}
|
||||
|
||||
template < typename Hander_t, typename PamInfo_t = LinuxPam >
|
||||
tl::expected< AuthenticationStatus, Error > handle(const CoreHandlerInterface< Hander_t > & coreHandler, const PamInfo_t & pam) const {
|
||||
RapidJSONPMRStackAlloc< 1024 > alloc{};
|
||||
Document body{rapidjson::kObjectType, &alloc};
|
||||
|
||||
this->addSystemToken(body, alloc);
|
||||
this->addTid(body, alloc);
|
||||
|
||||
const auto passcode = pam.scan([](const char * userInput) { return std::string{userInput}; }, "SMS passcode:");
|
||||
|
||||
body.AddMember("vericode", Value{passcode.value().c_str(), alloc}, alloc);
|
||||
|
||||
auto coreResponse = coreHandler.request(uri, body);
|
||||
|
||||
if(coreResponse.has_value()) {
|
||||
// const auto & rublonResponse = coreResponse.value()["result"];
|
||||
// {"status":"OK","result":true}
|
||||
return AuthenticationStatus{AuthenticationStatus::Action::Confirmed};
|
||||
} else {
|
||||
return tl::unexpected{this->coreErrorHandler(coreResponse)};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace rublon::method
|
||||
|
||||
@ -11,18 +11,40 @@
|
||||
#include <rublon/method/OTP.hpp>
|
||||
#include <rublon/method/SMS.hpp>
|
||||
|
||||
template < class F >
|
||||
struct return_type;
|
||||
|
||||
template < class R, class... A >
|
||||
struct return_type< R (*)(A...) > {
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
using return_type_t = typename return_type< T >::type;
|
||||
|
||||
namespace std {
|
||||
inline ::rublon::Value::ConstValueIterator begin(const rublon::Value & __ils) noexcept {
|
||||
return __ils.Begin();
|
||||
}
|
||||
inline ::rublon::Value::ConstValueIterator end(const rublon::Value & __ils) noexcept {
|
||||
return __ils.End();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::size_t size(const rublon::Value & __cont) {
|
||||
return __cont.Size();
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
namespace rublon {
|
||||
|
||||
class Method : public AuthenticationStep< Method > {
|
||||
using base_t = AuthenticationStep< Method >;
|
||||
|
||||
class MethodProxy {
|
||||
public:
|
||||
template < typename Method_t >
|
||||
Method(Method_t method, std::string systemToken, std::string tid) : base_t(std::move(systemToken), std::move(tid)), _impl{method} {}
|
||||
MethodProxy(Method_t method) : _impl{std::move(method)} {}
|
||||
|
||||
template < typename Handler_t, typename PamInfo_t = LinuxPam >
|
||||
tl::expected< AuthenticationStatus, Error > fire(const CoreHandlerInterface< Handler_t > & coreHandler,
|
||||
const PamInfo_t & pam) const {
|
||||
tl::expected< AuthenticationStatus, Error > fire(const CoreHandlerInterface< Handler_t > & coreHandler, const PamInfo_t & pam) const {
|
||||
return std::visit(
|
||||
[&](const auto & method) {
|
||||
rublon::log(LogLevel::Info, "Using '%s' method", method.name);
|
||||
@ -41,6 +63,20 @@ class PostMethod : public rublon::AuthenticationStep< PostMethod > {
|
||||
const char * uri = "/api/transaction/methodSSH";
|
||||
std::string _method;
|
||||
|
||||
tl::expected< MethodProxy, Error > doCreateMethod(const Document & coreResponse) const {
|
||||
const auto & rublonResponse = coreResponse["result"];
|
||||
std::string tid = rublonResponse["tid"].GetString();
|
||||
|
||||
if(_method == "totp") {
|
||||
return MethodProxy{method::OTP{this->_systemToken, std::move(tid)}};
|
||||
} else if(_method == "sms") {
|
||||
return MethodProxy{method::SMS{this->_systemToken, std::move(tid)}};
|
||||
}
|
||||
|
||||
else
|
||||
return tl::unexpected{MethodError{MethodError::BadMethod}};
|
||||
}
|
||||
|
||||
public:
|
||||
const char * name = "Confirm Method";
|
||||
|
||||
@ -48,7 +84,9 @@ class PostMethod : public rublon::AuthenticationStep< PostMethod > {
|
||||
: base_t(std::move(systemToken), std::move(tid)), _method{method} {}
|
||||
|
||||
template < typename Hander_t, typename PamInfo_t = LinuxPam >
|
||||
tl::expected< Method, Error > handle(const CoreHandlerInterface< Hander_t > & coreHandler) const {
|
||||
tl::expected< MethodProxy, Error > handle(const CoreHandlerInterface< Hander_t > & coreHandler) const {
|
||||
auto createMethod = [&](const auto & coreResponse) { return doCreateMethod(coreResponse); };
|
||||
|
||||
RapidJSONPMRStackAlloc< 1024 > alloc{};
|
||||
Document body{rapidjson::kObjectType, &alloc};
|
||||
|
||||
@ -59,41 +97,27 @@ class PostMethod : public rublon::AuthenticationStep< PostMethod > {
|
||||
body.AddMember("GDPRAccepted", "true", alloc);
|
||||
body.AddMember("tosAccepted", "true", alloc);
|
||||
|
||||
auto coreResponse = coreHandler.request(uri, body);
|
||||
|
||||
if(coreResponse.has_value()) {
|
||||
// log(LogLevel::Info, "[TMP] has response, processing", __PRETTY_FUNCTION__);
|
||||
// const auto & rublonResponse = coreResponse.value()["result"];
|
||||
// std::string tid = rublonResponse["tid"].GetString();
|
||||
|
||||
// if(_method == "totp") {
|
||||
// return Method{method::OTP{this->_systemToken, this->_tid}, this->_systemToken, this->_tid};
|
||||
// } else if(_method == "sms") {
|
||||
// return Method{method::SMS{this->_systemToken, this->_tid}, this->_systemToken, this->_tid};
|
||||
// }
|
||||
return Method{method::SMS{this->_systemToken, this->_tid}, this->_systemToken, this->_tid};
|
||||
} else {
|
||||
// return tl::unexpected{this->coreErrorHandler(coreResponse)};
|
||||
return tl::unexpected{Critical{}};
|
||||
}
|
||||
|
||||
// return tl::unexpected{PamAction::accept};
|
||||
return tl::unexpected{Critical{}};
|
||||
return coreHandler
|
||||
.request(uri, body) //
|
||||
.and_then(createMethod);
|
||||
}
|
||||
};
|
||||
|
||||
class MethodSelect {
|
||||
std::string systemToken;
|
||||
std::string _systemToken;
|
||||
std::string _tid;
|
||||
|
||||
std::vector< std::string > _methods;
|
||||
|
||||
public:
|
||||
template < typename Array_t >
|
||||
MethodSelect(std::string systemToken, std::string tid, const Array_t & methods) : systemToken{systemToken}, _tid{std::string{tid}} {
|
||||
for(auto it = methods.Begin(); it < methods.End(); it++) {
|
||||
_methods.emplace_back(it->GetString());
|
||||
}
|
||||
MethodSelect(std::string systemToken, std::string tid, const Array_t & methodsAvailableForUser)
|
||||
: _systemToken{std::move(systemToken)}, _tid{std::move(tid)} {
|
||||
_methods.reserve(std::size(methodsAvailableForUser));
|
||||
std::transform(
|
||||
std::begin(methodsAvailableForUser), std::end(methodsAvailableForUser), std::back_inserter(_methods), [](const auto & method) {
|
||||
return method.GetString();
|
||||
});
|
||||
}
|
||||
|
||||
template < typename Pam_t >
|
||||
@ -136,11 +160,12 @@ class MethodSelect {
|
||||
pam.print(
|
||||
"you selected: %s", methods_id.count(methodid.value_or(0)) ? methods_id.at(methodid.value_or(0)).c_str() : "unknown option");
|
||||
|
||||
if(methods_id.at(methodid.value_or(0)) == "totp") {
|
||||
return PostMethod{systemToken, _tid, methods_id.at(methodid.value_or(0))};
|
||||
/// TODO check if valid method
|
||||
|
||||
if(auto it = methods_id.find(methodid.value()); it != methods_id.end()) {
|
||||
return PostMethod{_systemToken, _tid, it->second};
|
||||
}
|
||||
|
||||
// return tl::unexpected{PamAction::accept};
|
||||
return tl::unexpected{Critical{}};
|
||||
}
|
||||
};
|
||||
50
PAM/ssh/include/rublon/method/passcode_based_auth.hpp
Normal file
50
PAM/ssh/include/rublon/method/passcode_based_auth.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
#include <rublon/authentication_step_interface.hpp>
|
||||
#include <rublon/pam.hpp>
|
||||
#include <rublon/pam_action.hpp>
|
||||
|
||||
namespace rublon::method {
|
||||
|
||||
class PasscodeBasedAuth : public AuthenticationStep< PasscodeBasedAuth > {
|
||||
using base_t = AuthenticationStep< PasscodeBasedAuth >;
|
||||
const char * uri = "/api/transaction/confirmCode";
|
||||
const char * userMessage{nullptr};
|
||||
|
||||
template < typename PamInfo_t = LinuxPam >
|
||||
std::string readPasscode(const PamInfo_t & pam) const {
|
||||
/// TODO handle bad user input / wrong code etc
|
||||
return pam.scan([](const char * userInput) { return std::string{userInput}; }, userMessage).value();
|
||||
}
|
||||
|
||||
public:
|
||||
const char * name;
|
||||
|
||||
PasscodeBasedAuth(std::string systemToken, std::string tid, const char * name, const char * userMessage)
|
||||
: base_t(std::move(systemToken), std::move(tid)), userMessage{userMessage}, name{name} {}
|
||||
|
||||
template < typename Hander_t, typename PamInfo_t = LinuxPam >
|
||||
tl::expected< AuthenticationStatus, Error > handle(const CoreHandlerInterface< Hander_t > & coreHandler, const PamInfo_t & pam) const {
|
||||
RapidJSONPMRStackAlloc< 1024 > alloc{};
|
||||
Document body{rapidjson::kObjectType, &alloc};
|
||||
|
||||
this->addSystemToken(body, alloc);
|
||||
this->addTid(body, alloc);
|
||||
|
||||
body.AddMember("vericode", Value{readPasscode(pam).c_str(), alloc}, alloc); /// TODO proper username
|
||||
|
||||
auto coreResponse = coreHandler.request(uri, body);
|
||||
|
||||
if(coreResponse.has_value()) {
|
||||
// {"status":"OK","result":{"error":"Hmm, that's not the right code. Try again."}}
|
||||
// const auto & rublonResponse = coreResponse.value()["result"];
|
||||
return AuthenticationStatus{AuthenticationStatus::Action::Confirmed};
|
||||
} else {
|
||||
return tl::unexpected{this->coreErrorHandler(coreResponse)};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace rublon::method
|
||||
@ -47,7 +47,7 @@ pam_sm_authenticate(pam_handle_t * pamh, [[maybe_unused]] int flags, [[maybe_unu
|
||||
|
||||
auto selectMethod = [&](const MethodSelect & selector) { return selector.create(pam); };
|
||||
auto confirmMethod = [&](const PostMethod & confirm) { return confirm.fire(CH); };
|
||||
auto verifi = [&](const Method & method) { return method.fire(CH, pam); };
|
||||
auto verifi = [&](const MethodProxy & method) { return method.fire(CH, pam); };
|
||||
|
||||
auto authStatus = Init{rublonConfig.value()}
|
||||
.fire(CH, pam) //
|
||||
|
||||
@ -23,7 +23,8 @@ add_executable(rublon-tests
|
||||
./authentication_step_common_tests.cpp
|
||||
./core_handler_tests.cpp
|
||||
./init_test.cpp
|
||||
./method_factory_test.cpp
|
||||
./method_select_tests.cpp
|
||||
./passcode_auth_tests.cpp
|
||||
./rublon_tests.cpp
|
||||
./sign_tests.cpp
|
||||
./utils_tests.cpp
|
||||
|
||||
@ -1,33 +1,3 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rublon/authentication_step_interface.hpp>
|
||||
|
||||
#include <tl/expected.hpp>
|
||||
class err {};
|
||||
|
||||
class err2 {};
|
||||
|
||||
struct expect {
|
||||
int s;
|
||||
};
|
||||
|
||||
struct moreexpected {
|
||||
int a;
|
||||
};
|
||||
|
||||
tl::expected< expect, err > foo(int a) {
|
||||
if(a > 10) {
|
||||
return tl::unexpected{err{}};
|
||||
}
|
||||
return expect{4 * a};
|
||||
}
|
||||
|
||||
TEST(expected, tests) {
|
||||
auto value = foo(11)
|
||||
.and_then([](const expect & expect) { return tl::expected< moreexpected, err >{moreexpected{expect.s * 2}}; })
|
||||
.or_else([](const err & error) { return tl::expected< moreexpected, err >{moreexpected{5}}; })
|
||||
.and_then([](const moreexpected &expected){return tl::expected<int, err>{6*expected.a};} )
|
||||
;
|
||||
|
||||
EXPECT_EQ(*value, 5 * 6);
|
||||
}
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
#include <rublon/core_handler_interface.hpp>
|
||||
|
||||
namespace mocks {
|
||||
|
||||
class CoreHandlerMock : public rublon::CoreHandlerInterface< CoreHandlerMock > {};
|
||||
|
||||
} // namespace mocks
|
||||
@ -18,7 +18,7 @@ constexpr T forward_or_transform(T t) {
|
||||
}
|
||||
|
||||
template < class T, class = is_string< T > >
|
||||
constexpr const char * forward_or_transform(T t) {
|
||||
constexpr const char * forward_or_transform(const T &t) {
|
||||
return t.c_str();
|
||||
}
|
||||
|
||||
@ -63,13 +63,13 @@ class CoreResponseGenerator {
|
||||
return _buf.data();
|
||||
}
|
||||
|
||||
CoreResponseGenerator & methods(std::initializer_list< std::string > newMethods) {
|
||||
CoreResponseGenerator & withMethods(std::initializer_list< std::string > newMethods) {
|
||||
_methods.clear();
|
||||
std::copy(newMethods.begin(), newMethods.end(), std::inserter(_methods, _methods.begin()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
CoreResponseGenerator & tid(std::string tid) {
|
||||
CoreResponseGenerator & withTid(std::string tid) {
|
||||
_tid = tid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -29,12 +29,12 @@ class CoreHandlerMock : public CoreHandlerInterface< CoreHandlerMock > {
|
||||
}
|
||||
|
||||
CoreHandlerMock & methods(std::initializer_list< std::string > methods) {
|
||||
gen.methods(methods);
|
||||
gen.withMethods(methods);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CoreHandlerMock & tid(std::string tid) {
|
||||
gen.tid(tid);
|
||||
gen.withTid(tid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ class PamInfoMock {
|
||||
|
||||
class MethodFactoryMock {
|
||||
public:
|
||||
using MethodFactoryCreate_t = tl::expected< Method, Error >;
|
||||
using MethodFactoryCreate_t = tl::expected< MethodProxy, Error >;
|
||||
|
||||
template < typename... Args >
|
||||
MethodFactoryMock(Args &&...) {}
|
||||
|
||||
12
PAM/ssh/tests/method_select_tests.cpp
Normal file
12
PAM/ssh/tests/method_select_tests.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include <rublon/method/method_select.hpp>
|
||||
|
||||
using namespace rublon;
|
||||
using namespace testing;
|
||||
|
||||
class MethodSelectTests : public Test {
|
||||
public:
|
||||
|
||||
PostMethod sut;
|
||||
};
|
||||
23
PAM/ssh/tests/passcode_auth_tests.cpp
Normal file
23
PAM/ssh/tests/passcode_auth_tests.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include <rublon/method/passcode_based_auth.hpp>
|
||||
|
||||
#include "core_handler_mock.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace rublon;
|
||||
|
||||
class PasscodeBasedAuthTest : public Test {
|
||||
public:
|
||||
PasscodeBasedAuthTest() : sut{systemToken, tid, name, userMessage} {}
|
||||
|
||||
std::string systemToken, tid;
|
||||
const char * name = "Test";
|
||||
const char * userMessage = "message";
|
||||
method::PasscodeBasedAuth sut;
|
||||
// co
|
||||
};
|
||||
|
||||
TEST_F(PasscodeBasedAuthTest, wrongPasscodeShouldFail){
|
||||
// sut.handle()
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user