diff --git a/modules/myedenred/pages.py b/modules/myedenred/pages.py index f98c9b44dbe7919a89831dcca30eb4ec213efae1..ef521f07a56b9d7ccd1c02e0b7ecf3a9589baa16 100644 --- a/modules/myedenred/pages.py +++ b/modules/myedenred/pages.py @@ -19,7 +19,9 @@ from __future__ import unicode_literals +import ast import re +import sys from weboob.browser.pages import HTMLPage, LoggedPage, JsonPage, RawPage from weboob.browser.elements import ItemElement, method, DictElement @@ -61,17 +63,8 @@ def get_json_content(self): # key in it (code_challenge). This JSON is available only one time in the # file, so there is no risk of duplicates. json_data = re.search(r'({[^{}]+code_challenge:[^{}]+})', self.text).group(1) - # Delete values that are variables concatenation (like `r + "/connect"`), - # we do not need them. - json_data = re.sub(r':([^{\",]+\+)', ':', json_data) - # Delete useless values like client_id:'a["default"].EDCId' - json_data = re.sub(r':(.?\[\".*?\"\]\..*?),', r':"",', json_data) - # There are values without quotes in the json, so we add quotes for the - # json.loads to work. - json_data = re.sub(r':([^\",+]+)', r':"\1"', json_data) - # Keys do not have quotes, adding them for the json.loads to work - json_data = re.sub(r'([^{\",+]+):', r'"\1":', json_data) - return json.loads(json_data) + + return parse_js_obj(json_data) class JsAppPage(RawPage): @@ -162,3 +155,26 @@ def obj_type(self): elif 'Annulation' in Field('label')(self): return Transaction.TYPE_PAYBACK return Transaction.TYPE_TRANSFER + + +# If node, an AST node, contains a string or a number, return +# that. Otherwise, return the node itself. +def get_ast_val(node): + if sys.version_info > (3, 5) and isinstance(node, ast.Constant): + return node.value + elif isinstance(node, ast.Name): + return node.id + elif isinstance(node, ast.Str): + return node.s + elif isinstance(node, ast.Num): + return node.n + + return node + + +# Return a dictionary containing values associated with keys found in +# `input`, a string. `input` looks like a JS literal object. +def parse_js_obj(input): + node = ast.parse(input).body[0].value + result = {get_ast_val(k): get_ast_val(v) for k, v in zip(node.keys, node.values)} + return result diff --git a/modules/myedenred/test.py b/modules/myedenred/test.py index 45245a7c9023f86039c8f0b59411b66dbf7c93c5..0d8648605c325ed09476bee14e33663a5e75eeed 100644 --- a/modules/myedenred/test.py +++ b/modules/myedenred/test.py @@ -22,6 +22,7 @@ from weboob.tools.test import BackendTest +from .pages import parseInput class MyedenredTest(BackendTest): MODULE = 'myedenred' @@ -37,3 +38,16 @@ def test_document(self): for doc in docs: content = self.backend.download_document(doc) assert content + + def test_parseInput(self): + input = ''' + {response_type:"code",client_id:a["default"].EDCId,scope:"openid offline_access edg-xp-appcontainer-api edg-xp-wallet-management-api",redirect_uri:f+"/connect",state:d,nonce:123,acr_values:a["default"].acr_values,ui_locales:"fr-fr",code_challenge:n,code_challenge_method:"S256"} + ''' + + result = parseInput(input) + + self.assertEqual(result["code_challenge_method"], "S256") + self.assertEqual(result["nonce"], "123") + self.assertEqual(result["response_type"], "code") + self.assertEqual(result["scope"], "openid offline_access edg-xp-appcontainer-api edg-xp-wallet-management-api") + self.assertEqual(result["ui_locales"], "fr-fr")