diff --git a/src/bugzillaintegration/libbugzilla/bugzilla.cpp b/src/bugzillaintegration/libbugzilla/bugzilla.cpp index ace2251b..a81fd87a 100644 --- a/src/bugzillaintegration/libbugzilla/bugzilla.cpp +++ b/src/bugzillaintegration/libbugzilla/bugzilla.cpp @@ -1,58 +1,56 @@ /* Copyright 2019 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bugzilla.h" namespace Bugzilla { QString version(KJob *kjob) { const APIJob *job = qobject_cast(kjob); const QString version = job->object().value(QLatin1String("version")).toString(); return version; } APIJob *version(const Connection &connection) { return connection.get(QStringLiteral("/version")); } LoginDetails login(KJob *kjob) { const APIJob *job = qobject_cast(kjob); const auto obj = job->object(); const QString token = obj.value(QLatin1String("token")).toString(); const int id = obj.value(QLatin1String("id")).toInt(-1); return LoginDetails { id, token }; } APIJob *login(const QString &username, const QString &password, const Connection &connection) { QUrlQuery query; query.addQueryItem(QStringLiteral("login"), username); - // https://bugs.kde.org/show_bug.cgi?id=413920 - // Force encoding. QUrlQuery by default woudn't encode '+' and bugzilla doesn't like that. - query.addQueryItem(QStringLiteral("password"), QString::fromUtf8(QUrl::toPercentEncoding(password))); + query.addQueryItem(QStringLiteral("password"), password); query.addQueryItem(QStringLiteral("restrict_login"), QStringLiteral("true")); return connection.get(QStringLiteral("/login"), query); } } // namespace Bugzilla diff --git a/src/bugzillaintegration/libbugzilla/connection.cpp b/src/bugzillaintegration/libbugzilla/connection.cpp index 0122bf5f..a84764cc 100644 --- a/src/bugzillaintegration/libbugzilla/connection.cpp +++ b/src/bugzillaintegration/libbugzilla/connection.cpp @@ -1,114 +1,124 @@ /* Copyright 2019 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "connection.h" #include #include #include "bugzilla_debug.h" namespace Bugzilla { // Static container for global default connection. // We need a container here because the connection may be anything derived from // Connection and its effective type may change (e.g. in autotests). class GlobalConnection { public: ~GlobalConnection() { delete m_connection; } Connection *m_connection = new HTTPConnection; }; Q_GLOBAL_STATIC(GlobalConnection, s_connection) Connection &connection() { return *(s_connection->m_connection); } void setConnection(Connection *newConnection) { delete s_connection->m_connection; s_connection->m_connection = newConnection; } HTTPConnection::HTTPConnection(const QUrl &root, QObject *parent) : Connection(parent) , m_root(root) { } HTTPConnection::~HTTPConnection() { } void HTTPConnection::setToken(const QString &authToken) { m_token = authToken; } APIJob *HTTPConnection::get(const QString &path, const QUrlQuery &query) const { qCDebug(BUGZILLA_LOG) << path << query.toString(); auto job = new TransferAPIJob(KIO::get(url(path, query), KIO::Reload, KIO::HideProgressInfo)); return job; } APIJob *HTTPConnection::post(const QString &path, const QByteArray &data, const QUrlQuery &query) const { qCDebug(BUGZILLA_LOG) << path << query.toString(); auto job = new TransferAPIJob(KIO::http_post(url(path, query), data, KIO::HideProgressInfo)); return job; } APIJob *HTTPConnection::put(const QString &path, const QByteArray &data, const QUrlQuery &query) const { qCDebug(BUGZILLA_LOG) << path << query.toString(); auto job = new TransferAPIJob(KIO::put(url(path, query), KIO::HideProgressInfo)); job->setPutData(data); return job; } QUrl HTTPConnection::root() const { return m_root; } QUrl HTTPConnection::url(const QString &appendix, QUrlQuery query) const { QUrl url(m_root); url.setPath(m_root.path() + appendix); if (!m_token.isEmpty()) { query.addQueryItem(QStringLiteral("token"), m_token); } - url.setQuery(query); + // https://bugs.kde.org/show_bug.cgi?id=413920 + // Force encoding. QUrlQuery by default wouldn't encode '+' and bugzilla doesn't like that... + // For any query argument. Tested with username, password, and products (for bug search) + // on bugzilla 5.0.6. As a result let's force full encoding on every argument. + QUrlQuery escapedQuery(query); // copy delimiter properties and the like + escapedQuery.clear(); // but then throw away the values + for (const auto &pair : query.queryItems(QUrl::FullyDecoded)) { + escapedQuery.addQueryItem(pair.first, QString::fromUtf8(QUrl::toPercentEncoding(pair.second))); + } + + url.setQuery(escapedQuery); return url; } } // namespace Bugzilla