1/*
2 * Copyright (C) by Klaas Freitag <freitag@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#ifndef CONNECTIONVALIDATOR_H
16#define CONNECTIONVALIDATOR_H
17
18#include "owncloudlib.h"
19#include <QObject>
20#include <QStringList>
21#include <QVariantMap>
22#include <QNetworkReply>
23#include "accountfwd.h"
24
25namespace OCC {
26
27/**
28 * This is a job-like class to check that the server is up and that we are connected.
29 * There are two entry points: checkServerAndAuth and checkAuthentication
30 * checkAuthentication is the quick version that only does the propfind
31 * while checkServerAndAuth is doing the 4 calls.
32 *
33 * We cannot use the capabilites call to test the login and the password because of
34 * https://github.com/owncloud/core/issues/12930
35 *
36 * Here follows the state machine
37
38\code{.unparsed}
39*---> checkServerAndAuth (check status.php)
40 Will asynchronously check for system proxy (if using system proxy)
41 And then invoke slotCheckServerAndAuth
42 CheckServerJob
43 |
44 +-> slotNoStatusFound --> X
45 |
46 +-> slotJobTimeout --> X
47 |
48 +-> slotStatusFound --+--> X (if credentials are still missing)
49 |
50 +---------------------------+
51 |
52*-+-> checkAuthentication (PROPFIND on root)
53 PropfindJob
54 |
55 +-> slotAuthFailed --> X
56 |
57 +-> slotAuthSuccess --+--> X (depending if coming from checkServerAndAuth or not)
58 |
59 +---------------------------+
60 |
61 +-> checkServerCapabilities --------------v (in parallel)
62 JsonApiJob (cloud/capabilities) JsonApiJob (ocs/v1.php/config)
63 | +-> ocsConfigReceived
64 +-> slotCapabilitiesRecieved -+
65 |
66 +-----------------------------------+
67 |
68 +-> fetchUser
69 PropfindJob
70 |
71 +-> slotUserFetched
72 AvatarJob
73 |
74 +-> slotAvatarImage --> reportResult()
75
76 \endcode
77 */
78class ConnectionValidator : public QObject
79{
80 Q_OBJECT
81public:
82 explicit ConnectionValidator(AccountPtr account, QObject *parent = 0);
83
84 enum Status {
85 Undefined,
86 Connected,
87 NotConfigured,
88 ServerVersionMismatch, // The server version is too old
89 CredentialsNotReady, // Credentials aren't ready
90 CredentialsWrong, // AuthenticationRequiredError
91 SslError, // SSL handshake error, certificate rejected by user?
92 StatusNotFound, // Error retrieving status.php
93 ServiceUnavailable, // 503 on authed request
94 MaintenanceMode, // maintenance enabled in status.php
95 Timeout // actually also used for other errors on the authed request
96 };
97 Q_ENUM(Status);
98
99 // How often should the Application ask this object to check for the connection?
100 enum { DefaultCallingIntervalMsec = 32 * 1000 };
101
102public slots:
103 /// Checks the server and the authentication.
104 void checkServerAndAuth();
105 void systemProxyLookupDone(const QNetworkProxy &proxy);
106
107 /// Checks authentication only.
108 void checkAuthentication();
109
110signals:
111 void connectionResult(ConnectionValidator::Status status, const QStringList &errors);
112
113protected slots:
114 void slotCheckServerAndAuth();
115
116 void slotStatusFound(const QUrl &url, const QJsonObject &info);
117 void slotNoStatusFound(QNetworkReply *reply);
118 void slotJobTimeout(const QUrl &url);
119
120 void slotAuthFailed(QNetworkReply *reply);
121 void slotAuthSuccess();
122
123 void slotCapabilitiesRecieved(const QJsonDocument &);
124 void slotUserFetched(const QJsonDocument &);
125#ifndef TOKEN_AUTH_ONLY
126 void slotAvatarImage(const QImage &img);
127#endif
128
129private:
130 void reportResult(Status status);
131 void checkServerCapabilities();
132 void fetchUser();
133 static void ocsConfigReceived(const QJsonDocument &json, AccountPtr account);
134
135 /** Sets the account's server version
136 *
137 * Returns false and reports ServerVersionMismatch for very old servers.
138 */
139 bool setAndCheckServerVersion(const QString &version);
140
141 QStringList _errors;
142 AccountPtr _account;
143 bool _isCheckingServerAndAuth;
144};
145}
146
147#endif // CONNECTIONVALIDATOR_H
148