File indexing completed on 2025-01-05 03:53:36

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2011-03-22
0007  * Description : a Iface C++ interface
0008  *
0009  * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2011      by Alexandre Mendes <alex dot mendes1988 at gmail dot com>
0011  * SPDX-FileCopyrightText: 2011      by Peter Potrowl <peter dot potrowl at gmail dot com>
0012  * SPDX-FileCopyrightText: 2011      by Manuel Campomanes <campomanes dot manuel at gmail dot com>
0013  *
0014  * SPDX-License-Identifier: GPL-2.0-or-later
0015  *
0016  * ============================================================ */
0017 
0018 #include "mediawiki_login.h"
0019 
0020 // Qt includes
0021 
0022 #include <QStringList>
0023 #include <QTimer>
0024 #include <QUrl>
0025 #include <QUrlQuery>
0026 #include <QXmlStreamReader>
0027 #include <QNetworkCookie>
0028 #include <QNetworkReply>
0029 #include <QNetworkRequest>
0030 
0031 // Local includes
0032 
0033 #include "mediawiki_iface.h"
0034 #include "mediawiki_job_p.h"
0035 
0036 namespace MediaWiki
0037 {
0038 
0039 class Q_DECL_HIDDEN LoginPrivate : public JobPrivate
0040 {
0041 
0042 public:
0043 
0044     LoginPrivate(Iface& MediaWiki, const QString& login, const QString& password)
0045         : JobPrivate(MediaWiki),
0046           login(login),
0047           password(password)
0048     {
0049     }
0050 
0051     static int error(const QString& error)
0052     {
0053         QStringList list;
0054         list << QStringLiteral("NoName")
0055              << QStringLiteral("Illegal")
0056              << QStringLiteral("NotExists")
0057              << QStringLiteral("EmptyPass")
0058              << QStringLiteral("WrongPass")
0059              << QStringLiteral("WrongPluginPass")
0060              << QStringLiteral("CreateBlocked")
0061              << QStringLiteral("Throttled")
0062              << QStringLiteral("Blocked")
0063              << QStringLiteral("NeedToken");
0064 
0065         int ret = list.indexOf(error);
0066 
0067         if (ret == -1)
0068         {
0069             ret = 0;
0070         }
0071 
0072         return (ret + (int)Login::LoginMissing);
0073     }
0074 
0075 public:
0076 
0077     QUrl    baseUrl;
0078     QString login;
0079     QString password;
0080     QString lgsessionid;
0081     QString lgtoken;
0082 };
0083 
0084 Login::Login(Iface& MediaWiki, const QString& login, const QString& password, QObject* const parent)
0085     : Job(*new LoginPrivate(MediaWiki, login, password), parent)
0086 {
0087 }
0088 
0089 Login::~Login()
0090 {
0091 }
0092 
0093 void Login::start()
0094 {
0095     QTimer::singleShot(0, this, SLOT(doWorkSendRequest()));
0096 }
0097 
0098 void Login::doWorkSendRequest()
0099 {
0100     Q_D(Login);
0101 
0102     // Set the url
0103     QUrl url   = d->MediaWiki.url();
0104     d->baseUrl = url;
0105 
0106     QUrlQuery query;
0107     query.addQueryItem(QStringLiteral("format"), QStringLiteral("xml"));
0108     query.addQueryItem(QStringLiteral("action"), QStringLiteral("login"));
0109     query.addQueryItem(QStringLiteral("lgname"), d->login);
0110     query.addQueryItem(QStringLiteral("lgpassword"), d->password);
0111 
0112     // Set the request
0113     QNetworkRequest request(url);
0114     request.setRawHeader(QByteArrayLiteral("User-Agent"), d->MediaWiki.userAgent().toUtf8());
0115     request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded"));
0116 
0117     // Send the request
0118     d->reply = d->manager->post(request, query.toString().toUtf8());
0119 
0120     connect(d->reply, SIGNAL(finished()),
0121             this, SLOT(doWorkProcessReply()));
0122 }
0123 
0124 void Login::doWorkProcessReply()
0125 {
0126     Q_D(Login);
0127 
0128     disconnect(d->reply, SIGNAL(finished()),
0129                this, SLOT(doWorkProcessReply()));
0130 
0131     if (d->reply->error() != QNetworkReply::NoError)
0132     {
0133         this->setError(Job::NetworkError);
0134         d->reply->close();
0135         d->reply->deleteLater();
0136         emitResult();
0137         return;
0138     }
0139 
0140     QXmlStreamReader reader(d->reply);
0141 
0142     while (!reader.atEnd() && !reader.hasError())
0143     {
0144         QXmlStreamReader::TokenType token = reader.readNext();
0145 
0146         if (token == QXmlStreamReader::StartElement)
0147         {
0148             QXmlStreamAttributes attrs = reader.attributes();
0149 
0150             if (reader.name() == QLatin1String("login"))
0151             {
0152                 if (attrs.value(QStringLiteral("result")).toString() == QLatin1String("Success"))
0153                 {
0154                     this->setError(Job::NoError);
0155                     d->lgtoken     = attrs.value(QStringLiteral("lgtoken")).toString();
0156                     d->lgsessionid = attrs.value(QStringLiteral("sessionid")).toString();
0157 
0158                     if (d->manager->cookieJar()->cookiesForUrl(d->MediaWiki.url()).isEmpty())
0159                     {
0160                         QList<QNetworkCookie> cookies;
0161                         QString prefix = attrs.value(QStringLiteral("cookieprefix")).toString();
0162 
0163                         QString prefixSession = prefix;
0164                         prefixSession.append(QStringLiteral("_session"));
0165                         QNetworkCookie cookie1(prefixSession.toUtf8(),attrs.value(QStringLiteral("sessionid")).toString().toUtf8());
0166                         cookies.append(cookie1);
0167 
0168                         QString prefixUserName = prefix;
0169                         prefixUserName.append(QStringLiteral("UserName"));
0170                         QNetworkCookie cookie2(prefixUserName.toUtf8(),attrs.value(QStringLiteral("lgusername")).toString().toUtf8());
0171                         cookies.append(cookie2);
0172 
0173                         QString prefixUserID = prefix;
0174                         prefixUserID.append(QStringLiteral("UserID"));
0175                         QNetworkCookie cookie3(prefixUserID.toUtf8(),attrs.value(QStringLiteral("lguserid")).toString().toUtf8());
0176                         cookies.append(cookie3);
0177 
0178                         QString prefixToken = prefix;
0179                         prefixToken.append(QStringLiteral("Token"));
0180                         QNetworkCookie cookie4(prefixToken.toUtf8(),attrs.value(QStringLiteral("lgtoken")).toString().toUtf8());
0181                         cookies.append(cookie4);
0182 
0183                         d->manager->cookieJar()->setCookiesFromUrl(cookies, d->MediaWiki.url());
0184                     }
0185 
0186                     d->reply->close();
0187                     d->reply->deleteLater();
0188                     emitResult();
0189                     return;
0190                 }
0191                 else if (attrs.value(QStringLiteral("result")).toString() == QLatin1String("NeedToken"))
0192                 {
0193                     this->setError(Job::NoError);
0194                     d->lgtoken     = attrs.value(QStringLiteral("token")).toString();
0195                     d->lgsessionid = attrs.value(QStringLiteral("sessionid")).toString();
0196 
0197                     if (d->manager->cookieJar()->cookiesForUrl(d->MediaWiki.url()).isEmpty())
0198                     {
0199                         QString prefix = attrs.value(QStringLiteral("cookieprefix")).toString();
0200                         prefix.append(QStringLiteral("_session"));
0201                         QNetworkCookie cookie(prefix.toUtf8(),QString(d->lgsessionid).toUtf8());
0202                         QList<QNetworkCookie> cookies;
0203                         cookies.append(cookie);
0204                         d->manager->cookieJar()->setCookiesFromUrl(cookies, d->MediaWiki.url());
0205                     }
0206                 }
0207                 else if (attrs.value(QStringLiteral("result")).toString() == QLatin1String("WrongToken"))
0208                 {
0209                     this->setError(LoginPrivate::error(attrs.value(QStringLiteral("result")).toString()));
0210                     d->reply->close();
0211                     d->reply->deleteLater();
0212                     emitResult();
0213                     return;
0214                 }
0215                 else if (attrs.value(QStringLiteral("result")).toString() == QLatin1String("Failed"))
0216                 {
0217                     this->setError(LoginPrivate::error(attrs.value(QStringLiteral("result")).toString()));
0218                     d->reply->close();
0219                     d->reply->deleteLater();
0220                     emitResult();
0221                     return;
0222                 }
0223             }
0224             else if (reader.name() == QLatin1String("error"))
0225             {
0226                 this->setError(LoginPrivate::error(attrs.value(QStringLiteral("code")).toString()));
0227                 d->reply->close();
0228                 d->reply->deleteLater();
0229                 emitResult();
0230                 return;
0231             }
0232         }
0233         else if (token == QXmlStreamReader::Invalid && reader.error() != QXmlStreamReader::PrematureEndOfDocumentError)
0234         {
0235             this->setError(XmlError);
0236             d->reply->close();
0237             d->reply->deleteLater();
0238             emitResult();
0239             return;
0240         }
0241     }
0242     d->reply->close();
0243     d->reply->deleteLater();
0244 
0245     QUrl url = d->baseUrl;
0246 
0247     QUrlQuery query;
0248     query.addQueryItem(QStringLiteral("format"), QStringLiteral("xml"));
0249     query.addQueryItem(QStringLiteral("action"), QStringLiteral("login"));
0250     query.addQueryItem(QStringLiteral("lgname"), d->login);
0251     query.addQueryItem(QStringLiteral("lgpassword"), d->password);
0252     query.addQueryItem(QStringLiteral("lgtoken"), (d->lgtoken).replace(QStringLiteral("+"), QStringLiteral("%2B")));
0253 
0254     // Set the request
0255     QNetworkRequest request(url);
0256     request.setRawHeader("User-Agent", d->MediaWiki.userAgent().toUtf8());
0257     request.setRawHeader("Cookie", d->manager->cookieJar()->cookiesForUrl(d->MediaWiki.url()).at(0).toRawForm());
0258     request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded"));
0259 
0260     // Send the request
0261     d->reply = d->manager->post(request, query.toString().toUtf8());
0262     connectReply();
0263 
0264     connect(d->reply, SIGNAL(finished()),
0265             this, SLOT(doWorkProcessReply()));
0266 }
0267 
0268 } // namespace MediaWiki
0269 
0270 #include "moc_mediawiki_login.cpp"