1 | /* |
2 | * Copyright (C) by Klaas Freitag <freitag@owncloud.com> |
3 | * Copyright (C) by Daniel Molkentin <danimo@owncloud.com> |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, but |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
13 | * for more details. |
14 | */ |
15 | |
16 | #ifndef NETWORKJOBS_H |
17 | #define NETWORKJOBS_H |
18 | |
19 | #include "abstractnetworkjob.h" |
20 | #include <QUrlQuery> |
21 | #include <functional> |
22 | |
23 | class QUrl; |
24 | class QJsonObject; |
25 | |
26 | namespace OCC { |
27 | |
28 | /** |
29 | * @brief The EntityExistsJob class |
30 | * @ingroup libsync |
31 | */ |
32 | class OWNCLOUDSYNC_EXPORT EntityExistsJob : public AbstractNetworkJob |
33 | { |
34 | Q_OBJECT |
35 | public: |
36 | explicit EntityExistsJob(AccountPtr account, const QString &path, QObject *parent = 0); |
37 | void start() Q_DECL_OVERRIDE; |
38 | |
39 | signals: |
40 | void exists(QNetworkReply *); |
41 | |
42 | private slots: |
43 | virtual bool finished() Q_DECL_OVERRIDE; |
44 | }; |
45 | |
46 | /** |
47 | * @brief The LsColJob class |
48 | * @ingroup libsync |
49 | */ |
50 | class OWNCLOUDSYNC_EXPORT LsColXMLParser : public QObject |
51 | { |
52 | Q_OBJECT |
53 | public: |
54 | explicit LsColXMLParser(); |
55 | |
56 | bool parse(const QByteArray &xml, QHash<QString, qint64> *sizes, const QString &expectedPath); |
57 | |
58 | signals: |
59 | void directoryListingSubfolders(const QStringList &items); |
60 | void directoryListingIterated(const QString &name, const QMap<QString, QString> &properties); |
61 | void finishedWithError(QNetworkReply *reply); |
62 | void finishedWithoutError(); |
63 | }; |
64 | |
65 | class OWNCLOUDSYNC_EXPORT LsColJob : public AbstractNetworkJob |
66 | { |
67 | Q_OBJECT |
68 | public: |
69 | explicit LsColJob(AccountPtr account, const QString &path, QObject *parent = 0); |
70 | explicit LsColJob(AccountPtr account, const QUrl &url, QObject *parent = 0); |
71 | void start() Q_DECL_OVERRIDE; |
72 | QHash<QString, qint64> _sizes; |
73 | |
74 | /** |
75 | * Used to specify which properties shall be retrieved. |
76 | * |
77 | * The properties can |
78 | * - contain no colon: they refer to a property in the DAV: namespace |
79 | * - contain a colon: and thus specify an explicit namespace, |
80 | * e.g. "ns:with:colons:bar", which is "bar" in the "ns:with:colons" namespace |
81 | */ |
82 | void setProperties(QList<QByteArray> properties); |
83 | QList<QByteArray> properties() const; |
84 | |
85 | signals: |
86 | void directoryListingSubfolders(const QStringList &items); |
87 | void directoryListingIterated(const QString &name, const QMap<QString, QString> &properties); |
88 | void finishedWithError(QNetworkReply *reply); |
89 | void finishedWithoutError(); |
90 | |
91 | private slots: |
92 | virtual bool finished() Q_DECL_OVERRIDE; |
93 | |
94 | private: |
95 | QList<QByteArray> _properties; |
96 | QUrl _url; // Used instead of path() if the url is specified in the constructor |
97 | }; |
98 | |
99 | /** |
100 | * @brief The PropfindJob class |
101 | * |
102 | * Setting the desired properties with setProperties() is mandatory. |
103 | * |
104 | * Note that this job is only for querying one item. |
105 | * There is also the LsColJob which can be used to list collections |
106 | * |
107 | * @ingroup libsync |
108 | */ |
109 | class OWNCLOUDSYNC_EXPORT PropfindJob : public AbstractNetworkJob |
110 | { |
111 | Q_OBJECT |
112 | public: |
113 | explicit PropfindJob(AccountPtr account, const QString &path, QObject *parent = 0); |
114 | void start() Q_DECL_OVERRIDE; |
115 | |
116 | /** |
117 | * Used to specify which properties shall be retrieved. |
118 | * |
119 | * The properties can |
120 | * - contain no colon: they refer to a property in the DAV: namespace |
121 | * - contain a colon: and thus specify an explicit namespace, |
122 | * e.g. "ns:with:colons:bar", which is "bar" in the "ns:with:colons" namespace |
123 | */ |
124 | void setProperties(QList<QByteArray> properties); |
125 | QList<QByteArray> properties() const; |
126 | |
127 | signals: |
128 | void result(const QVariantMap &values); |
129 | void finishedWithError(QNetworkReply *reply = 0); |
130 | |
131 | private slots: |
132 | virtual bool finished() Q_DECL_OVERRIDE; |
133 | |
134 | private: |
135 | QList<QByteArray> _properties; |
136 | }; |
137 | |
138 | #ifndef TOKEN_AUTH_ONLY |
139 | /** |
140 | * @brief Retrieves the account users avatar from the server using a GET request. |
141 | * |
142 | * If the server does not have the avatar, the result Pixmap is empty. |
143 | * |
144 | * @ingroup libsync |
145 | */ |
146 | class OWNCLOUDSYNC_EXPORT AvatarJob : public AbstractNetworkJob |
147 | { |
148 | Q_OBJECT |
149 | public: |
150 | /** |
151 | * @param userId The user for which to obtain the avatar |
152 | * @param size The size of the avatar (square so size*size) |
153 | */ |
154 | explicit AvatarJob(AccountPtr account, const QString &userId, int size, QObject *parent = 0); |
155 | |
156 | void start() Q_DECL_OVERRIDE; |
157 | |
158 | /** The retrieved avatar images don't have the circle shape by default */ |
159 | static QImage makeCircularAvatar(const QImage &baseAvatar); |
160 | |
161 | signals: |
162 | /** |
163 | * @brief avatarPixmap - returns either a valid pixmap or not. |
164 | */ |
165 | |
166 | void avatarPixmap(const QImage &); |
167 | |
168 | private slots: |
169 | virtual bool finished() Q_DECL_OVERRIDE; |
170 | |
171 | private: |
172 | QUrl _avatarUrl; |
173 | }; |
174 | #endif |
175 | |
176 | /** |
177 | * @brief Send a Proppatch request |
178 | * |
179 | * Setting the desired properties with setProperties() is mandatory. |
180 | * |
181 | * WARNING: Untested! |
182 | * |
183 | * @ingroup libsync |
184 | */ |
185 | class OWNCLOUDSYNC_EXPORT ProppatchJob : public AbstractNetworkJob |
186 | { |
187 | Q_OBJECT |
188 | public: |
189 | explicit ProppatchJob(AccountPtr account, const QString &path, QObject *parent = 0); |
190 | void start() Q_DECL_OVERRIDE; |
191 | |
192 | /** |
193 | * Used to specify which properties shall be set. |
194 | * |
195 | * The property keys can |
196 | * - contain no colon: they refer to a property in the DAV: namespace |
197 | * - contain a colon: and thus specify an explicit namespace, |
198 | * e.g. "ns:with:colons:bar", which is "bar" in the "ns:with:colons" namespace |
199 | */ |
200 | void setProperties(QMap<QByteArray, QByteArray> properties); |
201 | QMap<QByteArray, QByteArray> properties() const; |
202 | |
203 | signals: |
204 | void success(); |
205 | void finishedWithError(); |
206 | |
207 | private slots: |
208 | virtual bool finished() Q_DECL_OVERRIDE; |
209 | |
210 | private: |
211 | QMap<QByteArray, QByteArray> _properties; |
212 | }; |
213 | |
214 | /** |
215 | * @brief The MkColJob class |
216 | * @ingroup libsync |
217 | */ |
218 | class OWNCLOUDSYNC_EXPORT MkColJob : public AbstractNetworkJob |
219 | { |
220 | Q_OBJECT |
221 | QUrl _url; // Only used if the constructor taking a url is taken. |
222 | QMap<QByteArray, QByteArray> ; |
223 | |
224 | public: |
225 | explicit MkColJob(AccountPtr account, const QString &path, QObject *parent = 0); |
226 | explicit MkColJob(AccountPtr account, const QUrl &url, |
227 | const QMap<QByteArray, QByteArray> &, QObject *parent = 0); |
228 | void start() Q_DECL_OVERRIDE; |
229 | |
230 | signals: |
231 | void finished(QNetworkReply::NetworkError); |
232 | |
233 | private slots: |
234 | virtual bool finished() Q_DECL_OVERRIDE; |
235 | }; |
236 | |
237 | /** |
238 | * @brief The CheckServerJob class |
239 | * @ingroup libsync |
240 | */ |
241 | class OWNCLOUDSYNC_EXPORT CheckServerJob : public AbstractNetworkJob |
242 | { |
243 | Q_OBJECT |
244 | public: |
245 | explicit CheckServerJob(AccountPtr account, QObject *parent = 0); |
246 | void start() Q_DECL_OVERRIDE; |
247 | |
248 | static QString version(const QJsonObject &info); |
249 | static QString versionString(const QJsonObject &info); |
250 | static bool installed(const QJsonObject &info); |
251 | |
252 | signals: |
253 | /** Emitted when a status.php was successfully read. |
254 | * |
255 | * \a url see _serverStatusUrl (does not include "/status.php") |
256 | * \a info The status.php reply information |
257 | */ |
258 | void instanceFound(const QUrl &url, const QJsonObject &info); |
259 | |
260 | /** Emitted on invalid status.php reply. |
261 | * |
262 | * \a reply is never null |
263 | */ |
264 | void instanceNotFound(QNetworkReply *reply); |
265 | |
266 | /** A timeout occurred. |
267 | * |
268 | * \a url The specific url where the timeout happened. |
269 | */ |
270 | void timeout(const QUrl &url); |
271 | |
272 | private: |
273 | bool finished() Q_DECL_OVERRIDE; |
274 | void onTimedOut() Q_DECL_OVERRIDE; |
275 | private slots: |
276 | virtual void metaDataChangedSlot(); |
277 | virtual void encryptedSlot(); |
278 | void slotRedirected(QNetworkReply *reply, const QUrl &targetUrl, int redirectCount); |
279 | |
280 | private: |
281 | bool _subdirFallback; |
282 | |
283 | /** The permanent-redirect adjusted account url. |
284 | * |
285 | * Note that temporary redirects or a permanent redirect behind a temporary |
286 | * one do not affect this url. |
287 | */ |
288 | QUrl _serverUrl; |
289 | |
290 | /** Keep track of how many permanent redirect were applied. */ |
291 | int _permanentRedirects; |
292 | }; |
293 | |
294 | |
295 | /** |
296 | * @brief The RequestEtagJob class |
297 | */ |
298 | class OWNCLOUDSYNC_EXPORT RequestEtagJob : public AbstractNetworkJob |
299 | { |
300 | Q_OBJECT |
301 | public: |
302 | explicit RequestEtagJob(AccountPtr account, const QString &path, QObject *parent = 0); |
303 | void start() Q_DECL_OVERRIDE; |
304 | |
305 | signals: |
306 | void etagRetreived(const QString &etag); |
307 | |
308 | private slots: |
309 | virtual bool finished() Q_DECL_OVERRIDE; |
310 | }; |
311 | |
312 | /** |
313 | * @brief Job to check an API that return JSON |
314 | * |
315 | * Note! you need to be in the connected state before calling this because of a server bug: |
316 | * https://github.com/owncloud/core/issues/12930 |
317 | * |
318 | * To be used like this: |
319 | * \code |
320 | * _job = new JsonApiJob(account, QLatin1String("ocs/v1.php/foo/bar"), this); |
321 | * connect(job, SIGNAL(jsonReceived(QJsonDocument)), ...) |
322 | * The received QVariantMap is null in case of error |
323 | * \encode |
324 | * |
325 | * @ingroup libsync |
326 | */ |
327 | class OWNCLOUDSYNC_EXPORT JsonApiJob : public AbstractNetworkJob |
328 | { |
329 | Q_OBJECT |
330 | public: |
331 | explicit JsonApiJob(const AccountPtr &account, const QString &path, QObject *parent = 0); |
332 | |
333 | /** |
334 | * @brief addQueryParams - add more parameters to the ocs call |
335 | * @param params: list pairs of strings containing the parameter name and the value. |
336 | * |
337 | * All parameters from the passed list are appended to the query. Note |
338 | * that the format=json parameter is added automatically and does not |
339 | * need to be set this way. |
340 | * |
341 | * This function needs to be called before start() obviously. |
342 | */ |
343 | void addQueryParams(const QUrlQuery ¶ms); |
344 | |
345 | public slots: |
346 | void start() Q_DECL_OVERRIDE; |
347 | |
348 | protected: |
349 | bool finished() Q_DECL_OVERRIDE; |
350 | signals: |
351 | |
352 | /** |
353 | * @brief jsonReceived - signal to report the json answer from ocs |
354 | * @param json - the parsed json document |
355 | * @param statusCode - the OCS status code: 100 (!) for success |
356 | */ |
357 | void jsonReceived(const QJsonDocument &json, int statusCode); |
358 | |
359 | private: |
360 | QUrlQuery _additionalParams; |
361 | }; |
362 | |
363 | /** |
364 | * @brief Checks with auth type to use for a server |
365 | * @ingroup libsync |
366 | */ |
367 | class OWNCLOUDSYNC_EXPORT DetermineAuthTypeJob : public QObject |
368 | { |
369 | Q_OBJECT |
370 | public: |
371 | enum AuthType { |
372 | Basic, // also the catch-all fallback for backwards compatibility reasons |
373 | OAuth, |
374 | Shibboleth |
375 | }; |
376 | |
377 | explicit DetermineAuthTypeJob(AccountPtr account, QObject *parent = 0); |
378 | void start(); |
379 | signals: |
380 | void authType(AuthType); |
381 | |
382 | private: |
383 | void checkBothDone(); |
384 | |
385 | AccountPtr _account; |
386 | AuthType _resultGet = Basic; |
387 | AuthType _resultPropfind = Basic; |
388 | bool _getDone = false; |
389 | bool _propfindDone = false; |
390 | }; |
391 | |
392 | /** |
393 | * @brief A basic job around a network request without extra funtionality |
394 | * @ingroup libsync |
395 | * |
396 | * Primarily adds timeout and redirection handling. |
397 | */ |
398 | class OWNCLOUDSYNC_EXPORT SimpleNetworkJob : public AbstractNetworkJob |
399 | { |
400 | Q_OBJECT |
401 | public: |
402 | explicit SimpleNetworkJob(AccountPtr account, QObject *parent = 0); |
403 | |
404 | QNetworkReply *startRequest(const QByteArray &verb, const QUrl &url, |
405 | QNetworkRequest req = QNetworkRequest(), |
406 | QIODevice *requestBody = 0); |
407 | |
408 | signals: |
409 | void finishedSignal(QNetworkReply *reply); |
410 | private slots: |
411 | bool finished() Q_DECL_OVERRIDE; |
412 | }; |
413 | |
414 | /** |
415 | * @brief Runs a PROPFIND to figure out the private link url |
416 | * |
417 | * The numericFileId is used only to build the deprecatedPrivateLinkUrl |
418 | * locally as a fallback. If it's empty and the PROPFIND fails, targetFun |
419 | * will be called with an empty string. |
420 | * |
421 | * The job and signal connections are parented to the target QObject. |
422 | * |
423 | * Note: targetFun is guaranteed to be called only through the event |
424 | * loop and never directly. |
425 | */ |
426 | void OWNCLOUDSYNC_EXPORT fetchPrivateLinkUrl( |
427 | AccountPtr account, const QString &remotePath, |
428 | const QByteArray &numericFileId, QObject *target, |
429 | std::function<void(const QString &url)> targetFun); |
430 | |
431 | } // namespace OCC |
432 | |
433 | #endif // NETWORKJOBS_H |
434 | |