File indexing completed on 2025-01-19 10:46:01
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Martin Klapetek <mklapetek@kde.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "owncloudcontroller.h" 0008 0009 #include <KIO/DavJob> 0010 #include <KIO/Job> 0011 #include <KLocalizedString> 0012 #include <kio/global.h> 0013 0014 #include <QDebug> 0015 #include <QDomDocument> 0016 #include <QJsonDocument> 0017 #include <QJsonObject> 0018 #include <QString> 0019 0020 #include "../cloudurls.h" 0021 0022 OwncloudController::OwncloudController(QObject *parent) 0023 : QObject(parent) 0024 , m_errorMessage(QString()) 0025 , m_isWorking(false) 0026 { 0027 } 0028 0029 OwncloudController::~OwncloudController() 0030 { 0031 } 0032 0033 void OwncloudController::checkServer(const QString &username, const QString &password, const QString &path) 0034 { 0035 m_errorMessage.clear(); 0036 Q_EMIT errorMessageChanged(); 0037 0038 m_username = username; 0039 m_password = password; 0040 0041 checkServer(createStatusUrl(path)); 0042 } 0043 0044 void OwncloudController::checkServer(const QUrl &url) 0045 { 0046 qDebug() << "Checking for ownCloud instance at" << url; 0047 setWorking(true); 0048 KIO::TransferJob *job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo); 0049 job->setUiDelegate(nullptr); 0050 connect(job, SIGNAL(data(KIO::Job *, QByteArray)), SLOT(dataReceived(KIO::Job *, QByteArray))); 0051 connect(job, SIGNAL(finished(KJob *)), this, SLOT(fileChecked(KJob *))); 0052 } 0053 0054 void OwncloudController::figureOutServer(const QUrl &url) 0055 { 0056 if (/*url == QLatin1String("/") ||*/ url.isEmpty()) { 0057 serverCheckResult(false); 0058 return; 0059 } 0060 0061 m_json.clear(); 0062 0063 qDebug() << "Received url to figure out:" << url; 0064 // This needs 2x up cause first it just removes the status.php 0065 // and only the second call actually moves up 0066 QUrl urlUp = KIO::upUrl(KIO::upUrl(url)); 0067 urlUp.setPath(urlUp.path() + QLatin1Char('/') + QStringLiteral("status.php")); 0068 0069 if (urlUp != url) { 0070 checkServer(urlUp.adjusted(QUrl::NormalizePathSegments)); 0071 } else { 0072 serverCheckResult(false); 0073 } 0074 } 0075 0076 void OwncloudController::dataReceived(KIO::Job *job, const QByteArray &data) 0077 { 0078 Q_UNUSED(job); 0079 m_json.append(data); 0080 } 0081 0082 void OwncloudController::fileChecked(KJob *job) 0083 { 0084 KIO::TransferJob *kJob = qobject_cast<KIO::TransferJob *>(job); 0085 if (kJob->error()) { 0086 qDebug() << job->errorString(); 0087 qDebug() << job->errorText(); 0088 figureOutServer(kJob->url()); 0089 return; 0090 } 0091 0092 QJsonDocument parser = QJsonDocument::fromJson(m_json); 0093 QJsonObject map = parser.object(); 0094 if (!map.contains(QStringLiteral("version"))) { 0095 figureOutServer(kJob->url()); 0096 qDebug() << "No json"; 0097 return; 0098 } 0099 0100 m_server = kJob->url().adjusted(QUrl::RemoveFilename).toString(); 0101 qDebug() << "ownCloud appears to be running at the specified URL"; 0102 serverCheckResult(true); 0103 } 0104 0105 void OwncloudController::setWorking(bool start) 0106 { 0107 if (start == m_isWorking) { 0108 return; 0109 } 0110 0111 m_isWorking = start; 0112 Q_EMIT isWorkingChanged(); 0113 } 0114 0115 void OwncloudController::serverCheckResult(bool result) 0116 { 0117 if (!result) { 0118 m_errorMessage = i18n("Unable to connect to ownCloud at the given server URL. Please check the server URL."); 0119 setWorking(false); 0120 } else { 0121 m_errorMessage.clear(); 0122 0123 qDebug() << "Server URL ok, checking auth..."; 0124 0125 m_json.clear(); 0126 0127 QUrl url(m_server); 0128 0129 url.setUserName(m_username); 0130 url.setPassword(m_password); 0131 0132 if (!url.path().endsWith(QLatin1String("/"))) { 0133 url.setPath(url.path() + QLatin1Char('/')); 0134 } 0135 0136 url.setPath(url.path() + QLatin1String("remote.php/webdav")); 0137 0138 // Send a basic PROPFIND command to test access 0139 const QString requestStr = QStringLiteral( 0140 "<d:propfind xmlns:d=\"DAV:\">" 0141 "<d:prop>" 0142 "<d:current-user-principal />" 0143 "</d:prop>" 0144 "</d:propfind>"); 0145 0146 KIO::DavJob *job = KIO::davPropFind(url, QDomDocument(requestStr).toString(), QStringLiteral("1"), KIO::HideProgressInfo); 0147 connect(job, SIGNAL(finished(KJob *)), this, SLOT(authCheckResult(KJob *))); 0148 connect(job, SIGNAL(data(KIO::Job *, QByteArray)), SLOT(dataReceived(KIO::Job *, QByteArray))); 0149 0150 QVariantMap metadata{ 0151 {QStringLiteral("cookies"), QStringLiteral("none")}, 0152 {QStringLiteral("no-cache"), true}, 0153 }; 0154 0155 job->setMetaData(metadata); 0156 job->setUiDelegate(nullptr); 0157 job->start(); 0158 } 0159 0160 Q_EMIT errorMessageChanged(); 0161 } 0162 0163 void OwncloudController::authCheckResult(KJob *job) 0164 { 0165 if (job->error()) { 0166 qDebug() << job->errorString(); 0167 qDebug() << job->errorText(); 0168 } 0169 0170 KIO::DavJob *kJob = qobject_cast<KIO::DavJob *>(job); 0171 qDebug() << "Auth job finished, received error page:" << kJob->isErrorPage(); 0172 0173 if (kJob->isErrorPage()) { 0174 m_errorMessage = i18n("Unable to authenticate using the provided username and password"); 0175 } else { 0176 m_errorMessage.clear(); 0177 } 0178 0179 Q_EMIT errorMessageChanged(); 0180 0181 if (!kJob->isErrorPage()) { 0182 m_state = Services; 0183 Q_EMIT stateChanged(); 0184 } 0185 0186 setWorking(false); 0187 } 0188 0189 bool OwncloudController::isWorking() 0190 { 0191 return m_isWorking; 0192 } 0193 0194 QString OwncloudController::errorMessage() const 0195 { 0196 return m_errorMessage; 0197 } 0198 0199 void OwncloudController::finish(const QStringList &disabledServices) 0200 { 0201 QVariantMap data; 0202 data.insert(QStringLiteral("server"), m_server); 0203 0204 for (const QString &service : disabledServices) { 0205 data.insert(QStringLiteral("__service/") + service, false); 0206 } 0207 0208 QUrl serverUrl(m_server); 0209 0210 QUrl carddavUrl(serverUrl.adjusted(QUrl::StripTrailingSlash)); 0211 carddavUrl.setPath(carddavUrl.path() + QStringLiteral("/remote.php/carddav/addressbooks/%1").arg(m_username)); 0212 0213 QUrl webdavUrl(serverUrl.adjusted(QUrl::StripTrailingSlash)); 0214 webdavUrl.setPath(webdavUrl.path() + QStringLiteral("/remote.php/webdav")); 0215 0216 data.insert(QStringLiteral("carddavUrl"), carddavUrl); 0217 data.insert(QStringLiteral("dav/host"), carddavUrl.host()); 0218 data.insert(QStringLiteral("dav/storagePath"), webdavUrl.path()); 0219 0220 Q_EMIT wizardFinished(m_username, m_password, data); 0221 } 0222 0223 void OwncloudController::cancel() 0224 { 0225 Q_EMIT wizardCancelled(); 0226 } 0227 0228 QVariantList OwncloudController::availableServices() const 0229 { 0230 // TODO Find a way to not hardcode this 0231 return {QVariant::fromValue(Service{QStringLiteral("owncloud-storage"), i18n("Storage"), i18n("Storage integration")})}; 0232 }