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"