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 15 16 #ifndef ACCOUNTINFO_H 17 #define ACCOUNTINFO_H 18 19 #include <QByteArray> 20 #include <QElapsedTimer> 21 #include <QPointer> 22 #include "connectionvalidator.h" 23 #include "creds/abstractcredentials.h" 24 #include <memory> 25 26 class QSettings; 27 28 namespace OCC { 29 30 class AccountState; 31 class Account; 32 33 typedef QExplicitlySharedDataPointer<AccountState> AccountStatePtr; 34 35 /** 36 * @brief Extra info about an ownCloud server account. 37 * @ingroup gui 38 */ 39 class AccountState : public QObject, public QSharedData 40 { 41 Q_OBJECT 42 Q_PROPERTY(AccountPtr account MEMBER _account) 43 44 public: 45 enum State { 46 /// Not even attempting to connect, most likely because the 47 /// user explicitly signed out or cancelled a credential dialog. 48 SignedOut, 49 50 /// Account would like to be connected but hasn't heard back yet. 51 Disconnected, 52 53 /// The account is successfully talking to the server. 54 Connected, 55 56 /// There's a temporary problem with talking to the server, 57 /// don't bother the user too much and try again. 58 ServiceUnavailable, 59 60 /// Similar to ServiceUnavailable, but we know the server is down 61 /// for maintenance 62 MaintenanceMode, 63 64 /// Could not communicate with the server for some reason. 65 /// We assume this may resolve itself over time and will try 66 /// again automatically. 67 NetworkError, 68 69 /// Server configuration error. (For example: unsupported version) 70 ConfigurationError, 71 72 /// We are currently asking the user for credentials 73 AskingCredentials 74 }; 75 76 /// The actual current connectivity status. 77 typedef ConnectionValidator::Status ConnectionStatus; 78 79 /// Use the account as parent 80 explicit AccountState(AccountPtr account); 81 ~AccountState() override; 82 83 /** Creates an account state from settings and an Account object. 84 * 85 * Use from AccountManager with a prepared QSettings object only. 86 */ 87 static AccountState *loadFromSettings(AccountPtr account, QSettings &settings); 88 89 /** Writes account state information to settings. 90 * 91 * It does not write the Account data. 92 */ 93 void writeToSettings(QSettings &settings); 94 95 AccountPtr account() const; 96 97 ConnectionStatus connectionStatus() const; 98 QStringList connectionErrors() const; 99 100 State state() const; 101 static QString stateString(State state); 102 103 bool isSignedOut() const; 104 105 /** A user-triggered sign out which disconnects, stops syncs 106 * for the account and forgets the password. */ 107 void signOutByUi(); 108 109 /** Tries to connect from scratch. 110 * 111 * Does nothing for signed out accounts. 112 * Connected accounts will be disconnected and try anew. 113 * Disconnected accounts will go to checkConnectivity(). 114 * 115 * Useful for when network settings (proxy) change. 116 */ 117 void freshConnectionAttempt(); 118 119 /// Move from SignedOut state to Disconnected (attempting to connect) 120 void signIn(); 121 122 bool isConnected() const; 123 124 /** Returns a new settings object for this account, already in the right groups. */ 125 std::unique_ptr<QSettings> settings(); 126 127 /** Mark the timestamp when the last successful ETag check happened for 128 * this account. 129 * The checkConnectivity() method uses the timestamp to save a call to 130 * the server to validate the connection if the last successful etag job 131 * was not so long ago. 132 */ 133 void tagLastSuccessfullETagRequest(); 134 135 public slots: 136 /// Triggers a ping to the server to update state and 137 /// connection status and errors. 138 void checkConnectivity(); 139 140 private: 141 void setState(State state); 142 143 signals: 144 void stateChanged(State state); 145 void isConnectedChanged(); 146 147 protected Q_SLOTS: 148 void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList &errors); 149 void slotInvalidCredentials(); 150 void slotCredentialsFetched(AbstractCredentials *creds); 151 void slotCredentialsAsked(AbstractCredentials *creds); 152 153 private: 154 AccountPtr _account; 155 State _state; 156 ConnectionStatus _connectionStatus; 157 QStringList _connectionErrors; 158 bool _waitingForNewCredentials; 159 QElapsedTimer _timeSinceLastETagCheck; 160 QPointer<ConnectionValidator> _connectionValidator; 161 162 /** 163 * Starts counting when the server starts being back up after 503 or 164 * maintenance mode. The account will only become connected once this 165 * timer exceeds the _maintenanceToConnectedDelay value. 166 */ 167 QElapsedTimer _timeSinceMaintenanceOver; 168 169 /** 170 * Milliseconds for which to delay reconnection after 503/maintenance. 171 */ 172 int _maintenanceToConnectedDelay; 173 }; 174 } 175 176 Q_DECLARE_METATYPE(OCC::AccountState *) 177 Q_DECLARE_METATYPE(OCC::AccountStatePtr) 178 179 #endif //ACCOUNTINFO_H 180