account.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /*
  2. * Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. * for more details.
  13. */
  14. #ifndef SERVERCONNECTION_H
  15. #define SERVERCONNECTION_H
  16. #include <QByteArray>
  17. #include <QUrl>
  18. #include <QNetworkCookie>
  19. #include <QNetworkRequest>
  20. #include <QSslSocket>
  21. #include <QSslCertificate>
  22. #include <QSslConfiguration>
  23. #include <QSslCipher>
  24. #include <QSslError>
  25. #include <QSharedPointer>
  26. #ifndef TOKEN_AUTH_ONLY
  27. #include <QPixmap>
  28. #endif
  29. #include "common/utility.h"
  30. #include <memory>
  31. #include "capabilities.h"
  32. #include "clientsideencryption.h"
  33. #include "syncfileitem.h"
  34. class QSettings;
  35. class QNetworkReply;
  36. class QUrl;
  37. class QNetworkAccessManager;
  38. namespace QKeychain {
  39. class Job;
  40. class WritePasswordJob;
  41. class ReadPasswordJob;
  42. }
  43. namespace OCC {
  44. class AbstractCredentials;
  45. class Account;
  46. using AccountPtr = QSharedPointer<Account>;
  47. class AccessManager;
  48. class SimpleNetworkJob;
  49. class PushNotifications;
  50. class UserStatusConnector;
  51. class SyncJournalDb;
  52. /**
  53. * @brief Reimplement this to handle SSL errors from libsync
  54. * @ingroup libsync
  55. */
  56. class AbstractSslErrorHandler
  57. {
  58. public:
  59. virtual ~AbstractSslErrorHandler() = default;
  60. virtual bool handleErrors(QList<QSslError>, const QSslConfiguration &conf, QList<QSslCertificate> *, AccountPtr) = 0;
  61. };
  62. /**
  63. * @brief The Account class represents an account on an ownCloud Server
  64. * @ingroup libsync
  65. *
  66. * The Account has a name and url. It also has information about credentials,
  67. * SSL errors and certificates.
  68. */
  69. class OWNCLOUDSYNC_EXPORT Account : public QObject
  70. {
  71. Q_OBJECT
  72. Q_PROPERTY(QString id MEMBER _id)
  73. Q_PROPERTY(QString davUser MEMBER _davUser)
  74. Q_PROPERTY(QString displayName MEMBER _displayName)
  75. Q_PROPERTY(QString prettyName READ prettyName NOTIFY prettyNameChanged)
  76. Q_PROPERTY(QUrl url MEMBER _url)
  77. Q_PROPERTY(bool e2eEncryptionKeysGenerationAllowed MEMBER _e2eEncryptionKeysGenerationAllowed)
  78. public:
  79. static AccountPtr create();
  80. ~Account() override;
  81. AccountPtr sharedFromThis();
  82. [[nodiscard]] AccountPtr sharedFromThis() const;
  83. /**
  84. * The user that can be used in dav url.
  85. *
  86. * This can very well be different frome the login user that's
  87. * stored in credentials()->user().
  88. */
  89. [[nodiscard]] QString davUser() const;
  90. void setDavUser(const QString &newDavUser);
  91. [[nodiscard]] QString davDisplayName() const;
  92. void setDavDisplayName(const QString &newDisplayName);
  93. #ifndef TOKEN_AUTH_ONLY
  94. [[nodiscard]] QImage avatar() const;
  95. void setAvatar(const QImage &img);
  96. #endif
  97. /// The name of the account as shown in the toolbar
  98. [[nodiscard]] QString displayName() const;
  99. /// User id in a form 'user@example.de, optionally port is added (if it is not 80 or 443)
  100. [[nodiscard]] QString userIdAtHostWithPort() const;
  101. /// The name of the account that is displayed as nicely as possible,
  102. /// e.g. the actual name of the user (John Doe). If this cannot be
  103. /// provided, defaults to davUser (e.g. johndoe)
  104. [[nodiscard]] QString prettyName() const;
  105. [[nodiscard]] QColor accentColor() const;
  106. [[nodiscard]] QColor headerColor() const;
  107. [[nodiscard]] QColor headerTextColor() const;
  108. /// The internal id of the account.
  109. [[nodiscard]] QString id() const;
  110. /** Server url of the account */
  111. void setUrl(const QUrl &url);
  112. [[nodiscard]] QUrl url() const { return _url; }
  113. /// Adjusts _userVisibleUrl once the host to use is discovered.
  114. void setUserVisibleHost(const QString &host);
  115. /**
  116. * @brief The possibly themed dav path for the account. It has
  117. * a trailing slash.
  118. * @returns the (themeable) dav path for the account.
  119. */
  120. [[nodiscard]] QString davPath() const;
  121. /**
  122. * @brief The possibly themed dav path root for the account. It has
  123. * no trailing slash.
  124. * @returns the (themeable) dav path for the account.
  125. */
  126. [[nodiscard]] QString davPathRoot() const;
  127. /** Returns webdav entry URL, based on url() */
  128. [[nodiscard]] QUrl davUrl() const;
  129. /** Returns the legacy permalink url for a file.
  130. *
  131. * This uses the old way of manually building the url. New code should
  132. * use the "privatelink" property accessible via PROPFIND.
  133. */
  134. [[nodiscard]] QUrl deprecatedPrivateLinkUrl(const QByteArray &numericFileId) const;
  135. /** Holds the accounts credentials */
  136. [[nodiscard]] AbstractCredentials *credentials() const;
  137. void setCredentials(AbstractCredentials *cred);
  138. /** Create a network request on the account's QNAM.
  139. *
  140. * Network requests in AbstractNetworkJobs are created through
  141. * this function. Other places should prefer to use jobs or
  142. * sendRequest().
  143. */
  144. QNetworkReply *sendRawRequest(const QByteArray &verb,
  145. const QUrl &url,
  146. QNetworkRequest req = QNetworkRequest(),
  147. QIODevice *data = nullptr);
  148. QNetworkReply *sendRawRequest(const QByteArray &verb,
  149. const QUrl &url, QNetworkRequest req, const QByteArray &data);
  150. QNetworkReply *sendRawRequest(const QByteArray &verb,
  151. const QUrl &url, QNetworkRequest req, QHttpMultiPart *data);
  152. /** Create and start network job for a simple one-off request.
  153. *
  154. * More complicated requests typically create their own job types.
  155. */
  156. SimpleNetworkJob *sendRequest(const QByteArray &verb,
  157. const QUrl &url,
  158. QNetworkRequest req = QNetworkRequest(),
  159. QIODevice *data = nullptr);
  160. /** The ssl configuration during the first connection */
  161. QSslConfiguration getOrCreateSslConfig();
  162. [[nodiscard]] QSslConfiguration sslConfiguration() const { return _sslConfiguration; }
  163. void setSslConfiguration(const QSslConfiguration &config);
  164. // Because of bugs in Qt, we use this to store info needed for the SSL Button
  165. QSslCipher _sessionCipher;
  166. QByteArray _sessionTicket;
  167. QList<QSslCertificate> _peerCertificateChain;
  168. /** The certificates of the account */
  169. [[nodiscard]] QList<QSslCertificate> approvedCerts() const { return _approvedCerts; }
  170. void setApprovedCerts(const QList<QSslCertificate> certs);
  171. void addApprovedCerts(const QList<QSslCertificate> certs);
  172. // Usually when a user explicitly rejects a certificate we don't
  173. // ask again. After this call, a dialog will again be shown when
  174. // the next unknown certificate is encountered.
  175. void resetRejectedCertificates();
  176. // pluggable handler
  177. void setSslErrorHandler(AbstractSslErrorHandler *handler);
  178. // To be called by credentials only, for storing username and the like
  179. [[nodiscard]] QVariant credentialSetting(const QString &key) const;
  180. void setCredentialSetting(const QString &key, const QVariant &value);
  181. /** Assign a client certificate */
  182. void setCertificate(const QByteArray certficate = QByteArray(), const QString privateKey = QString());
  183. /** Access the server capabilities */
  184. [[nodiscard]] const Capabilities &capabilities() const;
  185. void setCapabilities(const QVariantMap &caps);
  186. /** Access the server version
  187. *
  188. * For servers >= 10.0.0, this can be the empty string until capabilities
  189. * have been received.
  190. */
  191. [[nodiscard]] QString serverVersion() const;
  192. /** Server version for easy comparison.
  193. *
  194. * Example: serverVersionInt() >= makeServerVersion(11, 2, 3)
  195. *
  196. * Will be 0 if the version is not available yet.
  197. */
  198. [[nodiscard]] int serverVersionInt() const;
  199. static constexpr int makeServerVersion(const int majorVersion, const int minorVersion, const int patchVersion) {
  200. return (majorVersion << 16) + (minorVersion << 8) + patchVersion;
  201. };
  202. void setServerVersion(const QString &version);
  203. /** Whether the server is too old.
  204. *
  205. * Not supporting server versions is a gradual process. There's a hard
  206. * compatibility limit (see ConnectionValidator) that forbids connecting
  207. * to extremely old servers. And there's a weak "untested, not
  208. * recommended, potentially dangerous" limit, that users might want
  209. * to go beyond.
  210. *
  211. * This function returns true if the server is beyond the weak limit.
  212. */
  213. [[nodiscard]] bool serverVersionUnsupported() const;
  214. [[nodiscard]] bool isUsernamePrefillSupported() const;
  215. [[nodiscard]] bool isChecksumRecalculateRequestSupported() const;
  216. [[nodiscard]] int checksumRecalculateServerVersionMinSupportedMajor() const;
  217. /** True when the server connection is using HTTP2 */
  218. bool isHttp2Supported() { return _http2Supported; }
  219. void setHttp2Supported(bool value) { _http2Supported = value; }
  220. void clearCookieJar();
  221. void lendCookieJarTo(QNetworkAccessManager *guest);
  222. QString cookieJarPath();
  223. void resetNetworkAccessManager();
  224. QNetworkAccessManager *networkAccessManager();
  225. QSharedPointer<QNetworkAccessManager> sharedNetworkAccessManager();
  226. /// Called by network jobs on credential errors, emits invalidCredentials()
  227. void handleInvalidCredentials();
  228. ClientSideEncryption* e2e();
  229. /// Used in RemoteWipe
  230. void retrieveAppPassword();
  231. void writeAppPasswordOnce(QString appPassword);
  232. void deleteAppPassword();
  233. void deleteAppToken();
  234. /// Direct Editing
  235. // Check for the directEditing capability
  236. void fetchDirectEditors(const QUrl &directEditingURL, const QString &directEditingETag);
  237. void setupUserStatusConnector();
  238. void trySetupPushNotifications();
  239. [[nodiscard]] PushNotifications *pushNotifications() const;
  240. void setPushNotificationsReconnectInterval(int interval);
  241. [[nodiscard]] std::shared_ptr<UserStatusConnector> userStatusConnector() const;
  242. void setLockFileState(const QString &serverRelativePath,
  243. SyncJournalDb * const journal,
  244. const SyncFileItem::LockStatus lockStatus);
  245. SyncFileItem::LockStatus fileLockStatus(SyncJournalDb * const journal,
  246. const QString &folderRelativePath) const;
  247. bool fileCanBeUnlocked(SyncJournalDb * const journal, const QString &folderRelativePath) const;
  248. void setTrustCertificates(bool trustCertificates);
  249. [[nodiscard]] bool trustCertificates() const;
  250. void setE2eEncryptionKeysGenerationAllowed(bool allowed);
  251. [[nodiscard]] bool e2eEncryptionKeysGenerationAllowed() const;
  252. public slots:
  253. /// Used when forgetting credentials
  254. void clearQNAMCache();
  255. void slotHandleSslErrors(QNetworkReply *, QList<QSslError>);
  256. signals:
  257. /// Emitted whenever there's network activity
  258. void propagatorNetworkActivity();
  259. /// Triggered by handleInvalidCredentials()
  260. void invalidCredentials();
  261. void credentialsFetched(OCC::AbstractCredentials *credentials);
  262. void credentialsAsked(OCC::AbstractCredentials *credentials);
  263. /// Forwards from QNetworkAccessManager::proxyAuthenticationRequired().
  264. void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
  265. // e.g. when the approved SSL certificates changed
  266. void wantsAccountSaved(OCC::Account *acc);
  267. void serverVersionChanged(OCC::Account *account, const QString &newVersion, const QString &oldVersion);
  268. void accountChangedAvatar();
  269. void accountChangedDisplayName();
  270. void prettyNameChanged();
  271. /// Used in RemoteWipe
  272. void appPasswordRetrieved(QString);
  273. void pushNotificationsReady(OCC::Account *account);
  274. void pushNotificationsDisabled(OCC::Account *account);
  275. void userStatusChanged();
  276. void serverUserStatusChanged();
  277. void capabilitiesChanged();
  278. void lockFileSuccess();
  279. void lockFileError(const QString&);
  280. protected Q_SLOTS:
  281. void slotCredentialsFetched();
  282. void slotCredentialsAsked();
  283. void slotDirectEditingRecieved(const QJsonDocument &json);
  284. private:
  285. Account(QObject *parent = nullptr);
  286. void setSharedThis(AccountPtr sharedThis);
  287. static QString davPathBase();
  288. bool _trustCertificates = false;
  289. bool _e2eEncryptionKeysGenerationAllowed = false;
  290. QWeakPointer<Account> _sharedThis;
  291. QString _id;
  292. QString _davUser;
  293. QString _displayName;
  294. QTimer _pushNotificationsReconnectTimer;
  295. #ifndef TOKEN_AUTH_ONLY
  296. QImage _avatarImg;
  297. #endif
  298. QMap<QString, QVariant> _settingsMap;
  299. QUrl _url;
  300. /** If url to use for any user-visible urls.
  301. *
  302. * If the server configures overwritehost this can be different from
  303. * the connection url in _url. We retrieve the visible host through
  304. * the ocs/v1.php/config endpoint in ConnectionValidator.
  305. */
  306. QUrl _userVisibleUrl;
  307. QList<QSslCertificate> _approvedCerts;
  308. QSslConfiguration _sslConfiguration;
  309. Capabilities _capabilities;
  310. QString _serverVersion;
  311. QScopedPointer<AbstractSslErrorHandler> _sslErrorHandler;
  312. QSharedPointer<QNetworkAccessManager> _am;
  313. QScopedPointer<AbstractCredentials> _credentials;
  314. bool _http2Supported = false;
  315. /// Certificates that were explicitly rejected by the user
  316. QList<QSslCertificate> _rejectedCertificates;
  317. static QString _configFileName;
  318. ClientSideEncryption _e2e;
  319. /// Used in RemoteWipe
  320. bool _wroteAppPassword = false;
  321. friend class AccountManager;
  322. // Direct Editing
  323. QString _lastDirectEditingETag;
  324. PushNotifications *_pushNotifications = nullptr;
  325. std::shared_ptr<UserStatusConnector> _userStatusConnector;
  326. /* IMPORTANT - remove later - FIXME MS@2019-12-07 -->
  327. * TODO: For "Log out" & "Remove account": Remove client CA certs and KEY!
  328. *
  329. * Disabled as long as selecting another cert is not supported by the UI.
  330. *
  331. * Being able to specify a new certificate is important anyway: expiry etc.
  332. *
  333. * We introduce this dirty hack here, to allow deleting them upon Remote Wipe.
  334. */
  335. public:
  336. void setRemoteWipeRequested_HACK() { _isRemoteWipeRequested_HACK = true; }
  337. bool isRemoteWipeRequested_HACK() { return _isRemoteWipeRequested_HACK; }
  338. private:
  339. bool _isRemoteWipeRequested_HACK = false;
  340. // <-- FIXME MS@2019-12-07
  341. };
  342. }
  343. Q_DECLARE_METATYPE(OCC::AccountPtr)
  344. Q_DECLARE_METATYPE(OCC::Account *)
  345. #endif //SERVERCONNECTION_H