Skip to content

Commit

Permalink
Add GUI login
Browse files Browse the repository at this point in the history
Use QtWebEngine for getting cookies and authorization code if login form contains recaptcha and downloader is compiled with -DUSE_QT_GUI=ON
  • Loading branch information
Sude- committed Mar 1, 2019
1 parent 01eed3e commit 1e8ebbf
Show file tree
Hide file tree
Showing 5 changed files with 347 additions and 118 deletions.
25 changes: 25 additions & 0 deletions CMakeLists.txt
Expand Up @@ -4,6 +4,13 @@ project (lgogdownloader LANGUAGES C CXX VERSION 3.4)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
set(LINK_LIBCRYPTO 0)

option(USE_QT_GUI "Build with Qt GUI login support" OFF)
if(USE_QT_GUI)
add_definitions(-DUSE_QT_GUI_LOGIN=1)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
endif(USE_QT_GUI)

find_program(READELF readelf DOC "Location of the readelf program")
find_program(GREP grep DOC "Location of the grep program")
find_package(Boost
Expand Down Expand Up @@ -51,6 +58,17 @@ file(GLOB SRC_FILES
src/ziputil.cpp
)

if(USE_QT_GUI)
find_package(Qt5Widgets CONFIG REQUIRED)
find_package(Qt5WebEngineWidgets CONFIG REQUIRED)

file(GLOB QT_GUI_SRC_FILES
src/gui_login.cpp
)
list(APPEND SRC_FILES ${QT_GUI_SRC_FILES})
endif(USE_QT_GUI)


set(GIT_CHECKOUT FALSE)
if(EXISTS ${PROJECT_SOURCE_DIR}/.git)
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/shallow)
Expand Down Expand Up @@ -127,6 +145,13 @@ if(LINK_LIBCRYPTO EQUAL 1)
)
endif(LINK_LIBCRYPTO EQUAL 1)

if(USE_QT_GUI)
target_link_libraries(${PROJECT_NAME}
PRIVATE Qt5::Widgets
PRIVATE Qt5::WebEngineWidgets
)
endif(USE_QT_GUI)

if(MSVC)
# Force to always compile with W4
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
Expand Down
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -13,6 +13,7 @@ This repository contains the code of unofficial [GOG](http://www.gog.com/) downl
* [boost](http://www.boost.org/) (regex, date-time, system, filesystem, program-options, iostreams)
* [libcrypto](https://www.openssl.org/) if libcurl is built with OpenSSL
* [zlib](https://www.zlib.net/)
* [qtwebengine](https://www.qt.io/) if built with -DUSE_QT_GUI=ON

## Make dependencies
* [cmake](https://cmake.org/) >= 3.0.0
Expand All @@ -26,7 +27,7 @@ This repository contains the code of unofficial [GOG](http://www.gog.com/) downl
libjsoncpp-dev liboauth-dev librhash-dev libtinyxml2-dev libhtmlcxx-dev \
libboost-system-dev libboost-filesystem-dev libboost-program-options-dev \
libboost-date-time-dev libboost-iostreams-dev help2man cmake libssl-dev \
pkg-config zlib1g-dev
pkg-config zlib1g-dev qtwebengine5-dev

## Build and install

Expand Down
41 changes: 41 additions & 0 deletions include/gui_login.h
@@ -0,0 +1,41 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://www.wtfpl.net/ for more details. */

#ifndef GUI_LOGIN_H
#define GUI_LOGIN_H

#include "config.h"
#include "util.h"
#include "globals.h"

#include <QObject>
#include <QWebEngineCookieStore>
#include <iostream>
#include <vector>

class GuiLogin : public QObject
{
Q_OBJECT

public:
GuiLogin();
virtual ~GuiLogin();

void Login();
std::string getCode();
std::vector<std::string> getCookies();

private:
QWebEngineCookieStore *cookiestore;
std::vector<std::string> cookies;
std::string auth_code;

public slots:
void loadFinished(bool success);
void cookieAdded(const QNetworkCookie &cookie);
};

#endif // GUI_LOGIN_H
134 changes: 134 additions & 0 deletions src/gui_login.cpp
@@ -0,0 +1,134 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://www.wtfpl.net/ for more details. */

#include "gui_login.h"

#include <QApplication>
#include <QtWidgets/QWidget>
#include <QtWebEngineWidgets/QWebEngineView>
#include <QStyle>
#include <QLayout>
#include <QDesktopWidget>
#include <QWebEngineProfile>

GuiLogin::GuiLogin()
{
// constructor
}

GuiLogin::~GuiLogin()
{
// destructor
}

void GuiLogin::loadFinished(bool success)
{
QWebEngineView *view = qobject_cast<QWebEngineView*>(sender());
std::string url = view->page()->url().toString().toUtf8().constData();
if (success && url.find("https://embed.gog.com/on_login_success") != std::string::npos)
{
std::string find_str = "code=";
auto pos = url.find(find_str);
if (pos != std::string::npos)
{
pos += find_str.length();
std::string code;
code.assign(url.begin()+pos, url.end());
if (!code.empty())
{
this->auth_code = code;
QCoreApplication::exit();
}
}
}
}

void GuiLogin::cookieAdded(const QNetworkCookie& cookie)
{
std::string raw_cookie = cookie.toRawForm().toStdString();
if (!raw_cookie.empty())
{
std::string set_cookie = "Set-Cookie: " + raw_cookie;
bool duplicate = false;
for (auto cookie : this->cookies)
{
if (set_cookie == cookie)
{
duplicate = true;
break;
}
}
if (!duplicate)
this->cookies.push_back(set_cookie);
}
}

void GuiLogin::Login()
{
QByteArray redirect_uri = QUrl::toPercentEncoding(QString::fromStdString(Globals::galaxyConf.getRedirectUri()));
std::string auth_url = "https://auth.gog.com/auth?client_id=" + Globals::galaxyConf.getClientId() + "&redirect_uri=" + redirect_uri.toStdString() + "&response_type=code";
QUrl url = QString::fromStdString(auth_url);

std::vector<char> version_string(
Globals::globalConfig.sVersionString.c_str(),
Globals::globalConfig.sVersionString.c_str() + Globals::globalConfig.sVersionString.size() + 1
);

int argc = 1;
char *argv[] = {&version_string[0]};
QApplication app(argc, argv);

QWidget window;
QVBoxLayout *layout = new QVBoxLayout;
QSize window_size(440, 540);

window.setGeometry(
QStyle::alignedRect(
Qt::LeftToRight,
Qt::AlignCenter,
window_size,
qApp->desktop()->availableGeometry()
)
);

QWebEngineView *webengine = new QWebEngineView(&window);
layout->addWidget(webengine);
QWebEngineProfile profile;
profile.setHttpUserAgent(QString::fromStdString(Globals::globalConfig.curlConf.sUserAgent));
QWebEnginePage page(&profile);
cookiestore = profile.cookieStore();

QObject::connect(
webengine, SIGNAL(loadFinished(bool)),
this, SLOT(loadFinished(bool))
);

QObject::connect(
this->cookiestore, SIGNAL(cookieAdded(const QNetworkCookie&)),
this, SLOT(cookieAdded(const QNetworkCookie&))
);

webengine->resize(window.frameSize());
webengine->setPage(&page);
webengine->setUrl(url);

window.setLayout(layout);
window.show();

app.exec();
}

std::string GuiLogin::getCode()
{
return this->auth_code;
}

std::vector<std::string> GuiLogin::getCookies()
{
return this->cookies;
}

#include "moc_gui_login.cpp"

0 comments on commit 1e8ebbf

Please sign in to comment.