Skip to content

Commit

Permalink
kde-apps/libkgapi: Fix 2FA, add USE=nls and missing DEPEND
Browse files Browse the repository at this point in the history
Package-Manager: Portage-2.3.3, Repoman-2.3.1
  • Loading branch information
a17r committed Apr 27, 2017
1 parent 3cbdafb commit 88f5d2d
Show file tree
Hide file tree
Showing 4 changed files with 550 additions and 0 deletions.
168 changes: 168 additions & 0 deletions kde-apps/libkgapi/files/libkgapi-17.04.0-auth1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
From 68b89bce22d0da234345ccffb869ae6863592624 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= <[email protected]>
Date: Thu, 27 Apr 2017 17:22:27 +0200
Subject: [PATCH 1/3] Auth: Adapt to changes in Google OAuth token retrieval
process

URLs and HTML code have changed a bit, which breaks authentication. Hopefully
they won't change it too often in the future.
---
src/core/ui/authwidget_p.cpp | 109 ++++++++++++++++++++++++-------------------
src/core/ui/authwidget_p.h | 6 +++
2 files changed, 67 insertions(+), 48 deletions(-)

diff --git a/src/core/ui/authwidget_p.cpp b/src/core/ui/authwidget_p.cpp
index 6de33f5..75d38cd 100644
--- a/src/core/ui/authwidget_p.cpp
+++ b/src/core/ui/authwidget_p.cpp
@@ -112,11 +112,35 @@ void AuthWidgetPrivate::emitError(const enum Error errCode, const QString& msg)

void AuthWidgetPrivate::webviewUrlChanged(const QUrl &url)
{
- qCDebug(KGAPIDebug) << url;
+ qCDebug(KGAPIDebug) << "URLChange:" << url;

- /* Access token here - hide browser and tell user to wait until we
- * finish the authentication process ourselves */
- if (url.host() == QLatin1String("accounts.google.com") && url.path() == QLatin1String("/o/oauth2/approval")) {
+ if (!isGoogleHost(url)) {
+ return;
+ }
+
+ // Username and password inputs are loaded dynamically, so we only get
+ // urlChanged, but not urlFinished.
+ if (isUsernameFrame(url)) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ if (!username.isEmpty()) {
+ webview->page()->runJavaScript(QStringLiteral("document.getElementById(\"identifierId\").value = \"%1\";").arg(username));
+ }
+#endif
+ } else if (isPasswordFrame(url)) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ if (!password.isEmpty()) {
+ webview->page()->runJavaScript(QStringLiteral("var elems = document.getElementsByTagName(\"input\");"
+ "for (var i = 0; i < elems.length; i++) {"
+ " if (elems[i].type == \"password\" && elems[i].name == \"password\") {"
+ " elems[i].value = \"%1\";"
+ " break;"
+ " }"
+ "}").arg(password));
+ }
+#endif
+ } else if (isTokenPage(url)) {
+ /* Access token here - hide browser and tell user to wait until we
+ * finish the authentication process ourselves */
webview->setVisible(false);
progressbar->setVisible(false);
label->setVisible(true);
@@ -131,57 +155,46 @@ void AuthWidgetPrivate::webviewFinished(bool ok)
qCWarning(KGAPIDebug) << "Failed to load" << webview->url();
}

- QUrl url = webview->url();
- qCDebug(KGAPIDebug) << url;
-
- if (url.host() == QLatin1String("accounts.google.com") && url.path() == QLatin1String("/ServiceLogin")) {
- if (username.isEmpty() && password.isEmpty()) {
- return;
- }
-
-#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
- const auto js = QStringLiteral("document.getElementById(\"%1\").value = \"%2\";");
- if (!username.isEmpty()) {
- webview->page()->runJavaScript(js.arg(QStringLiteral("Email"), username));
- }
-
- if (!password.isEmpty()) {
- webview->page()->runJavaScript(js.arg(QStringLiteral("Passwd"), password));
- }
-#endif
+ const QUrl url = webview->url();
+ qCDebug(KGAPIDebug) << "URLFinished:" << url;

+ if (!isGoogleHost(url)) {
return;
}

- if (url.host() == QLatin1String("accounts.google.com") && url.path() == QLatin1String("/o/oauth2/approval")) {
- QString title = webview->title();
- QString token;
-
- if (title.startsWith(QLatin1String("success"), Qt::CaseInsensitive)) {
- int pos = title.indexOf(QLatin1String("code="));
- /* Skip the 'code=' string as well */
- token = title.mid (pos + 5);
+ if (isTokenPage(url)) {
+ const auto token = url.queryItemValue(QStringLiteral("approvalCode"));
+ if (!token.isEmpty()) {
+ qCDebug(KGAPIDebug) << "Got token: " << token;
+ auto fetch = new KGAPI2::NewTokensFetchJob(token, apiKey, secretKey);
+ connect(fetch, &Job::finished, this, &AuthWidgetPrivate::tokensReceived);
} else {
- webview->page()->toHtml([title](const QString &html) {
- qCDebug(KGAPIDebug) << "Parsing token page failed. Title:" << title;
- qCDebug(KGAPIDebug) << html;
- });
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ qCWarning(KGAPIDebug) << "Failed to parse token from URL, peaking into HTML...";
+ webview->page()->runJavaScript(
+ QStringLiteral("document.getElementById(\"code\").value;"),
+ [this](const QVariant &result) {
+ const auto token = result.toString();
+ if (token.isEmpty()) {
+ qCWarning(KGAPIDebug) << "Peaked into HTML, but cound not find token :(";
+ webview->page()->toHtml([](const QString &html) {
+ qCDebug(KGAPIDebug) << "Parsing token page failed";
+ qCDebug(KGAPIDebug) << html;
+ });
+ emitError(AuthError, tr("Parsing token page failed."));
+ return;
+ }
+ qCDebug(KGAPIDebug) << "Peaked into HTML and found token: " << token;
+ auto fetch = new KGAPI2::NewTokensFetchJob(token, apiKey, secretKey);
+ connect(fetch, &Job::finished, this, &AuthWidgetPrivate::tokensReceived);
+ });
+#else
+ qCWarning(KGAPIDebug) << "Failed to parse token from URL!";
emitError(AuthError, tr("Parsing token page failed."));
- return;
- }
-
- if (token.isEmpty()) {
- webview->page()->toHtml([](const QString &html) {
- qCDebug(KGAPIDebug) << "Failed to obtain token.";
- qCDebug(KGAPIRaw) << html;
- });
- emitError(AuthError, tr("Failed to obtain token."));
- return;
+#endif
}
-
- KGAPI2::NewTokensFetchJob *fetchJob = new KGAPI2::NewTokensFetchJob(token, apiKey, secretKey);
- connect(fetchJob, &Job::finished,
- this, &AuthWidgetPrivate::tokensReceived);
+ } else {
+ //qCDebug(KGAPIDebug) << "Unhandled page:" << url.host() << ", " << url.path();
}
}

diff --git a/src/core/ui/authwidget_p.h b/src/core/ui/authwidget_p.h
index 673b0cb..9c488be 100644
--- a/src/core/ui/authwidget_p.h
+++ b/src/core/ui/authwidget_p.h
@@ -82,6 +82,12 @@ class Q_DECL_HIDDEN AuthWidgetPrivate: public QObject {
void setupUi();
void setProgress(AuthWidget::Progress progress);

+ bool isGoogleHost(const QUrl &url) const { return url.host() == QLatin1String("accounts.google.com"); }
+ bool isSigninPage(const QUrl &url) const { return url.path() == QLatin1String("/signin/oauth"); }
+ bool isUsernameFrame(const QUrl &url) { return url.path() == QLatin1String("/signin/oauth/identifier"); }
+ bool isPasswordFrame(const QUrl &url) { return url.path() == QLatin1String("/signin/v2/challenge/pwd"); }
+ bool isTokenPage(const QUrl &url) { return url.path() == QLatin1String("/o/oauth2/approval/v2"); }
+
AuthWidget *q;

friend class AuthWidget;
--
2.12.2

36 changes: 36 additions & 0 deletions kde-apps/libkgapi/files/libkgapi-17.04.0-auth2.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
From 5a20c7494f48da93914f50bbb54423ef540ef998 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= <[email protected]>
Date: Thu, 27 Apr 2017 17:24:03 +0200
Subject: [PATCH 2/3] Auth: don't store cookies

Don't store WebEngine cookies, otherwise Google will display the account
that user signed in with the last time, which may not be desirable.
---
src/core/ui/authwidget_p.cpp | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/src/core/ui/authwidget_p.cpp b/src/core/ui/authwidget_p.cpp
index 75d38cd..a51f4a9 100644
--- a/src/core/ui/authwidget_p.cpp
+++ b/src/core/ui/authwidget_p.cpp
@@ -26,6 +26,7 @@
#include "../../debug.h"

#include <QWebEngineView>
+#include <QWebEngineProfile>
#include <QNetworkReply>
#include <QContextMenuEvent>

@@ -36,6 +37,9 @@ using namespace KGAPI2;
WebView::WebView(QWidget *parent)
: QWebEngineView(parent)
{
+ // Don't store cookies, so that subsequent invocations of AuthJob won't remember
+ // the previous accounts.
+ QWebEngineProfile::defaultProfile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
}


--
2.12.2

Loading

0 comments on commit 88f5d2d

Please sign in to comment.