1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4//
5// W A R N I N G
6// -------------
7//
8// This file is not part of the Qt API. It exists for the convenience
9// of the Network Access API. This header file may change from
10// version to version without notice, or even be removed.
11//
12// We mean it.
13//
14
15#ifndef QABSTRACTOAUTH2_P_H
16#define QABSTRACTOAUTH2_P_H
17
18#include <chrono>
19#include <optional>
20
21#include <private/qabstractoauth_p.h>
22
23#include <QtNetworkAuth/qoauthglobal.h>
24#include <QtNetworkAuth/qabstractoauth2.h>
25
26#include <QtCore/qchronotimer.h>
27#include <QtCore/qurl.h>
28#include <QtCore/qstring.h>
29#include <QtCore/qpointer.h>
30
31#include <QtNetwork/qnetworkreply.h>
32
33#include <utility>
34
35QT_BEGIN_NAMESPACE
36
37class QNetworkAccessManager;
38
39class QAbstractOAuth2Private : public QAbstractOAuthPrivate
40{
41 Q_DECLARE_PUBLIC(QAbstractOAuth2)
42
43public:
44 QAbstractOAuth2Private(const std::pair<QString, QString> &clientCredentials,
45 const QUrl &authorizationUrl, QNetworkAccessManager *manager = nullptr);
46 ~QAbstractOAuth2Private();
47
48 void setExpiresAt(const QDateTime &expiration);
49 void setGrantedScopeTokens(const QSet<QByteArray> &tokens);
50 static QString joinedScope(const QSet<QByteArray> &scopeTokens);
51 static QSet<QByteArray> splitScope(QStringView scope);
52 static bool checkRequestedScopeTokensValid(const QSet<QByteArray> &tokens);
53 static bool checkRequestedScopeTokenValid(QByteArrayView token);
54 static void warnOnInvalidScopeToken(QStringView token);
55 static QString generateRandomState();
56 static QString generateNonce();
57 QNetworkRequest createRequest(QUrl url, const QVariantMap *parameters = nullptr);
58 bool authorizationShouldIncludeNonce() const;
59 void setIdToken(const QString &token);
60 void _q_tokenRequestFailed(QAbstractOAuth::Error error, const QString& errorString);
61 void _q_tokenRequestFinished(const QVariantMap &values);
62 bool handleRfcErrorResponseIfPresent(const QVariantMap &data);
63 struct RequestAndBody
64 {
65 QNetworkRequest request;
66 QByteArray body;
67 };
68 [[nodiscard]] RequestAndBody createRefreshRequestAndBody(const QUrl &url);
69
70 Q_DECL_COLD_FUNCTION
71 void logAuthorizationStageWarning(QLatin1StringView message);
72 Q_DECL_COLD_FUNCTION
73 void logAuthorizationStageWarning(QLatin1StringView message, int detail);
74 Q_DECL_COLD_FUNCTION
75 void logTokenStageWarning(QLatin1StringView message);
76
77 struct CallerInfo {
78 QPointer<const QObject> contextObject = nullptr;
79 QtPrivate::SlotObjUniquePtr slot;
80 };
81 CallerInfo networkRequestModifier;
82 void callNetworkRequestModifier(QNetworkRequest &request, QAbstractOAuth::Stage stage);
83 bool verifyThreadAffinity(const QObject *contextObject);
84
85 void initializeRefreshHandling();
86 void updateRefreshTimer(bool clientSideUpdate);
87
88 QString clientIdentifierSharedKey;
89 QSet<QByteArray> requestedScopeTokens;
90 QSet<QByteArray> grantedScopeTokens;
91 QString state = generateRandomState();
92 QString userAgent = QStringLiteral("QtOAuth/1.0 (+https://www.qt.io)");
93 QString responseType;
94 const QString bearerFormat = QStringLiteral("Bearer %1"); // Case sensitive
95 QDateTime expiresAtUtc;
96 QString refreshToken;
97 std::chrono::seconds refreshLeadTime = std::chrono::seconds::zero();
98 QChronoTimer refreshTimer;
99#ifndef QOAUTH2_NO_LEGACY_SCOPE
100 QString legacyScope;
101 bool legacyScopeWasSetByUser = false;
102#endif
103 bool autoRefresh = false;
104 QAbstractOAuth2::NonceMode nonceMode = QAbstractOAuth2::NonceMode::Automatic;
105 QString nonce;
106 QString idToken;
107 QString tokenType;
108 QUrl tokenUrl;
109 // RFC (6749) doesn't state any maximum value for the lifetime, use long just in case
110 qlonglong tokenLifetime = 0;
111#ifndef QT_NO_SSL
112 std::optional<QSslConfiguration> sslConfiguration;
113#endif
114};
115
116namespace QtOAuth2RfcKeywords
117{
118 inline constexpr auto accessToken = QLatin1StringView("access_token");
119 inline constexpr auto apiKey = QLatin1StringView("api_key");
120 inline constexpr auto clientIdentifier = QLatin1StringView("client_id");
121 inline constexpr auto clientSharedSecret = QLatin1StringView("client_secret");
122 inline constexpr auto code = QLatin1StringView("code");
123 inline constexpr auto error = QLatin1StringView("error");
124 inline constexpr auto errorDescription = QLatin1StringView("error_description");
125 inline constexpr auto errorUri = QLatin1StringView("error_uri");
126 inline constexpr auto expiresIn = QLatin1StringView("expires_in");
127 inline constexpr auto grantType = QLatin1StringView("grant_type");
128 inline constexpr auto redirectUri = QLatin1StringView("redirect_uri");
129 inline constexpr auto refreshToken = QLatin1StringView("refresh_token");
130 inline constexpr auto responseType = QLatin1StringView("response_type");
131 inline constexpr auto scope = QLatin1StringView("scope");
132 inline constexpr auto state = QLatin1StringView("state");
133 inline constexpr auto tokenType = QLatin1StringView("token_type");
134 inline constexpr auto codeVerifier = QLatin1StringView("code_verifier");
135 inline constexpr auto codeChallenge = QLatin1StringView("code_challenge");
136 inline constexpr auto codeChallengeMethod = QLatin1StringView("code_challenge_method");
137 inline constexpr auto nonce = QLatin1StringView("nonce");
138 inline constexpr auto idToken = QLatin1StringView("id_token");
139 inline constexpr auto deviceCode = QLatin1StringView("device_code");
140 inline constexpr auto userCode = QLatin1StringView("user_code");
141 // RFC keyword is verification_uri[_complete], but some servers use 'url' (note L)
142 // https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
143 inline constexpr auto verificationUri = QLatin1StringView("verification_uri");
144 inline constexpr auto verificationUrl = QLatin1StringView("verification_url");
145 inline constexpr auto completeVerificationUri = QLatin1StringView("verification_uri_complete");
146 inline constexpr auto completeVerificationUrl = QLatin1StringView("verification_url_complete");
147 inline constexpr auto interval = QLatin1StringView("interval");
148}
149
150QT_END_NAMESPACE
151
152#endif // QABSTRACTOAUTH2_P_H
153

source code of qtnetworkauth/src/oauth/qabstractoauth2_p.h