diff --git a/contrib/webextension-session-importer/README b/contrib/webextension-session-importer/README new file mode 100644 index 0000000000000000000000000000000000000000..aa43c33fa996c3737776562c8a5728e9b62da48c --- /dev/null +++ b/contrib/webextension-session-importer/README @@ -0,0 +1,28 @@ +Weboob session importer +======================= + +This is a webextension to export a weboob session URL and cookies and load it in +a real browser. + +Build +----- + +The extension can be temporarily loaded by loading "manifest.json" in +about:debugging in Firefox and chrome://extensions/ in Chromium. + +To build a package, `web-ext build` can be used. +(See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Getting_started_with_web-ext) + +Use +--- + +To export the session with weboob-debug for example: + +>>> print(json.dumps(browser.export_session())) + +Copy the JSON output (sample): + +{"url": "https://example.com/foo", "cookies": [{"name": "foo", "value": "bar"}]} + +Then click on the Weboob toolbar button of your browser and paste the JSON. +The browser will set the cookies from weboob and go to the same URL. diff --git a/contrib/webextension-session-importer/bg.png b/contrib/webextension-session-importer/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..7c380ffaa9034ee1254c3a6f569977a829f1696e Binary files /dev/null and b/contrib/webextension-session-importer/bg.png differ diff --git a/contrib/webextension-session-importer/logo.png b/contrib/webextension-session-importer/logo.png new file mode 120000 index 0000000000000000000000000000000000000000..0ab286ce1fe7c16e87d19072f09de592c8b3b74d --- /dev/null +++ b/contrib/webextension-session-importer/logo.png @@ -0,0 +1 @@ +../../docs/source/_static/favicon.ico \ No newline at end of file diff --git a/contrib/webextension-session-importer/manifest.json b/contrib/webextension-session-importer/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..9c4220b62f0235a9c68bc97ce4b9bf41330344aa --- /dev/null +++ b/contrib/webextension-session-importer/manifest.json @@ -0,0 +1,25 @@ +{ + "manifest_version": 2, + "name": "Weboob session importer", + "version": "0.0.1", + + "description": "Import Weboob session URL and cookies", + "homepage_url": "http://weboob.org", + + "icons": { + "48": "logo.png" + }, + + "permissions": [ + "", + "cookies", + "tabs" + ], + + "browser_action": { + "browser_style": true, + "default_icon": "logo.png", + "default_title": "Import Weboob session", + "default_popup": "popup.html" + } +} diff --git a/contrib/webextension-session-importer/popup.html b/contrib/webextension-session-importer/popup.html new file mode 100644 index 0000000000000000000000000000000000000000..867e75bb6fe43d8a38b9614a4a30ddc0e945859a --- /dev/null +++ b/contrib/webextension-session-importer/popup.html @@ -0,0 +1,27 @@ + + + + + + + + + +
+ + + + + + diff --git a/contrib/webextension-session-importer/popup.js b/contrib/webextension-session-importer/popup.js new file mode 100644 index 0000000000000000000000000000000000000000..61f4d0307887f32ecfdee78941bb5b21182a156c --- /dev/null +++ b/contrib/webextension-session-importer/popup.js @@ -0,0 +1,121 @@ +var makePromise; + +if (navigator.userAgent.indexOf('Firefox') > -1) { + makePromise = function() { + var args = Array.prototype.slice.call(arguments); + var f = args.shift(); + var self = args.shift(); + + return f.apply(self, args); + } +} else { /* In chrome, navigator is an empty object, wtf? */ + browser = chrome; + + /* chrome APIs don't return Promise objects */ + makePromise = function() { + var args = Array.prototype.slice.call(arguments); + var f = args.shift(); + var self = args.shift(); + + return new Promise(function(resolve, reject) { + args.push(function() { + resolve.apply(null, arguments); + }); + f.apply(self, args); + }); + } +} + +function loadCookies() { + var onGetCookies = function(url, cookies) { + var objs = cookies.map(function(cookie) { + return { + name: cookie.name, + value: cookie.value, + domain: cookie.domain, + path: cookie.path, + secure: cookie.secure, + httpOnly: cookie.httpOnly, + expirationDate: cookie.expirationDate, + storeId: cookie.storeId + }; + }); + var ret = { + url: url, + cookies: objs + }; + + document.getElementById('data').placeholder = JSON.stringify(ret, null, 2); + }; + + var onGetActive = function(tabs) { + makePromise(browser.cookies.getAll, browser.cookies, { + url: tabs[0].url + }).then(function(cookies) { onGetCookies(tabs[0].url, cookies); }); + }; + + makePromise(browser.tabs.query, browser.tabs, { + active: true, + currentWindow: true + }).then(onGetActive); +} + +function clearCookies(cookieStoreId, url) { + return new Promise(function(resolve, reject) { + var onGetCookie = function(cookies) { + var promises = cookies.map(function(cookie) { + return makePromise(browser.cookies.remove, browser.cookies, { + url: url, + name: cookie.name, + storeId: cookie.storeId + }); + }); + Promise.all(promises).then(function() { resolve(); }); + }; + + makePromise(browser.cookies.getAll, browser.cookies, { + url: url + /* TODO when FF 52 is out: use cookieStoreId to support private browsing */ + }).then(onGetCookie); + }); +} + +function setCookies(cookieStoreId, url, objs) { + return new Promise(function(resolve, reject) { + var promises = objs.map(function(obj) { + obj.url = url; + /* FF52: use cookieStoreId */ + return makePromise(browser.cookies.set, browser.cookies, obj); + }); + + Promise.all(promises).then(function() { resolve(); }); + }); +} + +function setState() { + var data = JSON.parse(document.getElementById('data').value); + var objs = data.cookies; + var url = data.url; + + var onGetActive = function(tabs) { + clearCookies(tabs[0].cookieStoreId, url).then(function() { + setCookies(tabs[0].cookieStoreId, url, objs).then(function() { + makePromise(browser.tabs.update, browser.tabs, tabs[0].id, { + url: url + }).then(function() { + window.close(); + }); + }); + }); + }; + + makePromise(browser.tabs.query, browser.tabs, { + active: true, + currentWindow: true + }).then(onGetActive); +} + +window.addEventListener('load', loadCookies); +window.addEventListener('load', function() { + document.getElementById('submit').addEventListener('click', setState); +}); diff --git a/weboob/browser/browsers.py b/weboob/browser/browsers.py index 05e366fa0a4b4c1046178f29054aea63ab9bb45f..8e8781fd74028f65151821a0acb623fcca1818c8 100644 --- a/weboob/browser/browsers.py +++ b/weboob/browser/browsers.py @@ -479,6 +479,21 @@ def get_referrer(self, oldurl, newurl): return return oldurl + def export_session(self): + def make_cookie(c): + d = { + k: getattr(c, k) for k in ['name', 'value', 'domain', 'path', 'secure'] + } + #d['session'] = c.discard + d['httpOnly'] = 'httponly' in [k.lower() for k in c._rest.keys()] + d['expirationDate'] = getattr(c, 'expires', None) + return d + + return { + 'url': self.url, + 'cookies': [make_cookie(c) for c in self.session.cookies], + } + class UrlNotAllowed(Exception): """