File indexing completed on 2024-11-24 04:17:00
0001 /* 0002 SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org> 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #include "nextcloudauthenticator.h" 0007 0008 #include <QDebug> 0009 #include <QDesktopServices> 0010 #include <QJsonDocument> 0011 #include <QJsonObject> 0012 #include <QNetworkAccessManager> 0013 #include <QNetworkReply> 0014 #include <QTimer> 0015 0016 NextcloudAuthenticator::NextcloudAuthenticator(QObject *parent) 0017 : QObject(parent) 0018 { 0019 } 0020 0021 NextcloudAuthenticator::~NextcloudAuthenticator() = default; 0022 0023 void NextcloudAuthenticator::setNetworkAccessManager(QNetworkAccessManager *nam) 0024 { 0025 m_nam = nam; 0026 } 0027 0028 void NextcloudAuthenticator::authenticate(const QUrl &baseUrl, const QString &appName) 0029 { 0030 Q_ASSERT(m_nam); 0031 0032 QUrl login2Url(baseUrl); 0033 login2Url.setPath(login2Url.path() + QLatin1String("/index.php/login/v2")); 0034 0035 QNetworkRequest req(login2Url); 0036 req.setHeader(QNetworkRequest::UserAgentHeader, appName); 0037 auto reply = m_nam->post(req, QByteArray()); 0038 connect(reply, &QNetworkReply::finished, this, [this, reply]() { post1Finished(reply); }); 0039 } 0040 0041 void NextcloudAuthenticator::post1Finished(QNetworkReply *reply) 0042 { 0043 reply->deleteLater(); 0044 if (reply->error() != QNetworkReply::NoError) { 0045 qWarning() << reply->errorString(); 0046 return; 0047 } 0048 0049 const auto obj = QJsonDocument::fromJson(reply->readAll()).object(); 0050 const auto loginUrl = QUrl(obj.value(QLatin1String("login")).toString()); 0051 QDesktopServices::openUrl(loginUrl); 0052 0053 const auto pollObj = obj.value(QLatin1String("poll")).toObject(); 0054 m_pollEndpoint = QUrl(pollObj.value(QLatin1String("endpoint")).toString()); 0055 m_pollToken = "token=" + pollObj.value(QLatin1String("token")).toString().toUtf8(); 0056 0057 QTimer::singleShot(std::chrono::seconds(5), Qt::VeryCoarseTimer, this, &NextcloudAuthenticator::login2Poll); 0058 } 0059 0060 void NextcloudAuthenticator::login2Poll() 0061 { 0062 QNetworkRequest req(m_pollEndpoint); 0063 req.setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("application/x-www-form-urlencoded")); 0064 auto reply = m_nam->post(req, m_pollToken); 0065 connect(reply, &QNetworkReply::finished, this, [this, reply]() { 0066 reply->deleteLater(); 0067 if (reply->error() == QNetworkReply::ContentNotFoundError) { 0068 QTimer::singleShot(std::chrono::seconds(5), Qt::VeryCoarseTimer, this, &NextcloudAuthenticator::login2Poll); 0069 return; 0070 } 0071 if (reply->error() != QNetworkReply::NoError) { 0072 qWarning() << reply->errorString(); 0073 return; 0074 } 0075 0076 const auto obj = QJsonDocument::fromJson(reply->readAll()).object(); 0077 Q_EMIT authenticated(obj.value(QLatin1String("loginName")).toString(), obj.value(QLatin1String("appPassword")).toString()); 0078 }); 0079 }