File indexing completed on 2024-11-24 04:43:52
0001 /* 0002 SPDX-FileCopyrightText: 2018 Krzysztof Nowicki <krissn@op.pl> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <functional> 0010 0011 #include <QBuffer> 0012 #include <QDialog> 0013 #include <QHBoxLayout> 0014 #include <QIcon> 0015 #include <QJsonDocument> 0016 #include <QJsonObject> 0017 #include <QLoggingCategory> 0018 #include <QPointer> 0019 #include <QUrl> 0020 #include <QWidget> 0021 0022 #include <KLocalizedString> 0023 Q_DECLARE_LOGGING_CATEGORY(EWSCLI_LOG) 0024 0025 namespace Mock 0026 { 0027 class QWebEngineUrlRequestJob : public QObject 0028 { 0029 Q_OBJECT 0030 public: 0031 explicit QWebEngineUrlRequestJob(const QUrl &url, QObject *parent) 0032 : QObject(parent) 0033 , mUrl(url) 0034 { 0035 } 0036 0037 ~QWebEngineUrlRequestJob() override = default; 0038 0039 QUrl requestUrl() const; 0040 0041 QUrl mUrl; 0042 }; 0043 0044 class QWebEngineUrlRequestInfo : public QObject 0045 { 0046 Q_OBJECT 0047 public: 0048 explicit QWebEngineUrlRequestInfo(const QUrl &url, QObject *parent) 0049 : QObject(parent) 0050 , mBlocked(false) 0051 , mUrl(url) 0052 { 0053 } 0054 0055 ~QWebEngineUrlRequestInfo() override = default; 0056 0057 QUrl requestUrl() const; 0058 void block(bool shouldBlock); 0059 void setHttpHeader(const QByteArray &name, const QByteArray &value); 0060 void redirect(const QUrl &url); 0061 0062 bool mBlocked; 0063 QUrl mUrl; 0064 }; 0065 0066 class QWebEngineUrlRequestInterceptor : public QObject 0067 { 0068 Q_OBJECT 0069 public: 0070 explicit QWebEngineUrlRequestInterceptor(QObject *parent); 0071 ~QWebEngineUrlRequestInterceptor() override; 0072 0073 virtual void interceptRequest(QWebEngineUrlRequestInfo &info) = 0; 0074 }; 0075 0076 class QWebEngineUrlSchemeHandler : public QObject 0077 { 0078 Q_OBJECT 0079 public: 0080 QWebEngineUrlSchemeHandler(QObject *parent); 0081 ~QWebEngineUrlSchemeHandler() override; 0082 0083 virtual void requestStarted(QWebEngineUrlRequestJob *request) = 0; 0084 }; 0085 0086 class QWebEngineProfile : public QObject 0087 { 0088 Q_OBJECT 0089 public: 0090 explicit QWebEngineProfile(QObject *parent = nullptr); 0091 ~QWebEngineProfile() override; 0092 0093 void setHttpUserAgent(const QString &ua); 0094 void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor); 0095 void installUrlSchemeHandler(QByteArray const &scheme, QWebEngineUrlSchemeHandler *handler); 0096 Q_SIGNALS: 0097 void logEvent(const QString &event); 0098 0099 public: 0100 QString mUserAgent; 0101 QWebEngineUrlRequestInterceptor *mInterceptor; 0102 QString mScheme; 0103 QWebEngineUrlSchemeHandler *mHandler; 0104 }; 0105 0106 class QWebEnginePage : public QObject 0107 { 0108 Q_OBJECT 0109 public: 0110 explicit QWebEnginePage(QWebEngineProfile *profile, QObject *parent = nullptr); 0111 ~QWebEnginePage() override; 0112 Q_SIGNALS: 0113 void logEvent(const QString &event); 0114 0115 public: 0116 QWebEngineProfile *mProfile; 0117 }; 0118 0119 class QWebEngineView : public QWidget 0120 { 0121 Q_OBJECT 0122 public: 0123 using AuthFunc = std::function<void(const QUrl &, QVariantMap &)>; 0124 0125 explicit QWebEngineView(QWidget *parent); 0126 ~QWebEngineView() override; 0127 0128 void load(const QUrl &url); 0129 void setPage(QWebEnginePage *page); 0130 void stop(); 0131 0132 void setAuthFunction(const AuthFunc &func); 0133 void setRedirectUri(const QString &uri); 0134 0135 static QPointer<QWebEngineView> instance; 0136 Q_SIGNALS: 0137 void logEvent(const QString &event); 0138 0139 protected: 0140 void simulatePageLoad(const QUrl &url); 0141 0142 QWebEnginePage *mPage; 0143 QString mRedirectUri; 0144 AuthFunc mAuthFunction; 0145 }; 0146 0147 class QNetworkRequest 0148 { 0149 public: 0150 enum KnownHeaders { 0151 ContentTypeHeader, 0152 }; 0153 }; 0154 0155 class QNetworkReply : public QBuffer 0156 { 0157 Q_OBJECT 0158 public: 0159 enum NetworkError { 0160 NoError = 0, 0161 }; 0162 Q_ENUM(NetworkError) 0163 0164 explicit QNetworkReply(QObject *parent) 0165 : QBuffer(parent) 0166 { 0167 } 0168 0169 ~QNetworkReply() override = default; 0170 0171 NetworkError error() const; 0172 QVariant header(QNetworkRequest::KnownHeaders header) const; 0173 0174 QMap<QNetworkRequest::KnownHeaders, QVariant> mHeaders; 0175 NetworkError mError; 0176 }; 0177 0178 class QAbstractOAuthReplyHandler : public QObject 0179 { 0180 Q_OBJECT 0181 public: 0182 QAbstractOAuthReplyHandler(QObject *parent); 0183 ~QAbstractOAuthReplyHandler() override; 0184 0185 virtual QString callback() const = 0; 0186 virtual void networkReplyFinished(QNetworkReply *reply) = 0; 0187 Q_SIGNALS: 0188 void replyDataReceived(const QByteArray &data); 0189 void tokensReceived(const QVariantMap &tokens); 0190 }; 0191 0192 class QAbstractOAuth : public QObject 0193 { 0194 Q_OBJECT 0195 public: 0196 Q_ENUMS(Stage) 0197 enum class Stage { 0198 RequestingTemporaryCredentials, 0199 RequestingAuthorization, 0200 RequestingAccessToken, 0201 RefreshingAccessToken, 0202 }; 0203 0204 Q_ENUMS(Status) 0205 enum class Status { 0206 NotAuthenticated, 0207 TemporaryCredentialsReceived, 0208 Granted, 0209 RefreshingToken, 0210 }; 0211 0212 explicit QAbstractOAuth(QObject *parent); 0213 ~QAbstractOAuth() override = default; 0214 0215 void setReplyHandler(QAbstractOAuthReplyHandler *handler); 0216 void setAuthorizationUrl(const QUrl &url); 0217 void setClientIdentifier(const QString &identifier); 0218 void setModifyParametersFunction(const std::function<void(QAbstractOAuth::Stage, QMap<QString, QVariant> *)> &func); 0219 QString token() const; 0220 void setToken(const QString &token); 0221 Status status() const; 0222 Q_SIGNALS: 0223 void authorizeWithBrowser(const QUrl &url); 0224 void granted(); 0225 void logEvent(const QString &event); 0226 0227 protected: 0228 QAbstractOAuthReplyHandler *mReplyHandler; 0229 QUrl mAuthUrl; 0230 QString mClientId; 0231 std::function<void(QAbstractOAuth::Stage, QMap<QString, QVariant> *)> mModifyParamsFunc; 0232 QString mToken; 0233 QString mRefreshToken; 0234 QUrl mTokenUrl; 0235 QString mResource; 0236 Status mStatus; 0237 }; 0238 0239 class QAbstractOAuth2 : public QAbstractOAuth 0240 { 0241 Q_OBJECT 0242 public: 0243 explicit QAbstractOAuth2(QObject *parent); 0244 ~QAbstractOAuth2() override = default; 0245 0246 QString refreshToken() const; 0247 void setRefreshToken(const QString &token); 0248 0249 Q_SIGNALS: 0250 void authorizationCallbackReceived(QMap<QString, QVariant> const ¶ms); 0251 void error(const QString &error, const QString &errorDescription, const QUrl &uri); 0252 }; 0253 0254 class QOAuth2AuthorizationCodeFlow : public QAbstractOAuth2 0255 { 0256 Q_OBJECT 0257 public: 0258 using TokenFunc = std::function<QNetworkReply::NetworkError(QString &, QMap<QNetworkRequest::KnownHeaders, QVariant> &)>; 0259 0260 explicit QOAuth2AuthorizationCodeFlow(QObject *parent = nullptr); 0261 ~QOAuth2AuthorizationCodeFlow() override; 0262 0263 void setAccessTokenUrl(const QUrl &url); 0264 void grant(); 0265 void refreshAccessToken(); 0266 0267 QString redirectUri() const; 0268 void setTokenFunction(const TokenFunc &func); 0269 void setState(const QString &state); 0270 0271 static QUrlQuery mapToSortedQuery(QMap<QString, QVariant> const &map); 0272 0273 static QPointer<QOAuth2AuthorizationCodeFlow> instance; 0274 0275 protected: 0276 void authCallbackReceived(QMap<QString, QVariant> const ¶ms); 0277 void replyDataCallbackReceived(const QByteArray &data); 0278 void tokenCallbackReceived(const QVariantMap &tokens); 0279 void doRefreshAccessToken(); 0280 0281 TokenFunc mTokenFunc; 0282 QString mState; 0283 }; 0284 0285 class KJob : public QObject 0286 { 0287 Q_OBJECT 0288 public: 0289 explicit KJob(QObject *) 0290 { 0291 } 0292 0293 ~KJob() override = default; 0294 0295 int error() const 0296 { 0297 return 0; 0298 } 0299 0300 const QString &errorString() const; 0301 Q_SIGNALS: 0302 void result(KJob *job); 0303 }; 0304 0305 class EwsPKeyAuthJob : public KJob 0306 { 0307 Q_OBJECT 0308 public: 0309 explicit EwsPKeyAuthJob(const QUrl &pkeyUri, const QString &certFile, const QString &keyFile, const QString &keyPassword, QObject *parent); 0310 ~EwsPKeyAuthJob() override = default; 0311 void start() 0312 { 0313 } 0314 0315 const QUrl &resultUri() const; 0316 QString getAuthHeader(); 0317 }; 0318 0319 QString browserDisplayRequestString(); 0320 QString modifyParamsAuthString(const QString &clientId, const QString &returnUri, const QString &state); 0321 QString 0322 authUrlString(const QString &authUrl, const QString &clientId, const QString &returnUri, const QString &email, const QString &resource, const QString &state); 0323 QString authorizeWithBrowserString(const QString &url); 0324 QString loadWebPageString(const QString &url); 0325 QString interceptRequestString(const QString &url); 0326 QString interceptRequestBlockedString(bool blocked); 0327 QString authorizationCallbackReceivedString(const QString &code); 0328 QString modifyParamsTokenString(const QString &clientId, const QString &returnUri, const QString &code); 0329 QString networkReplyFinishedString(const QString &data); 0330 QString replyDataCallbackString(const QString &data); 0331 QString tokenCallbackString(const QString &accessToken, 0332 const QString &refreshToken, 0333 const QString &idToken, 0334 quint64 time, 0335 unsigned int tokenLifetime, 0336 unsigned int extTokenLifetime, 0337 const QString &resource); 0338 QString requestWalletMapString(); 0339 }