-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathoauthcredentialssetupwizardstate.cpp
More file actions
117 lines (98 loc) · 4.78 KB
/
oauthcredentialssetupwizardstate.cpp
File metadata and controls
117 lines (98 loc) · 4.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
* Copyright (C) Fabian Müller <fmueller@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "gui/newwizard/states/oauthcredentialssetupwizardstate.h"
#include "gui/newwizard/jobs/webfingeruserinfojobfactory.h"
#include "gui/newwizard/pages/oauthcredentialssetupwizardpage.h"
namespace OCC::Wizard {
OAuthCredentialsSetupWizardState::OAuthCredentialsSetupWizardState(SetupWizardContext *context)
: AbstractSetupWizardState(context)
{
const auto authServerUrl = [this]() {
auto authServerUrl = _context->accountBuilder().webFingerAuthenticationServerUrl();
if (!authServerUrl.isEmpty()) {
return authServerUrl;
}
return _context->accountBuilder().serverUrl();
}();
auto oAuth = new OAuth(authServerUrl, _context->accessManager(), {}, this);
// Use the desktop-specific client_id if provided by webfinger
// See: https://github.com/opencloud-eu/desktop/issues/246
const QString desktopClientId = _context->accountBuilder().webFingerDesktopClientId();
if (!desktopClientId.isEmpty()) {
oAuth->setClientId(desktopClientId);
}
_page = new OAuthCredentialsSetupWizardPage(oAuth, authServerUrl);
connect(oAuth, &OAuth::result, this, [oAuth, this](OAuth::Result result, const QString &token, const QString &refreshToken) {
_context->window()->slotStartTransition();
// bring window up top again, as the browser may have been raised in front of it
_context->window()->raise();
auto finish = [result, token, refreshToken, oAuth, this] {
oAuth->deleteLater();
switch (result) {
case OAuth::Result::LoggedIn: {
_context->accountBuilder().setAuthenticationStrategy(
std::make_unique<OAuth2AuthenticationStrategy>(token, refreshToken, oAuth->dynamicRegistrationData(), oAuth->idToken()));
Q_EMIT evaluationSuccessful();
break;
}
case OAuth::Result::Error: {
Q_EMIT evaluationFailed(tr("Error while trying to log in to OAuth2-enabled server."));
break;
}
case OAuth::Result::ErrorInsecureUrl: {
Q_EMIT evaluationFailed(tr("Oauth2 authentication requires a secured connection."));
break;
}
}
};
// SECOND WEBFINGER CALL (authenticated):
// This discovers which OpenCloud instance(s) the authenticated user has access to.
// Uses the OAuth bearer token and resource="acct:me@{host}".
// Looking for: rel="http://webfinger.opencloud/rel/server-instance"
// See issue #271 for why we perform WebFinger twice.
// Backend WebFinger docs: https://github.com/opencloud-eu/opencloud/blob/main/services/webfinger/README.md
if (!_context->accountBuilder().webFingerAuthenticationServerUrl().isEmpty()) {
auto *job = Jobs::WebFingerInstanceLookupJobFactory(_context->accessManager(), token).startJob(_context->accountBuilder().serverUrl(), this);
connect(job, &CoreJob::finished, this, [finish, job, this]() {
if (!job->success()) {
Q_EMIT evaluationFailed(QStringLiteral("Failed to look up instances: %1").arg(job->errorMessage()));
} else {
const auto instanceUrls = qvariant_cast<QVector<QUrl>>(job->result());
if (instanceUrls.isEmpty()) {
Q_EMIT evaluationFailed(QStringLiteral("Server returned empty list of instances"));
} else {
_context->accountBuilder().setWebFingerInstances(instanceUrls);
}
}
finish();
});
} else {
finish();
}
});
// the implementation moves to the next state automatically once ready, no user interaction needed
_context->window()->disableNextButton();
oAuth->startAuthentication();
}
SetupWizardState OAuthCredentialsSetupWizardState::state() const
{
return SetupWizardState::CredentialsState;
}
void OAuthCredentialsSetupWizardState::evaluatePage()
{
// the next button is disabled anyway, since moving forward is controlled by the OAuth object signal handlers
// therefore, this method should never ever be called
Q_UNREACHABLE();
}
} // OCC::Wizard