account.h 15 KB

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