2015-09-07 14:50:01 +03:00
|
|
|
/*
|
|
|
|
* Copyright (C) by Roeland Jago Douma <roeland@famdouma.nl>
|
|
|
|
*
|
|
|
|
* 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-09-07 14:50:01 +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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ocsjob.h"
|
|
|
|
#include "networkjobs.h"
|
|
|
|
#include "account.h"
|
|
|
|
|
|
|
|
#include <QBuffer>
|
2017-04-26 12:38:10 +03:00
|
|
|
#include <QJsonDocument>
|
|
|
|
#include <QJsonObject>
|
2015-09-07 14:50:01 +03:00
|
|
|
|
|
|
|
namespace OCC {
|
|
|
|
|
2017-12-28 22:33:10 +03:00
|
|
|
Q_LOGGING_CATEGORY(lcOcs, "nextcloud.gui.sharing.ocs", QtInfoMsg)
|
2017-05-09 15:24:11 +03:00
|
|
|
|
2015-11-11 15:28:20 +03:00
|
|
|
OcsJob::OcsJob(AccountPtr account)
|
|
|
|
: AbstractNetworkJob(account, "")
|
2015-09-07 14:50:01 +03:00
|
|
|
{
|
2016-03-14 17:41:20 +03:00
|
|
|
_passStatusCodes.append(OCS_SUCCESS_STATUS_CODE);
|
2017-08-03 19:03:58 +03:00
|
|
|
_passStatusCodes.append(OCS_SUCCESS_STATUS_CODE_V2);
|
2018-04-09 11:54:30 +03:00
|
|
|
_passStatusCodes.append(OCS_NOT_MODIFIED_STATUS_CODE_V2);
|
2015-09-07 14:50:01 +03:00
|
|
|
setIgnoreCredentialFailure(true);
|
|
|
|
}
|
|
|
|
|
2015-10-15 21:54:52 +03:00
|
|
|
void OcsJob::setVerb(const QByteArray &verb)
|
2015-09-07 14:50:01 +03:00
|
|
|
{
|
|
|
|
_verb = verb;
|
|
|
|
}
|
|
|
|
|
2015-10-15 22:58:16 +03:00
|
|
|
void OcsJob::addParam(const QString &name, const QString &value)
|
2015-09-07 14:50:01 +03:00
|
|
|
{
|
2022-09-02 12:48:52 +03:00
|
|
|
_params.insert(name, value);
|
2015-09-07 14:50:01 +03:00
|
|
|
}
|
|
|
|
|
2015-10-15 21:54:52 +03:00
|
|
|
void OcsJob::addPassStatusCode(int code)
|
2015-09-07 14:50:01 +03:00
|
|
|
{
|
|
|
|
_passStatusCodes.append(code);
|
|
|
|
}
|
|
|
|
|
2015-10-29 13:09:10 +03:00
|
|
|
void OcsJob::appendPath(const QString &id)
|
2015-10-16 09:28:13 +03:00
|
|
|
{
|
2015-10-29 18:03:47 +03:00
|
|
|
setPath(path() + QLatin1Char('/') + id);
|
2015-10-16 09:28:13 +03:00
|
|
|
}
|
|
|
|
|
2018-04-09 11:54:30 +03:00
|
|
|
void OcsJob::addRawHeader(const QByteArray &headerName, const QByteArray &value)
|
|
|
|
{
|
|
|
|
_request.setRawHeader(headerName, value);
|
|
|
|
}
|
|
|
|
|
2022-09-02 12:48:52 +03:00
|
|
|
QString OcsJob::getParamValue(const QString &key) const
|
|
|
|
{
|
|
|
|
return _params.value(key);
|
|
|
|
}
|
|
|
|
|
2017-12-08 14:27:04 +03:00
|
|
|
static QUrlQuery percentEncodeQueryItems(
|
2022-09-02 12:48:52 +03:00
|
|
|
const QHash<QString, QString> &items)
|
2016-07-12 15:25:33 +03:00
|
|
|
{
|
2017-12-08 14:27:04 +03:00
|
|
|
QUrlQuery result;
|
|
|
|
// Note: QUrlQuery::setQueryItems() does not fully percent encode
|
|
|
|
// the query items, see #5042
|
2022-09-02 12:48:52 +03:00
|
|
|
for (auto it = std::cbegin(items); it != std::cend(items); ++it) {
|
2017-12-08 14:27:04 +03:00
|
|
|
result.addQueryItem(
|
2022-09-02 12:48:52 +03:00
|
|
|
QUrl::toPercentEncoding(it.key()),
|
|
|
|
QUrl::toPercentEncoding(it.value()));
|
2016-07-12 15:25:33 +03:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-10-15 21:54:52 +03:00
|
|
|
void OcsJob::start()
|
2015-09-07 14:50:01 +03:00
|
|
|
{
|
2018-04-09 11:54:30 +03:00
|
|
|
addRawHeader("Ocs-APIREQUEST", "true");
|
|
|
|
addRawHeader("Content-Type", "application/x-www-form-urlencoded");
|
2015-09-07 14:50:01 +03:00
|
|
|
|
2020-05-18 21:54:23 +03:00
|
|
|
auto *buffer = new QBuffer;
|
2015-10-15 22:58:16 +03:00
|
|
|
|
2017-12-08 14:27:04 +03:00
|
|
|
QUrlQuery queryItems;
|
2015-10-15 22:58:16 +03:00
|
|
|
if (_verb == "GET") {
|
2017-12-08 14:27:04 +03:00
|
|
|
queryItems = percentEncodeQueryItems(_params);
|
2015-10-15 22:58:16 +03:00
|
|
|
} else if (_verb == "POST" || _verb == "PUT") {
|
|
|
|
// Url encode the _postParams and put them in a buffer.
|
|
|
|
QByteArray postData;
|
2022-09-02 12:48:52 +03:00
|
|
|
for (auto it = std::cbegin(_params); it != std::cend(_params); ++it) {
|
2015-10-15 22:58:16 +03:00
|
|
|
if (!postData.isEmpty()) {
|
|
|
|
postData.append("&");
|
|
|
|
}
|
2022-09-02 12:48:52 +03:00
|
|
|
postData.append(QUrl::toPercentEncoding(it.key()));
|
2015-10-15 22:58:16 +03:00
|
|
|
postData.append("=");
|
2022-09-02 12:48:52 +03:00
|
|
|
postData.append(QUrl::toPercentEncoding(it.value()));
|
2015-09-07 14:50:01 +03:00
|
|
|
}
|
2015-10-15 22:58:16 +03:00
|
|
|
buffer->setData(postData);
|
2015-09-07 14:50:01 +03:00
|
|
|
}
|
2017-12-08 14:27:04 +03:00
|
|
|
queryItems.addQueryItem(QLatin1String("format"), QLatin1String("json"));
|
|
|
|
QUrl url = Utility::concatUrlPath(account()->url(), path(), queryItems);
|
2018-04-09 11:54:30 +03:00
|
|
|
sendRequest(_verb, url, _request, buffer);
|
2015-09-07 14:50:01 +03:00
|
|
|
AbstractNetworkJob::start();
|
|
|
|
}
|
|
|
|
|
2015-10-15 21:54:52 +03:00
|
|
|
bool OcsJob::finished()
|
2015-09-07 14:50:01 +03:00
|
|
|
{
|
2017-04-26 13:15:33 +03:00
|
|
|
const QByteArray replyData = reply()->readAll();
|
2015-09-07 14:50:01 +03:00
|
|
|
|
2023-02-03 20:38:52 +03:00
|
|
|
QJsonParseError error{};
|
2018-04-10 16:40:17 +03:00
|
|
|
QString message;
|
|
|
|
int statusCode = 0;
|
2017-04-26 13:15:33 +03:00
|
|
|
auto json = QJsonDocument::fromJson(replyData, &error);
|
2018-04-10 16:40:17 +03:00
|
|
|
|
|
|
|
// when it is null we might have a 304 so get status code from reply() and gives a warning...
|
2017-04-26 12:38:10 +03:00
|
|
|
if (error.error != QJsonParseError::NoError) {
|
2018-04-10 16:40:17 +03:00
|
|
|
statusCode = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
2017-03-30 14:46:20 +03:00
|
|
|
qCWarning(lcOcs) << "Could not parse reply to"
|
2015-10-15 22:58:16 +03:00
|
|
|
<< _verb
|
2016-10-25 13:04:22 +03:00
|
|
|
<< Utility::concatUrlPath(account()->url(), path())
|
2015-10-15 22:58:16 +03:00
|
|
|
<< _params
|
2017-04-26 12:38:10 +03:00
|
|
|
<< error.errorString()
|
2015-09-07 14:50:01 +03:00
|
|
|
<< ":" << replyData;
|
2018-04-10 16:40:17 +03:00
|
|
|
} else {
|
|
|
|
statusCode = getJsonReturnCode(json, message);
|
2015-09-07 14:50:01 +03:00
|
|
|
}
|
|
|
|
|
2018-04-10 16:40:17 +03:00
|
|
|
//... then it checks for the statusCode
|
2015-09-07 14:50:01 +03:00
|
|
|
if (!_passStatusCodes.contains(statusCode)) {
|
2017-03-30 14:46:20 +03:00
|
|
|
qCWarning(lcOcs) << "Reply to"
|
2015-10-15 22:58:16 +03:00
|
|
|
<< _verb
|
2016-10-25 13:04:22 +03:00
|
|
|
<< Utility::concatUrlPath(account()->url(), path())
|
2015-10-15 22:58:16 +03:00
|
|
|
<< _params
|
2015-09-07 14:50:01 +03:00
|
|
|
<< "has unexpected status code:" << statusCode << replyData;
|
2015-10-29 18:56:23 +03:00
|
|
|
emit ocsError(statusCode, message);
|
2018-04-10 16:40:17 +03:00
|
|
|
|
2015-10-29 18:56:23 +03:00
|
|
|
} else {
|
2018-04-09 11:54:30 +03:00
|
|
|
// save new ETag value
|
|
|
|
if(reply()->rawHeaderList().contains("ETag"))
|
|
|
|
emit etagResponseHeaderReceived(reply()->rawHeader("ETag"), statusCode);
|
|
|
|
|
|
|
|
emit jobFinished(json, statusCode);
|
2015-09-07 14:50:01 +03:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-04-26 12:38:10 +03:00
|
|
|
int OcsJob::getJsonReturnCode(const QJsonDocument &json, QString &message)
|
2015-09-07 14:50:01 +03:00
|
|
|
{
|
|
|
|
//TODO proper checking
|
2017-04-26 12:38:10 +03:00
|
|
|
auto meta = json.object().value("ocs").toObject().value("meta").toObject();
|
|
|
|
int code = meta.value("statuscode").toInt();
|
|
|
|
message = meta.value("message").toString();
|
2015-09-07 14:50:01 +03:00
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
}
|