diff options
| author | Michele Calgaro <michele.calgaro@yahoo.it> | 2024-06-07 23:30:05 +0900 |
|---|---|---|
| committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2024-06-07 23:30:05 +0900 |
| commit | 17b259df9cb6b28779d4881b2b6c805ee2e48eea (patch) | |
| tree | 5ed61937459cb7081089111b0242c01ec178f1f3 /reader/src/network/authentication | |
| parent | 1cba8bce178eb2d6719c6f7f21e2c9352c5513a6 (diff) | |
| download | tde-ebook-reader-17b259df9cb6b28779d4881b2b6c805ee2e48eea.tar.gz tde-ebook-reader-17b259df9cb6b28779d4881b2b6c805ee2e48eea.zip | |
Rename to tde-ebook-reader
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'reader/src/network/authentication')
6 files changed, 998 insertions, 0 deletions
diff --git a/reader/src/network/authentication/NetworkAuthenticationManager.cpp b/reader/src/network/authentication/NetworkAuthenticationManager.cpp new file mode 100644 index 0000000..137388f --- /dev/null +++ b/reader/src/network/authentication/NetworkAuthenticationManager.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2009-2012 Geometer Plus <contact@geometerplus.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include "NetworkAuthenticationManager.h" + +#include "../NetworkLink.h" +#include "../NetworkErrors.h" + +NetworkAuthenticationManager::NetworkAuthenticationManager(const NetworkLink &link) : + Link(link), + UserNameOption(ZLCategoryKey::NETWORK, link.getSiteName(), "userName", ""), + SkipIPOption(ZLCategoryKey::NETWORK, link.getSiteName(), "skipIP", true) { +} + +NetworkAuthenticationManager::~NetworkAuthenticationManager() { +} + +bool NetworkAuthenticationManager::needsInitialization() { + return false; +} + +std::string NetworkAuthenticationManager::initialize(shared_ptr<ZLNetworkRequest::Listener> listener) { + listener->finished(); + return NetworkErrors::errorMessage(NetworkErrors::ERROR_UNSUPPORTED_OPERATION); +} + +bool NetworkAuthenticationManager::needPurchase(const NetworkBookItem &) { + return true; +} + +std::string NetworkAuthenticationManager::purchaseBook(const NetworkBookItem &, shared_ptr<ZLNetworkRequest::Listener> listener) { + std::string error = NetworkErrors::errorMessage(NetworkErrors::ERROR_UNSUPPORTED_OPERATION); + listener->finished(error); + return error; +} + + +std::string NetworkAuthenticationManager::topupAccountLink() { + return ""; +} + +std::string NetworkAuthenticationManager::currentAccount() { + return ""; +} + +bool NetworkAuthenticationManager::skipIPSupported() { + return false; +} + +bool NetworkAuthenticationManager::registrationSupported() { + return false; +} + +std::string NetworkAuthenticationManager::registerUser(const std::string &, const std::string &, const std::string &) { + return NetworkErrors::errorMessage(NetworkErrors::ERROR_UNSUPPORTED_OPERATION); +} + +bool NetworkAuthenticationManager::passwordRecoverySupported() { + return false; +} + +std::string NetworkAuthenticationManager::recoverPassword(const std::string &) { + return NetworkErrors::errorMessage(NetworkErrors::ERROR_UNSUPPORTED_OPERATION); +} diff --git a/reader/src/network/authentication/NetworkAuthenticationManager.h b/reader/src/network/authentication/NetworkAuthenticationManager.h new file mode 100644 index 0000000..75ae9dd --- /dev/null +++ b/reader/src/network/authentication/NetworkAuthenticationManager.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2009-2012 Geometer Plus <contact@geometerplus.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef __NETWORKAUTHENTICATIONMANAGER_H__ +#define __NETWORKAUTHENTICATIONMANAGER_H__ + +#include <shared_ptr.h> +#include <ZLOptions.h> +#include <ZLBoolean3.h> + +#include "../NetworkItems.h" +#include "../BookReference.h" + +class NetworkLink; + +class NetworkAuthenticationManager { + +public: + NetworkAuthenticationManager(const NetworkLink &link); + virtual ~NetworkAuthenticationManager(); + +public: + const NetworkLink &Link; + ZLStringOption UserNameOption; + ZLBooleanOption SkipIPOption; + +public: + struct AuthenticationStatus { + const ZLBoolean3 Status; + const std::string Message; + + AuthenticationStatus(bool status); + AuthenticationStatus(const std::string &msg); + }; + + virtual AuthenticationStatus isAuthorised(shared_ptr<ZLNetworkRequest::Listener> listener = 0) = 0; + virtual std::string authorise(const std::string &pwd, shared_ptr<ZLNetworkRequest::Listener> listener) = 0; // returns error message + virtual void logOut() = 0; + + virtual bool skipIPSupported(); + + virtual shared_ptr<BookReference> downloadReference(const NetworkBookItem &book) = 0; + +public: // Account specific methods (can be called only if authorised!!!) + virtual const std::string ¤tUserName() = 0; + virtual bool needsInitialization(); + virtual std::string initialize(shared_ptr<ZLNetworkRequest::Listener> listener); // returns error message + virtual bool needPurchase(const NetworkBookItem &book); // returns true if link must be purchased before downloading + virtual std::string purchaseBook(const NetworkBookItem &, shared_ptr<ZLNetworkRequest::Listener> listener); // returns error message + + virtual std::string topupAccountLink(); + virtual std::string currentAccount(); + + virtual const NetworkItem::List &purchasedBooks() const = 0; + +public: // new User Registration + virtual bool registrationSupported(); + virtual std::string registerUser(const std::string &login, const std::string &password, const std::string &email); + +public: // Password Recovery + virtual bool passwordRecoverySupported(); + virtual std::string recoverPassword(const std::string &email); + +private: // disable copying + NetworkAuthenticationManager(const NetworkAuthenticationManager &); + const NetworkAuthenticationManager &operator = (const NetworkAuthenticationManager &); +}; + +inline NetworkAuthenticationManager::AuthenticationStatus::AuthenticationStatus(bool status) : Status(status ? B3_TRUE : B3_FALSE) {} +inline NetworkAuthenticationManager::AuthenticationStatus::AuthenticationStatus(const std::string &msg) : Status(B3_UNDEFINED), Message(msg) {} + +#endif /* __NETWORKAUTHENTICATIONMANAGER_H__ */ diff --git a/reader/src/network/authentication/litres/LitResAuthenticationDataParser.cpp b/reader/src/network/authentication/litres/LitResAuthenticationDataParser.cpp new file mode 100644 index 0000000..b1b6c69 --- /dev/null +++ b/reader/src/network/authentication/litres/LitResAuthenticationDataParser.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2009-2012 Geometer Plus <contact@geometerplus.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include "LitResAuthenticationDataParser.h" + + +static const std::string TAG_AUTHORIZATION_OK = "catalit-authorization-ok"; +static const std::string TAG_AUTHORIZATION_FAILED = "catalit-authorization-failed"; + +static const std::string TAG_PURCHASE_OK = "catalit-purchase-ok"; +static const std::string TAG_PURCHASE_FAILED = "catalit-purchase-failed"; + +static const std::string TAG_DOWNLOAD_FAILED = "catalit-download-failed"; + +static const std::string TAG_REGISTRATION_FAILED = "catalit-registration-failed"; + +static const std::string TAG_PASSWORD_RECOVERY_OK = "catalit-pass-recover-ok"; +static const std::string TAG_PASSWORD_RECOVERY_FAILED = "catalit-pass-recover-failed"; + +LitResAuthenticationDataParser::LitResAuthenticationDataParser() { +} + +void LitResAuthenticationDataParser::startElementHandler(const char *tag, const char **attributes) { + myAttributes.clear(); + while (*attributes != 0) { + std::string name(*attributes++); + if (*attributes == 0) { + break; + } + std::string value(*attributes++); + myAttributes.insert(std::make_pair(name, value)); + } + processTag(tag); +} + + + + + +LitResLoginDataParser::LitResLoginDataParser(std::string &firstName, std::string &lastName, std::string &sid) : + myFirstName(firstName), myLastName(lastName), mySid(sid) { +} + +void LitResLoginDataParser::processTag(const std::string &tag) { + if (TAG_AUTHORIZATION_FAILED == tag) { + setErrorCode(NetworkErrors::ERROR_AUTHENTICATION_FAILED); + } else if (TAG_AUTHORIZATION_OK == tag) { + myFirstName = attributes()["first-name"]; + myLastName = attributes()["first-name"]; + mySid = attributes()["sid"]; + } +} + + +LitResPurchaseDataParser::LitResPurchaseDataParser(std::string &account, std::string &bookId) : + myAccount(account), myBookId(bookId) { +} + +void LitResPurchaseDataParser::processTag(const std::string &tag) { + if (TAG_AUTHORIZATION_FAILED == tag) { + setErrorCode(NetworkErrors::ERROR_AUTHENTICATION_FAILED); + } else { + myAccount = attributes()["account"]; + myBookId = attributes()["art"]; + if (TAG_PURCHASE_OK == tag) { + // nop + } else if (TAG_PURCHASE_FAILED == tag) { + const std::string &error = attributes()["error"]; + if ("1" == error) { + setErrorCode(NetworkErrors::ERROR_PURCHASE_NOT_ENOUGH_MONEY); + } else if ("2" == error) { + setErrorCode(NetworkErrors::ERROR_PURCHASE_MISSING_BOOK); + } else if ("3" == error) { + setErrorCode(NetworkErrors::ERROR_PURCHASE_ALREADY_PURCHASED); + } else { + setErrorCode(NetworkErrors::ERROR_INTERNAL); + } + } + } +} + + +/*LitResDownloadErrorDataParser::LitResDownloadErrorDataParser() { +} + +void LitResDownloadErrorDataParser::processTag(const std::string &tag) { + if (TAG_AUTHORIZATION_FAILED == tag) { + setErrorCode(NetworkErrors::ERROR_AUTHENTICATION_FAILED); + } else { + if (TAG_DOWNLOAD_FAILED == tag) { + const std::string &error = attributes()["error"]; + if ("1" == error) { + setErrorCode(NetworkErrors::ERROR_BOOK_NOT_PURCHASED); + } else if ("2" == error) { + setErrorCode(NetworkErrors::ERROR_DOWNLOAD_LIMIT_EXCEEDED); + } else { + setErrorCode(NetworkErrors::ERROR_INTERNAL); + } + } + } +}*/ + + +LitResRegisterUserDataParser::LitResRegisterUserDataParser(std::string &sid) : mySid(sid) { +} + +void LitResRegisterUserDataParser::processTag(const std::string &tag) { + if (TAG_REGISTRATION_FAILED == tag) { + const std::string &error = attributes()["error"]; + if ("1" == error) { + setErrorCode(NetworkErrors::ERROR_LOGIN_ALREADY_TAKEN); + } else if ("2" == error) { + setErrorCode(NetworkErrors::ERROR_LOGIN_WAS_NOT_SPECIFIED); + } else if ("3" == error) { + setErrorCode(NetworkErrors::ERROR_PASSWORD_WAS_NOT_SPECIFIED); + } else if ("4" == error) { + setErrorCode(NetworkErrors::ERROR_INVALID_EMAIL); + } else if ("5" == error) { + setErrorCode(NetworkErrors::ERROR_TOO_MANY_REGISTRATIONS); + } else { + setErrorCode(NetworkErrors::ERROR_INTERNAL); + } + } else if (TAG_AUTHORIZATION_OK == tag) { + mySid = attributes()["sid"]; + } +} + + +void LitResPasswordRecoveryDataParser::processTag(const std::string &tag) { + if (TAG_PASSWORD_RECOVERY_FAILED == tag) { + const std::string &error = attributes()["error"]; + if ("1" == error) { + setErrorCode(NetworkErrors::ERROR_NO_USER_EMAIL); + } else if ("2" == error) { + setErrorCode(NetworkErrors::ERROR_EMAIL_WAS_NOT_SPECIFIED); + } else { + setErrorCode(NetworkErrors::ERROR_INTERNAL); + } + } else if (TAG_PASSWORD_RECOVERY_OK == tag) { + // NOP + } +} diff --git a/reader/src/network/authentication/litres/LitResAuthenticationDataParser.h b/reader/src/network/authentication/litres/LitResAuthenticationDataParser.h new file mode 100644 index 0000000..60baa02 --- /dev/null +++ b/reader/src/network/authentication/litres/LitResAuthenticationDataParser.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2009-2012 Geometer Plus <contact@geometerplus.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef __LITRESAUTHENTICATIONDATAPARSER_H__ +#define __LITRESAUTHENTICATIONDATAPARSER_H__ + +#include <ZLXMLReader.h> + +#include "../../NetworkErrors.h" + + +class LitResAuthenticationDataParser : public ZLXMLReader { + +public: + LitResAuthenticationDataParser(); + +private: + void startElementHandler(const char *tag, const char **attributes); + +protected: + void setErrorCode(const std::string &msg); + std::map<std::string, std::string> &attributes(); + + virtual void processTag(const std::string &tag) = 0; + +private: + std::map<std::string, std::string> myAttributes; +}; + +inline void LitResAuthenticationDataParser::setErrorCode(const std::string &msg) { setErrorMessage(NetworkErrors::errorMessage(msg)); } +inline std::map<std::string, std::string> &LitResAuthenticationDataParser::attributes() { return myAttributes; } + + +class LitResLoginDataParser : public LitResAuthenticationDataParser { + +public: + LitResLoginDataParser(std::string &firstName, std::string &lastName, std::string &sid); + +private: + void processTag(const std::string &tag); + +private: + std::string &myFirstName; + std::string &myLastName; + std::string &mySid; +}; + + +class LitResPurchaseDataParser : public LitResAuthenticationDataParser { + +public: + LitResPurchaseDataParser(std::string &account, std::string &bookId); + +private: + void processTag(const std::string &tag); + +private: + std::string &myAccount; + std::string &myBookId; +}; + + +/*class LitResDownloadErrorDataParser : public LitResAuthenticationDataParser { + +public: + LitResDownloadErrorDataParser(); + +private: + void processTag(const std::string &tag); + +};*/ + +class LitResRegisterUserDataParser : public LitResAuthenticationDataParser { + +public: + LitResRegisterUserDataParser(std::string &sid); + +private: + void processTag(const std::string &tag); + +private: + std::string &mySid; +}; + +class LitResPasswordRecoveryDataParser : public LitResAuthenticationDataParser { + +private: + void processTag(const std::string &tag); +}; + +#endif /* __LITRESAUTHENTICATIONDATAPARSER_H__ */ diff --git a/reader/src/network/authentication/litres/LitResAuthenticationManager.cpp b/reader/src/network/authentication/litres/LitResAuthenticationManager.cpp new file mode 100644 index 0000000..e552b5c --- /dev/null +++ b/reader/src/network/authentication/litres/LitResAuthenticationManager.cpp @@ -0,0 +1,472 @@ +/* + * Copyright (C) 2009-2012 Geometer Plus <contact@geometerplus.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include <ZLNetworkUtil.h> +#include <ZLNetworkManager.h> +#include <ZLUserData.h> +#include <ZLExecutionUtil.h> + +#include "../../tree/NetworkLibrary.h" + +#include "../../litres/LitResBooksFeedParser.h" +#include "../../litres/LitResUtil.h" +#include "LitResAuthenticationManager.h" +#include "LitResAuthenticationDataParser.h" + +#include "../../NetworkErrors.h" +#include "../../NetworkLink.h" +#include "../../NetworkLinkCollection.h" + +LitResAuthenticationManager::LitResAuthenticationManager(const NetworkLink &link) : + NetworkAuthenticationManager(link), + mySidChecked(false), + mySidUserNameOption(ZLCategoryKey::NETWORK, link.getSiteName(), "sidUserName", ""), + mySidOption(ZLCategoryKey::NETWORK, link.getSiteName(), "sid", "") +{ +} + +class LitResAuthorisationScope : public ZLUserData { +public: + std::string firstName; + std::string lastName; + std::string newSid; + shared_ptr<ZLNetworkRequest::Listener> listener; +}; + +NetworkAuthenticationManager::AuthenticationStatus LitResAuthenticationManager::isAuthorised(shared_ptr<ZLNetworkRequest::Listener> listener) { + const bool useNetwork = !listener.isNull(); + bool authState = !mySidUserNameOption.value().empty() && !mySidOption.value().empty(); + if (mySidChecked || !useNetwork) { + if (!listener.isNull()) + listener->finished(authState ? std::string() : "Not authorised"); + return AuthenticationStatus(authState); + } + + if (!authState) { + mySidChecked = true; + mySidUserNameOption.setValue(""); + mySidOption.setValue(""); + listener->finished("Not authorised"); + return AuthenticationStatus(false); + } + + LitResAuthorisationScope *scope = new LitResAuthorisationScope; + scope->listener = listener; + shared_ptr<ZLXMLReader> xmlReader = new LitResLoginDataParser(scope->firstName, scope->lastName, scope->newSid); + + std::string url = Link.url(NetworkLink::URL_SIGN_IN); + ZLNetworkUtil::appendParameter(url, "sid", mySidOption.value()); + + shared_ptr<ZLNetworkRequest> networkData = ZLNetworkManager::Instance().createXMLParserRequest(url, xmlReader); + networkData->setListener(ZLExecutionUtil::createListener(scope, this, &LitResAuthenticationManager::onAuthorised)); + ZLNetworkManager::Instance().performAsync(networkData); + return AuthenticationStatus(std::string()); +} + +std::string LitResAuthenticationManager::authorise(const std::string &pwd, shared_ptr<ZLNetworkRequest::Listener> listener) { + LitResAuthorisationScope *scope = new LitResAuthorisationScope; + scope->listener = listener; + shared_ptr<ZLXMLReader> xmlReader = new LitResLoginDataParser(scope->firstName, scope->lastName, scope->newSid); + + std::string url = Link.url(NetworkLink::URL_SIGN_IN); + ZLNetworkUtil::appendParameter(url, "login", UserNameOption.value()); + ZLNetworkUtil::appendParameter(url, "pwd", pwd); + ZLNetworkUtil::appendParameter(url, "skip_ip", "1"); + + shared_ptr<ZLNetworkRequest> networkData = + ZLNetworkManager::Instance().createXMLParserRequest( + url, + xmlReader + ); + + networkData->setListener(ZLExecutionUtil::createListener(scope, this, &LitResAuthenticationManager::onAuthorised)); + return ZLNetworkManager::Instance().performAsync(networkData); +} + +void LitResAuthenticationManager::onAuthorised(ZLUserDataHolder &data, const std::string &error) { + LitResAuthorisationScope &scope = static_cast<LitResAuthorisationScope&>(*data.getUserData("scope")); + + if (error == NetworkErrors::errorMessage(NetworkErrors::ERROR_TIMEOUT_EXPIRED)) { + scope.listener->finished(error); + return; + } + + mySidChecked = true; + if (!error.empty()) { + mySidUserNameOption.setValue(""); + mySidOption.setValue(""); + } else { + mySidOption.setValue(scope.newSid); + mySidUserNameOption.setValue(UserNameOption.value()); + } + + scope.listener->finished(error); +} + + +void LitResAuthenticationManager::logOut() { + mySidChecked = true; + mySidUserNameOption.setValue(""); + mySidOption.setValue(""); + + myInitializedDataSid.clear(); + myPurchasedBooksIds.clear(); + myPurchasedBooksList.clear(); + myAccount.clear(); +} + +const std::string &LitResAuthenticationManager::currentUserName() { + return mySidUserNameOption.value(); +} + +bool LitResAuthenticationManager::needPurchase(const NetworkBookItem &book) { + return myPurchasedBooksIds.count(book.Id) == 0; +} + +class LitResPurchaseBookScope : public ZLUserData { +public: + std::string account; + std::string bookId; + const NetworkBookItem *book; + shared_ptr<ZLNetworkRequest::Listener> listener; +}; + +std::string LitResAuthenticationManager::purchaseBook(const NetworkBookItem &book, shared_ptr<ZLNetworkRequest::Listener> listener) { + const std::string &sid = mySidOption.value(); + std::string error; + if (sid.empty()) { + error = NetworkErrors::errorMessage(NetworkErrors::ERROR_AUTHENTICATION_FAILED); + listener->finished(error); + return error; + } + + shared_ptr<BookReference> reference = book.reference(BookReference::BUY); + if (reference.isNull()) { + // TODO: add correct error message + error = "Oh, that's impossible"; + listener->finished(error); + return error; + } + std::string query = reference->URL; + ZLNetworkUtil::appendParameter(query, "sid", sid); + + LitResPurchaseBookScope *scope = new LitResPurchaseBookScope; + scope->book = &book; + scope->listener = listener; + + shared_ptr<ZLXMLReader> xmlReader = new LitResPurchaseDataParser(scope->account, scope->bookId); + shared_ptr<ZLNetworkRequest> networkData = ZLNetworkManager::Instance().createXMLParserRequest(query, xmlReader); + networkData->setListener(ZLExecutionUtil::createListener(scope, this, &LitResAuthenticationManager::onBookPurchased)); + return ZLNetworkManager::Instance().performAsync(networkData); +} + +void LitResAuthenticationManager::onBookPurchased(ZLUserDataHolder &data, const std::string &error) { + LitResPurchaseBookScope &scope = static_cast<LitResPurchaseBookScope&>(*data.getUserData("scope")); + shared_ptr<ZLNetworkRequest::Listener> listener = scope.listener; + if (!scope.account.empty()) { + myAccount = BuyBookReference::price(scope.account, "RUB"); + } + if (error == NetworkErrors::errorMessage(NetworkErrors::ERROR_AUTHENTICATION_FAILED)) { + mySidChecked = true; + mySidUserNameOption.setValue(""); + mySidOption.setValue(""); + } + const std::string alreadyPurchasedError = NetworkErrors::errorMessage(NetworkErrors::ERROR_PURCHASE_ALREADY_PURCHASED); + if (error != alreadyPurchasedError) { + if (!error.empty()) { + listener->finished(error); + return; + } + if (scope.bookId != scope.book->Id) { + listener->finished(NetworkErrors::errorMessage(NetworkErrors::ERROR_SOMETHING_WRONG, Link.getSiteName())); + return; + } + } + myPurchasedBooksIds.insert(scope.book->Id); + myPurchasedBooksList.push_back(new NetworkBookItem(*scope.book, 0)); + listener->finished(error); +} + +shared_ptr<BookReference> LitResAuthenticationManager::downloadReference(const NetworkBookItem &book) { + const std::string &sid = mySidOption.value(); + if (sid.empty()) { + return 0; + } + shared_ptr<BookReference> reference = + book.reference(BookReference::DOWNLOAD_FULL_CONDITIONAL); + if (reference.isNull()) { + return 0; + } + std::string url = reference->URL; + ZLNetworkUtil::appendParameter(url, "sid", sid); + return new DecoratedBookReference(*reference, url); +} + +void LitResAuthenticationManager::collectPurchasedBooks(NetworkItem::List &list) { + list.assign(myPurchasedBooksList.begin(), myPurchasedBooksList.end()); +} + +const std::set<std::string> &LitResAuthenticationManager::getPurchasedIds() const { + return myPurchasedBooksIds; +} + +const NetworkItem::List &LitResAuthenticationManager::purchasedBooks() const { + return myPurchasedBooksList; +} + +std::string LitResAuthenticationManager::topupAccountLink() { + const std::string &sid = mySidOption.value(); + if (sid.empty()) { + return std::string(); + } + std::string url = Link.url(NetworkLink::URL_TOPUP); + ZLNetworkUtil::appendParameter(url, "sid", sid); + return url; +} + +std::string LitResAuthenticationManager::currentAccount() { + return myAccount; +} + +bool LitResAuthenticationManager::needsInitialization() { + const std::string &sid = mySidOption.value(); + if (sid.empty()) { + return false; + } + return sid != myInitializedDataSid; +} + +class LitResInitializationScope : public ZLUserData { +public: + std::string dummy; + std::string error; + shared_ptr<ZLNetworkRequest::Listener> listener; +}; + +std::string LitResAuthenticationManager::initialize(shared_ptr<ZLNetworkRequest::Listener> listener) { + const std::string &sid = mySidOption.value(); + if (sid.empty()) { + listener->finished(NetworkErrors::errorMessage(NetworkErrors::ERROR_AUTHENTICATION_FAILED)); + return NetworkErrors::errorMessage(NetworkErrors::ERROR_AUTHENTICATION_FAILED); + } + if (sid == myInitializedDataSid) { + listener->finished(std::string()); + return std::string(); + } + + LitResInitializationScope *scope = new LitResInitializationScope; + scope->listener = listener; + + shared_ptr<ZLNetworkRequest> request = loadPurchasedBooks(myPurchasedBooksIds, myPurchasedBooksList); + request->setListener(ZLExecutionUtil::createListener(scope, this, &LitResAuthenticationManager::onBooksLoaded)); + return ZLNetworkManager::Instance().performAsync(request); +} + +void LitResAuthenticationManager::onBooksLoaded(ZLUserDataHolder &data, const std::string &error) { + LitResInitializationScope &scope = static_cast<LitResInitializationScope&>(*data.getUserData("scope")); + + if (error == NetworkErrors::errorMessage(NetworkErrors::ERROR_TIMEOUT_EXPIRED)) { + scope.listener->finished(error); + return; + } + + scope.error = error; + shared_ptr<ZLNetworkRequest> request = loadAccount(scope.dummy); + request->setListener(ZLExecutionUtil::createListener(new ZLUserDataHolder(data), this, &LitResAuthenticationManager::onAccountReceived)); + ZLNetworkManager::Instance().performAsync(request); +} + +void LitResAuthenticationManager::onAccountReceived(ZLUserDataHolder &data, const std::string &error) { + LitResInitializationScope &scope = static_cast<LitResInitializationScope&>(*data.getUserData("scope")); + + if (error == NetworkErrors::errorMessage(NetworkErrors::ERROR_TIMEOUT_EXPIRED)) { + scope.listener->finished(error); + return; + } + + if (!error.empty() && !scope.error.empty()) { + scope.error.append("\n").append(error); + } else if (!error.empty()) { + scope.error = error; + } + if (!scope.error.empty()) { + myInitializedDataSid.clear(); + loadPurchasedBooksOnError(myPurchasedBooksIds, myPurchasedBooksList); + loadAccountOnError(); + scope.listener->finished(scope.error); + return; + } + myInitializedDataSid = mySidOption.value(); + loadPurchasedBooksOnSuccess(myPurchasedBooksIds, myPurchasedBooksList); + loadAccountOnSuccess(); + scope.listener->finished(); +} + +shared_ptr<ZLNetworkRequest> LitResAuthenticationManager::loadPurchasedBooks(std::set<std::string> &purchasedBooksIds, NetworkItem::List &purchasedBooksList) { + const std::string &sid = mySidOption.value(); + purchasedBooksIds.clear(); + purchasedBooksList.clear(); + + std::string query; + ZLNetworkUtil::appendParameter(query, "my", "1"); + ZLNetworkUtil::appendParameter(query, "sid", sid); + + return ZLNetworkManager::Instance().createXMLParserRequest( + LitResUtil::url(Link, "pages/catalit_browser/" + query), + new LitResBooksFeedParser(Link, purchasedBooksList) + ); +} + +void LitResAuthenticationManager::loadPurchasedBooksOnError(std::set<std::string> &purchasedBooksIds, NetworkItem::List &purchasedBooksList) { + purchasedBooksIds.clear(); + purchasedBooksList.clear(); +} + +void LitResAuthenticationManager::loadPurchasedBooksOnSuccess(std::set<std::string> &purchasedBooksIds, NetworkItem::List &purchasedBooksList) { + for (NetworkItem::List::iterator it = purchasedBooksList.begin(); it != purchasedBooksList.end(); ++it) { + NetworkBookItem &book = (NetworkBookItem&)**it; + book.Index = 0; + purchasedBooksIds.insert(book.Id); + } + + NetworkLibrary::Instance().invalidateVisibility(); + NetworkLibrary::Instance().synchronize(); + NetworkLibrary::Instance().refresh(); +} + +shared_ptr<ZLNetworkRequest> LitResAuthenticationManager::loadAccount(std::string &dummy1) { + const std::string &sid = mySidOption.value(); + + myAccount.clear(); + + std::string query; + ZLNetworkUtil::appendParameter(query, "sid", sid); + ZLNetworkUtil::appendParameter(query, "art", "0"); + + return ZLNetworkManager::Instance().createXMLParserRequest( + LitResUtil::url(Link, "pages/purchase_book/" + query), + new LitResPurchaseDataParser(myAccount, dummy1) + ); +} + +void LitResAuthenticationManager::loadAccountOnError() { + myAccount.clear(); +} + +void LitResAuthenticationManager::loadAccountOnSuccess() { + myAccount = BuyBookReference::price(myAccount, "RUB"); +} + +bool LitResAuthenticationManager::skipIPSupported() { + return true; +} + +bool LitResAuthenticationManager::registrationSupported() { + return true; +} + +std::string LitResAuthenticationManager::registerUser(const std::string &login, const std::string &password, const std::string &email) { + std::string newSid; + shared_ptr<ZLXMLReader> xmlReader = new LitResRegisterUserDataParser(newSid); + + std::string url = Link.url(NetworkLink::URL_SIGN_UP); + ZLNetworkUtil::appendParameter(url, "new_login", login); + ZLNetworkUtil::appendParameter(url, "new_pwd1", password); + ZLNetworkUtil::appendParameter(url, "mail", email); + + shared_ptr<ZLNetworkRequest> networkData = + ZLNetworkManager::Instance().createXMLParserRequest( + url, xmlReader + ); + std::string error = ZLNetworkManager::Instance().perform(networkData); + + mySidChecked = true; + if (!error.empty()) { + mySidUserNameOption.setValue(""); + mySidOption.setValue(""); + return error; + } + mySidOption.setValue(newSid); + mySidUserNameOption.setValue(login); + return ""; +} + +bool LitResAuthenticationManager::passwordRecoverySupported() { + return true; +} + +std::string LitResAuthenticationManager::recoverPassword(const std::string &email) { + std::string url = Link.url(NetworkLink::URL_RECOVER_PASSWORD); + ZLNetworkUtil::appendParameter(url, "mail", email); + + shared_ptr<ZLNetworkRequest> networkData = + ZLNetworkManager::Instance().createXMLParserRequest( + url, new LitResPasswordRecoveryDataParser() + ); + return ZLNetworkManager::Instance().perform(networkData); +} + +class LitResReloadPurchasedBooksScope : public ZLUserData { +public: + std::set<std::string> purchasedBooksIds; + NetworkItem::List purchasedBooksList; + shared_ptr<ZLNetworkRequest::Listener> Listener; +}; + +std::string LitResAuthenticationManager::reloadPurchasedBooks(shared_ptr<ZLNetworkRequest::Listener> listener) { + const std::string &sid = mySidOption.value(); + std::string error; + if (sid.empty()) { + error = NetworkErrors::errorMessage(NetworkErrors::ERROR_AUTHENTICATION_FAILED); + listener->finished(error); + return error; + } + if (sid != myInitializedDataSid) { + mySidChecked = true; + mySidUserNameOption.setValue(""); + mySidOption.setValue(""); + error = NetworkErrors::errorMessage(NetworkErrors::ERROR_AUTHENTICATION_FAILED); + listener->finished(error); + return error; + } + + LitResReloadPurchasedBooksScope *scope = new LitResReloadPurchasedBooksScope; + shared_ptr<ZLNetworkRequest> networkData = loadPurchasedBooks(scope->purchasedBooksIds, scope->purchasedBooksList); + scope->Listener = listener; + + networkData->setListener(ZLExecutionUtil::createListener(scope, this, &LitResAuthenticationManager::onBooksReloaded)); + return ZLNetworkManager::Instance().performAsync(networkData); +} + +void LitResAuthenticationManager::onBooksReloaded(ZLUserDataHolder &data, const std::string &error) { + LitResReloadPurchasedBooksScope &scope = static_cast<LitResReloadPurchasedBooksScope&>(*data.getUserData("scope")); + shared_ptr<ZLNetworkRequest::Listener> listener = scope.Listener; + if (!error.empty()) { + if (error == NetworkErrors::errorMessage(NetworkErrors::ERROR_AUTHENTICATION_FAILED)) { + logOut(); //should it logOut in this case? + } + listener->finished(error); + return; + } + loadPurchasedBooksOnSuccess(scope.purchasedBooksIds, scope.purchasedBooksList); + myPurchasedBooksIds = scope.purchasedBooksIds; + myPurchasedBooksList = scope.purchasedBooksList; + listener->finished(std::string()); +} + diff --git a/reader/src/network/authentication/litres/LitResAuthenticationManager.h b/reader/src/network/authentication/litres/LitResAuthenticationManager.h new file mode 100644 index 0000000..6aefa6d --- /dev/null +++ b/reader/src/network/authentication/litres/LitResAuthenticationManager.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2009-2012 Geometer Plus <contact@geometerplus.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef __LITRESAUTHENTICATIONMANAGER_H__ +#define __LITRESAUTHENTICATIONMANAGER_H__ + +#include <set> + +#include <ZLNetworkRequest.h> +#include <ZLUserData.h> + +#include "../NetworkAuthenticationManager.h" +#include "../../NetworkItems.h" + +class LitResAuthenticationManager : public NetworkAuthenticationManager { + +public: + LitResAuthenticationManager(const NetworkLink &link); + +public: + AuthenticationStatus isAuthorised(shared_ptr<ZLNetworkRequest::Listener> listener = 0); + std::string authorise(const std::string &pwd, shared_ptr<ZLNetworkRequest::Listener> listener); + void logOut(); + bool skipIPSupported(); + + const std::string ¤tUserName(); + bool needsInitialization(); + std::string initialize(shared_ptr<ZLNetworkRequest::Listener> listener); + bool needPurchase(const NetworkBookItem &book); + std::string purchaseBook(const NetworkBookItem &, shared_ptr<ZLNetworkRequest::Listener> listener); + shared_ptr<BookReference> downloadReference(const NetworkBookItem &book); + + std::string topupAccountLink(); + std::string currentAccount(); + + std::string reloadPurchasedBooks(shared_ptr<ZLNetworkRequest::Listener> listener); + void collectPurchasedBooks(NetworkItem::List &list); + const std::set<std::string> &getPurchasedIds() const; + const NetworkItem::List &purchasedBooks() const; + +private: + void onAuthorised(ZLUserDataHolder &data, const std::string &error); + void onBookPurchased(ZLUserDataHolder &data, const std::string &error); + void onBooksLoaded(ZLUserDataHolder &data, const std::string &error); + void onAccountReceived(ZLUserDataHolder &data, const std::string &error); + void onBooksReloaded(ZLUserDataHolder &data, const std::string &error); + +private: + shared_ptr<ZLNetworkRequest> loadPurchasedBooks(std::set<std::string> &purchasedBooksIds, NetworkItem::List &purchasedBooksList); + void loadPurchasedBooksOnError(std::set<std::string> &purchasedBooksIds, NetworkItem::List &purchasedBooksList); + void loadPurchasedBooksOnSuccess(std::set<std::string> &purchasedBooksIds, NetworkItem::List &purchasedBooksList); + + shared_ptr<ZLNetworkRequest> loadAccount(std::string &dummy1); + void loadAccountOnError(); + void loadAccountOnSuccess(); + +public: // new User Registration + bool registrationSupported(); + std::string registerUser(const std::string &login, const std::string &password, const std::string &email); + +public: // Password Recovery + bool passwordRecoverySupported(); + std::string recoverPassword(const std::string &email); + +private: + bool mySidChecked; + + ZLStringOption mySidUserNameOption; + ZLStringOption mySidOption; + + std::string myInitializedDataSid; + std::set<std::string> myPurchasedBooksIds; + NetworkItem::List myPurchasedBooksList; + std::string myAccount; +}; + +#endif /* __LITRESAUTHENTICATIONMANAGER_H__ */ |
