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 &params);
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 &params);
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 }