File indexing completed on 2024-04-21 15:32:07

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