Cavoke  1.1.0
A Platform for creating and hosting multiplayer turn-based board games
Loading...
Searching...
No Matches
AuthenticationManager.cpp
1#include "AuthenticationManager.h"
2#include <QDesktopServices>
3#include <QOAuthHttpServerReplyHandler>
4#include <QUrlQuery>
5#include <QtDebug>
6
7//#if defined(INCLUDE_OWN_QT_KEYCHAIN)
8//#include "keychain.h"
9//#else
10//#include <qt5keychain/keychain.h>
11//#endif
12
13void cavoke::auth::AuthenticationManager::init() {
14 oauth2.setAuthorizationUrl(QUrl(authorizationUrl));
15 oauth2.setAccessTokenUrl(QUrl(accessTokenUrl));
16 oauth2.setClientIdentifier(clientId);
17 oauth2.setScope(scope);
18
19 connect(&oauth2, &QOAuth2AuthorizationCodeFlow::statusChanged,
20 [=](QAbstractOAuth::Status status) {
21 if (status == QAbstractOAuth::Status::Granted) {
22 qDebug() << "Now authenticated!!";
23 writeSecurePassword(refresh_token_profile,
24 oauth2.refreshToken());
25 if (oauth2.token().isEmpty()) {
26 qWarning() << "Authentication completed successfully, "
27 "but token is empty!! Forcing a relogin";
28 relogin();
29 }
30 emit authenticated();
31 } else if (status == QAbstractOAuth::Status::NotAuthenticated) {
32 qWarning() << "Unauthenticated";
33 }
34 });
35 oauth2.setModifyParametersFunction(
36 [&](QAbstractOAuth::Stage stage, auto *parameters) {
37 if (stage == QAbstractOAuth::Stage::RequestingAuthorization)
38 parameters->insert("audience", audience);
39 });
40 connect(&oauth2, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, this,
41 [&](const QUrl &url) {
42 // logout link with redirect to authorization
43 QUrl route{logoutUrl};
44 route.setQuery(QUrlQuery{
45 {"returnTo", QUrl::toPercentEncoding(url.toEncoded())}});
46 QDesktopServices::openUrl(route);
47 });
48 readSecurePassword(refresh_token_profile,
49 [&](const QString &refresh_token) {
50 qDebug() << "Loaded refresh token from Keychain!";
51 oauth2.setRefreshToken(refresh_token);
52 oauth2.refreshAccessToken();
53 });
54}
55bool cavoke::auth::AuthenticationManager::checkAuthStatus() {
56 return !oauth2.token().isEmpty();
57}
58void cavoke::auth::AuthenticationManager::writeSecurePassword(
59 const QString &profile,
60 const QString &pass) {
61 // FIXME: move to qkeychain
62 settings.setValue(profile, pass);
63 // auto *job = new QKeychain::WritePasswordJob("cavoke_keychain");
64 // job->setAutoDelete(false);
65 // job->setInsecureFallback(false);
66 // job->setKey(profile);
67 // job->setTextData(pass);
68 // connect(job, &QKeychain::WritePasswordJob::finished, this,
69 // [](QKeychain::Job *job) {
70 // if (job->error()) {
71 // qWarning() << job->errorString();
72 // }
73 // job->deleteLater();
74 // });
75 // job->start();
76}
77template <typename L>
78void cavoke::auth::AuthenticationManager::readSecurePassword(
79 const QString &profile,
80 L callback) {
81 // FIXME: move to qkeychain
82 callback(settings.value(profile).toString());
83 // auto *job = new QKeychain::ReadPasswordJob("cavoke_keychain");
84 // job->setAutoDelete(false);
85 // job->setInsecureFallback(false);
86 // job->setKey(profile);
87 // connect(job, &QKeychain::ReadPasswordJob::finished, this,
88 // [=](QKeychain::Job *job) {
89 // if (job->error()) {
90 // qWarning() << job->errorString();
91 // }
92 // auto readJob = dynamic_cast<QKeychain::ReadPasswordJob
93 // *>(job); callback(readJob->textData());
94 // job->deleteLater();
95 // });
96 // job->start();
97}
98void cavoke::auth::AuthenticationManager::deleteSecurePassword(
99 const QString &profile) {
100 // FIXME: move to qkeychain
101 settings.setValue(profile, "");
102 // auto *job = new QKeychain::DeletePasswordJob("cavoke_keychain");
103 // job->setAutoDelete(false);
104 // job->setInsecureFallback(false);
105 // job->setKey(profile);
106 // job->setProperty("profile", profile);
107 // connect(job, &QKeychain::WritePasswordJob::finished, this,
108 // [](QKeychain::Job *job) {
109 // if (job->error()) {
110 // qWarning() << job->errorString();
111 // }
112 // job->deleteLater();
113 // });
114 // job->start();
115}
116
117void cavoke::auth::AuthenticationManager::relogin() {
118 deleteSecurePassword(refresh_token_profile);
119 oauth2.setRefreshToken("");
120 // Immediately asks user to relogin
121 // Terrible solution, couldn't find anything better
122 // At least he can decline, so fine....
123 oauth2.grant();
124}
125
126const QString cavoke::auth::AuthenticationManager::authorizationUrl =
127 "https://cavoke.eu.auth0.com/authorize";
128const QString cavoke::auth::AuthenticationManager::accessTokenUrl =
129 "https://cavoke.eu.auth0.com/oauth/token";
130const QString cavoke::auth::AuthenticationManager::logoutUrl =
131 "https://cavoke.eu.auth0.com/v2/logout";
132const QString cavoke::auth::AuthenticationManager::clientId =
133 "yxkEiSikGF6JSaFwIikeLQlUNAUUR0ak";
134const QString cavoke::auth::AuthenticationManager::scope =
135 "identity sessions profile users offline_access";
136const QString cavoke::auth::AuthenticationManager::audience =
137 "https://develop.api.cavoke.wlko.me"; // NOTE: should not equal to HOST, as
138 // this must be registered as API
139 // endpoint. Basically don't change
140 // this.
141const QString cavoke::auth::AuthenticationManager::refresh_token_profile =
142 "cavoke_profiles_refresh";