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
79 AudacityProject* project, const TranslatableString& alternativeActionLabel)
80{
81 using namespace sync;
82 auto& oauthService = GetOAuthService();
83
84 // Assume, that the token is valid
85 // Services will need to handle 403 errors and refresh the token
86 if (GetOAuthService().HasAccessToken())
87 return { AuthResult::Status::Authorised, {} };
88
90 auto popSuppress =
92
93 if (oauthService.HasRefreshToken())
94 {
95 std::promise<std::optional<AuthResult>> promise;
96
97 oauthService.ValidateAuth(
98 [&promise](auto...) { promise.set_value({}); }, true);
99
100 if (auto waitResult = WaitForAuth(promise.get_future(), project))
101 return *waitResult;
102 }
103
104 auto linkResult =
105 sync::LinkAccountDialog { project, alternativeActionLabel }.ShowDialog();
106
107 if (linkResult == LinkAccountDialog::CancelButtonIdentifier())
108 return { AuthResult::Status::Cancelled, {} };
109
110 if (linkResult == LinkAccountDialog::AlternativeButtonIdentifier())
112
113 std::promise<std::optional<AuthResult>> promise;
114
115 auto authSubscription = oauthService.Subscribe(
116 [&promise](auto& result)
117 {
118 promise.set_value(
119 result.authorised ?
120 AuthResult { AuthResult::Status::Authorised, {} } :
122 std::string(result.errorMessage) });
123 });
124
126 { audacity::ToWXString(GetServiceConfig().GetOAuthLoginPage()) });
127
128 auto waitResult = WaitForAuth(promise.get_future(), project);
129
130 if (waitResult)
131 return *waitResult;
132
133 return AuthResult { AuthResult::Status::Failure, {} };
134}
135
136AuthorizationHandler::AuthorizationHandler()
137 : mAuthStateChangedSubscription(GetOAuthService().Subscribe(
138 [this](const auto& message) { OnAuthStateChanged(message); }))
139{
140}
141
143{
144 ++mSuppressed;
145}
146
148{
149 assert(mSuppressed > 0);
150
151 if (mSuppressed > 0)
152 --mSuppressed;
153}
154
156 const AuthStateChangedMessage& message)
157{
158 if (mSuppressed > 0 || message.silent)
159 return;
160
161 if (!message.errorMessage.empty())
162 {
163 LinkFailedDialog dialog { nullptr };
164 dialog.ShowModal();
165 }
166 else if (message.authorised)
167 {
168 LinkSucceededDialog dialog { nullptr };
169 dialog.ShowModal();
170 }
171}
172} // namespace audacity::cloud::audiocom
Declare functions to perform UTF-8 to std::wstring conversions.
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:245
std::optional< AuthResult > WaitForAuth(std::future< std::optional< AuthResult > > future, const AudacityProject *project)
TaggedIdentifier< DialogButtonIdentifierTag > DialogButtonIdentifier
AuthorizationHandler & GetAuthorizationHandler()
OAuthService & GetOAuthService()
Returns the instance of the OAuthService.
AuthResult PerformBlockingAuth(AudacityProject *project, const TranslatableString &alternativeActionLabel)
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:27
bool authorised
Flag that indicates if user is authorised.
Definition: OAuthService.h:33
std::string_view errorMessage
Error message returned by the server in case of oauth error.
Definition: OAuthService.h:31