Commit ea2752d3 authored by Damien Cassou's avatar Damien Cassou Committed by Vincent A

[myedenred] improve parsing in JsUserPage: make it more robust and readable

parent 870cdfe4
Pipeline #3161 passed with stages
in 23 minutes and 20 seconds
......@@ -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 @@ class JsUserPage(RawPage):
# key in it (code_challenge). This JSON is available only one time in the
# file, so there is no risk of duplicates.
json_data ='({[^{}]+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 @@ class TransactionsPage(LoggedPage, JsonPage):
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):
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
......@@ -22,6 +22,7 @@ from __future__ import unicode_literals
from import BackendTest
from .pages import parseInput
class MyedenredTest(BackendTest):
MODULE = 'myedenred'
......@@ -37,3 +38,16 @@ class MyedenredTest(BackendTest):
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")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment