summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vrátil <[email protected]>2017-06-21 17:12:08 +0200
committerDaniel Vrátil <[email protected]>2017-06-21 19:38:51 +0200
commit106d015bdbe74078bd67a912b3f5210fc852c594 (patch)
treeaf66159e396588c3fee3f47ce4c4cedfea6244fe
parent95075609a8f1a7c928a756560ce53d027eed2ed0 (diff)
FB: Use a dedicated webengine profile and store cookies
We use a dedicated QtWebEngineProfile for each resource instance and for each profile we store all cookies that Facebook creates during login. This will allow us to query the webpage later to sync birthdays. It also allows us to inject the cookies back into the profile before refreshing token so that user does not have to re-enter their password every time.
-rw-r--r--resources/facebook/tokenjobs.cpp59
1 files changed, 49 insertions, 10 deletions
diff --git a/resources/facebook/tokenjobs.cpp b/resources/facebook/tokenjobs.cpp
index 4a2b8e9..686b142 100644
--- a/resources/facebook/tokenjobs.cpp
+++ b/resources/facebook/tokenjobs.cpp
@@ -33,10 +33,11 @@
#include <QJsonDocument>
#include <QJsonObject>
-#include <QtWebEngineWidgets/QWebEngineView>
-#include <QtWebEngineWidgets/QWebEngineSettings>
-#include <QtWebEngineWidgets/QWebEnginePage>
-#include <QtWebEngineWidgets/QWebEngineProfile>
+#include <QWebEngineView>
+#include <QWebEngineSettings>
+#include <QWebEnginePage>
+#include <QWebEngineProfile>
+#include <QWebEngineCookieStore>
#include <KWallet/Wallet>
@@ -48,6 +49,7 @@ static const auto KWalletFolder = QStringLiteral("Facebook");
static const auto KWalletKeyToken = QStringLiteral("token");
static const auto KWalletKeyName = QStringLiteral("name");
static const auto KWalletKeyId = QStringLiteral("id");
+static const auto KWalletKeyCookies = QStringLiteral("cookies");
class TokenManager
{
@@ -62,6 +64,7 @@ public:
QString token;
QString userName;
QString id;
+ QByteArray cookies;
};
Q_GLOBAL_STATIC(TokenManager, d)
@@ -86,8 +89,8 @@ class WebPage : public QWebEnginePage
{
Q_OBJECT
public:
- explicit WebPage(QObject *parent = nullptr)
- : QWebEnginePage(parent)
+ explicit WebPage(QWebEngineProfile *profile, QObject *parent = nullptr)
+ : QWebEnginePage(profile, parent)
{}
QWebEngineCertificateError *lastCeritificateError() const
@@ -118,7 +121,8 @@ class AuthDialog : public QDialog
Q_OBJECT
public:
- AuthDialog(QWidget *parent = nullptr)
+ AuthDialog(const QByteArray &cookies, FacebookResource *resource,
+ QWidget *parent = nullptr)
: QDialog(parent)
{
setModal(true);
@@ -155,8 +159,28 @@ public:
progressBar->setValue(0);
v->addWidget(progressBar);
+ // Create a special profile just for us
+ auto profile = new QWebEngineProfile(resource->identifier(), this);
+ auto cookieStore = profile->cookieStore();
+ cookieStore->deleteAllCookies(); // delete all cookies from it
+ const auto parsedCookies = QNetworkCookie::parseCookies(cookies);
+ for (const auto &parsedCookie : parsedCookies) {
+ cookieStore->setCookie(parsedCookie, QUrl(QStringLiteral(".facebook.com")));
+ mCookies.insert(parsedCookie.name(), parsedCookie.toRawForm());
+ }
+ connect(cookieStore, &QWebEngineCookieStore::cookieAdded,
+ this, [this](const QNetworkCookie &cookie) {
+ if (cookie.domain() == QLatin1String(".facebook.com")) {
+ mCookies.insert(cookie.name(), cookie.toRawForm());
+ }
+ });
+ connect(cookieStore, &QWebEngineCookieStore::cookieRemoved,
+ this, [this](const QNetworkCookie &cookie) {
+ mCookies.remove(cookie.name());
+ });
+
mView = new WebView(this);
- auto webpage = new WebPage(mView);
+ auto webpage = new WebPage(profile, mView);
connect(webpage, &WebPage::sslError,
this, [this]() {
setSslIcon(QStringLiteral("security-low"));
@@ -198,6 +222,15 @@ public:
return mToken;
}
+ QByteArray cookies() const
+ {
+ QByteArray rv;
+ for (auto it = mCookies.cbegin(), end = mCookies.cend(); it != end; ++it) {
+ rv += it.value() + '\n';
+ }
+ return rv;
+ }
+
Q_SIGNALS:
void authDone();
@@ -252,6 +285,7 @@ private:
QToolButton *mSslIndicator = nullptr;
QLineEdit *mUrlEdit = nullptr;
QString mToken;
+ QMap<QByteArray, QByteArray> mCookies;
};
} // namespace
@@ -324,11 +358,12 @@ QString LoginJob::token() const
void LoginJob::doStart()
{
- auto dlg = new AuthDialog;
+ auto dlg = new AuthDialog(d->cookies, qobject_cast<FacebookResource*>(parent()));
connect(dlg, &AuthDialog::authDone,
this, [this, dlg]() {
dlg->deleteLater();
d->token = dlg->token();
+ d->cookies = dlg->cookies();
if (d->token.isEmpty()) {
emitError(i18n("Failed to obtain access token from Facebook"));
return;
@@ -358,7 +393,9 @@ void LoginJob::fetchUserInfo()
d->wallet->writeMap(qobject_cast<FacebookResource*>(parent())->identifier(),
{ { KWalletKeyToken, d->token },
{ KWalletKeyName, d->userName },
- { KWalletKeyId, d->id } });
+ { KWalletKeyId, d->id },
+ { KWalletKeyCookies, QString::fromUtf8(d->cookies) }
+ });
emitResult();
});
job->start();
@@ -381,6 +418,7 @@ void LogoutJob::doStart()
d->token.clear();
d->userName.clear();
d->id.clear();
+ d->cookies.clear();
if (!d->wallet->isOpen()) {
emitError(i18n("Failed to open KWallet"));
@@ -442,6 +480,7 @@ void GetTokenJob::doStart()
d->token = entries.value(KWalletKeyToken);
d->userName = entries.value(KWalletKeyName);
d->id = entries.value(KWalletKeyId);
+ d->cookies = entries.value(KWalletKeyCookies).toUtf8();
emitResult();
}