File indexing completed on 2024-12-22 04:57:54

0001 /*
0002     SPDX-License-Identifier: BSD-2-Clause
0003 */
0004 
0005 #pragma once
0006 
0007 #include <QNetworkAccessManager>
0008 #include <QNetworkReply>
0009 
0010 #include "o0abstractstore.h"
0011 #include "o0baseauth.h"
0012 #include "o2reply.h"
0013 
0014 class O2ReplyServer;
0015 
0016 /// Simple OAuth2 authenticator.
0017 class O2 : public O0BaseAuth
0018 {
0019     Q_OBJECT
0020     Q_ENUMS(GrantFlow)
0021 
0022 public:
0023     /// Authorization flow types.
0024     enum GrantFlow {
0025         GrantFlowAuthorizationCode, ///< @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1
0026         GrantFlowImplicit, ///< @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.2
0027         GrantFlowResourceOwnerPasswordCredentials,
0028     };
0029 
0030     /// Authorization flow.
0031     Q_PROPERTY(GrantFlow grantFlow READ grantFlow WRITE setGrantFlow NOTIFY grantFlowChanged)
0032     GrantFlow grantFlow() const;
0033     void setGrantFlow(GrantFlow value);
0034 
0035     /// Resource owner username.
0036     /// O2 instances with the same (username, password) share the same "linked" and "token" properties.
0037     Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged)
0038     QString username() const;
0039     void setUsername(const QString &value);
0040 
0041     /// Resource owner password.
0042     /// O2 instances with the same (username, password) share the same "linked" and "token" properties.
0043     Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged)
0044     QString password() const;
0045     void setPassword(const QString &value);
0046 
0047     /// Scope of authentication.
0048     Q_PROPERTY(QString scope READ scope WRITE setScope NOTIFY scopeChanged)
0049     QString scope() const;
0050     void setScope(const QString &value);
0051 
0052     /// Localhost policy. By default it's value is http://127.0.0.1:%1/, however some services may
0053     /// require the use of http://localhost:%1/ or any other value.
0054     Q_PROPERTY(QString localhostPolicy READ localhostPolicy WRITE setLocalhostPolicy)
0055     QString localhostPolicy() const;
0056     void setLocalhostPolicy(const QString &value);
0057 
0058     /// API key.
0059     Q_PROPERTY(QString apiKey READ apiKey WRITE setApiKey)
0060     QString apiKey() const;
0061     void setApiKey(const QString &value);
0062 
0063     /// Page content on local host after successful oauth.
0064     /// Provide it in case you do not want to close the browser, but display something
0065     Q_PROPERTY(QByteArray replyContent READ replyContent WRITE setReplyContent)
0066     QByteArray replyContent() const;
0067     void setReplyContent(const QByteArray &value);
0068 
0069     /// Allow ignoring SSL errors?
0070     /// E.g. SurveyMonkey fails on Mac due to SSL error. Ignoring the error circumvents the problem
0071     Q_PROPERTY(bool ignoreSslErrors READ ignoreSslErrors WRITE setIgnoreSslErrors)
0072     bool ignoreSslErrors();
0073     void setIgnoreSslErrors(bool ignoreSslErrors);
0074 
0075     /// Request URL.
0076     Q_PROPERTY(QString requestUrl READ requestUrl WRITE setRequestUrl NOTIFY requestUrlChanged)
0077     QString requestUrl() const;
0078     void setRequestUrl(const QString &value);
0079 
0080     /// Token request URL.
0081     Q_PROPERTY(QString tokenUrl READ tokenUrl WRITE setTokenUrl NOTIFY tokenUrlChanged)
0082     QString tokenUrl();
0083     void setTokenUrl(const QString &value);
0084 
0085     /// Token refresh URL.
0086     Q_PROPERTY(QString refreshTokenUrl READ refreshTokenUrl WRITE setRefreshTokenUrl NOTIFY refreshTokenUrlChanged)
0087     QString refreshTokenUrl();
0088     void setRefreshTokenUrl(const QString &value);
0089 
0090 public:
0091     /// Constructor.
0092     /// @param  parent  Parent object.
0093     explicit O2(QObject *parent = nullptr);
0094 
0095     /// Get authentication code.
0096     QString code() const;
0097 
0098     /// Get refresh token.
0099     QString refreshToken();
0100 
0101     /// Get token expiration time (seconds from Epoch).
0102     int expires();
0103 
0104 public Q_SLOTS:
0105     /// Authenticate.
0106     Q_INVOKABLE void link() override;
0107 
0108     /// De-authenticate.
0109     Q_INVOKABLE void unlink() override;
0110 
0111     /// Refresh token.
0112     Q_INVOKABLE void refresh();
0113 
0114 Q_SIGNALS:
0115     /// Emitted when a token refresh has been completed or failed.
0116     void refreshFinished(QNetworkReply::NetworkError error);
0117 
0118     // Property change signals
0119     void grantFlowChanged();
0120     void scopeChanged();
0121     void usernameChanged();
0122     void passwordChanged();
0123     void requestUrlChanged();
0124     void refreshTokenUrlChanged();
0125     void tokenUrlChanged();
0126 
0127 protected Q_SLOTS:
0128     /// Handle verification response.
0129     virtual void onVerificationReceived(const QMultiMap<QString, QString> &);
0130 
0131     /// Handle completion of a token request.
0132     virtual void onTokenReplyFinished();
0133 
0134     /// Handle failure of a token request.
0135     virtual void onTokenReplyError(QNetworkReply::NetworkError error);
0136 
0137     /// Handle completion of a refresh request.
0138     virtual void onRefreshFinished();
0139 
0140     /// Handle failure of a refresh request.
0141     virtual void onRefreshError(QNetworkReply::NetworkError error);
0142 
0143 protected:
0144     /// Build HTTP request body.
0145     QByteArray buildRequestBody(const QMap<QString, QString> &parameters);
0146 
0147     /// Set authentication code.
0148     void setCode(const QString &v);
0149 
0150     /// Set refresh token.
0151     void setRefreshToken(const QString &v);
0152 
0153     /// Set token expiration time.
0154     void setExpires(int v);
0155 
0156 protected:
0157     QString username_;
0158     QString password_;
0159     QUrl requestUrl_;
0160     QUrl tokenUrl_;
0161     QUrl refreshTokenUrl_;
0162     QString scope_;
0163     QString code_;
0164     QString localhostPolicy_;
0165     QString apiKey_;
0166     QNetworkAccessManager *manager_ = nullptr;
0167     O2ReplyServer *replyServer_ = nullptr;
0168     O2ReplyList timedReplies_;
0169     GrantFlow grantFlow_;
0170 };