Created
November 24, 2021 17:07
-
-
Save pminiszewski/cd6d388b356ade1ba097bfc14f71984a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The algorithm | |
// 1. Create http request | |
// 2. Attach the access token to the http request headers | |
// 3. If there is no access token stored in memory: | |
// 3.1 Notify user that username/password must be provided | |
// 2.2 On User input create another request to the authentication server, retrieve access token and store it in memory. | |
// 4. Attach token, execute request and return results | |
// This is a GUI app, so user will be presented with some modal window asking for login and password. | |
//How http requests are constructed? | |
rxcpp::observable<messages::account::TestAccount> Account::get_account_info() | |
{ | |
rxcpp::observable<>::just<SessionPtr>(cpr::Url{"https://api.example.com/account"}) //prepare request object | |
.subscribe_on(rxcpp::observe_on_new_thread()) | |
.lift<http::SessionPtr>(operators::auth::AttachJwtToSession(registry_)) // attach token header | |
.lift<cpr::Response>(http::get(registry_)) // Execute request | |
.lift<TestAccount>(http::parse_body<TestAccount>()) // convert response to object | |
.observe_on(registry_.ctx<core::RuntimeContext>().rx_run_loop) | |
; | |
} | |
//GLOBAL DEFINES | |
std::string jwt_string_; | |
rx::subjects::subject<bool> event_login_requested; | |
rx::subjects::subject<messages::auth0::Auth0TokenResponse> event_login_succeeded; | |
rx::subjects::subject<sdk::api::UserCredentialsLoginPassword> event_credentials_received; | |
//The operator implementation | |
rx::subscriber<http::SessionPtr> AttachJwtToSession::operator()(rx::subscriber<http::SessionPtr> _session_sub) const | |
{ | |
std::string jwt_string = jwt_string_; | |
return rx::make_subscriber<http::SessionPtr>( | |
[=](http::SessionPtr _session) | |
{ | |
if (verify_valid_jwt(jwt_string)) | |
{ | |
_session->UpdateHeader({{"Authorization", "Bearer " + jwt_string}}); | |
_session_sub.on_next(_session); | |
} | |
else | |
{ | |
event_login_requested.get_subscriber().on_next(true); //bring up the login modal window | |
std::string u, p; | |
// This is called by user upon providing login/password via login popup. | |
event_credentials_received.get_observable(). | |
as_blocking(). | |
subscribe([&u, &p](sdk::api::UserCredentialsLoginPassword _creds){ | |
u = _creds.login; | |
p = _creds.password; | |
}); | |
cpr::Response _response = cpr::Post( | |
cpr::Url{"https://auth.example.com/oauth/token"}, | |
cpr::Payload{ | |
{"username",u.c_str()}, | |
{"password", p.c_str()}}); | |
if (_response.status_code == 200) | |
{ | |
using namespace messages::auth0; | |
using namespace google::protobuf::util; | |
Auth0TokenResponse res_msg; | |
if (JsonStringToMessage(_response.text, &res_msg).ok()) //Authentication succeeed | |
{ | |
jwt_string_ = res_msg.access_token(); | |
event_login_succeeded.get_subscriber().on_next(res_msg); | |
_session->UpdateHeader({{"Authorization", "Bearer " + res_msg.access_token()}}); | |
_session_sub.on_next(_session); | |
} | |
} | |
// Some error handling goes here | |
} | |
}, | |
[=](const rxu::error_ptr &_err) | |
{ _session_sub.on_error(_err); }, | |
[=]() | |
{ _session_sub.on_completed(); }); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment