owncloudcontroller.cpp 6.22 KB
Newer Older
1
2
3
4
5
/*
 *  SPDX-FileCopyrightText: 2015 Martin Klapetek <mklapetek@kde.org>
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 */
6

7
#include "owncloudcontroller.h"
8

9
#include <KIO/DavJob>
10
#include <KIO/Job>
11
#include <KLocalizedString>
12
#include <kio/global.h>
13

14
#include <QDebug>
15
16
17
#include <QJsonDocument>
#include <QJsonObject>

18
19
#include "../cloudurls.h"

20
OwncloudController::OwncloudController(QObject *parent)
21
22
23
    : QObject(parent)
    , m_errorMessage(QString())
    , m_isWorking(false)
24
25
26
{
}

27
OwncloudController::~OwncloudController()
28
29
30
{
}

31
void OwncloudController::checkServer(const QString &username, const QString &password, const QString &path)
32
33
34
35
36
37
38
{
    m_errorMessage.clear();
    Q_EMIT errorMessageChanged();

    m_username = username;
    m_password = password;

39
    checkServer(createStatusUrl(path));
40
41
}

42
void OwncloudController::checkServer(const QUrl &url)
43
44
45
46
{
    qDebug() << "Checking for ownCloud instance at" << url;
    setWorking(true);
    KIO::TransferJob *job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
47
    job->setUiDelegate(nullptr);
48
49
    connect(job, SIGNAL(data(KIO::Job *, QByteArray)), SLOT(dataReceived(KIO::Job *, QByteArray)));
    connect(job, SIGNAL(finished(KJob *)), this, SLOT(fileChecked(KJob *)));
50
51
}

52
void OwncloudController::figureOutServer(const QUrl &url)
53
54
{
    if (/*url == QLatin1String("/") ||*/ url.isEmpty()) {
55
        serverCheckResult(false);
56
57
58
59
60
61
62
63
64
        return;
    }

    m_json.clear();

    qDebug() << "Received url to figure out:" << url;
    // This needs 2x up cause first it just removes the status.php
    // and only the second call actually moves up
    QUrl urlUp = KIO::upUrl(KIO::upUrl(url));
65
    urlUp.setPath(urlUp.path() + QLatin1Char('/') + QStringLiteral("status.php"));
66
67
68
69

    if (urlUp != url) {
        checkServer(urlUp.adjusted(QUrl::NormalizePathSegments));
    } else {
70
        serverCheckResult(false);
71
72
73
    }
}

74
void OwncloudController::dataReceived(KIO::Job *job, const QByteArray &data)
75
76
77
78
79
{
    Q_UNUSED(job);
    m_json.append(data);
}

80
void OwncloudController::fileChecked(KJob *job)
81
82
83
84
85
86
87
88
89
90
91
{
    KIO::TransferJob *kJob = qobject_cast<KIO::TransferJob *>(job);
    if (kJob->error()) {
        qDebug() << job->errorString();
        qDebug() << job->errorText();
        figureOutServer(kJob->url());
        return;
    }

    QJsonDocument parser = QJsonDocument::fromJson(m_json);
    QJsonObject map = parser.object();
92
    if (!map.contains(QStringLiteral("version"))) {
93
94
95
96
97
98
99
        figureOutServer(kJob->url());
        qDebug() << "No json";
        return;
    }

    m_server = kJob->url().adjusted(QUrl::RemoveFilename).toString();
    qDebug() << "ownCloud appears to be running at the specified URL";
100
    serverCheckResult(true);
101
102
}

103
void OwncloudController::setWorking(bool start)
104
105
106
107
108
109
110
111
112
{
    if (start == m_isWorking) {
        return;
    }

    m_isWorking = start;
    Q_EMIT isWorkingChanged();
}

113
void OwncloudController::serverCheckResult(bool result)
114
115
116
117
118
119
120
121
122
{
    if (!result) {
        m_errorMessage = i18n("Unable to connect to ownCloud at the given server URL. Please check the server URL.");
        setWorking(false);
    } else {
        m_errorMessage.clear();

        qDebug() << "Server URL ok, checking auth...";

123
124
        m_json.clear();

125
126
127
128
129
        QUrl url(m_server);

        url.setUserName(m_username);
        url.setPassword(m_password);

130
        if (!url.path().endsWith(QLatin1String("/"))) {
131
            url.setPath(url.path() + QLatin1Char('/'));
132
133
        }

134
        url.setPath(url.path() + QLatin1String("remote.php/webdav"));
135

136
137
138
139
140
141
142
143
        // Send a basic PROPFIND command to test access
        const QString requestStr = QStringLiteral(
            "<d:propfind xmlns:d=\"DAV:\">"
            "<d:prop>"
            "<d:current-user-principal />"
            "</d:prop>"
            "</d:propfind>");

144
        KIO::DavJob *job = KIO::davPropFind(url, QDomDocument(requestStr), QStringLiteral("1"), KIO::HideProgressInfo);
145
146
        connect(job, SIGNAL(finished(KJob *)), this, SLOT(authCheckResult(KJob *)));
        connect(job, SIGNAL(data(KIO::Job *, QByteArray)), SLOT(dataReceived(KIO::Job *, QByteArray)));
147

148
149
150
151
        QVariantMap metadata{
            {QStringLiteral("cookies"), QStringLiteral("none")},
            {QStringLiteral("no-cache"), true},
        };
152
153

        job->setMetaData(metadata);
154
        job->setUiDelegate(nullptr);
155
        job->start();
156
157
158
159
160
    }

    Q_EMIT errorMessageChanged();
}

161
void OwncloudController::authCheckResult(KJob *job)
162
163
164
165
166
167
{
    if (job->error()) {
        qDebug() << job->errorString();
        qDebug() << job->errorText();
    }

168
    KIO::DavJob *kJob = qobject_cast<KIO::DavJob *>(job);
169
170
    qDebug() << "Auth job finished, received error page:" << kJob->isErrorPage();

171
172
173
174
175
176
177
    if (kJob->isErrorPage()) {
        m_errorMessage = i18n("Unable to authenticate using the provided username and password");
    } else {
        m_errorMessage.clear();
    }

    Q_EMIT errorMessageChanged();
178

179
180
181
182
183
    if (!kJob->isErrorPage()) {
        m_state = Services;
        Q_EMIT stateChanged();
    }

184
185
186
    setWorking(false);
}

187
bool OwncloudController::isWorking()
188
189
190
191
{
    return m_isWorking;
}

192
QString OwncloudController::errorMessage() const
193
194
195
196
{
    return m_errorMessage;
}

197
void OwncloudController::finish(const QStringList &disabledServices)
198
199
{
    QVariantMap data;
200
    data.insert(QStringLiteral("server"), m_server);
201

202
    for (const QString &service : disabledServices) {
203
        data.insert(QStringLiteral("__service/") + service, false);
204
205
    }

206
207
208
    QUrl serverUrl(m_server);

    QUrl carddavUrl(serverUrl.adjusted(QUrl::StripTrailingSlash));
209
    carddavUrl.setPath(carddavUrl.path() + QStringLiteral("/remote.php/carddav/addressbooks/%1").arg(m_username));
210

211
212
213
    QUrl webdavUrl(serverUrl.adjusted(QUrl::StripTrailingSlash));
    webdavUrl.setPath(webdavUrl.path() + QStringLiteral("/remote.php/webdav"));

214
215
    data.insert(QStringLiteral("carddavUrl"), carddavUrl);
    data.insert(QStringLiteral("dav/host"), carddavUrl.host());
216
    data.insert(QStringLiteral("dav/storagePath"), webdavUrl.path());
217
218
219

    Q_EMIT wizardFinished(m_username, m_password, data);
}
220

221
222
223
224
225
void OwncloudController::cancel()
{
    Q_EMIT wizardCancelled();
}

226
227
228
QVariantList OwncloudController::availableServices() const
{
    // TODO Find a way to not hardcode this
229
    return {QVariant::fromValue(Service{QStringLiteral("owncloud-storage"), i18n("Storage"), i18n("Storage integration")})};
230
}