diff --git a/PAM/ssh/CMakeLists.txt b/PAM/ssh/CMakeLists.txt index b1be9ac..4e4af9f 100644 --- a/PAM/ssh/CMakeLists.txt +++ b/PAM/ssh/CMakeLists.txt @@ -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 diff --git a/PAM/ssh/include/rublon/authentication_step_interface.hpp b/PAM/ssh/include/rublon/authentication_step_interface.hpp index 9b91c02..d3e056c 100644 --- a/PAM/ssh/include/rublon/authentication_step_interface.hpp +++ b/PAM/ssh/include/rublon/authentication_step_interface.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"); diff --git a/PAM/ssh/include/rublon/core_handler.hpp b/PAM/ssh/include/rublon/core_handler.hpp index 8537709..e35c0fb 100644 --- a/PAM/ssh/include/rublon/core_handler.hpp +++ b/PAM/ssh/include/rublon/core_handler.hpp @@ -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")) { @@ -69,20 +69,17 @@ 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 rublon::Document & body) const { - auto bind_this = [this](auto memfn) { return [&](const auto & arg) { return (*this.*memfn)(arg); }; }; + 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); }; - 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}; }); } }; diff --git a/PAM/ssh/include/rublon/curl.hpp b/PAM/ssh/include/rublon/curl.hpp index f7e5aeb..2e303de 100644 --- a/PAM/ssh/include/rublon/curl.hpp +++ b/PAM/ssh/include/rublon/curl.hpp @@ -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); diff --git a/PAM/ssh/include/rublon/error.hpp b/PAM/ssh/include/rublon/error.hpp index 7618659..4d573fd 100644 --- a/PAM/ssh/include/rublon/error.hpp +++ b/PAM/ssh/include/rublon/error.hpp @@ -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; @@ -72,10 +89,10 @@ class Error { constexpr bool sockerError() const { return _error.index() == 2; } - - Category category()const noexcept{ + + Category category() const noexcept { return static_cast< Category >(_error.index()); - } + } }; } // namespace rublon diff --git a/PAM/ssh/include/rublon/init.hpp b/PAM/ssh/include/rublon/init.hpp index 329ff2e..341e37c 100644 --- a/PAM/ssh/include/rublon/init.hpp +++ b/PAM/ssh/include/rublon/init.hpp @@ -6,7 +6,7 @@ #include #include -#include +#include namespace rublon { class Verify {}; diff --git a/PAM/ssh/include/rublon/method/OTP.hpp b/PAM/ssh/include/rublon/method/OTP.hpp index ab5a59c..f62219b 100644 --- a/PAM/ssh/include/rublon/method/OTP.hpp +++ b/PAM/ssh/include/rublon/method/OTP.hpp @@ -6,40 +6,14 @@ #include #include +#include + 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) : 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)}; - } - } + OTP(std::string systemToken, std::string tid) : PasscodeBasedAuth(std::move(systemToken), std::move(tid), "OTP", "Mobile TOTP from Rublon Authenticator:") {} + }; } // namespace rublon::method diff --git a/PAM/ssh/include/rublon/method/SMS.hpp b/PAM/ssh/include/rublon/method/SMS.hpp index 5370c22..9fb5521 100644 --- a/PAM/ssh/include/rublon/method/SMS.hpp +++ b/PAM/ssh/include/rublon/method/SMS.hpp @@ -6,39 +6,14 @@ #include #include +#include + 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) : 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)}; - } - } + SMS(std::string systemToken, std::string tid) : PasscodeBasedAuth(std::move(systemToken), std::move(tid), "SMS", "SMS passcode:") {} + }; } // namespace rublon::method diff --git a/PAM/ssh/include/rublon/method/method_factory.hpp b/PAM/ssh/include/rublon/method/method_select.hpp similarity index 60% rename from PAM/ssh/include/rublon/method/method_factory.hpp rename to PAM/ssh/include/rublon/method/method_select.hpp index 7433210..182931b 100644 --- a/PAM/ssh/include/rublon/method/method_factory.hpp +++ b/PAM/ssh/include/rublon/method/method_select.hpp @@ -11,18 +11,40 @@ #include #include +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{}}; } }; diff --git a/PAM/ssh/include/rublon/method/passcode_based_auth.hpp b/PAM/ssh/include/rublon/method/passcode_based_auth.hpp new file mode 100644 index 0000000..b8b1546 --- /dev/null +++ b/PAM/ssh/include/rublon/method/passcode_based_auth.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include + +#include +#include +#include + +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 diff --git a/PAM/ssh/lib/pam.cpp b/PAM/ssh/lib/pam.cpp index 1d5344b..f7f7222 100644 --- a/PAM/ssh/lib/pam.cpp +++ b/PAM/ssh/lib/pam.cpp @@ -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) // diff --git a/PAM/ssh/tests/CMakeLists.txt b/PAM/ssh/tests/CMakeLists.txt index 8ddca53..f547894 100644 --- a/PAM/ssh/tests/CMakeLists.txt +++ b/PAM/ssh/tests/CMakeLists.txt @@ -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 diff --git a/PAM/ssh/tests/authentication_step_common_tests.cpp b/PAM/ssh/tests/authentication_step_common_tests.cpp index 2779746..e2e6d3c 100644 --- a/PAM/ssh/tests/authentication_step_common_tests.cpp +++ b/PAM/ssh/tests/authentication_step_common_tests.cpp @@ -1,33 +1,3 @@ #include - #include - #include -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{6*expected.a};} ) - ; - - EXPECT_EQ(*value, 5 * 6); -} diff --git a/PAM/ssh/tests/core_handler_mock.hpp b/PAM/ssh/tests/core_handler_mock.hpp index e69de29..6095a50 100644 --- a/PAM/ssh/tests/core_handler_mock.hpp +++ b/PAM/ssh/tests/core_handler_mock.hpp @@ -0,0 +1,7 @@ +#include + +namespace mocks { + +class CoreHandlerMock : public rublon::CoreHandlerInterface< CoreHandlerMock > {}; + +} // namespace mocks diff --git a/PAM/ssh/tests/core_response_generator.hpp b/PAM/ssh/tests/core_response_generator.hpp index 85243b8..024b0b8 100644 --- a/PAM/ssh/tests/core_response_generator.hpp +++ b/PAM/ssh/tests/core_response_generator.hpp @@ -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(); } @@ -62,14 +62,14 @@ class CoreResponseGenerator { print_methods()); 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; } diff --git a/PAM/ssh/tests/init_test.cpp b/PAM/ssh/tests/init_test.cpp index 59485b0..30a97e6 100644 --- a/PAM/ssh/tests/init_test.cpp +++ b/PAM/ssh/tests/init_test.cpp @@ -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 &&...) {} diff --git a/PAM/ssh/tests/method_factory_test.cpp b/PAM/ssh/tests/method_factory_test.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/PAM/ssh/tests/method_select_tests.cpp b/PAM/ssh/tests/method_select_tests.cpp new file mode 100644 index 0000000..31edb42 --- /dev/null +++ b/PAM/ssh/tests/method_select_tests.cpp @@ -0,0 +1,12 @@ +#include + +#include + +using namespace rublon; +using namespace testing; + +class MethodSelectTests : public Test { + public: + + PostMethod sut; +}; diff --git a/PAM/ssh/tests/passcode_auth_tests.cpp b/PAM/ssh/tests/passcode_auth_tests.cpp new file mode 100644 index 0000000..f20d444 --- /dev/null +++ b/PAM/ssh/tests/passcode_auth_tests.cpp @@ -0,0 +1,23 @@ +#include + +#include + +#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() +}