#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