fix build on debian
This commit is contained in:
parent
c052281006
commit
e9f612753b
@ -3,6 +3,9 @@ include_directories(extern/rapidjson/include)
|
||||
|
||||
add_library(rublon-ssh
|
||||
INTERFACE
|
||||
)
|
||||
|
||||
add_library(rublon-ssh_ide INTERFACE
|
||||
./include/rublon/authentication_step_interface.hpp
|
||||
./include/rublon/configuration.hpp
|
||||
./include/rublon/core_handler.hpp
|
||||
@ -18,16 +21,13 @@ add_library(rublon-ssh
|
||||
./include/rublon/rublon.hpp
|
||||
./include/rublon/sign.hpp
|
||||
./include/rublon/span.hpp
|
||||
./include/rublon/utils.hpp
|
||||
)
|
||||
|
||||
./include/rublon/utils.hpp)
|
||||
|
||||
target_include_directories(rublon-ssh
|
||||
PUBLIC INTERFACE
|
||||
INTERFACE
|
||||
extern
|
||||
${CMAKE_CURRENT_LIST_DIR}/include
|
||||
)
|
||||
|
||||
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(tests)
|
||||
|
||||
@ -48,11 +48,9 @@ class Init : public AuthenticationStep< Init< MethodFactory_t, PamInfo_t > > {
|
||||
|
||||
if(httpResponse.has_value()) {
|
||||
log(LogLevel::Info, "[TMP] has response, processing", __PRETTY_FUNCTION__);
|
||||
const auto & rublonResponse = httpResponse.value()["response"];
|
||||
|
||||
const auto & rublonResponse = httpResponse.value()["result"];
|
||||
std::string tid = rublonResponse["tid"].GetString();
|
||||
|
||||
return _methodFactory.create(rublonResponse["methods"].GetArray());
|
||||
return _methodFactory.create(rublonResponse["methods"].GetArray(), std::move(tid));
|
||||
} else {
|
||||
// mostly connectio errors
|
||||
switch(httpResponse.error().errorClass) {
|
||||
|
||||
@ -5,25 +5,25 @@
|
||||
#include <variant>
|
||||
|
||||
#include <rublon/core_handler.hpp>
|
||||
#include <rublon/pam_action.hpp>
|
||||
#include <rublon/pam.hpp>
|
||||
#include <rublon/pam_action.hpp>
|
||||
|
||||
#include <rublon/method/OTP.hpp>
|
||||
#include <rublon/method/SMS.hpp>
|
||||
|
||||
namespace rublon{
|
||||
namespace rublon {
|
||||
|
||||
class Method {
|
||||
std::string tid;
|
||||
|
||||
|
||||
public:
|
||||
Method() {}
|
||||
|
||||
|
||||
template < typename Handler_t >
|
||||
tl::expected< int , PamAction > fire(const CoreHandlerInterface< Handler_t > & coreHandler) {
|
||||
tl::expected< int, PamAction > fire(const CoreHandlerInterface< Handler_t > & coreHandler) {
|
||||
return std::visit([&](const auto & method) { return method.fire(coreHandler); }, _impl);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::variant< method::OTP, method::SMS > _impl;
|
||||
};
|
||||
@ -31,16 +31,17 @@ class Method {
|
||||
template < typename Pam_t = LinuxPam >
|
||||
class MethodFactory {
|
||||
const Pam_t & pam;
|
||||
|
||||
|
||||
public:
|
||||
MethodFactory(const Pam_t & pam) : pam{pam} {}
|
||||
|
||||
|
||||
template < typename Array_t >
|
||||
tl::expected< Method, PamAction > create(const Array_t & methods) const {
|
||||
tl::expected< Method, PamAction > create(const Array_t & methods, const std::string & tid) const {
|
||||
std::pmr::map< int, std::pmr::string > methods_id;
|
||||
pam.print("%s", "");
|
||||
int i;
|
||||
for(const auto & method : methods) {
|
||||
rublon::log(LogLevel::Debug, "method %s found at pos %d", method.GetString(), i);
|
||||
if(method == "email") {
|
||||
pam.print("%d: Email Link", i + 1);
|
||||
methods_id[++i] = "email";
|
||||
@ -62,15 +63,20 @@ class MethodFactory {
|
||||
methods_id[++i] = "sms";
|
||||
}
|
||||
}
|
||||
|
||||
auto methodid = pam.scan([](char * userinput) { return std::stoi(userinput); }, "\nSelect method [1-%d]: ", methods.Size());
|
||||
|
||||
pam.print("you selected: %s", methods_id.count(methodid.value_or(0)) ? methods_id.at(methodid.value_or(0)).c_str() : "unknown option");
|
||||
|
||||
|
||||
|
||||
|
||||
auto methodid = pam.scan(
|
||||
[](char * userinput) {
|
||||
rublon::log(LogLevel::Debug, "User input: %s", userinput);
|
||||
return std::stoi(userinput);
|
||||
},
|
||||
"\nSelect method [1-%d]: ",
|
||||
methods.Size());
|
||||
|
||||
pam.print(
|
||||
"you selected: %s", methods_id.count(methodid.value_or(0)) ? methods_id.at(methodid.value_or(0)).c_str() : "unknown option");
|
||||
|
||||
return tl::unexpected{PamAction::accept};
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace rublon
|
||||
|
||||
@ -30,7 +30,7 @@ inline auto dateStr() {
|
||||
|
||||
constexpr const char* LogLevelNames[] {"Debug", "Info", "Warning", "Error"};
|
||||
|
||||
static LogLevel g_level = Debug;
|
||||
constexpr LogLevel g_level = Debug;
|
||||
|
||||
namespace details{
|
||||
static void doLog(LogLevel level, const char * line) noexcept {
|
||||
|
||||
@ -55,32 +55,45 @@ class CoreResponseGenerator {
|
||||
std::array< char, 2048 > _buf;
|
||||
io::sprintf(_buf.data(),
|
||||
generateBrokenData ? result_broken_template : result_ok_template,
|
||||
tid,
|
||||
_tid,
|
||||
status,
|
||||
companyName,
|
||||
applicationName,
|
||||
print_methods());
|
||||
return _buf.data();
|
||||
}
|
||||
|
||||
CoreResponseGenerator & methods(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) {
|
||||
_tid = tid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string _tid{generateTid()};
|
||||
std::string status;
|
||||
std::string companyName{"rublon"};
|
||||
std::string applicationName{"test_app"};
|
||||
std::set< std::string > _methods{"email", "totp", "qrcode", "push"};
|
||||
|
||||
bool skipSignatureGeneration{false};
|
||||
bool generateBrokenData{false};
|
||||
private:
|
||||
std::string print_methods() {
|
||||
std::string ret;
|
||||
for(const auto & m : methods)
|
||||
for(const auto & m : _methods)
|
||||
ret += "\"" + m + "\",";
|
||||
ret.pop_back();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static std::string generateTid() {
|
||||
return gen_random(32);
|
||||
}
|
||||
|
||||
std::string tid{generateTid()};
|
||||
std::string status;
|
||||
std::string companyName{"rublon"};
|
||||
std::string applicationName{"test_app"};
|
||||
std::set< std::string > methods{"email", "totp", "qrcode", "push"};
|
||||
|
||||
bool skipSignatureGeneration{false};
|
||||
bool generateBrokenData{false};
|
||||
|
||||
};
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include <rublon/configuration.hpp>
|
||||
|
||||
#include "core_response_generator.hpp"
|
||||
#include "rublon/sign.hpp"
|
||||
|
||||
namespace {
|
||||
rublon::Configuration conf{rublon::Configuration::Parameters{//
|
||||
@ -21,7 +22,7 @@ rublon::Configuration conf{rublon::Configuration::Parameters{//
|
||||
false}};
|
||||
} // namespace
|
||||
|
||||
class HttpHandlerMock {
|
||||
class HttpHandlerMock : public CoreResponseGenerator{
|
||||
auto signResponse(rublon::Response & res) {
|
||||
const auto & sign =
|
||||
skipSignatureGeneration ? std::array< char, 64 >{} : rublon::signData(res.body, conf.parameters.secretKey.c_str());
|
||||
@ -32,12 +33,12 @@ class HttpHandlerMock {
|
||||
MOCK_METHOD(std::optional< rublon::Response >, request, ( std::string_view, const rublon::Request & ), (const));
|
||||
|
||||
HttpHandlerMock & statusPending() {
|
||||
gen.status = "pending";
|
||||
status = "pending";
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpHandlerMock & brokenBody() {
|
||||
gen.generateBrokenData = true;
|
||||
generateBrokenData = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -48,7 +49,7 @@ class HttpHandlerMock {
|
||||
|
||||
operator rublon::Response() {
|
||||
rublon::Response res;
|
||||
res.body = gen.generateBody();
|
||||
res.body = generateBody();
|
||||
|
||||
signResponse(res);
|
||||
|
||||
@ -56,5 +57,4 @@ class HttpHandlerMock {
|
||||
}
|
||||
|
||||
bool skipSignatureGeneration;
|
||||
CoreResponseGenerator gen;
|
||||
};
|
||||
|
||||
@ -27,6 +27,16 @@ class CoreHandlerMock : public CoreHandlerInterface< CoreHandlerMock > {
|
||||
gen.generateBrokenData = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CoreHandlerMock & methods(std::initializer_list<std::string> methods) {
|
||||
gen.methods(methods);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CoreHandlerMock & tid(std::string tid) {
|
||||
gen.tid(tid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator tl::expected< Document, CoreHandlerError >() {
|
||||
auto body = gen.generateBody();
|
||||
@ -37,6 +47,10 @@ class CoreHandlerMock : public CoreHandlerInterface< CoreHandlerMock > {
|
||||
return doc;
|
||||
}
|
||||
|
||||
auto create() {
|
||||
return static_cast< tl::expected< Document, CoreHandlerError > >(*this);
|
||||
}
|
||||
|
||||
CoreResponseGenerator gen;
|
||||
};
|
||||
|
||||
@ -50,9 +64,21 @@ class PamInfoMock {
|
||||
template < typename Pam >
|
||||
class MethodFactoryMock {
|
||||
public:
|
||||
using MethodFactoryCreate_t = tl::expected< Method, PamAction >;
|
||||
|
||||
MethodFactoryMock(const Pam &) {}
|
||||
|
||||
MOCK_METHOD(MethodFactoryCreate_t, create_mocked, (std::vector< std::string > methods, std::string tid), (const));
|
||||
|
||||
template < typename Array_t >
|
||||
tl::expected< Method, PamAction > create(const Array_t & methods) const {}
|
||||
MethodFactoryCreate_t create(const Array_t & methods, const std::string & tid) const {
|
||||
std::vector< std::string > _methods;
|
||||
std::transform(std::begin(methods), std::end(methods), std::back_inserter(_methods), [](const auto & el) {
|
||||
return std::string{el.GetString()};
|
||||
});
|
||||
|
||||
return create_mocked(_methods, tid);
|
||||
}
|
||||
};
|
||||
|
||||
class InitTestable : public Init< MethodFactoryMock, PamInfoMock > {
|
||||
@ -61,6 +87,9 @@ class InitTestable : public Init< MethodFactoryMock, PamInfoMock > {
|
||||
PamInfoMock & pam() {
|
||||
return _pamInfo;
|
||||
}
|
||||
MethodFactoryMock<PamInfoMock> & methodFactory(){
|
||||
return _methodFactory;
|
||||
}
|
||||
};
|
||||
|
||||
class RublonHttpInitTest : public testing::Test {
|
||||
@ -69,17 +98,20 @@ class RublonHttpInitTest : public testing::Test {
|
||||
EXPECT_CALL(pam, ip()).WillOnce(Return("192.168.0.1"));
|
||||
EXPECT_CALL(pam, username()).WillOnce(Return("bwi"));
|
||||
}
|
||||
|
||||
RublonHttpInitTest() : coreHandler{}, sut{conf}, pam{sut.pam()}, methodFactoryMock{sut.methodFactory()} {
|
||||
expectDefaultPamInfo();
|
||||
}
|
||||
|
||||
RublonHttpInitTest() : coreHandler{}, sut{conf}, pam{sut.pam()} {}
|
||||
CoreHandlerMock coreHandler;
|
||||
InitTestable sut{conf};
|
||||
PamInfoMock & pam;
|
||||
MethodFactoryMock<PamInfoMock> &methodFactoryMock;
|
||||
};
|
||||
|
||||
using CoreReturn = tl::expected< Document, CoreHandlerError >;
|
||||
|
||||
TEST_F(RublonHttpInitTest, initializationSendsRequestOnGoodPath) {
|
||||
expectDefaultPamInfo();
|
||||
EXPECT_CALL(coreHandler, request("/api/transaction/init", _))
|
||||
.WillOnce(Return(tl::unexpected{CoreHandlerError{CoreHandlerError::BadSigature}}));
|
||||
sut.handle(coreHandler);
|
||||
@ -90,26 +122,27 @@ MATCHER_P(HoldsPamAction, action, "") {
|
||||
}
|
||||
|
||||
TEST_F(RublonHttpInitTest, rublon_Accept_pamLoginWhenThereIsNoConnection) {
|
||||
expectDefaultPamInfo();
|
||||
EXPECT_CALL(coreHandler, request(_, _)).WillOnce(Return(tl::unexpected{CoreHandlerError{CoreHandlerError::ConnectionError}}));
|
||||
EXPECT_THAT(sut.handle(coreHandler), HoldsPamAction(PamAction::decline));
|
||||
}
|
||||
|
||||
TEST_F(RublonHttpInitTest, rublon_Decline_pamLoginWhenServerHasBadSignature) {
|
||||
expectDefaultPamInfo();
|
||||
EXPECT_CALL(coreHandler, request(_, _)).WillOnce(Return(tl::unexpected{CoreHandlerError{CoreHandlerError::BadSigature}}));
|
||||
EXPECT_THAT(sut.handle(coreHandler), HoldsPamAction(PamAction::decline));
|
||||
}
|
||||
|
||||
TEST_F(RublonHttpInitTest, rublon_Decline_pamLoginWhenServerReturnsBrokenData) {
|
||||
expectDefaultPamInfo();
|
||||
EXPECT_CALL(coreHandler, request(_, _)).WillOnce(Return(tl::unexpected{CoreHandlerError{CoreHandlerError::BrokenData}}));
|
||||
EXPECT_THAT(sut.handle(coreHandler), HoldsPamAction(PamAction::decline));
|
||||
}
|
||||
|
||||
TEST_F(RublonHttpInitTest, rublon_Decline_pamLoginWhenServerReturnsCoreException) {
|
||||
expectDefaultPamInfo();
|
||||
EXPECT_CALL(coreHandler, request(_, _)).WillOnce(Return(tl::unexpected{CoreHandlerError{CoreHandlerError::CoreException}}));
|
||||
EXPECT_THAT(sut.handle(coreHandler), HoldsPamAction(PamAction::decline));
|
||||
}
|
||||
|
||||
TEST_F(RublonHttpInitTest, AllNeededInformationNeedsToBePassedToMethodFactory) {
|
||||
EXPECT_CALL(coreHandler, request(_, _)).WillOnce(Return(coreHandler.statusPending().methods({"sms", "otp"}).tid("transaction ID").create()));
|
||||
EXPECT_CALL(methodFactoryMock, create_mocked(_,"transaction ID") );
|
||||
sut.handle(coreHandler);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user