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