2015-10-29 13:09:10 +03:00
|
|
|
/*
|
|
|
|
* Copyright (C) by Roeland Jago Douma <rullzer@owncloud.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
2016-10-25 12:00:07 +03:00
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
2015-10-29 13:09:10 +03:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*/
|
|
|
|
|
2016-09-14 16:31:05 +03:00
|
|
|
#include "sharemanager.h"
|
2015-10-29 13:09:10 +03:00
|
|
|
#include "ocssharejob.h"
|
|
|
|
#include "account.h"
|
2017-10-23 20:08:46 +03:00
|
|
|
#include "folderman.h"
|
|
|
|
#include "accountstate.h"
|
2023-05-08 19:06:23 +03:00
|
|
|
#include "clientsideencryption.h"
|
|
|
|
#include "updatee2eefolderusersmetadatajob.h"
|
2015-10-29 13:09:10 +03:00
|
|
|
|
|
|
|
#include <QUrl>
|
2017-04-26 12:38:10 +03:00
|
|
|
#include <QJsonDocument>
|
|
|
|
#include <QJsonObject>
|
|
|
|
#include <QJsonArray>
|
2015-10-29 13:09:10 +03:00
|
|
|
|
2021-04-16 14:17:09 +03:00
|
|
|
Q_LOGGING_CATEGORY(lcUserGroupShare, "nextcloud.gui.usergroupshare", QtInfoMsg)
|
|
|
|
|
2015-10-29 13:09:10 +03:00
|
|
|
namespace OCC {
|
|
|
|
|
2017-10-23 20:08:46 +03:00
|
|
|
/**
|
|
|
|
* When a share is modified, we need to tell the folders so they can adjust overlay icons
|
|
|
|
*/
|
2022-05-23 16:23:42 +03:00
|
|
|
static void updateFolder(const AccountPtr &account, QStringView path)
|
2017-10-23 20:08:46 +03:00
|
|
|
{
|
|
|
|
foreach (Folder *f, FolderMan::instance()->map()) {
|
|
|
|
if (f->accountState()->account() != account)
|
|
|
|
continue;
|
|
|
|
auto folderPath = f->remotePath();
|
|
|
|
if (path.startsWith(folderPath) && (path == folderPath || folderPath.endsWith('/') || path[folderPath.size()] == '/')) {
|
|
|
|
// Workaround the fact that the server does not invalidate the etags of parent directories
|
|
|
|
// when something is shared.
|
2022-05-23 16:23:42 +03:00
|
|
|
auto relative = path.mid(f->remotePathTrailingSlash().length());
|
2019-02-13 16:18:54 +03:00
|
|
|
f->journalDb()->schedulePathForRemoteDiscovery(relative.toString());
|
2017-10-23 20:08:46 +03:00
|
|
|
|
|
|
|
// Schedule a sync so it can update the remote permission flag and let the socket API
|
|
|
|
// know about the shared icon.
|
|
|
|
f->scheduleThisFolderSoon();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-14 16:31:05 +03:00
|
|
|
Share::Share(AccountPtr account,
|
|
|
|
const QString &id,
|
2019-06-21 19:36:45 +03:00
|
|
|
const QString &uidowner,
|
|
|
|
const QString &ownerDisplayName,
|
2016-09-14 16:31:05 +03:00
|
|
|
const QString &path,
|
2015-10-31 15:39:08 +03:00
|
|
|
const ShareType shareType,
|
2021-04-20 17:36:42 +03:00
|
|
|
bool isPasswordSet,
|
2015-10-31 15:39:08 +03:00
|
|
|
const Permissions permissions,
|
2022-07-25 19:57:18 +03:00
|
|
|
const ShareePtr shareWith)
|
2015-10-29 16:27:49 +03:00
|
|
|
: _account(account)
|
2015-10-29 13:09:10 +03:00
|
|
|
, _id(id)
|
2019-06-21 19:36:45 +03:00
|
|
|
, _uidowner(uidowner)
|
|
|
|
, _ownerDisplayName(ownerDisplayName)
|
2015-10-29 13:09:10 +03:00
|
|
|
, _path(path)
|
|
|
|
, _shareType(shareType)
|
2021-04-20 17:36:42 +03:00
|
|
|
, _isPasswordSet(isPasswordSet)
|
2015-10-31 15:39:08 +03:00
|
|
|
, _permissions(permissions)
|
|
|
|
, _shareWith(shareWith)
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-12-08 14:58:56 +03:00
|
|
|
AccountPtr Share::account() const
|
|
|
|
{
|
|
|
|
return _account;
|
|
|
|
}
|
|
|
|
|
2017-10-23 20:08:46 +03:00
|
|
|
QString Share::path() const
|
|
|
|
{
|
|
|
|
return _path;
|
|
|
|
}
|
|
|
|
|
2015-10-29 15:48:53 +03:00
|
|
|
QString Share::getId() const
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
|
|
|
return _id;
|
|
|
|
}
|
|
|
|
|
2019-06-21 19:36:45 +03:00
|
|
|
QString Share::getUidOwner() const
|
|
|
|
{
|
|
|
|
return _uidowner;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Share::getOwnerDisplayName() const
|
|
|
|
{
|
|
|
|
return _ownerDisplayName;
|
|
|
|
}
|
|
|
|
|
2015-10-29 23:47:47 +03:00
|
|
|
Share::ShareType Share::getShareType() const
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
|
|
|
return _shareType;
|
|
|
|
}
|
|
|
|
|
2022-07-25 19:57:18 +03:00
|
|
|
ShareePtr Share::getShareWith() const
|
2015-11-05 00:00:35 +03:00
|
|
|
{
|
|
|
|
return _shareWith;
|
|
|
|
}
|
|
|
|
|
2021-04-20 17:36:42 +03:00
|
|
|
void Share::setPassword(const QString &password)
|
|
|
|
{
|
2021-04-28 12:43:27 +03:00
|
|
|
auto * const job = new OcsShareJob(_account);
|
2021-04-20 17:36:42 +03:00
|
|
|
connect(job, &OcsShareJob::shareJobFinished, this, &Share::slotPasswordSet);
|
|
|
|
connect(job, &OcsJob::ocsError, this, &Share::slotSetPasswordError);
|
|
|
|
job->setPassword(getId(), password);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Share::isPasswordSet() const
|
|
|
|
{
|
|
|
|
return _isPasswordSet;
|
|
|
|
}
|
|
|
|
|
2015-10-31 15:39:08 +03:00
|
|
|
void Share::setPermissions(Permissions permissions)
|
|
|
|
{
|
2020-05-18 21:54:23 +03:00
|
|
|
auto *job = new OcsShareJob(_account);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(job, &OcsShareJob::shareJobFinished, this, &Share::slotPermissionsSet);
|
|
|
|
connect(job, &OcsJob::ocsError, this, &Share::slotOcsError);
|
2015-10-31 15:39:08 +03:00
|
|
|
job->setPermissions(getId(), permissions);
|
|
|
|
}
|
|
|
|
|
2017-04-26 12:38:10 +03:00
|
|
|
void Share::slotPermissionsSet(const QJsonDocument &, const QVariant &value)
|
2015-10-31 15:39:08 +03:00
|
|
|
{
|
|
|
|
_permissions = (Permissions)value.toInt();
|
|
|
|
emit permissionsSet();
|
|
|
|
}
|
|
|
|
|
2015-10-29 23:47:47 +03:00
|
|
|
Share::Permissions Share::getPermissions() const
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
|
|
|
return _permissions;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Share::deleteShare()
|
|
|
|
{
|
2020-05-18 21:54:23 +03:00
|
|
|
auto *job = new OcsShareJob(_account);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(job, &OcsShareJob::shareJobFinished, this, &Share::slotDeleted);
|
|
|
|
connect(job, &OcsJob::ocsError, this, &Share::slotOcsError);
|
2015-10-29 13:09:10 +03:00
|
|
|
job->deleteShare(getId());
|
|
|
|
}
|
|
|
|
|
2021-11-02 12:01:00 +03:00
|
|
|
bool Share::isShareTypeUserGroupEmailRoomOrRemote(const ShareType type)
|
2021-11-01 18:37:23 +03:00
|
|
|
{
|
|
|
|
return (type == Share::TypeUser || type == Share::TypeGroup || type == Share::TypeEmail || type == Share::TypeRoom
|
|
|
|
|| type == Share::TypeRemote);
|
|
|
|
}
|
|
|
|
|
2015-10-29 18:56:23 +03:00
|
|
|
void Share::slotDeleted()
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
2017-10-23 20:08:46 +03:00
|
|
|
updateFolder(_account, _path);
|
2020-10-14 19:35:12 +03:00
|
|
|
emit shareDeleted();
|
2015-10-29 13:09:10 +03:00
|
|
|
}
|
|
|
|
|
2015-10-29 18:56:23 +03:00
|
|
|
void Share::slotOcsError(int statusCode, const QString &message)
|
|
|
|
{
|
2016-09-14 16:31:05 +03:00
|
|
|
emit serverError(statusCode, message);
|
2015-10-29 18:56:23 +03:00
|
|
|
}
|
|
|
|
|
2021-04-20 17:36:42 +03:00
|
|
|
void Share::slotPasswordSet(const QJsonDocument &, const QVariant &value)
|
|
|
|
{
|
|
|
|
_isPasswordSet = !value.toString().isEmpty();
|
|
|
|
emit passwordSet();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Share::slotSetPasswordError(int statusCode, const QString &message)
|
|
|
|
{
|
|
|
|
emit passwordSetError(statusCode, message);
|
|
|
|
}
|
|
|
|
|
2015-10-29 15:48:53 +03:00
|
|
|
QUrl LinkShare::getLink() const
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
|
|
|
return _url;
|
|
|
|
}
|
|
|
|
|
2017-05-02 13:58:01 +03:00
|
|
|
QUrl LinkShare::getDirectDownloadLink() const
|
|
|
|
{
|
|
|
|
QUrl url = _url;
|
|
|
|
url.setPath(url.path() + "/download");
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
2015-10-29 15:48:53 +03:00
|
|
|
QDate LinkShare::getExpireDate() const
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
|
|
|
return _expireDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
LinkShare::LinkShare(AccountPtr account,
|
|
|
|
const QString &id,
|
2019-06-21 19:36:45 +03:00
|
|
|
const QString &uidowner,
|
|
|
|
const QString &ownerDisplayName,
|
2015-10-29 13:09:10 +03:00
|
|
|
const QString &path,
|
2017-04-12 12:09:20 +03:00
|
|
|
const QString &name,
|
|
|
|
const QString &token,
|
2015-10-29 23:47:47 +03:00
|
|
|
Permissions permissions,
|
2021-04-20 17:36:42 +03:00
|
|
|
bool isPasswordSet,
|
2015-10-29 13:09:10 +03:00
|
|
|
const QUrl &url,
|
2021-09-14 21:57:28 +03:00
|
|
|
const QDate &expireDate,
|
2021-09-14 15:10:44 +03:00
|
|
|
const QString ¬e,
|
2023-04-19 21:28:07 +03:00
|
|
|
const QString &label,
|
|
|
|
const bool hideDownload)
|
2021-04-20 17:36:42 +03:00
|
|
|
: Share(account, id, uidowner, ownerDisplayName, path, Share::TypeLink, isPasswordSet, permissions)
|
2017-04-05 10:38:46 +03:00
|
|
|
, _name(name)
|
2017-04-12 12:09:20 +03:00
|
|
|
, _token(token)
|
2021-09-14 21:57:28 +03:00
|
|
|
, _note(note)
|
2015-10-29 13:09:10 +03:00
|
|
|
, _expireDate(expireDate)
|
|
|
|
, _url(url)
|
2021-09-14 15:10:44 +03:00
|
|
|
, _label(label)
|
2023-04-19 21:28:07 +03:00
|
|
|
, _hideDownload(hideDownload)
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-06-15 16:38:22 +03:00
|
|
|
bool LinkShare::getPublicUpload() const
|
2015-10-29 13:47:14 +03:00
|
|
|
{
|
2017-06-15 16:38:22 +03:00
|
|
|
return _permissions & SharePermissionCreate;
|
2015-10-29 13:47:14 +03:00
|
|
|
}
|
|
|
|
|
2017-06-15 16:38:22 +03:00
|
|
|
bool LinkShare::getShowFileListing() const
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
2017-06-15 16:38:22 +03:00
|
|
|
return _permissions & SharePermissionRead;
|
2015-10-29 13:09:10 +03:00
|
|
|
}
|
|
|
|
|
2017-04-05 10:38:46 +03:00
|
|
|
QString LinkShare::getName() const
|
|
|
|
{
|
|
|
|
return _name;
|
|
|
|
}
|
|
|
|
|
2019-09-18 14:37:49 +03:00
|
|
|
QString LinkShare::getNote() const
|
|
|
|
{
|
|
|
|
return _note;
|
|
|
|
}
|
|
|
|
|
2021-09-14 15:10:44 +03:00
|
|
|
QString LinkShare::getLabel() const
|
|
|
|
{
|
|
|
|
return _label;
|
|
|
|
}
|
|
|
|
|
2023-04-19 21:28:07 +03:00
|
|
|
bool LinkShare::getHideDownload() const
|
|
|
|
{
|
|
|
|
return _hideDownload;
|
|
|
|
}
|
|
|
|
|
2017-04-12 12:09:20 +03:00
|
|
|
void LinkShare::setName(const QString &name)
|
|
|
|
{
|
2021-09-20 16:31:03 +03:00
|
|
|
createShareJob(&LinkShare::slotNameSet)->setName(getId(), name);
|
2017-04-12 12:09:20 +03:00
|
|
|
}
|
|
|
|
|
2019-09-18 14:37:49 +03:00
|
|
|
void LinkShare::setNote(const QString ¬e)
|
|
|
|
{
|
2021-09-20 16:31:03 +03:00
|
|
|
createShareJob(&LinkShare::slotNoteSet)->setNote(getId(), note);
|
2019-09-18 14:37:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void LinkShare::slotNoteSet(const QJsonDocument &, const QVariant ¬e)
|
|
|
|
{
|
|
|
|
_note = note.toString();
|
|
|
|
emit noteSet();
|
|
|
|
}
|
|
|
|
|
2017-04-12 12:09:20 +03:00
|
|
|
QString LinkShare::getToken() const
|
|
|
|
{
|
|
|
|
return _token;
|
|
|
|
}
|
|
|
|
|
2015-10-29 13:09:10 +03:00
|
|
|
void LinkShare::setExpireDate(const QDate &date)
|
|
|
|
{
|
2021-09-20 16:31:03 +03:00
|
|
|
createShareJob(&LinkShare::slotExpireDateSet)->setExpireDate(getId(), date);
|
2015-10-29 13:09:10 +03:00
|
|
|
}
|
|
|
|
|
2021-09-14 15:10:44 +03:00
|
|
|
void LinkShare::setLabel(const QString &label)
|
|
|
|
{
|
2021-09-20 16:31:03 +03:00
|
|
|
createShareJob(&LinkShare::slotLabelSet)->setLabel(getId(), label);
|
|
|
|
}
|
|
|
|
|
2023-04-19 21:28:07 +03:00
|
|
|
void LinkShare::setHideDownload(const bool hideDownload)
|
|
|
|
{
|
|
|
|
createShareJob(&LinkShare::slotHideDownloadSet)->setHideDownload(getId(), hideDownload);
|
|
|
|
}
|
|
|
|
|
2021-09-20 16:31:03 +03:00
|
|
|
template <typename LinkShareSlot>
|
|
|
|
OcsShareJob *LinkShare::createShareJob(const LinkShareSlot slotFunction) {
|
2021-09-14 15:10:44 +03:00
|
|
|
auto *job = new OcsShareJob(_account);
|
2021-09-20 16:31:03 +03:00
|
|
|
connect(job, &OcsShareJob::shareJobFinished, this, slotFunction);
|
2021-09-14 15:10:44 +03:00
|
|
|
connect(job, &OcsJob::ocsError, this, &LinkShare::slotOcsError);
|
2021-09-20 16:31:03 +03:00
|
|
|
return job;
|
2021-09-14 15:10:44 +03:00
|
|
|
}
|
|
|
|
|
2017-04-26 12:38:10 +03:00
|
|
|
void LinkShare::slotExpireDateSet(const QJsonDocument &reply, const QVariant &value)
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
2017-04-26 12:38:10 +03:00
|
|
|
auto data = reply.object().value("ocs").toObject().value("data").toObject();
|
2016-04-19 12:22:32 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the reply provides a data back (more REST style)
|
|
|
|
* they use this date.
|
|
|
|
*/
|
2017-04-26 12:38:10 +03:00
|
|
|
if (data.value("expiration").isString()) {
|
2016-04-19 12:22:32 +03:00
|
|
|
_expireDate = QDate::fromString(data.value("expiration").toString(), "yyyy-MM-dd 00:00:00");
|
|
|
|
} else {
|
|
|
|
_expireDate = value.toDate();
|
|
|
|
}
|
2015-10-29 13:09:10 +03:00
|
|
|
emit expireDateSet();
|
|
|
|
}
|
|
|
|
|
2017-04-26 12:38:10 +03:00
|
|
|
void LinkShare::slotNameSet(const QJsonDocument &, const QVariant &value)
|
2017-04-12 12:09:20 +03:00
|
|
|
{
|
|
|
|
_name = value.toString();
|
|
|
|
emit nameSet();
|
|
|
|
}
|
|
|
|
|
2021-09-14 15:10:44 +03:00
|
|
|
void LinkShare::slotLabelSet(const QJsonDocument &, const QVariant &label)
|
|
|
|
{
|
|
|
|
if (_label != label.toString()) {
|
|
|
|
_label = label.toString();
|
|
|
|
emit labelSet();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-19 21:28:07 +03:00
|
|
|
void LinkShare::slotHideDownloadSet(const QJsonDocument &jsonDoc, const QVariant &hideDownload)
|
|
|
|
{
|
|
|
|
Q_UNUSED(jsonDoc);
|
|
|
|
if (!hideDownload.isValid()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_hideDownload = hideDownload.toBool();
|
|
|
|
emit hideDownloadSet();
|
|
|
|
}
|
|
|
|
|
2021-04-14 17:36:16 +03:00
|
|
|
UserGroupShare::UserGroupShare(AccountPtr account,
|
|
|
|
const QString &id,
|
|
|
|
const QString &owner,
|
|
|
|
const QString &ownerDisplayName,
|
|
|
|
const QString &path,
|
|
|
|
const ShareType shareType,
|
2021-04-20 17:36:42 +03:00
|
|
|
bool isPasswordSet,
|
2021-04-14 17:36:16 +03:00
|
|
|
const Permissions permissions,
|
2022-07-25 19:57:18 +03:00
|
|
|
const ShareePtr shareWith,
|
2021-04-15 16:47:10 +03:00
|
|
|
const QDate &expireDate,
|
|
|
|
const QString ¬e)
|
2021-04-20 17:36:42 +03:00
|
|
|
: Share(account, id, owner, ownerDisplayName, path, shareType, isPasswordSet, permissions, shareWith)
|
2021-04-15 16:47:10 +03:00
|
|
|
, _note(note)
|
2021-04-20 17:36:42 +03:00
|
|
|
, _expireDate(expireDate)
|
2021-04-14 17:36:16 +03:00
|
|
|
{
|
2021-11-02 12:01:00 +03:00
|
|
|
Q_ASSERT(Share::isShareTypeUserGroupEmailRoomOrRemote(shareType));
|
2021-04-14 17:36:16 +03:00
|
|
|
Q_ASSERT(shareWith);
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserGroupShare::setNote(const QString ¬e)
|
|
|
|
{
|
|
|
|
auto *job = new OcsShareJob(_account);
|
|
|
|
connect(job, &OcsShareJob::shareJobFinished, this, &UserGroupShare::slotNoteSet);
|
2021-04-16 19:16:34 +03:00
|
|
|
connect(job, &OcsJob::ocsError, this, &UserGroupShare::noteSetError);
|
2021-04-14 17:36:16 +03:00
|
|
|
job->setNote(getId(), note);
|
|
|
|
}
|
|
|
|
|
2021-04-15 16:47:10 +03:00
|
|
|
QString UserGroupShare::getNote() const
|
|
|
|
{
|
|
|
|
return _note;
|
|
|
|
}
|
|
|
|
|
2021-04-14 17:36:16 +03:00
|
|
|
void UserGroupShare::slotNoteSet(const QJsonDocument &, const QVariant ¬e)
|
|
|
|
{
|
|
|
|
_note = note.toString();
|
|
|
|
emit noteSet();
|
|
|
|
}
|
|
|
|
|
2021-04-15 14:06:53 +03:00
|
|
|
QDate UserGroupShare::getExpireDate() const
|
|
|
|
{
|
|
|
|
return _expireDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserGroupShare::setExpireDate(const QDate &date)
|
|
|
|
{
|
2021-08-17 16:39:18 +03:00
|
|
|
if (_expireDate == date) {
|
|
|
|
emit expireDateSet();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-04-15 14:06:53 +03:00
|
|
|
auto *job = new OcsShareJob(_account);
|
|
|
|
connect(job, &OcsShareJob::shareJobFinished, this, &UserGroupShare::slotExpireDateSet);
|
|
|
|
connect(job, &OcsJob::ocsError, this, &UserGroupShare::slotOcsError);
|
|
|
|
job->setExpireDate(getId(), date);
|
|
|
|
}
|
|
|
|
|
|
|
|
void UserGroupShare::slotExpireDateSet(const QJsonDocument &reply, const QVariant &value)
|
|
|
|
{
|
|
|
|
auto data = reply.object().value("ocs").toObject().value("data").toObject();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the reply provides a data back (more REST style)
|
|
|
|
* they use this date.
|
|
|
|
*/
|
|
|
|
if (data.value("expiration").isString()) {
|
|
|
|
_expireDate = QDate::fromString(data.value("expiration").toString(), "yyyy-MM-dd 00:00:00");
|
|
|
|
} else {
|
|
|
|
_expireDate = value.toDate();
|
|
|
|
}
|
|
|
|
emit expireDateSet();
|
|
|
|
}
|
|
|
|
|
2015-10-29 13:09:10 +03:00
|
|
|
ShareManager::ShareManager(AccountPtr account, QObject *parent)
|
|
|
|
: QObject(parent)
|
|
|
|
, _account(account)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ShareManager::createLinkShare(const QString &path,
|
2017-04-05 10:38:46 +03:00
|
|
|
const QString &name,
|
2015-10-29 13:09:10 +03:00
|
|
|
const QString &password)
|
|
|
|
{
|
2020-05-18 21:54:23 +03:00
|
|
|
auto *job = new OcsShareJob(_account);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(job, &OcsShareJob::shareJobFinished, this, &ShareManager::slotLinkShareCreated);
|
|
|
|
connect(job, &OcsJob::ocsError, this, &ShareManager::slotOcsError);
|
2017-04-05 10:38:46 +03:00
|
|
|
job->createLinkShare(path, name, password);
|
2015-10-29 13:09:10 +03:00
|
|
|
}
|
|
|
|
|
2023-01-12 20:55:04 +03:00
|
|
|
void ShareManager::createSecureFileDropShare(const QString &path, const QString &name, const QString &password)
|
|
|
|
{
|
|
|
|
const auto createShareJob = new OcsShareJob(_account);
|
|
|
|
connect(createShareJob, &OcsShareJob::shareJobFinished, this, &ShareManager::slotLinkShareCreated);
|
|
|
|
connect(createShareJob, &OcsJob::ocsError, this, &ShareManager::slotOcsError);
|
|
|
|
createShareJob->createSecureFileDropLinkShare(path, name, password);
|
|
|
|
}
|
|
|
|
|
2017-04-26 12:38:10 +03:00
|
|
|
void ShareManager::slotLinkShareCreated(const QJsonDocument &reply)
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
|
|
|
QString message;
|
|
|
|
int code = OcsShareJob::getJsonReturnCode(reply, message);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Before we had decent sharing capabilities on the server a 403 "generally"
|
2015-10-29 15:39:29 +03:00
|
|
|
* meant that a share was password protected
|
2015-10-29 13:09:10 +03:00
|
|
|
*/
|
|
|
|
if (code == 403) {
|
2016-01-19 16:03:13 +03:00
|
|
|
emit linkShareRequiresPassword(message);
|
2015-10-29 15:31:36 +03:00
|
|
|
return;
|
2016-09-14 16:31:05 +03:00
|
|
|
}
|
2015-10-29 13:09:10 +03:00
|
|
|
|
|
|
|
//Parse share
|
2017-04-26 12:38:10 +03:00
|
|
|
auto data = reply.object().value("ocs").toObject().value("data").toObject();
|
2015-10-29 13:09:10 +03:00
|
|
|
QSharedPointer<LinkShare> share(parseLinkShare(data));
|
|
|
|
|
|
|
|
emit linkShareCreated(share);
|
2017-10-23 20:08:46 +03:00
|
|
|
|
|
|
|
updateFolder(_account, share->path());
|
2015-10-29 13:09:10 +03:00
|
|
|
}
|
|
|
|
|
2016-01-21 16:10:37 +03:00
|
|
|
|
2015-10-31 15:39:08 +03:00
|
|
|
void ShareManager::createShare(const QString &path,
|
|
|
|
const Share::ShareType shareType,
|
|
|
|
const QString shareWith,
|
2021-04-20 17:36:42 +03:00
|
|
|
const Share::Permissions desiredPermissions,
|
|
|
|
const QString &password)
|
2015-10-31 15:39:08 +03:00
|
|
|
{
|
2016-01-21 16:10:37 +03:00
|
|
|
auto job = new OcsShareJob(_account);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(job, &OcsJob::ocsError, this, &ShareManager::slotOcsError);
|
2017-10-17 18:29:48 +03:00
|
|
|
connect(job, &OcsShareJob::shareJobFinished, this,
|
|
|
|
[=](const QJsonDocument &reply) {
|
|
|
|
// Find existing share permissions (if this was shared with us)
|
2023-08-10 09:58:05 +03:00
|
|
|
Share::Permissions existingPermissions = SharePermissionAll;
|
2017-10-17 18:29:48 +03:00
|
|
|
foreach (const QJsonValue &element, reply.object()["ocs"].toObject()["data"].toArray()) {
|
|
|
|
auto map = element.toObject();
|
|
|
|
if (map["file_target"] == path)
|
|
|
|
existingPermissions = Share::Permissions(map["permissions"].toInt());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Limit the permissions we request for a share to the ones the item
|
|
|
|
// was shared with initially.
|
2018-02-09 16:39:12 +03:00
|
|
|
auto validPermissions = desiredPermissions;
|
2023-08-10 09:58:05 +03:00
|
|
|
if (validPermissions == SharePermissionAll) {
|
2018-02-09 16:39:12 +03:00
|
|
|
validPermissions = existingPermissions;
|
|
|
|
}
|
2023-08-10 09:58:05 +03:00
|
|
|
if (existingPermissions != SharePermissionAll) {
|
2018-02-09 16:39:12 +03:00
|
|
|
validPermissions &= existingPermissions;
|
2017-10-17 18:29:48 +03:00
|
|
|
}
|
|
|
|
|
2020-05-18 21:54:23 +03:00
|
|
|
auto *job = new OcsShareJob(_account);
|
2017-10-17 18:29:48 +03:00
|
|
|
connect(job, &OcsShareJob::shareJobFinished, this, &ShareManager::slotShareCreated);
|
|
|
|
connect(job, &OcsJob::ocsError, this, &ShareManager::slotOcsError);
|
2021-04-20 17:36:42 +03:00
|
|
|
job->createShare(path, shareType, shareWith, validPermissions, password);
|
2017-10-17 18:29:48 +03:00
|
|
|
});
|
2016-01-21 16:10:37 +03:00
|
|
|
job->getSharedWithMe();
|
|
|
|
}
|
|
|
|
|
2024-03-10 00:17:27 +03:00
|
|
|
void ShareManager::createE2EeShareJob(const QString &fullRemotePath,
|
2023-05-08 19:06:23 +03:00
|
|
|
const ShareePtr sharee,
|
|
|
|
const Share::Permissions permissions,
|
|
|
|
const QString &password)
|
|
|
|
{
|
|
|
|
Folder *folder = nullptr;
|
|
|
|
for (const auto &f : FolderMan::instance()->map()) {
|
|
|
|
if (f->accountState()->account() != _account) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
folder = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!folder) {
|
|
|
|
emit serverError(0, "Failed creating share");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-03-10 00:17:27 +03:00
|
|
|
Q_ASSERT(folder->remotePath() == QStringLiteral("/") ||
|
|
|
|
Utility::noLeadingSlashPath(fullRemotePath).startsWith(Utility::noLeadingSlashPath(Utility::noTrailingSlashPath(folder->remotePath()))));
|
|
|
|
|
2023-05-08 19:06:23 +03:00
|
|
|
const auto createE2eeShareJob = new UpdateE2eeFolderUsersMetadataJob(_account,
|
|
|
|
folder->journalDb(),
|
|
|
|
folder->remotePath(),
|
|
|
|
UpdateE2eeFolderUsersMetadataJob::Add,
|
2024-03-10 00:17:27 +03:00
|
|
|
fullRemotePath,
|
2023-05-08 19:06:23 +03:00
|
|
|
sharee->shareWith(),
|
|
|
|
QSslCertificate{},
|
|
|
|
this);
|
|
|
|
|
|
|
|
createE2eeShareJob->setUserData({sharee, permissions, password});
|
|
|
|
connect(createE2eeShareJob, &UpdateE2eeFolderUsersMetadataJob::finished, this, &ShareManager::slotCreateE2eeShareJobFinised);
|
|
|
|
createE2eeShareJob->start();
|
|
|
|
}
|
2015-10-31 15:39:08 +03:00
|
|
|
|
2017-04-26 12:38:10 +03:00
|
|
|
void ShareManager::slotShareCreated(const QJsonDocument &reply)
|
2015-10-31 15:39:08 +03:00
|
|
|
{
|
|
|
|
//Parse share
|
2017-04-26 12:38:10 +03:00
|
|
|
auto data = reply.object().value("ocs").toObject().value("data").toObject();
|
2022-07-25 19:57:18 +03:00
|
|
|
SharePtr share(parseShare(data));
|
2015-10-31 15:39:08 +03:00
|
|
|
|
|
|
|
emit shareCreated(share);
|
2017-10-23 20:08:46 +03:00
|
|
|
|
|
|
|
updateFolder(_account, share->path());
|
2015-10-31 15:39:08 +03:00
|
|
|
}
|
|
|
|
|
2015-10-29 13:09:10 +03:00
|
|
|
void ShareManager::fetchShares(const QString &path)
|
|
|
|
{
|
2020-05-18 21:54:23 +03:00
|
|
|
auto *job = new OcsShareJob(_account);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(job, &OcsShareJob::shareJobFinished, this, &ShareManager::slotSharesFetched);
|
|
|
|
connect(job, &OcsJob::ocsError, this, &ShareManager::slotOcsError);
|
2015-10-29 13:09:10 +03:00
|
|
|
job->getShares(path);
|
|
|
|
}
|
|
|
|
|
2017-04-26 12:38:10 +03:00
|
|
|
void ShareManager::slotSharesFetched(const QJsonDocument &reply)
|
2015-10-29 13:09:10 +03:00
|
|
|
{
|
2022-10-06 14:21:33 +03:00
|
|
|
qDebug() << reply;
|
2017-04-26 12:38:10 +03:00
|
|
|
auto tmpShares = reply.object().value("ocs").toObject().value("data").toArray();
|
2015-10-29 13:09:10 +03:00
|
|
|
const QString versionString = _account->serverVersion();
|
2017-05-09 15:24:11 +03:00
|
|
|
qCDebug(lcSharing) << versionString << "Fetched" << tmpShares.count() << "shares";
|
2015-10-29 13:09:10 +03:00
|
|
|
|
2022-07-25 19:57:18 +03:00
|
|
|
QList<SharePtr> shares;
|
2015-10-29 13:09:10 +03:00
|
|
|
|
2015-10-29 16:00:28 +03:00
|
|
|
foreach (const auto &share, tmpShares) {
|
2017-04-26 12:38:10 +03:00
|
|
|
auto data = share.toObject();
|
2015-10-29 13:09:10 +03:00
|
|
|
|
|
|
|
auto shareType = data.value("share_type").toInt();
|
|
|
|
|
2022-07-25 19:57:18 +03:00
|
|
|
SharePtr newShare;
|
2015-10-29 13:09:10 +03:00
|
|
|
|
2015-10-29 23:47:47 +03:00
|
|
|
if (shareType == Share::TypeLink) {
|
2015-10-29 13:09:10 +03:00
|
|
|
newShare = parseLinkShare(data);
|
2021-11-02 12:01:00 +03:00
|
|
|
} else if (Share::isShareTypeUserGroupEmailRoomOrRemote(static_cast <Share::ShareType>(shareType))) {
|
2021-04-14 17:36:16 +03:00
|
|
|
newShare = parseUserGroupShare(data);
|
2015-10-29 13:09:10 +03:00
|
|
|
} else {
|
2015-10-31 15:39:08 +03:00
|
|
|
newShare = parseShare(data);
|
2015-10-29 13:09:10 +03:00
|
|
|
}
|
|
|
|
|
2022-07-25 19:57:18 +03:00
|
|
|
shares.append(SharePtr(newShare));
|
2015-10-29 13:09:10 +03:00
|
|
|
}
|
|
|
|
|
2017-05-09 15:24:11 +03:00
|
|
|
qCDebug(lcSharing) << "Sending " << shares.count() << "shares";
|
2015-10-29 13:09:10 +03:00
|
|
|
emit sharesFetched(shares);
|
|
|
|
}
|
|
|
|
|
2021-04-14 17:36:16 +03:00
|
|
|
QSharedPointer<UserGroupShare> ShareManager::parseUserGroupShare(const QJsonObject &data)
|
|
|
|
{
|
2022-07-25 19:57:18 +03:00
|
|
|
ShareePtr sharee(new Sharee(data.value("share_with").toString(),
|
2021-04-14 17:36:16 +03:00
|
|
|
data.value("share_with_displayname").toString(),
|
|
|
|
static_cast<Sharee::Type>(data.value("share_type").toInt())));
|
|
|
|
|
2021-04-15 14:06:53 +03:00
|
|
|
QDate expireDate;
|
|
|
|
if (data.value("expiration").isString()) {
|
|
|
|
expireDate = QDate::fromString(data.value("expiration").toString(), "yyyy-MM-dd 00:00:00");
|
|
|
|
}
|
|
|
|
|
2021-04-15 16:47:10 +03:00
|
|
|
QString note;
|
|
|
|
if (data.value("note").isString()) {
|
|
|
|
note = data.value("note").toString();
|
|
|
|
}
|
|
|
|
|
2021-04-14 17:36:16 +03:00
|
|
|
return QSharedPointer<UserGroupShare>(new UserGroupShare(_account,
|
|
|
|
data.value("id").toVariant().toString(), // "id" used to be an integer, support both
|
|
|
|
data.value("uid_owner").toVariant().toString(),
|
|
|
|
data.value("displayname_owner").toVariant().toString(),
|
|
|
|
data.value("path").toString(),
|
|
|
|
static_cast<Share::ShareType>(data.value("share_type").toInt()),
|
2021-04-20 17:36:42 +03:00
|
|
|
!data.value("password").toString().isEmpty(),
|
2021-04-14 17:36:16 +03:00
|
|
|
static_cast<Share::Permissions>(data.value("permissions").toInt()),
|
2021-04-15 14:06:53 +03:00
|
|
|
sharee,
|
2021-04-15 16:47:10 +03:00
|
|
|
expireDate,
|
|
|
|
note));
|
2021-04-14 17:36:16 +03:00
|
|
|
}
|
|
|
|
|
2017-04-26 12:38:10 +03:00
|
|
|
QSharedPointer<LinkShare> ShareManager::parseLinkShare(const QJsonObject &data)
|
2017-04-12 12:09:20 +03:00
|
|
|
{
|
2015-10-29 13:09:10 +03:00
|
|
|
QUrl url;
|
|
|
|
|
|
|
|
// From ownCloud server 8.2 the url field is always set for public shares
|
|
|
|
if (data.contains("url")) {
|
|
|
|
url = QUrl(data.value("url").toString());
|
2017-03-14 17:57:57 +03:00
|
|
|
} else if (_account->serverVersionInt() >= Account::makeServerVersion(8, 0, 0)) {
|
2015-10-29 13:09:10 +03:00
|
|
|
// From ownCloud server version 8 on, a different share link scheme is used.
|
2017-02-23 16:54:17 +03:00
|
|
|
url = QUrl(Utility::concatUrlPath(_account->url(), QLatin1String("index.php/s/") + data.value("token").toString())).toString();
|
2015-10-29 13:09:10 +03:00
|
|
|
} else {
|
2017-12-08 12:10:28 +03:00
|
|
|
QUrlQuery queryArgs;
|
|
|
|
queryArgs.addQueryItem(QLatin1String("service"), QLatin1String("files"));
|
|
|
|
queryArgs.addQueryItem(QLatin1String("t"), data.value("token").toString());
|
2016-10-25 13:04:22 +03:00
|
|
|
url = QUrl(Utility::concatUrlPath(_account->url(), QLatin1String("public.php"), queryArgs).toString());
|
2015-10-29 13:09:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
QDate expireDate;
|
2017-04-26 12:38:10 +03:00
|
|
|
if (data.value("expiration").isString()) {
|
2015-10-29 13:09:10 +03:00
|
|
|
expireDate = QDate::fromString(data.value("expiration").toString(), "yyyy-MM-dd 00:00:00");
|
|
|
|
}
|
2021-09-14 21:57:28 +03:00
|
|
|
|
|
|
|
QString note;
|
|
|
|
if (data.value("note").isString()) {
|
|
|
|
note = data.value("note").toString();
|
|
|
|
}
|
2015-10-29 13:09:10 +03:00
|
|
|
|
2015-10-29 16:27:49 +03:00
|
|
|
return QSharedPointer<LinkShare>(new LinkShare(_account,
|
2017-05-18 13:41:28 +03:00
|
|
|
data.value("id").toVariant().toString(), // "id" used to be an integer, support both
|
2019-06-21 19:36:45 +03:00
|
|
|
data.value("uid_owner").toString(),
|
|
|
|
data.value("displayname_owner").toString(),
|
2015-10-29 16:27:49 +03:00
|
|
|
data.value("path").toString(),
|
2017-04-12 12:09:20 +03:00
|
|
|
data.value("name").toString(),
|
|
|
|
data.value("token").toString(),
|
2015-10-29 23:47:47 +03:00
|
|
|
(Share::Permissions)data.value("permissions").toInt(),
|
2017-04-26 12:38:10 +03:00
|
|
|
data.value("share_with").isString(), // has password?
|
2015-10-29 16:27:49 +03:00
|
|
|
url,
|
2021-09-14 21:57:28 +03:00
|
|
|
expireDate,
|
2021-09-14 15:10:44 +03:00
|
|
|
note,
|
2023-04-19 21:28:07 +03:00
|
|
|
data.value("label").toString(),
|
|
|
|
data.value("hide_download").toInt() == 1));
|
2015-10-29 13:09:10 +03:00
|
|
|
}
|
|
|
|
|
2022-07-25 19:57:18 +03:00
|
|
|
SharePtr ShareManager::parseShare(const QJsonObject &data) const
|
2015-11-05 00:00:35 +03:00
|
|
|
{
|
2022-07-25 19:57:18 +03:00
|
|
|
ShareePtr sharee(new Sharee(data.value("share_with").toString(),
|
2015-11-05 00:00:35 +03:00
|
|
|
data.value("share_with_displayname").toString(),
|
|
|
|
(Sharee::Type)data.value("share_type").toInt()));
|
2016-09-14 16:31:05 +03:00
|
|
|
|
2022-07-25 19:57:18 +03:00
|
|
|
return SharePtr(new Share(_account,
|
2017-05-18 13:41:28 +03:00
|
|
|
data.value("id").toVariant().toString(), // "id" used to be an integer, support both
|
2019-06-21 19:36:45 +03:00
|
|
|
data.value("uid_owner").toVariant().toString(),
|
|
|
|
data.value("displayname_owner").toVariant().toString(),
|
2015-10-31 15:39:08 +03:00
|
|
|
data.value("path").toString(),
|
|
|
|
(Share::ShareType)data.value("share_type").toInt(),
|
2021-04-20 17:36:42 +03:00
|
|
|
!data.value("password").toString().isEmpty(),
|
2015-10-31 15:39:08 +03:00
|
|
|
(Share::Permissions)data.value("permissions").toInt(),
|
2015-11-05 00:00:35 +03:00
|
|
|
sharee));
|
2015-10-31 15:39:08 +03:00
|
|
|
}
|
|
|
|
|
2015-10-29 18:56:23 +03:00
|
|
|
void ShareManager::slotOcsError(int statusCode, const QString &message)
|
|
|
|
{
|
2016-01-21 16:10:37 +03:00
|
|
|
emit serverError(statusCode, message);
|
2015-10-29 18:56:23 +03:00
|
|
|
}
|
2023-05-08 19:06:23 +03:00
|
|
|
|
|
|
|
|
|
|
|
void ShareManager::slotCreateE2eeShareJobFinised(int statusCode, const QString &message)
|
|
|
|
{
|
|
|
|
const auto job = qobject_cast<UpdateE2eeFolderUsersMetadataJob *>(sender());
|
|
|
|
Q_ASSERT(job);
|
|
|
|
if (!job) {
|
|
|
|
qCWarning(lcUserGroupShare) << "slotCreateE2eeShareJobFinised must be called by UpdateE2eeShareMetadataJob::finished signal!";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
disconnect(job, &UpdateE2eeFolderUsersMetadataJob::finished, this, &ShareManager::slotCreateE2eeShareJobFinised);
|
|
|
|
const auto userData = job->userData();
|
|
|
|
Q_ASSERT(userData.sharee);
|
|
|
|
if (!userData.sharee) {
|
|
|
|
qCWarning(lcUserGroupShare) << "missing userData Map in UpdateE2eeShareMetadataJob instance!";
|
|
|
|
emit serverError(-1, tr("Error"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (statusCode != 200) {
|
|
|
|
emit serverError(statusCode, message);
|
|
|
|
} else {
|
|
|
|
createShare(job->path(), Share::ShareType(userData.sharee->type()), userData.sharee->shareWith(), userData.desiredPermissions, userData.password);
|
|
|
|
}
|
|
|
|
}
|
2015-10-29 13:09:10 +03:00
|
|
|
}
|