File indexing completed on 2025-01-05 03:53:45
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2018-07-08 0007 * Description : Base class for web service talkers. 0008 * 0009 * SPDX-FileCopyrightText: 2018 by Thanh Trung Dinh <dinhthanhtrung1996 at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #ifndef DIGIKAM_WS_TALKER_H 0016 #define DIGIKAM_WS_TALKER_H 0017 0018 // Qt includes 0019 0020 #include <QtGlobal> 0021 #include <QList> 0022 #include <QPair> 0023 #include <QString> 0024 #include <QUrl> 0025 #include <QWidget> 0026 #include <QSettings> 0027 #include <QNetworkReply> 0028 #include <QNetworkAccessManager> 0029 #include <QMap> 0030 0031 // Local includes 0032 0033 #include "o0settingsstore.h" 0034 #include "wsitem.h" 0035 #include "wswizard.h" 0036 0037 using namespace Digikam; 0038 0039 namespace DigikamGenericUnifiedPlugin 0040 { 0041 0042 class WSTalker : public QObject 0043 { 0044 Q_OBJECT 0045 0046 public: 0047 0048 enum State 0049 { 0050 DEFAULT = 0, 0051 GETUSER, 0052 LISTALBUMS, 0053 CREATEALBUM, 0054 ADDPHOTO 0055 }; 0056 0057 public: 0058 0059 explicit WSTalker(QWidget* const parent); 0060 ~WSTalker(); 0061 0062 /* 0063 * Get ID of an existent user account saved when he logged in before, 0064 * knowing user name. 0065 */ 0066 QString getUserID(const QString& userName); 0067 0068 /* 0069 * Link user account (login). 0070 */ 0071 virtual void link(); 0072 0073 /* 0074 * Unlink user account (logout). 0075 */ 0076 virtual void unlink(); 0077 0078 /* 0079 * Return true if account is linked. 0080 */ 0081 virtual bool linked() const; 0082 0083 /* 0084 * This method load account that user chooses to login. If it exists and doesn't expire yet, 0085 * then obtain the saved token and pass the authentication process. Otherwise, relogin. 0086 */ 0087 virtual void authenticate(); 0088 0089 /* 0090 * Force user to login on web service login page. 0091 */ 0092 void reauthenticate(); 0093 0094 /* 0095 * Abort any network request realizing at the moment. 0096 */ 0097 void cancel(); 0098 0099 protected: 0100 0101 /* 0102 * Return a map of all information stored in the previous login of userName account. 0103 */ 0104 QMap<QString, QVariant> getUserAccountInfo(const QString& userName); 0105 0106 /* 0107 * Save all necessary information of user account to disk. That information will be retrieved 0108 * by getUserAccountInfo(userName) when needed. 0109 */ 0110 void saveUserAccount(const QString& userName, 0111 const QString& userID, 0112 long long int expire, 0113 const QString& accessToken, 0114 const QString& refreshToken = QString()); 0115 0116 /* 0117 * Remove all information of user account that was stored by saveUserAccount(...) 0118 * TODO: this method should be called when user uninstalls digiKam. 0119 */ 0120 void removeUserAccount(const QString& userName); 0121 0122 /* 0123 * Save as removeUserAccount(userName), but for all accounts. 0124 */ 0125 void removeAllAccounts(); 0126 0127 /* 0128 * A wrapper method of getUserAccountInfo(userName), but perform further verification 0129 * on account's validation and further operation in case that account is expired. 0130 */ 0131 bool loadUserAccount(const QString& userName); 0132 0133 /* 0134 * This method can be (and must be) reimplemented in derived class. Indeed, it will hard code 0135 * (at runtime) O2's settings (i.e accessToken, refreshToken, expired date and value of linked state). 0136 * It forces O2 to link to another account according to user's selection. Otherwise, O2 will 0137 * "remember" account from previous login and always link to that account, if an obligated reauthenticate 0138 * (unlink and then link) is not realized. 0139 */ 0140 virtual void resetTalker(const QString& expire, const QString& accessToken, const QString& refreshToken); 0141 0142 /* 0143 * Sort list of albums by ascending order of titles. 0144 */ 0145 virtual void sortAlbumsList(QList<WSAlbum>& albumsList); 0146 0147 /* 0148 * These methods are reimplemented in derived class and used to parse response of network requests 0149 * for user's information or APIs of web service. They will be called asynchronously when responses 0150 * for net request are received. 0151 */ 0152 virtual void parseResponseGetLoggedInUser(const QByteArray& data); 0153 virtual void parseResponseListAlbums(const QByteArray& data); 0154 virtual void parseResponseCreateAlbum(const QByteArray& data); 0155 virtual void parseResponseAddPhoto(const QByteArray& data); 0156 0157 /* 0158 * This method is called when authentication is complete. It should be reimplemented in derived class 0159 * and call saveUserAccount(...) inside. Here, we implement a minimised version so that derived class 0160 * can call it if needed. 0161 */ 0162 virtual void authenticationDone(int errCode, const QString& errMsg); 0163 0164 public: 0165 0166 /* 0167 * These methods are reimplemented in derived class, and will be used to make network requests 0168 * for user's information or APIs of web service. 0169 */ 0170 virtual void getLoggedInUser(); 0171 virtual void listAlbums(long long userID = 0); 0172 virtual void createNewAlbum(); 0173 virtual void addPhoto(const QString& imgPath, const QString& albumID, const QString& caption); 0174 0175 Q_SIGNALS: 0176 0177 void signalBusy(bool val); 0178 void signalOpenBrowser(const QUrl& url); 0179 void signalCloseBrowser(); 0180 void signalAuthenticationComplete(bool); 0181 void signalCreateAlbumDone(int errCode, const QString& errMsg, const QString& newAlbumId); 0182 void signalListAlbumsDone(int errCode, const QString& errMsg, const QList <WSAlbum>& albumsList); 0183 void signalAddPhotoDone(int errCode, const QString& errMsg); 0184 0185 protected Q_SLOTS: 0186 0187 /* 0188 * Slots for signals from O2 authentication flow 0189 */ 0190 void slotFinished(QNetworkReply* reply); 0191 void slotOpenBrowser(const QUrl& url); 0192 void slotCloseBrowser(); 0193 virtual void slotLinkingFailed(); 0194 virtual void slotLinkingSucceeded(); 0195 0196 /* 0197 * This is a particular slot, only used in case that digiKam will intercept O2 authentication flow, 0198 * catch all navigation from web service, and the final url whose fragment contains accessToken 0199 * and other necessary information. digiKam then parses the response to get accessToken and join back to 0200 * O2's authentication flow by calling this method. 0201 * 0202 * Facebook is a web service where this approach is used, 0203 * because the callback url is not http://127.0.0.1/ // krazy:exclude=insecurenet 0204 */ 0205 virtual void slotResponseTokenReceived(const QMap<QString, QString>& rep); 0206 0207 protected: 0208 0209 QNetworkAccessManager* m_netMngr; 0210 QNetworkReply* m_reply; 0211 0212 State m_state; 0213 0214 QSettings* m_settings; 0215 O0SettingsStore* m_store; 0216 0217 QString m_userName; 0218 0219 WSWizard* m_wizard; 0220 }; 0221 0222 } // namespace DigikamGenericUnifiedPlugin 0223 0224 #endif // DIGIKAM_WS_TALKER_H