Add 'non interactove' implementation

This commit is contained in:
Bartosz Wieczorek 2024-11-26 19:54:29 +01:00
parent 864d783834
commit 7e9bf0d15a
9 changed files with 76 additions and 57 deletions

View File

@ -17,6 +17,9 @@ set(CMAKE_POSITION_INDEPENDENT_CODE YES)
add_compile_options(-Wall -Wextra -Wno-format-security)
# add_compile_options(-g -fsanitize=address,undefined,float-divide-by-zero,float-cast-overflow,null -fsanitize-address-use-after-scope -fno-sanitize-recover=all -fno-sanitize=alignment -fno-omit-frame-pointer)
# add_link_options(-g -fsanitize=address,undefined,float-divide-by-zero,float-cast-overflow,null -fsanitize-address-use-after-scope -fno-sanitize-recover=all -fno-sanitize=alignment -fno-omit-frame-pointer)
add_compile_definitions(RUBLON_VERSION_STRING="${RUBLON_VERSION_STRING}")
option(ENABLE_TESTS "Enable tests" OFF)

View File

@ -114,11 +114,17 @@ FetchContent_Declare(
FetchContent_MakeAvailable(libwebsockets)
set(RAPIDJSON_BUILD_DOC OFF)
set(RAPIDJSON_BUILD_EXAMPLES OFF)
set(RAPIDJSON_BUILD_TESTS OFF)
set(RAPIDJSON_HAS_STDSTRING OFF)
FetchContent_Declare(
RapidJSON
URL https://github.com/Tencent/rapidjson/archive/refs/tags/v1.1.0.zip
URL_HASH MD5=ceb1cf16e693a3170c173dc040a9d2bd
PATCH_COMMAND patch -p1 < ${CMAKE_CURRENT_LIST_DIR}/patches/rapidjson.patch
# PATCH_COMMAND patch -p1 < ${CMAKE_CURRENT_LIST_DIR}/patches/rapidjson.patch
)
if(NOT RapidJSON_POPULATED)

View File

@ -67,7 +67,7 @@ class Status {
}
void updateAppVersion(std::string_view newVersion) {
RapidJSONPMRStackAlloc< 128 > stackAlloc;
RapidJSONPMRStackAlloc< 512 > stackAlloc;
auto jsonPointer = JSONPointer{_appVersionKey.data(), &stackAlloc};
auto version = jsonPointer.Get(_data);
if(not version || version->GetString() != newVersion) {
@ -77,7 +77,7 @@ class Status {
}
void updateSystemVersion(std::string_view system) {
RapidJSONPMRStackAlloc< 128 > stackAlloc;
RapidJSONPMRStackAlloc< 512 > stackAlloc;
auto jsonPointer = JSONPointer{_paramSystemName.data(), &stackAlloc};
auto version = jsonPointer.Get(_data);
if(not version || version->GetString() != system) {

View File

@ -1,5 +1,6 @@
#pragma once
#include "rublon/error.hpp"
#include "rublon/static_string.hpp"
#include <memory>
#include <optional>
@ -58,10 +59,12 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
bool hasException(const Document & coreResponse) const {
using namespace std::string_view_literals;
log(LogLevel::Debug, "TMP Checking error status in core response");
return coreResponse.HasMember("status") and coreResponse["status"].GetString() == "ERROR"sv;
}
bool isUnHealthy(const Document & coreResponse) const {
log(LogLevel::Debug, "TMP Checking errors in core response");
return coreResponse.HasParseError();
}
@ -102,7 +105,7 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
tl::expected< Document, Error > resp{&alloc};
resp->Parse(response.body.c_str());
log(LogLevel::Debug, "Begin, Core Response validation");
log(LogLevel::Debug, "Starting Core Response validation");
if(isUnHealthy(*resp)) {
log(LogLevel::Error, "Rublon Core responded with broken data");
@ -122,11 +125,13 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
// additional check for mallformed responses (A invalid response, without any x-rublon-signature will stop at this check)
return tl::unexpected{CoreHandlerError{CoreHandlerError::BadSigature}};
}
log(LogLevel::Debug, "Core Response validated OK");
return resp;
}
tl::unexpected< Error > handleCoreException(std::string_view exceptionString) const {
log(LogLevel::Debug, "TMP got core exception: %s", exceptionString.data() );
// can happen only dyring check application step
if(auto error = RublonCheckApplicationException::fromString(exceptionString); error.has_value())
return tl::unexpected{Error{error.value()}};
@ -138,7 +143,9 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
// verification error wrong passcode etc.
if(auto error = WerificationError::fromString(exceptionString); error.has_value())
return tl::unexpected{Error{error.value()}};
// CoreHandlerError::TransactionAccessTokenExpiredException
// other exceptions, just "throw"
// TODO Handle
return tl::unexpected{Error{CoreHandlerError{CoreHandlerError::RublonCoreException}}};

View File

@ -1,6 +1,7 @@
#pragma once
#include "rublon/memory.hpp"
#include "rublon/utils.hpp"
#include <rublon/bits.hpp>
#include <rublon/authentication_step_interface.hpp>
@ -23,15 +24,25 @@ class Init : public AuthenticationStep {
const char * apiPath = "/api/transaction/init";
tl::expected< MethodSelect_t, Error > createMethod(const Document & coreResponse) const {
memory::MonotonicStackResource< 256 > stackResource;
rublon::log(LogLevel::Debug, "TMP create method");
memory::MonotonicStackResource< 512 > stackResource;
rublon::log(LogLevel::Debug, "TMP stack resource created");
RapidJSONPMRAlloc alloc{&stackResource};
rublon::log(LogLevel::Debug, "TMP alloc created");
const auto & rublonResponse = coreResponse["result"];
const auto * rublonMethods = JSONPointer{"/result/methods", &alloc}.Get(coreResponse);
rublon::log(LogLevel::Debug, "TMP json methods pointers created");
const auto * rublonTid = JSONPointer{"/result/tid", &alloc}.Get(coreResponse);
if(not rublonMethods)
log(LogLevel::Error, "core response has no methods");
if(not rublonTid)
log(LogLevel::Error, "core response has no transaction ID");
rublon::log(LogLevel::Debug, "TMP json pointers created");
_session.updateTransactionId(rublonTid);
return MethodSelect_t{_session, rublonResponse["methods"], _session.config().prompt, _session.config().autopushPrompt};
return MethodSelect_t{_session, *rublonMethods, _session.config().prompt, _session.config().autopushPrompt};
}
void addPamInfo(Document & coreRequest, const Pam_t & pam) const {
@ -68,7 +79,7 @@ class Init : public AuthenticationStep {
const auto * rublonStatus = JSONPointer{"/result/status", &alloc}.Get(coreResponse);
const auto * rublonWebURI = JSONPointer{"/result/webURI", &alloc}.Get(coreResponse);
if(rublonStatus) {
const auto & status = rublonStatus->GetString();
log(LogLevel::Warning, "Got enrolement message with stats %s", status);

View File

@ -1,5 +1,6 @@
#pragma once
#include "rapidjson/encodings.h"
#include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h>
#include <rapidjson/pointer.h>
@ -137,7 +138,6 @@ inline auto begin(const rublon::Value & __ils) noexcept {
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();
}

View File

@ -1,6 +1,4 @@
#pragma once
#include "rublon/json.hpp"
#include "rublon/utils.hpp"
#include <algorithm>
#include <set>
#include <string_view>
@ -8,9 +6,11 @@
#include <rublon/bits.hpp>
#include <rublon/error.hpp>
#include <rublon/json.hpp>
#include <rublon/memory.hpp>
#include <rublon/pam_action.hpp>
#include <rublon/session.hpp>
#include <rublon/utils.hpp>
#include <rublon/method/EMAIL.hpp>
#include <rublon/method/PUSH.hpp>
@ -135,6 +135,7 @@ class MethodSelect {
template < typename Array_t >
MethodSelect(Session & session, const Array_t & methodsEnabledInCore, int prompts, bool autopushPrompt)
: _session{session}, _prompts{prompts}, _autopushPrompt{autopushPrompt} {
rublon::log(LogLevel::Debug, "Checking what methods from core are supported");
using namespace std::string_view_literals;
_methodsAvailable.reserve(std::size(methodsEnabledInCore));
@ -175,10 +176,11 @@ class MethodSelect {
};
auto printAvailableMethods = [&]() -> tl::expected< int, MethodError > {
rublon::log(LogLevel::Debug, "TMP printing available methods");
int i{};
for(const auto & method : _methodsAvailable) {
if(method == "totp") {
if(_session.inInteractiveMode()) {
if(not _session.inInteractiveMode()) {
logMethodSkippedInteractive(method);
continue;
}
@ -198,7 +200,7 @@ class MethodSelect {
}
if(method == "yotp") {
if(_session.inInteractiveMode()) {
if(not _session.inInteractiveMode()) {
logMethodSkippedInteractive(method);
continue;
}
@ -210,7 +212,7 @@ class MethodSelect {
}
if(method == "sms") {
if(_session.inInteractiveMode()) {
if(not _session.inInteractiveMode()) {
logMethodSkippedInteractive(method);
continue;
}
@ -260,6 +262,7 @@ class MethodSelect {
};
const auto createMethod = [&](std::uint32_t methodid) -> tl::expected< PostMethod, MethodError > {
rublon::log(LogLevel::Debug, "Trace Create method %d", methods_id);
auto hasMethod = methods_id.find(methodid) != methods_id.end();
if(!hasMethod) {
log(LogLevel::Error, "User selected option %d, which is not correct", methodid);
@ -283,7 +286,7 @@ class MethodSelect {
log(LogLevel::Debug,
"Automatically selected first available non interactive authentication method: %s",
methods_names.at(key).c_str());
pam.print("Automatically selected first available non interactive authentication method: %s",
methods_names.at(key).c_str());
return key;
@ -301,6 +304,7 @@ class MethodSelect {
};
auto reducePromptCount = [&](int selected_method) -> tl::expected< uint32_t, MethodError > {
rublon::log(LogLevel::Debug, "Trace User has %d prompts available", prompts);
prompts--;
return selected_method;
};

View File

@ -21,7 +21,7 @@ class RublonFactory {
return tl::unexpected{ConfigurationError{}};
}
return Session{pam, config.value()};
return Session{pam, config.value(), false};
}
};

View File

@ -1,63 +1,51 @@
diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h
index e3e20dfb..ecd454dd 100644
index e3e20dfb..592c5678 100644
--- a/include/rapidjson/document.h
+++ b/include/rapidjson/document.h
@@ -99,15 +99,13 @@ struct GenericMember {
@@ -97,17 +97,20 @@ struct GenericMember {
\see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
*/
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
template <bool Const, typename Encoding, typename Allocator>
class GenericMemberIterator
- : public std::iterator<std::random_access_iterator_tag
- , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
+ {
: public std::iterator<std::random_access_iterator_tag
, typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
-
+
friend class GenericValue<Encoding,Allocator>;
template <bool, typename, typename> friend class GenericMemberIterator;
typedef GenericMember<Encoding,Allocator> PlainType;
typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
- typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
+#pragma GCC diagnostic pop
public:
//! Iterator type itself
@@ -116,13 +114,12 @@ public:
typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator;
//! Non-constant iterator type
typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
-
- //! Pointer to (const) GenericMember
- typedef typename BaseType::pointer Pointer;
- //! Reference to (const) GenericMember
- typedef typename BaseType::reference Reference;
- //! Signed integer type (e.g. \c ptrdiff_t)
- typedef typename BaseType::difference_type DifferenceType;
+
+ typedef ValueType value_type;
+ typedef ValueType * Pointer;
+ typedef ValueType & Reference;
+ typedef std::ptrdiff_t DifferenceType;
+ typedef std::random_access_iterator_tag iterator_category;
//! Default constructor (singular value)
/*! Creates an iterator pointing to no element.
@@ -1936,7 +1933,9 @@ private:
@@ -1936,7 +1939,10 @@ private:
if (count) {
GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
SetElementsPointer(e);
- std::memcpy(e, values, count * sizeof(GenericValue));
+ for(SizeType i=0;i<count;i++){
+ *e = values[i];
+ }
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wclass-memaccess"
std::memcpy(e, values, count * sizeof(GenericValue));
+#pragma GCC diagnostic pop
}
else
SetElementsPointer(0);
@@ -1949,7 +1948,9 @@ private:
@@ -1949,7 +1955,10 @@ private:
if (count) {
Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
SetMembersPointer(m);
- std::memcpy(m, members, count * sizeof(Member));
+ for(SizeType i=0;i<count;i++){
+ *m = members[i];
+ }
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wclass-memaccess"
std::memcpy(m, members, count * sizeof(Member));
+#pragma GCC diagnostic pop
}
else
SetMembersPointer(0);
diff --git a/package.json b/package.json
index 843463d7..cc6087a5 100644
Binary files a/package.json and b/package.json differ