From 65d2eda73bd0f8754fcea1bd17021e27b4d18285 Mon Sep 17 00:00:00 2001 From: nicofrand Date: Wed, 14 Nov 2018 19:11:47 +0100 Subject: [PATCH] [paypal] Fix paypal module --- modules/paypal/browser.py | 5 +- modules/paypal/pages.py | 67 ++++---------------------- weboob/tools/js.py | 99 +++++++++++++++++++++++++++------------ 3 files changed, 81 insertions(+), 90 deletions(-) diff --git a/modules/paypal/browser.py b/modules/paypal/browser.py index 79f27bea90..4a6a00d042 100644 --- a/modules/paypal/browser.py +++ b/modules/paypal/browser.py @@ -79,7 +79,6 @@ def __init__(self, *args, **kwargs): super(Paypal, self).__init__(*args, **kwargs) def do_login(self): - raise BrowserUnavailable() assert isinstance(self.username, basestring) assert isinstance(self.password, basestring) @@ -88,6 +87,7 @@ def do_login(self): response = self.open(self.page.get_script_url()) token, csrf, key, value, sessionID, cookie = self.page.get_token_and_csrf(response.text) + self.session.cookies.update({'xppcts': cookie}) data = {} data['ads_token_js'] = token @@ -114,7 +114,8 @@ def do_login(self): self.detect_account_type() def detect_account_type(self): - self.page.detect_account_type() + if self.page: + self.page.detect_account_type() @need_login def get_accounts(self): diff --git a/modules/paypal/pages.py b/modules/paypal/pages.py index 3bd10a1d5e..458066b7b6 100644 --- a/modules/paypal/pages.py +++ b/modules/paypal/pages.py @@ -96,6 +96,9 @@ def exec_decoder(mtc): csrf = re.search(r"%s'([^']+)'" % re.escape("'&_csrf='+encodeURIComponent("), cleaner_code).group(1) key, value = re.findall(r"'(\w+)','(\w+)'", cleaner_code)[-1] + # Remove setCookie function content + cleaner_code = re.sub(r"'setCookie'.*(?=,'removeCookie')", "'setCookie':function(){}", cleaner_code) + # Detect the name of the function that computes the token, detect the # variable that stores the result and store it as a global. get_token_func_name = re.search(r"ads_token_js='\+encodeURIComponent\((\w+)\)", cleaner_code).group(1) @@ -107,64 +110,6 @@ def exec_decoder(mtc): cleaner_code = cleaner_code.replace(loop_func_name + "();", "") cleaner_code = cleaner_code.replace("data;", "return;") - # Simulate a browser environment - simulate_browser_code = """ - if (!document.createAttribute) { - document.createAttribute = null; - } - - if (!document.domain) { - document.domain = "paypal.com"; - } - - if (!document.styleSheets) { - document.styleSheets = null; - } - - if (!document.characterSet) { - document.characterSet = "UTF-8"; - } - - if (!document.documentElement) { - document.documentElement = {}; - } - - if (!window.innerWidth || !window.innerHeight) { - window.innerWidth = 1280; - window.innerHeight = 800; - } - - if (typeof(screen) === "undefined") { - var screen = window.screen = { - width: 1280, - height: 800 - }; - } - - if (typeof(history) === "undefined") { - var history = window.history = {}; - } - - if (typeof(location) === "undefined") { - var location = window.location = { - host: "paypal.com" - }; - } - - var XMLHttpRequest = function() {}; - XMLHttpRequest.prototype.onreadystatechange = function(){}; - XMLHttpRequest.prototype.open = function(){}; - XMLHttpRequest.prototype.setRequestHeader = function(){}; - XMLHttpRequest.prototype.send = function(){}; - window.XMLHttpRequest = XMLHttpRequest; - - if (!navigator.appName) { - navigator.appName = "Netscape"; - } - - navigator.userAgent = "Mozilla/5.0 (X11; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0"; - """ - # Add a function that returns the token cleaner_code += """ function GET_ADS_JS_TOKEN() @@ -173,7 +118,11 @@ def exec_decoder(mtc): } """ - token = str(Javascript(simulate_browser_code + cleaner_code).call("GET_ADS_JS_TOKEN")) + try: + token = str(Javascript(cleaner_code, None, "paypal.com").call("GET_ADS_JS_TOKEN")) + except: + raise BrowserUnavailable() + return token, csrf, key, value, sessionID, cookie def login(self, login, password, ): diff --git a/weboob/tools/js.py b/weboob/tools/js.py index c9cbb3fa97..78dd558875 100644 --- a/weboob/tools/js.py +++ b/weboob/tools/js.py @@ -26,38 +26,67 @@ class Javascript(object): HEADER = """ - function btoa(str) { - var buffer - ; - - if (str instanceof Buffer) { - buffer = str; - } else { - buffer = new Buffer(str.toString(), 'binary'); + function btoa(str) { + var buffer; + + if (str instanceof Buffer) { + buffer = str; + } else { + buffer = new Buffer(str.toString(), 'binary'); + } + + return buffer.toString('base64'); + } + + function atob(str) { + return new Buffer(str, 'base64').toString('binary'); } - return buffer.toString('base64'); - } - - function atob(str) { - return new Buffer(str, 'base64').toString('binary'); - } - - document = {}; - - /* JS code checks that some PhantomJS globals aren't defined on the - * global window object; put an empty window object, so that all these - * tests fail. - * It then tests the user agent against some known scrappers; just put - * the default Tor user agent in there. - */ - window = {}; - navigator = { - userAgent: "Mozilla/5.0 (Windows NT 6.1; rv:52.0) Gecko/20100101 Firefox/52.0" - }; + document = { + createAttribute: null, + styleSheets: null, + characterSet: "UTF-8", + documentElement: {} + }; + + history = {}; + + screen = { + width: 1280, + height: 800 + }; + + var XMLHttpRequest = function() {}; + XMLHttpRequest.prototype.onreadystatechange = function(){}; + XMLHttpRequest.prototype.open = function(){}; + XMLHttpRequest.prototype.setRequestHeader = function(){}; + XMLHttpRequest.prototype.send = function(){}; + + /* JS code checks that some PhantomJS globals aren't defined on the + * global window object; put an empty window object, so that all these + * tests fail. + * It then tests the user agent against some known scrappers; just put + * the default Tor user agent in there. + */ + window = { + document: document, + history: history, + screen: screen, + XMLHttpRequest: XMLHttpRequest, + + innerWidth: 1280, + innerHeight: 800, + + close: function(){} + }; + + navigator = { + userAgent: "Mozilla/5.0 (X11; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0", + appName: "Netscape" + }; """ - def __init__(self, script, logger=None): + def __init__(self, script, logger=None, domain=""): try: import execjs except ImportError: @@ -66,7 +95,19 @@ def __init__(self, script, logger=None): self.runner = execjs.get() self.logger = getLogger('js', logger) - self.ctx = self.runner.compile(self.HEADER + script) + window_emulator = self.HEADER + + if domain: + window_emulator += "document.domain = '" + domain + "';" + window_emulator += """ + if (typeof(location) === "undefined") { + var location = window.location = { + host: document.domain + }; + } + """ + + self.ctx = self.runner.compile(window_emulator + script) def call(self, *args, **kwargs): retval = self.ctx.call(*args, **kwargs) -- GitLab