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