Audacity 3.2.0
AuthorizationHandler.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 AuthorizationHandler.cpp
7
8 Dmitry Vedenko
9
10**********************************************************************/
12
13#include <chrono>
14#include <future>
15#include <optional>
16
17#include "OAuthService.h"
18#include "ServiceConfig.h"
19
25
26#include "CodeConversions.h"
27#include "HelpSystem.h"
28#include "MemoryX.h"
29
31{
32namespace
33{
35
36std::optional<AuthResult> WaitForAuth(
37 std::future<std::optional<AuthResult>> future,
39{
40 using namespace sync;
41
42 if (
43 future.wait_for(std::chrono::milliseconds { 100 }) !=
44 std::future_status::ready)
45 {
46 auto waitResult =
47 WaitForActionDialog {
48 project, XO("Waiting for audio.com"),
49 XO("An action on audio.com is required before you can continue. You can cancel this operation."),
50 false
51 }
52 .ShowDialog(
53 [&future]() -> DialogButtonIdentifier
54 {
55 if (
56 future.wait_for(std::chrono::milliseconds { 50 }) !=
57 std::future_status::ready)
58 return {};
59
60 return { L"done" };
61 });
62
63 if (waitResult == WaitForActionDialog::CancelButtonIdentifier())
65 }
66
67 if (GetOAuthService().HasAccessToken())
69
70 return future.get();
71}
72} // namespace
73
75{
76 return handler;
77}
78
81 const TranslatableString& alternativeActionLabel)
82{
83 using namespace sync;
84 auto& oauthService = GetOAuthService();
85
86 // Assume, that the token is valid
87 // Services will need to handle 403 errors and refresh the token
88 if (GetOAuthService().HasAccessToken())
89 return { AuthResult::Status::Authorised, {} };
90
92 auto popSuppress =
94
95 if (oauthService.HasRefreshToken())
96 {
97 std::promise<std::optional<AuthResult>> promise;
98
99 oauthService.ValidateAuth(
100 [&promise](auto...) { promise.set_value({}); }, trace, true);
101
102 if (auto waitResult = WaitForAuth(promise.get_future(), project))
103 return *waitResult;
104 }
105
106 auto linkResult =
107 sync::LinkAccountDialog { project, alternativeActionLabel }.ShowDialog();
108
109 if (linkResult == LinkAccountDialog::CancelButtonIdentifier())
110 return { AuthResult::Status::Cancelled, {} };
111
112 if (linkResult == LinkAccountDialog::AlternativeButtonIdentifier())
114
115 std::promise<std::optional<AuthResult>> promise;
116
117 auto authSubscription = oauthService.Subscribe(
118 [&promise](auto& result)
119 {
120 promise.set_value(
121 result.authorised ?
122 AuthResult { AuthResult::Status::Authorised, {} } :
124 std::string(result.errorMessage) });
125 });
126
128
129 auto waitResult = WaitForAuth(promise.get_future(), project);
130
131 if (waitResult)
132 return *waitResult;
133
134 return AuthResult { AuthResult::Status::Failure, {} };
135}
136
137AuthorizationHandler::AuthorizationHandler()
138 : mAuthStateChangedSubscription(GetOAuthService().Subscribe(
139 [this](const auto& message) { OnAuthStateChanged(message); }))
140{
141}
142
144{
145 ++mSuppressed;
146}
147
149{
150 assert(mSuppressed > 0);
151
152 if (mSuppressed > 0)
153 --mSuppressed;
154}
155
157 const AuthStateChangedMessage& message)
158{
159 if (mSuppressed > 0 || message.silent)
160 return;
161
162 if (!message.errorMessage.empty())
163 {
164 LinkFailedDialog dialog { nullptr, message.trace };
165 dialog.ShowModal();
166 }
167 else if (message.authorised)
168 {
169 LinkSucceededDialog dialog { nullptr };
170 dialog.ShowModal();
171 }
172}
173} // namespace audacity::cloud::audiocom
Declare functions to perform UTF-8 to std::wstring conversions.
AudiocomTrace
Definition: ExportUtils.h:27
XO("Cut/Copy/Paste")
const auto project
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static bool SignIn(wxWindow *parent, Mode mode=Mode::SignIn)
Holds a msgid for the translation catalog; may also bind format arguments.
void OnAuthStateChanged(const AuthStateChangedMessage &message)
std::optional< AuthResult > WaitForAuth(std::future< std::optional< AuthResult > > future, const AudacityProject *project)
TaggedIdentifier< DialogButtonIdentifierTag > DialogButtonIdentifier
AuthorizationHandler & GetAuthorizationHandler()
AuthResult PerformBlockingAuth(AudacityProject *project, AudiocomTrace trace, const TranslatableString &alternativeActionLabel)
OAuthService & GetOAuthService()
Returns the instance of the OAuthService.
Message that is sent when authorization state changes.
Definition: OAuthService.h:29
bool authorised
Flag that indicates if user is authorised.
Definition: OAuthService.h:36
std::string_view errorMessage
Error message returned by the server in case of oauth error.
Definition: OAuthService.h:33