1 /*
2  * Copyright (C) by Roeland Jago Douma <rullzer@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 SHAREMANAGER_H
16 #define SHAREMANAGER_H
17 
18 #include "accountfwd.h"
19 #include "sharee.h"
20 #include "sharepermissions.h"
21 
22 #include <QObject>
23 #include <QDate>
24 #include <QString>
25 #include <QList>
26 #include <QSharedPointer>
27 #include <QUrl>
28 
29 class QJsonDocument;
30 class QJsonObject;
31 
32 namespace OCC {
33 
34 class OcsShareJob;
35 
36 class Share : public QObject
37 {
38     Q_OBJECT
39 
40 public:
41     /**
42      * Possible share types
43      * Need to be in sync with Sharee::Type
44      */
45     enum ShareType {
46         TypeUser = Sharee::User,
47         TypeGroup = Sharee::Group,
48         TypeLink = 3,
49         TypeEmail = Sharee::Email,
50         TypeRemote = Sharee::Federated,
51         TypeCircle = Sharee::Circle,
52         TypeRoom = Sharee::Room
53     };
54 
55     using Permissions = SharePermissions;
56 
57     /*
58      * Constructor for shares
59      */
60     explicit Share(AccountPtr account,
61         const QString &id,
62         const QString &owner,
63         const QString &ownerDisplayName,
64         const QString &path,
65         const ShareType shareType,
66         bool isPasswordSet = false,
67         const Permissions permissions = SharePermissionDefault,
68         const QSharedPointer<Sharee> shareWith = QSharedPointer<Sharee>(nullptr));
69 
70     /**
71      * The account the share is defined on.
72      */
73     AccountPtr account() const;
74 
75     QString path() const;
76 
77     /*
78      * Get the id
79      */
80     QString getId() const;
81 
82     /*
83      * Get the uid_owner
84      */
85     QString getUidOwner() const;
86 
87     /*
88      * Get the owner display name
89      */
90     QString getOwnerDisplayName() const;
91 
92     /*
93      * Get the shareType
94      */
95     ShareType getShareType() const;
96 
97     /*
98      * Get the shareWith
99      */
100     QSharedPointer<Sharee> getShareWith() const;
101 
102     /*
103      * Get permissions
104      */
105     Permissions getPermissions() const;
106 
107     /*
108      * Set the permissions of a share
109      *
110      * On success the permissionsSet signal is emitted
111      * In case of a server error the serverError signal is emitted.
112      */
113     void setPermissions(Permissions permissions);
114 
115     /*
116      * Set the password for remote share
117      *
118      * On success the passwordSet signal is emitted
119      * In case of a server error the passwordSetError signal is emitted.
120      */
121     void setPassword(const QString &password);
122 
123     bool isPasswordSet() const;
124 
125     /*
126      * Deletes a share
127      *
128      * On success the shareDeleted signal is emitted
129      * In case of a server error the serverError signal is emitted.
130      */
131     void deleteShare();
132 
133      /*
134      * Is it a share with a user or group (local or remote)
135      */
136     static bool isShareTypeUserGroupEmailRoomOrRemote(const ShareType type);
137 
138 signals:
139     void permissionsSet();
140     void shareDeleted();
141     void serverError(int code, const QString &message);
142     void passwordSet();
143     void passwordSetError(int statusCode, const QString &message);
144 
145 protected:
146     AccountPtr _account;
147     QString _id;
148     QString _uidowner;
149     QString _ownerDisplayName;
150     QString _path;
151     ShareType _shareType;
152     bool _isPasswordSet;
153     Permissions _permissions;
154     QSharedPointer<Sharee> _shareWith;
155 
156 protected slots:
157     void slotOcsError(int statusCode, const QString &message);
158     void slotPasswordSet(const QJsonDocument &, const QVariant &value);
159     void slotSetPasswordError(int statusCode, const QString &message);
160 
161 private slots:
162     void slotDeleted();
163     void slotPermissionsSet(const QJsonDocument &, const QVariant &value);
164 };
165 
166 /**
167  * A Link share is just like a regular share but then slightly different.
168  * There are several methods in the API that either work differently for
169  * link shares or are only available to link shares.
170  */
171 class LinkShare : public Share
172 {
173     Q_OBJECT
174 public:
175     explicit LinkShare(AccountPtr account,
176         const QString &id,
177         const QString &uidowner,
178         const QString &ownerDisplayName,
179         const QString &path,
180         const QString &name,
181         const QString &token,
182         const Permissions permissions,
183         bool isPasswordSet,
184         const QUrl &url,
185         const QDate &expireDate,
186         const QString &note,
187         const QString &label);
188 
189     /*
190      * Get the share link
191      */
192     QUrl getLink() const;
193 
194     /*
195      * The share's link for direct downloading.
196      */
197     QUrl getDirectDownloadLink() const;
198 
199     /*
200      * Get the publicUpload status of this share
201      */
202     bool getPublicUpload() const;
203 
204     /*
205      * Whether directory listings are available (READ permission)
206      */
207     bool getShowFileListing() const;
208 
209     /*
210      * Returns the name of the link share. Can be empty.
211      */
212     QString getName() const;
213 
214     /*
215      * Returns the note of the link share.
216      */
217     QString getNote() const;
218 
219     /*
220      * Returns the label of the link share.
221      */
222     QString getLabel() const;
223 
224     /*
225      * Set the name of the link share.
226      *
227      * Emits either nameSet() or serverError().
228      */
229     void setName(const QString &name);
230 
231     /*
232      * Set the note of the link share.
233      */
234     void setNote(const QString &note);
235 
236     /*
237      * Returns the token of the link share.
238      */
239     QString getToken() const;
240 
241     /*
242      * Get the expiration date
243      */
244     QDate getExpireDate() const;
245 
246     /*
247      * Set the expiration date
248      *
249      * On success the expireDateSet signal is emitted
250      * In case of a server error the serverError signal is emitted.
251      */
252     void setExpireDate(const QDate &expireDate);
253 
254     /*
255      * Set the label of the share link.
256      */
257     void setLabel(const QString &label);
258 
259     /*
260      * Create OcsShareJob and connect to signal/slots
261      */
262     template <typename LinkShareSlot>
263     OcsShareJob *createShareJob(const LinkShareSlot slotFunction);
264 
265 
266 signals:
267     void expireDateSet();
268     void noteSet();
269     void nameSet();
270     void labelSet();
271 
272 private slots:
273     void slotNoteSet(const QJsonDocument &, const QVariant &value);
274     void slotExpireDateSet(const QJsonDocument &reply, const QVariant &value);
275     void slotNameSet(const QJsonDocument &, const QVariant &value);
276     void slotLabelSet(const QJsonDocument &, const QVariant &value);
277 
278 private:
279     QString _name;
280     QString _token;
281     QString _note;
282     QDate _expireDate;
283     QUrl _url;
284     QString _label;
285 };
286 
287 class UserGroupShare : public Share
288 {
289     Q_OBJECT
290 public:
291     UserGroupShare(AccountPtr account,
292         const QString &id,
293         const QString &owner,
294         const QString &ownerDisplayName,
295         const QString &path,
296         const ShareType shareType,
297         bool isPasswordSet,
298         const Permissions permissions,
299         const QSharedPointer<Sharee> shareWith,
300         const QDate &expireDate,
301         const QString &note);
302 
303     void setNote(const QString &note);
304 
305     QString getNote() const;
306 
307     void slotNoteSet(const QJsonDocument &, const QVariant &note);
308 
309     void setExpireDate(const QDate &date);
310 
311     QDate getExpireDate() const;
312 
313     void slotExpireDateSet(const QJsonDocument &reply, const QVariant &value);
314 
315 signals:
316     void noteSet();
317     void noteSetError();
318     void expireDateSet();
319 
320 private:
321     QString _note;
322     QDate _expireDate;
323 };
324 
325 /**
326  * The share manager allows for creating, retrieving and deletion
327  * of shares. It abstracts away from the OCS Share API, all the usages
328  * shares should talk to this manager and not use OCS Share Job directly
329  */
330 class ShareManager : public QObject
331 {
332     Q_OBJECT
333 public:
334     explicit ShareManager(AccountPtr _account, QObject *parent = nullptr);
335 
336     /**
337      * Tell the manager to create a link share
338      *
339      * @param path The path of the linkshare relative to the user folder on the server
340      * @param name The name of the created share, may be empty
341      * @param password The password of the share, may be empty
342      *
343      * On success the signal linkShareCreated is emitted
344      * For older server the linkShareRequiresPassword signal is emitted when it seems appropiate
345      * In case of a server error the serverError signal is emitted
346      */
347     void createLinkShare(const QString &path,
348         const QString &name,
349         const QString &password);
350 
351     /**
352      * Tell the manager to create a new share
353      *
354      * @param path The path of the share relative to the user folder on the server
355      * @param shareType The type of share (TypeUser, TypeGroup, TypeRemote)
356      * @param Permissions The share permissions
357      *
358      * On success the signal shareCreated is emitted
359      * In case of a server error the serverError signal is emitted
360      */
361     void createShare(const QString &path,
362         const Share::ShareType shareType,
363         const QString shareWith,
364         const Share::Permissions permissions,
365         const QString &password = "");
366 
367     /**
368      * Fetch all the shares for path
369      *
370      * @param path The path to get the shares for relative to the users folder on the server
371      *
372      * On success the sharesFetched signal is emitted
373      * In case of a server error the serverError signal is emitted
374      */
375     void fetchShares(const QString &path);
376 
377 signals:
378     void shareCreated(const QSharedPointer<Share> &share);
379     void linkShareCreated(const QSharedPointer<LinkShare> &share);
380     void sharesFetched(const QList<QSharedPointer<Share>> &shares);
381     void serverError(int code, const QString &message);
382 
383     /** Emitted when creating a link share with password fails.
384      *
385      * @param message the error message reported by the server
386      *
387      * See createLinkShare().
388      */
389     void linkShareRequiresPassword(const QString &message);
390 
391 private slots:
392     void slotSharesFetched(const QJsonDocument &reply);
393     void slotLinkShareCreated(const QJsonDocument &reply);
394     void slotShareCreated(const QJsonDocument &reply);
395     void slotOcsError(int statusCode, const QString &message);
396 private:
397     QSharedPointer<LinkShare> parseLinkShare(const QJsonObject &data);
398     QSharedPointer<UserGroupShare> parseUserGroupShare(const QJsonObject &data);
399     QSharedPointer<Share> parseShare(const QJsonObject &data);
400 
401     AccountPtr _account;
402 };
403 }
404 
405 #endif // SHAREMANAGER_H
406