diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e98ff5..795f962 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
- No unreleased changes so far
+## [0.35.1] - 2022-01-28
+### Fixed
+- Quick fix for login problem due to changes of the login page
+
## [0.35.0] - 2022-01-24
### Changed
- Better tracking of several parallel requests
@@ -469,7 +473,8 @@ Minor fix in observer interface
## [0.1.0] - 2021-05-26
Initial release
-[unreleased]: https://github.com/tillsteinbach/WeConnect-python/compare/v0.35.0...HEAD
+[unreleased]: https://github.com/tillsteinbach/WeConnect-python/compare/v0.35.1...HEAD
+[0.35.1]: https://github.com/tillsteinbach/WeConnect-python/releases/tag/v0.35.1
[0.35.0]: https://github.com/tillsteinbach/WeConnect-python/releases/tag/v0.35.0
[0.34.0]: https://github.com/tillsteinbach/WeConnect-python/releases/tag/v0.34.0
[0.33.0]: https://github.com/tillsteinbach/WeConnect-python/releases/tag/v0.33.0
diff --git a/weconnect/weconnect.py b/weconnect/weconnect.py
index 5aa1b57..32e3b19 100644
--- a/weconnect/weconnect.py
+++ b/weconnect/weconnect.py
@@ -365,45 +365,44 @@ def login(self) -> None: # noqa: C901 # pylint: disable=R0914, R0912, too-many-
# Post form content and retrieve credentials page
login2Response: requests.Response = self.__session.post(login2Url, headers=loginHeadersForm, data=formData, allow_redirects=True,
timeout=self.timeout)
+
if login2Response.status_code != requests.codes['ok']: # pylint: disable=E1101
if login2Response.status_code == requests.codes['internal_server_error']:
raise RetrievalError('Temporary server error during login')
raise APICompatibilityError('Retrieving credentials page was not successfull,'
f' status code: {login2Response.status_code}')
- # Find credentials form on page to obtain inputs
- credentialsFormRegex = r'
[^\"]+)\"[^>]*>' \
- r'(?P.+?(?=))'
- match = re.search(credentialsFormRegex, login2Response.text, flags=re.DOTALL)
+ credentialsTemplateRegex = r'))\s+\};\s+'
+ match = re.search(credentialsTemplateRegex, login2Response.text, flags=re.DOTALL)
if match is None:
- formErrorRegex = r'.*' \
- r'(?P.+?(?=)).*'
- errorMatch: Optional[Match[str]] = re.search(formErrorRegex, login2Response.text, flags=re.DOTALL)
- if errorMatch is not None:
- raise AuthentificationError(errorMatch.groupdict()['errorMessage'])
-
- accountNotFoundRegex = r'
.*
.*
' \
- r'(?P.+?(?=
))
.*
.*'
- errorMatch = re.search(accountNotFoundRegex, login2Response.text, flags=re.DOTALL)
- if errorMatch is not None:
- errorMessage: str = re.sub('<[^<]+?>', '', errorMatch.groupdict()['errorMessage'])
- raise AuthentificationError(errorMessage)
raise APICompatibilityError('No credentials form found')
- # retrieve target url from form
- target = match.groupdict()['formAction']
-
- # Find all inputs and put those in formData dictionary
- input2Regex = r'[^\"]+)\"([\\n\\r\s]value=\"(?P[^\"]+)\")?[^/]*/>'
- form2Data: Dict[str, str] = {}
- for match in re.finditer(input2Regex, match.groupdict()['formContent']):
- if match.groupdict()['name']:
- form2Data[match.groupdict()['name']] = match.groupdict()['value']
+ if match.groupdict()['templateModel']:
+ lineRegex = r'\s*(?P[^\:]+)\:\s+[\'\{]?(?P.+)[\'\}][,]?'
+ form2Data: Dict[str, str] = {}
+ for match in re.finditer(lineRegex, match.groupdict()['templateModel']):
+ if match.groupdict()['name'] == 'templateModel':
+ templateModelString = '{' + match.groupdict()['value'] + '}'
+ if templateModelString.endswith(','):
+ templateModelString = templateModelString[:-len(',')]
+ templateModel = json.loads(templateModelString)
+ if 'relayState' in templateModel:
+ form2Data['relayState'] = templateModel['relayState']
+ if 'hmac' in templateModel:
+ form2Data['hmac'] = templateModel['hmac']
+ if 'emailPasswordForm' in templateModel and 'email' in templateModel['emailPasswordForm']:
+ form2Data['email'] = templateModel['emailPasswordForm']['email']
+ if 'errorCode' in templateModel:
+ raise AuthentificationError('Error during login, is the username correct?')
+ elif match.groupdict()['name'] == 'csrf_token':
+ form2Data['_csrf'] = match.groupdict()['value']
+ form2Data['password'] = self.password
if not all(x in ['_csrf', 'relayState', 'hmac', 'email', 'password'] for x in form2Data):
raise APICompatibilityError('Could not find all required input fields in login page')
form2Data['password'] = self.password
- # build url from form action
- login3Url: str = 'https://identity.vwgroup.io' + target
+ # TODO improve build url from form action
+ login3Url = 'https://identity.vwgroup.io/signin-service/v1/a24fba63-34b3-4d43-b181-942111e6bda8@apps_vw-dilab_com/login/authenticate'
# Post form content and retrieve userId in forwarding Location
login3Response: requests.Response = self.__session.post(login3Url, headers=loginHeadersForm, data=form2Data, allow_redirects=False,