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
24
25#include "CodeConversions.h"
26#include "HelpSystem.h"
27#include "MemoryX.h"
28
30{
31namespace
32{
34
35std::optional<AuthResult> WaitForAuth(
36 std::future<std::optional<AuthResult>> future,
38{
39 using namespace sync;
40
41 if (
42 future.wait_for(std::chrono::milliseconds { 100 }) !=
43 std::future_status::ready)
44 {
45 auto waitResult =
46 WaitForActionDialog {
47 project, XO("Waiting for audio.com"),
48 XO("An action on audio.com is required before you can continue. You can cancel this operation."),
49 false
50 }
51 .ShowDialog(
52 [&future]() -> DialogButtonIdentifier
53 {
54 if (
55 future.wait_for(std::chrono::milliseconds { 50 }) !=
56 std::future_status::ready)
57 return {};
58
59 return { L"done" };
60 });
61
62 if (waitResult == WaitForActionDialog::CancelButtonIdentifier())
64 }
65
66 if (GetOAuthService().HasAccessToken())
68
69 return future.get();
70}
71} // namespace
72
74{
75 return handler;
76}
77
80 const TranslatableString& alternativeActionLabel)
81{
82 using namespace sync;
83 auto& oauthService = GetOAuthService();
84
85 // Assume, that the token is valid
86 // Services will need to handle 403 errors and refresh the token
87 if (GetOAuthService().HasAccessToken())
88 return { AuthResult::Status::Authorised, {} };
89
91 auto popSuppress =
93
94 if (oauthService.HasRefreshToken())
95 {
96 std::promise<std::optional<AuthResult>> promise;
97
98 oauthService.ValidateAuth(
99 [&promise](auto...) { promise.set_value({}); }, trace, true);
100
101 if (auto waitResult = WaitForAuth(promise.get_future(), project))
102 return *waitResult;
103 }
104
105 auto linkResult =
106 sync::LinkAccountDialog { project, alternativeActionLabel }.ShowDialog();
107
108 if (linkResult == LinkAccountDialog::CancelButtonIdentifier())
109 return { AuthResult::Status::Cancelled, {} };
110
111 if (linkResult == LinkAccountDialog::AlternativeButtonIdentifier())
113
114 std::promise<std::optional<AuthResult>> promise;
115
116 auto authSubscription = oauthService.Subscribe(
117 [&promise](auto& result)
118 {
119 promise.set_value(
120 result.authorised ?
121 AuthResult { AuthResult::Status::Authorised, {} } :
123 std::string(result.errorMessage) });
124 });
125
127 { audacity::ToWXString(GetServiceConfig().GetOAuthLoginPage(trace)) });
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
Holds a msgid for the translation catalog; may also bind format arguments.
void OnAuthStateChanged(const AuthStateChangedMessage &message)
bool OpenInDefaultBrowser(const wxString &url)
Open an URL in default browser.
Definition: BasicUI.cpp:246
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.
const ServiceConfig & GetServiceConfig()
Returns the instance of the ServiceConfig.
wxString ToWXString(const std::string &str)
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