Arquivos
client/src/gui/share.cpp
T
Roeland Jago Douma 598941948c Use expireDate if returned by the OCS Share API
If an app modifies the expiration date (for example the password policy
app) then on more recent versions of the server we will get the share
object back REST style. We should use that info!

Fixes #4409
2016-04-19 11:22:32 +02:00

389 linhas
12 KiB
C++

/*
* 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
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include "share.h"
#include "ocssharejob.h"
#include "account.h"
#include <QUrl>
namespace {
struct CreateShare
{
QString path;
OCC::Share::ShareType shareType;
QString shareWith;
OCC::Share::Permissions permissions;
};
} // anonymous namespace
Q_DECLARE_METATYPE(CreateShare)
namespace OCC {
Share::Share(AccountPtr account,
const QString& id,
const QString& path,
const ShareType shareType,
const Permissions permissions,
const QSharedPointer<Sharee> shareWith)
: _account(account),
_id(id),
_path(path),
_shareType(shareType),
_permissions(permissions),
_shareWith(shareWith)
{
}
AccountPtr Share::account() const
{
return _account;
}
QString Share::getId() const
{
return _id;
}
Share::ShareType Share::getShareType() const
{
return _shareType;
}
QSharedPointer<Sharee> Share::getShareWith() const
{
return _shareWith;
}
void Share::setPermissions(Permissions permissions)
{
OcsShareJob *job = new OcsShareJob(_account);
connect(job, SIGNAL(shareJobFinished(QVariantMap, QVariant)), SLOT(slotPermissionsSet(QVariantMap, QVariant)));
connect(job, SIGNAL(ocsError(int, QString)), SLOT(slotOcsError(int, QString)));
job->setPermissions(getId(), permissions);
}
void Share::slotPermissionsSet(const QVariantMap &, const QVariant &value)
{
_permissions = (Permissions)value.toInt();
emit permissionsSet();
}
Share::Permissions Share::getPermissions() const
{
return _permissions;
}
void Share::deleteShare()
{
OcsShareJob *job = new OcsShareJob(_account);
connect(job, SIGNAL(shareJobFinished(QVariantMap, QVariant)), SLOT(slotDeleted()));
connect(job, SIGNAL(ocsError(int, const QString &)), SLOT(slotOcsError(int, const QString &)));
job->deleteShare(getId());
}
void Share::slotDeleted()
{
emit shareDeleted();
}
void Share::slotOcsError(int statusCode, const QString &message)
{
emit serverError(statusCode, message);
}
QUrl LinkShare::getLink() const
{
return _url;
}
QDate LinkShare::getExpireDate() const
{
return _expireDate;
}
bool LinkShare::isPasswordSet() const
{
return _passwordSet;
}
LinkShare::LinkShare(AccountPtr account,
const QString& id,
const QString& path,
Permissions permissions,
bool passwordSet,
const QUrl& url,
const QDate& expireDate)
: Share(account, id, path, Share::TypeLink, permissions),
_passwordSet(passwordSet),
_expireDate(expireDate),
_url(url)
{
}
bool LinkShare::getPublicUpload()
{
return ((_permissions & SharePermissionUpdate) &&
(_permissions & SharePermissionCreate));
}
void LinkShare::setPublicUpload(bool publicUpload)
{
OcsShareJob *job = new OcsShareJob(_account);
connect(job, SIGNAL(shareJobFinished(QVariantMap, QVariant)), SLOT(slotPublicUploadSet(QVariantMap, QVariant)));
connect(job, SIGNAL(ocsError(int, QString)), SLOT(slotOcsError(int, QString)));
job->setPublicUpload(getId(), publicUpload);
}
void LinkShare::slotPublicUploadSet(const QVariantMap&, const QVariant &value)
{
if (value.toBool()) {
_permissions = SharePermissionRead | SharePermissionUpdate | SharePermissionCreate;
} else {
_permissions = SharePermissionRead;
}
emit publicUploadSet();
}
void LinkShare::setPassword(const QString &password)
{
OcsShareJob *job = new OcsShareJob(_account);
connect(job, SIGNAL(shareJobFinished(QVariantMap, QVariant)), SLOT(slotPasswordSet(QVariantMap, QVariant)));
connect(job, SIGNAL(ocsError(int, QString)), SLOT(slotSetPasswordError(int,QString)));
job->setPassword(getId(), password);
}
void LinkShare::slotPasswordSet(const QVariantMap&, const QVariant &value)
{
_passwordSet = value.toString() == "";
emit passwordSet();
}
void LinkShare::setExpireDate(const QDate &date)
{
OcsShareJob *job = new OcsShareJob(_account);
connect(job, SIGNAL(shareJobFinished(QVariantMap, QVariant)), SLOT(slotExpireDateSet(QVariantMap, QVariant)));
connect(job, SIGNAL(ocsError(int, QString)), SLOT(slotOcsError(int, QString)));
job->setExpireDate(getId(), date);
}
void LinkShare::slotExpireDateSet(const QVariantMap& reply, const QVariant &value)
{
auto data = reply.value("ocs").toMap().value("data").toMap();
/*
* If the reply provides a data back (more REST style)
* they use this date.
*/
if (data.value("expiration").isValid()) {
_expireDate = QDate::fromString(data.value("expiration").toString(), "yyyy-MM-dd 00:00:00");
} else {
_expireDate = value.toDate();
}
emit expireDateSet();
}
void LinkShare::slotSetPasswordError(int statusCode, const QString &message)
{
emit passwordSetError(statusCode, message);
}
ShareManager::ShareManager(AccountPtr account, QObject *parent)
: QObject(parent),
_account(account)
{
}
void ShareManager::createLinkShare(const QString &path,
const QString &password)
{
OcsShareJob *job = new OcsShareJob(_account);
connect(job, SIGNAL(shareJobFinished(QVariantMap, QVariant)), SLOT(slotLinkShareCreated(QVariantMap)));
connect(job, SIGNAL(ocsError(int, QString)), SLOT(slotOcsError(int, QString)));
job->createLinkShare(path, password);
}
void ShareManager::slotLinkShareCreated(const QVariantMap &reply)
{
QString message;
int code = OcsShareJob::getJsonReturnCode(reply, message);
/*
* Before we had decent sharing capabilities on the server a 403 "generally"
* meant that a share was password protected
*/
if (code == 403) {
emit linkShareRequiresPassword(message);
return;
}
//Parse share
auto data = reply.value("ocs").toMap().value("data").toMap();
QSharedPointer<LinkShare> share(parseLinkShare(data));
emit linkShareCreated(share);
}
void ShareManager::createShare(const QString& path,
const Share::ShareType shareType,
const QString shareWith,
const Share::Permissions permissions)
{
auto job = new OcsShareJob(_account);
// Store values that we need for creating this share later.
CreateShare continuation;
continuation.path = path;
continuation.shareType = shareType;
continuation.shareWith = shareWith;
continuation.permissions = permissions;
_jobContinuation[job] = QVariant::fromValue(continuation);
connect(job, SIGNAL(shareJobFinished(QVariantMap,QVariant)), SLOT(slotCreateShare(QVariantMap)));
connect(job, SIGNAL(ocsError(int,QString)), SLOT(slotOcsError(int,QString)));
job->getSharedWithMe();
}
void ShareManager::slotCreateShare(const QVariantMap &reply)
{
if (!_jobContinuation.contains(sender()))
return;
CreateShare cont = _jobContinuation[sender()].value<CreateShare>();
if (cont.path.isEmpty())
return;
_jobContinuation.remove(sender());
// Find existing share permissions (if this was shared with us)
Share::Permissions existingPermissions = SharePermissionDefault;
foreach (const QVariant & element, reply["ocs"].toMap()["data"].toList()) {
QVariantMap map = element.toMap();
if (map["file_target"] == cont.path)
existingPermissions = Share::Permissions(map["permissions"].toInt());
}
// Limit the permissions we request for a share to the ones the item
// was shared with initially.
if (cont.permissions == SharePermissionDefault) {
cont.permissions = existingPermissions;
} else if (existingPermissions != SharePermissionDefault) {
cont.permissions &= existingPermissions;
}
OcsShareJob *job = new OcsShareJob(_account);
connect(job, SIGNAL(shareJobFinished(QVariantMap, QVariant)), SLOT(slotShareCreated(QVariantMap)));
connect(job, SIGNAL(ocsError(int, QString)), SLOT(slotOcsError(int, QString)));
job->createShare(cont.path, cont.shareType, cont.shareWith, cont.permissions);
}
void ShareManager::slotShareCreated(const QVariantMap &reply)
{
//Parse share
auto data = reply.value("ocs").toMap().value("data").toMap();
QSharedPointer<Share> share(parseShare(data));
emit shareCreated(share);
}
void ShareManager::fetchShares(const QString &path)
{
OcsShareJob *job = new OcsShareJob(_account);
connect(job, SIGNAL(shareJobFinished(QVariantMap, QVariant)), SLOT(slotSharesFetched(QVariantMap)));
connect(job, SIGNAL(ocsError(int, QString)), SLOT(slotOcsError(int, QString)));
job->getShares(path);
}
void ShareManager::slotSharesFetched(const QVariantMap &reply)
{
auto tmpShares = reply.value("ocs").toMap().value("data").toList();
const QString versionString = _account->serverVersion();
qDebug() << Q_FUNC_INFO << versionString << "Fetched" << tmpShares.count() << "shares";
QList<QSharedPointer<Share>> shares;
foreach(const auto &share, tmpShares) {
auto data = share.toMap();
auto shareType = data.value("share_type").toInt();
QSharedPointer<Share> newShare;
if (shareType == Share::TypeLink) {
newShare = parseLinkShare(data);
} else {
newShare = parseShare(data);
}
shares.append(QSharedPointer<Share>(newShare));
}
qDebug() << Q_FUNC_INFO << "Sending " << shares.count() << "shares";
emit sharesFetched(shares);
}
QSharedPointer<LinkShare> ShareManager::parseLinkShare(const QVariantMap &data) {
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());
} else if (_account->serverVersionInt() >= (8 << 16)) {
// From ownCloud server version 8 on, a different share link scheme is used.
url = QUrl(Account::concatUrlPath(_account->url(), QString("index.php/s/%1").arg(data.value("token").toString())).toString());
} else {
QList<QPair<QString, QString>> queryArgs;
queryArgs.append(qMakePair(QString("service"), QString("files")));
queryArgs.append(qMakePair(QString("t"), data.value("token").toString()));
url = QUrl(Account::concatUrlPath(_account->url(), QLatin1String("public.php"), queryArgs).toString());
}
QDate expireDate;
if (data.value("expiration").isValid()) {
expireDate = QDate::fromString(data.value("expiration").toString(), "yyyy-MM-dd 00:00:00");
}
return QSharedPointer<LinkShare>(new LinkShare(_account,
data.value("id").toString(),
data.value("path").toString(),
(Share::Permissions)data.value("permissions").toInt(),
data.value("share_with").isValid(),
url,
expireDate));
}
QSharedPointer<Share> ShareManager::parseShare(const QVariantMap &data)
{
QSharedPointer<Sharee> sharee(new Sharee(data.value("share_with").toString(),
data.value("share_with_displayname").toString(),
(Sharee::Type)data.value("share_type").toInt()));
return QSharedPointer<Share>(new Share(_account,
data.value("id").toString(),
data.value("path").toString(),
(Share::ShareType)data.value("share_type").toInt(),
(Share::Permissions)data.value("permissions").toInt(),
sharee));
}
void ShareManager::slotOcsError(int statusCode, const QString &message)
{
emit serverError(statusCode, message);
}
}