From 43bfb812e52ea7f60e3b6ab710c5b3be0a19e7ae Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Wed, 22 Jul 2020 00:08:29 -0400 Subject: [PATCH 01/16] Allow for multiple attributes --- flask_saml2/sp/parser.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/flask_saml2/sp/parser.py b/flask_saml2/sp/parser.py index 2dd63a0..ddb3fd1 100644 --- a/flask_saml2/sp/parser.py +++ b/flask_saml2/sp/parser.py @@ -1,4 +1,4 @@ -from typing import Mapping, Optional +from typing import Mapping, Optional, List, Union from flask_saml2.types import XmlNode from flask_saml2.utils import cached_property @@ -51,10 +51,20 @@ def nameid_format(self) -> str: return self._xpath(self.subject, 'saml:NameID/@Format')[0] @cached_property - def attributes(self) -> Mapping[str, str]: + def attributes(self) -> Mapping[str, Union[str, List[str]]]: attributes = self._xpath(self.assertion, 'saml:AttributeStatement/saml:Attribute') - return {el.get('Name'): self._xpath(el, 'saml:AttributeValue')[0].text - for el in attributes} + ret = {} + for el in attributes: + name = el.get('Name') + attrs = self._xpath(el, 'saml:AttributeValue') + if len(attrs) == 1: + ret[name] = attrs[0].text + else: + vals = [] + for a in attrs: + vals.append(a.text) + ret[name] = vals + return ret @cached_property def conditions(self) -> Optional[XmlNode]: From 7da4a8a55599746bf95829bf6df694a047259af9 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Wed, 22 Jul 2020 00:10:45 -0400 Subject: [PATCH 02/16] pass tox tests --- flask_saml2/sp/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask_saml2/sp/parser.py b/flask_saml2/sp/parser.py index ddb3fd1..e40046a 100644 --- a/flask_saml2/sp/parser.py +++ b/flask_saml2/sp/parser.py @@ -1,4 +1,4 @@ -from typing import Mapping, Optional, List, Union +from typing import List, Mapping, Optional, Union from flask_saml2.types import XmlNode from flask_saml2.utils import cached_property From c3a01a761c89e4731fc8f0a087475b829cfaa625 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Tue, 11 Aug 2020 15:53:20 -0400 Subject: [PATCH 03/16] add debugging logs --- flask_saml2/sp/views.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flask_saml2/sp/views.py b/flask_saml2/sp/views.py index 1c116b6..c4d5108 100644 --- a/flask_saml2/sp/views.py +++ b/flask_saml2/sp/views.py @@ -84,9 +84,12 @@ def post(self): for handler in self.sp.get_idp_handlers(): try: response = handler.get_response_parser(saml_request) + print("got response", response) auth_data = handler.get_auth_data(response) return self.sp.login_successful(auth_data, relay_state) except CannotHandleAssertion: + print(saml_request) + print(relay_state) continue except UserNotAuthorized: return self.sp.render_template('flask_saml2_sp/user_not_authorized.html') From 2a015c782fb16ca90e0f3449b40a53fd4f00de98 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Tue, 11 Aug 2020 16:03:08 -0400 Subject: [PATCH 04/16] add debugging logs --- flask_saml2/sp/views.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/flask_saml2/sp/views.py b/flask_saml2/sp/views.py index c4d5108..c4bdb51 100644 --- a/flask_saml2/sp/views.py +++ b/flask_saml2/sp/views.py @@ -81,15 +81,17 @@ def post(self): saml_request = request.form['SAMLResponse'] relay_state = request.form['RelayState'] + print("In ACs") + print(saml_request) + print(relay_state) for handler in self.sp.get_idp_handlers(): + print(handler) try: response = handler.get_response_parser(saml_request) print("got response", response) auth_data = handler.get_auth_data(response) return self.sp.login_successful(auth_data, relay_state) except CannotHandleAssertion: - print(saml_request) - print(relay_state) continue except UserNotAuthorized: return self.sp.render_template('flask_saml2_sp/user_not_authorized.html') From 5a2f118d089d7c82e031641338a4006c06026026 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Tue, 11 Aug 2020 16:06:17 -0400 Subject: [PATCH 05/16] add debugging logs --- flask_saml2/sp/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flask_saml2/sp/views.py b/flask_saml2/sp/views.py index c4bdb51..a2253f2 100644 --- a/flask_saml2/sp/views.py +++ b/flask_saml2/sp/views.py @@ -82,10 +82,10 @@ def post(self): relay_state = request.form['RelayState'] print("In ACs") - print(saml_request) - print(relay_state) + print("saml_request", saml_request) + print("relay_state", relay_state) for handler in self.sp.get_idp_handlers(): - print(handler) + print("handler", handler) try: response = handler.get_response_parser(saml_request) print("got response", response) From 533f517bce0a8db9624f02958a475422088441fe Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Tue, 11 Aug 2020 17:38:14 -0400 Subject: [PATCH 06/16] add debugging logs --- flask_saml2/sp/sp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/flask_saml2/sp/sp.py b/flask_saml2/sp/sp.py index 7535958..8408b22 100644 --- a/flask_saml2/sp/sp.py +++ b/flask_saml2/sp/sp.py @@ -131,6 +131,7 @@ def get_identity_providers(self) -> Iterable[Tuple[str, dict]]: Defaults to ``current_app.config['SAML2_IDENTITY_PROVIDERS']``. """ + print(current_app.config) return current_app.config['SAML2_IDENTITY_PROVIDERS'] def get_login_url(self) -> str: From b65a8957acf5ad7bc9d6e33f2c7adeba6cc2d3fe Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Tue, 11 Aug 2020 18:08:58 -0400 Subject: [PATCH 07/16] add debugging logs --- flask_saml2/sp/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/flask_saml2/sp/views.py b/flask_saml2/sp/views.py index a2253f2..fde4380 100644 --- a/flask_saml2/sp/views.py +++ b/flask_saml2/sp/views.py @@ -82,6 +82,7 @@ def post(self): relay_state = request.form['RelayState'] print("In ACs") + print("request", request.form) print("saml_request", saml_request) print("relay_state", relay_state) for handler in self.sp.get_idp_handlers(): From 78e72ebebe8c2c38bb25841e6d0faeb29c08d764 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Tue, 11 Aug 2020 23:22:01 -0400 Subject: [PATCH 08/16] add debugging logs --- flask_saml2/sp/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flask_saml2/sp/views.py b/flask_saml2/sp/views.py index fde4380..f52154f 100644 --- a/flask_saml2/sp/views.py +++ b/flask_saml2/sp/views.py @@ -83,6 +83,8 @@ def post(self): print("In ACs") print("request", request.form) + print("relaystateraw", request.form['RelayState']) + print("samlrespraw", request.form['SAMLResponse']) print("saml_request", saml_request) print("relay_state", relay_state) for handler in self.sp.get_idp_handlers(): From 15bbb03489acb05429f3e8aa5436edf262565e7d Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Tue, 11 Aug 2020 23:32:25 -0400 Subject: [PATCH 09/16] add debugging logs --- flask_saml2/sp/idphandler.py | 1 + flask_saml2/sp/sp.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/flask_saml2/sp/idphandler.py b/flask_saml2/sp/idphandler.py index 50788ad..3f6419a 100644 --- a/flask_saml2/sp/idphandler.py +++ b/flask_saml2/sp/idphandler.py @@ -29,6 +29,7 @@ def to_dict(self) -> dict: Return a dict of all attributes. You can store this dict in a session store, and recreate this instance using :meth:`from_dict`. """ + print("doing to dict") data = attr.asdict(self, filter=lambda a, v: a.name != 'handler') return { 'data': data, diff --git a/flask_saml2/sp/sp.py b/flask_saml2/sp/sp.py index 8408b22..cb5bfdc 100644 --- a/flask_saml2/sp/sp.py +++ b/flask_saml2/sp/sp.py @@ -48,6 +48,7 @@ def login_successful( Subclasses may override this method and return a different response, but they *must* call ``super()``. """ + print("in login success") self.set_auth_data_in_session(auth_data) return redirect(relay_state) @@ -271,6 +272,7 @@ def set_auth_data_in_session(self, auth_data: AuthData): """Store authentication details from the :class:`IdPHandler` in the browser session. """ + print("setting auth data in session") session[self.session_auth_data_key] = auth_data.to_dict() def clear_auth_data_in_session(self): From de917496b4dd3c1287b3f76368961b909501f2a9 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Tue, 11 Aug 2020 23:42:25 -0400 Subject: [PATCH 10/16] add debugging logs --- flask_saml2/sp/idphandler.py | 2 ++ flask_saml2/sp/sp.py | 3 ++- flask_saml2/sp/views.py | 7 +------ 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/flask_saml2/sp/idphandler.py b/flask_saml2/sp/idphandler.py index 3f6419a..e76c994 100644 --- a/flask_saml2/sp/idphandler.py +++ b/flask_saml2/sp/idphandler.py @@ -42,6 +42,8 @@ def from_dict(cls, sp, data: dict): Construct an :class:`AuthData` instance from a dict such as :meth:`to_dict` produces. """ + print("in from dict") + print("handler data", data['handler']) return cls(**{ **data['data'], 'handler': sp.get_idp_handler_by_entity_id(data['handler']), diff --git a/flask_saml2/sp/sp.py b/flask_saml2/sp/sp.py index cb5bfdc..f65b7fa 100644 --- a/flask_saml2/sp/sp.py +++ b/flask_saml2/sp/sp.py @@ -132,7 +132,6 @@ def get_identity_providers(self) -> Iterable[Tuple[str, dict]]: Defaults to ``current_app.config['SAML2_IDENTITY_PROVIDERS']``. """ - print(current_app.config) return current_app.config['SAML2_IDENTITY_PROVIDERS'] def get_login_url(self) -> str: @@ -230,6 +229,7 @@ def get_idp_handler_by_entity_id(self, entity_id) -> IdPHandler: for handler in self.get_idp_handlers(): if handler.entity_id == entity_id: return handler + print("NO IDP HANDLER IWTH ENTITY ID") raise ValueError(f"No IdP handler with entity ID {entity_id}") def get_idp_handler_by_current_session(self) -> IdPHandler: @@ -285,6 +285,7 @@ def get_auth_data_in_session(self) -> AuthData: """Get an :class:`AuthData` instance from the session data stored for the currently logged in user. """ + print("getting auth data") return AuthData.from_dict(self, session[self.session_auth_data_key]) def make_absolute_url(self, url: str) -> str: diff --git a/flask_saml2/sp/views.py b/flask_saml2/sp/views.py index f52154f..950d1b3 100644 --- a/flask_saml2/sp/views.py +++ b/flask_saml2/sp/views.py @@ -81,18 +81,13 @@ def post(self): saml_request = request.form['SAMLResponse'] relay_state = request.form['RelayState'] - print("In ACs") - print("request", request.form) - print("relaystateraw", request.form['RelayState']) - print("samlrespraw", request.form['SAMLResponse']) - print("saml_request", saml_request) - print("relay_state", relay_state) for handler in self.sp.get_idp_handlers(): print("handler", handler) try: response = handler.get_response_parser(saml_request) print("got response", response) auth_data = handler.get_auth_data(response) + print("got auth data", auth_data) return self.sp.login_successful(auth_data, relay_state) except CannotHandleAssertion: continue From 09071be893159ef2c7df821925d3c95688b08167 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Tue, 11 Aug 2020 23:51:40 -0400 Subject: [PATCH 11/16] add debugging logs --- flask_saml2/sp/idphandler.py | 6 +++--- flask_saml2/sp/sp.py | 8 ++++---- flask_saml2/sp/views.py | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/flask_saml2/sp/idphandler.py b/flask_saml2/sp/idphandler.py index e76c994..d98a5df 100644 --- a/flask_saml2/sp/idphandler.py +++ b/flask_saml2/sp/idphandler.py @@ -29,7 +29,7 @@ def to_dict(self) -> dict: Return a dict of all attributes. You can store this dict in a session store, and recreate this instance using :meth:`from_dict`. """ - print("doing to dict") + print("doing to dict", flush=True) data = attr.asdict(self, filter=lambda a, v: a.name != 'handler') return { 'data': data, @@ -42,8 +42,8 @@ def from_dict(cls, sp, data: dict): Construct an :class:`AuthData` instance from a dict such as :meth:`to_dict` produces. """ - print("in from dict") - print("handler data", data['handler']) + print("in from dict", flush=True) + print("handler data", data['handler'], flush=True) return cls(**{ **data['data'], 'handler': sp.get_idp_handler_by_entity_id(data['handler']), diff --git a/flask_saml2/sp/sp.py b/flask_saml2/sp/sp.py index f65b7fa..48c7ed6 100644 --- a/flask_saml2/sp/sp.py +++ b/flask_saml2/sp/sp.py @@ -48,7 +48,7 @@ def login_successful( Subclasses may override this method and return a different response, but they *must* call ``super()``. """ - print("in login success") + print("in login success", flush=True) self.set_auth_data_in_session(auth_data) return redirect(relay_state) @@ -229,7 +229,7 @@ def get_idp_handler_by_entity_id(self, entity_id) -> IdPHandler: for handler in self.get_idp_handlers(): if handler.entity_id == entity_id: return handler - print("NO IDP HANDLER IWTH ENTITY ID") + print("NO IDP HANDLER IWTH ENTITY ID", flush=True) raise ValueError(f"No IdP handler with entity ID {entity_id}") def get_idp_handler_by_current_session(self) -> IdPHandler: @@ -272,7 +272,7 @@ def set_auth_data_in_session(self, auth_data: AuthData): """Store authentication details from the :class:`IdPHandler` in the browser session. """ - print("setting auth data in session") + print("setting auth data in session", flush=True) session[self.session_auth_data_key] = auth_data.to_dict() def clear_auth_data_in_session(self): @@ -285,7 +285,7 @@ def get_auth_data_in_session(self) -> AuthData: """Get an :class:`AuthData` instance from the session data stored for the currently logged in user. """ - print("getting auth data") + print("getting auth data", flush=True) return AuthData.from_dict(self, session[self.session_auth_data_key]) def make_absolute_url(self, url: str) -> str: diff --git a/flask_saml2/sp/views.py b/flask_saml2/sp/views.py index 950d1b3..c88b36e 100644 --- a/flask_saml2/sp/views.py +++ b/flask_saml2/sp/views.py @@ -82,12 +82,12 @@ def post(self): relay_state = request.form['RelayState'] for handler in self.sp.get_idp_handlers(): - print("handler", handler) + print("handler", handler, flush=True) try: response = handler.get_response_parser(saml_request) - print("got response", response) + print("got response", response, flush=True) auth_data = handler.get_auth_data(response) - print("got auth data", auth_data) + print("got auth data", auth_data, flush=True) return self.sp.login_successful(auth_data, relay_state) except CannotHandleAssertion: continue From a4700c0b7ea9a4f8b807c0a4311b72389bbc3817 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Wed, 12 Aug 2020 00:02:33 -0400 Subject: [PATCH 12/16] add debugging logs --- flask_saml2/sp/idphandler.py | 6 ++++++ flask_saml2/sp/sp.py | 1 + 2 files changed, 7 insertions(+) diff --git a/flask_saml2/sp/idphandler.py b/flask_saml2/sp/idphandler.py index d98a5df..4b9b40b 100644 --- a/flask_saml2/sp/idphandler.py +++ b/flask_saml2/sp/idphandler.py @@ -240,7 +240,9 @@ def get_auth_data(self, response: ResponseParser) -> AuthData: def validate_response(self, response: ResponseParser): # Check it came from the right place + print("validating response", flush=True) if self.entity_id != response.issuer: + print("entity id not equal to response.issue", self.entity_id, response.issuer, flush=True) raise CannotHandleAssertion( f'Entity ID mismatch {self.entity_id} != {response.issuer}') @@ -251,16 +253,20 @@ def validate_response(self, response: ResponseParser): not_on_or_after = response.conditions.get('NotOnOrAfter') try: if not_before is not None and now < iso8601.parse_date(not_before): + print(f'NotBefore={not_before} check failed', flush=True) raise CannotHandleAssertion(f'NotBefore={not_before} check failed') if not_on_or_after is not None and now >= iso8601.parse_date(not_on_or_after): + print(f'NotOnOrAfter={not_on_or_after} check failed', flush=True) raise CannotHandleAssertion(f'NotOnOrAfter={not_on_or_after} check failed') except ValueError as err: + print(f'could not parse date {not_before} or {not_on_or_after}', flush=True) raise CannotHandleAssertion("Could not parse date") from err # Validate the AudienceRestriction elements, if they exist audiences = response._xpath(response.conditions, './saml:AudienceRestriction/saml:Audience') entity_id = self.sp.get_sp_entity_id() if len(audiences) and not any(el.text == entity_id for el in audiences): + print("No valid audiences", audiences, entity_id flush=True) raise CannotHandleAssertion("No valid AudienceRestriction found") def format_datetime(self, value: datetime.datetime) -> str: diff --git a/flask_saml2/sp/sp.py b/flask_saml2/sp/sp.py index 48c7ed6..4991eb6 100644 --- a/flask_saml2/sp/sp.py +++ b/flask_saml2/sp/sp.py @@ -236,6 +236,7 @@ def get_idp_handler_by_current_session(self) -> IdPHandler: """Get the :class:`IdPHandler` used to authenticate the currently logged in user. """ + print("") auth_data = self.get_auth_data_in_session() return auth_data.handler From 514014a9075964513a5461a316406ac636dfa451 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Wed, 12 Aug 2020 00:06:49 -0400 Subject: [PATCH 13/16] add debugging logs --- flask_saml2/sp/idphandler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask_saml2/sp/idphandler.py b/flask_saml2/sp/idphandler.py index 4b9b40b..b0debd0 100644 --- a/flask_saml2/sp/idphandler.py +++ b/flask_saml2/sp/idphandler.py @@ -266,7 +266,7 @@ def validate_response(self, response: ResponseParser): audiences = response._xpath(response.conditions, './saml:AudienceRestriction/saml:Audience') entity_id = self.sp.get_sp_entity_id() if len(audiences) and not any(el.text == entity_id for el in audiences): - print("No valid audiences", audiences, entity_id flush=True) + print("No valid audiences", audiences, entity_id, flush=True) raise CannotHandleAssertion("No valid AudienceRestriction found") def format_datetime(self, value: datetime.datetime) -> str: From 12f28d4bb0df181f7ccb0e93ab01b2d27a0b46a6 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Wed, 12 Aug 2020 00:16:17 -0400 Subject: [PATCH 14/16] add debugging logs --- flask_saml2/sp/idphandler.py | 5 +++-- flask_saml2/sp/views.py | 10 ++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/flask_saml2/sp/idphandler.py b/flask_saml2/sp/idphandler.py index b0debd0..6482289 100644 --- a/flask_saml2/sp/idphandler.py +++ b/flask_saml2/sp/idphandler.py @@ -265,9 +265,10 @@ def validate_response(self, response: ResponseParser): # Validate the AudienceRestriction elements, if they exist audiences = response._xpath(response.conditions, './saml:AudienceRestriction/saml:Audience') entity_id = self.sp.get_sp_entity_id() + adnc = [el.text for el in audiences] if len(audiences) and not any(el.text == entity_id for el in audiences): - print("No valid audiences", audiences, entity_id, flush=True) - raise CannotHandleAssertion("No valid AudienceRestriction found") + print("No valid audiences", audiences, entity_id, adnc, flush=True) + raise CannotHandleAssertion(f"No valid AudienceRestriction found: {adnc}, {entity_id}") def format_datetime(self, value: datetime.datetime) -> str: """ diff --git a/flask_saml2/sp/views.py b/flask_saml2/sp/views.py index c88b36e..824ca70 100644 --- a/flask_saml2/sp/views.py +++ b/flask_saml2/sp/views.py @@ -81,6 +81,8 @@ def post(self): saml_request = request.form['SAMLResponse'] relay_state = request.form['RelayState'] + errors = [] + for handler in self.sp.get_idp_handlers(): print("handler", handler, flush=True) try: @@ -89,10 +91,14 @@ def post(self): auth_data = handler.get_auth_data(response) print("got auth data", auth_data, flush=True) return self.sp.login_successful(auth_data, relay_state) - except CannotHandleAssertion: - continue + except CannotHandleAssertion as e: + errors.append(e) except UserNotAuthorized: return self.sp.render_template('flask_saml2_sp/user_not_authorized.html') + error_string = "" + for e in errors: + error_string = f"{error_string} - {e} \n" + return f"Could not log in for various reasons, here is a list of errors encountered: \n {error_string}" class Metadata(SAML2View): From a98decb6339dff22faf51fd44be0e3c4b49c72a4 Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Wed, 12 Aug 2020 00:37:47 -0400 Subject: [PATCH 15/16] found the bug, added better error page --- flask_saml2/sp/idphandler.py | 10 ---------- flask_saml2/sp/sp.py | 5 ----- flask_saml2/sp/views.py | 7 ++----- 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/flask_saml2/sp/idphandler.py b/flask_saml2/sp/idphandler.py index 6482289..d15b18c 100644 --- a/flask_saml2/sp/idphandler.py +++ b/flask_saml2/sp/idphandler.py @@ -29,7 +29,6 @@ def to_dict(self) -> dict: Return a dict of all attributes. You can store this dict in a session store, and recreate this instance using :meth:`from_dict`. """ - print("doing to dict", flush=True) data = attr.asdict(self, filter=lambda a, v: a.name != 'handler') return { 'data': data, @@ -42,8 +41,6 @@ def from_dict(cls, sp, data: dict): Construct an :class:`AuthData` instance from a dict such as :meth:`to_dict` produces. """ - print("in from dict", flush=True) - print("handler data", data['handler'], flush=True) return cls(**{ **data['data'], 'handler': sp.get_idp_handler_by_entity_id(data['handler']), @@ -240,9 +237,7 @@ def get_auth_data(self, response: ResponseParser) -> AuthData: def validate_response(self, response: ResponseParser): # Check it came from the right place - print("validating response", flush=True) if self.entity_id != response.issuer: - print("entity id not equal to response.issue", self.entity_id, response.issuer, flush=True) raise CannotHandleAssertion( f'Entity ID mismatch {self.entity_id} != {response.issuer}') @@ -253,13 +248,9 @@ def validate_response(self, response: ResponseParser): not_on_or_after = response.conditions.get('NotOnOrAfter') try: if not_before is not None and now < iso8601.parse_date(not_before): - print(f'NotBefore={not_before} check failed', flush=True) raise CannotHandleAssertion(f'NotBefore={not_before} check failed') if not_on_or_after is not None and now >= iso8601.parse_date(not_on_or_after): - print(f'NotOnOrAfter={not_on_or_after} check failed', flush=True) - raise CannotHandleAssertion(f'NotOnOrAfter={not_on_or_after} check failed') except ValueError as err: - print(f'could not parse date {not_before} or {not_on_or_after}', flush=True) raise CannotHandleAssertion("Could not parse date") from err # Validate the AudienceRestriction elements, if they exist @@ -267,7 +258,6 @@ def validate_response(self, response: ResponseParser): entity_id = self.sp.get_sp_entity_id() adnc = [el.text for el in audiences] if len(audiences) and not any(el.text == entity_id for el in audiences): - print("No valid audiences", audiences, entity_id, adnc, flush=True) raise CannotHandleAssertion(f"No valid AudienceRestriction found: {adnc}, {entity_id}") def format_datetime(self, value: datetime.datetime) -> str: diff --git a/flask_saml2/sp/sp.py b/flask_saml2/sp/sp.py index 4991eb6..7535958 100644 --- a/flask_saml2/sp/sp.py +++ b/flask_saml2/sp/sp.py @@ -48,7 +48,6 @@ def login_successful( Subclasses may override this method and return a different response, but they *must* call ``super()``. """ - print("in login success", flush=True) self.set_auth_data_in_session(auth_data) return redirect(relay_state) @@ -229,14 +228,12 @@ def get_idp_handler_by_entity_id(self, entity_id) -> IdPHandler: for handler in self.get_idp_handlers(): if handler.entity_id == entity_id: return handler - print("NO IDP HANDLER IWTH ENTITY ID", flush=True) raise ValueError(f"No IdP handler with entity ID {entity_id}") def get_idp_handler_by_current_session(self) -> IdPHandler: """Get the :class:`IdPHandler` used to authenticate the currently logged in user. """ - print("") auth_data = self.get_auth_data_in_session() return auth_data.handler @@ -273,7 +270,6 @@ def set_auth_data_in_session(self, auth_data: AuthData): """Store authentication details from the :class:`IdPHandler` in the browser session. """ - print("setting auth data in session", flush=True) session[self.session_auth_data_key] = auth_data.to_dict() def clear_auth_data_in_session(self): @@ -286,7 +282,6 @@ def get_auth_data_in_session(self) -> AuthData: """Get an :class:`AuthData` instance from the session data stored for the currently logged in user. """ - print("getting auth data", flush=True) return AuthData.from_dict(self, session[self.session_auth_data_key]) def make_absolute_url(self, url: str) -> str: diff --git a/flask_saml2/sp/views.py b/flask_saml2/sp/views.py index 824ca70..fd1c6ac 100644 --- a/flask_saml2/sp/views.py +++ b/flask_saml2/sp/views.py @@ -84,12 +84,9 @@ def post(self): errors = [] for handler in self.sp.get_idp_handlers(): - print("handler", handler, flush=True) try: response = handler.get_response_parser(saml_request) - print("got response", response, flush=True) auth_data = handler.get_auth_data(response) - print("got auth data", auth_data, flush=True) return self.sp.login_successful(auth_data, relay_state) except CannotHandleAssertion as e: errors.append(e) @@ -97,8 +94,8 @@ def post(self): return self.sp.render_template('flask_saml2_sp/user_not_authorized.html') error_string = "" for e in errors: - error_string = f"{error_string} - {e} \n" - return f"Could not log in for various reasons, here is a list of errors encountered: \n {error_string}" + error_string = f"{error_string} - {e}
" + return f"Could not log in for various reasons, here is a list of errors encountered:
{error_string}" class Metadata(SAML2View): From cae1cd41a5d8ed4780d6cfe88a17c26a112c1a3c Mon Sep 17 00:00:00 2001 From: Tanishq Dubey Date: Wed, 12 Aug 2020 09:06:48 -0400 Subject: [PATCH 16/16] fix bad deletion of code --- flask_saml2/sp/idphandler.py | 1 + 1 file changed, 1 insertion(+) diff --git a/flask_saml2/sp/idphandler.py b/flask_saml2/sp/idphandler.py index d15b18c..7c640c1 100644 --- a/flask_saml2/sp/idphandler.py +++ b/flask_saml2/sp/idphandler.py @@ -250,6 +250,7 @@ def validate_response(self, response: ResponseParser): if not_before is not None and now < iso8601.parse_date(not_before): raise CannotHandleAssertion(f'NotBefore={not_before} check failed') if not_on_or_after is not None and now >= iso8601.parse_date(not_on_or_after): + raise CannotHandleAssertion(f'NotOnOrAfter={not_on_or_after} check failed') except ValueError as err: raise CannotHandleAssertion("Could not parse date") from err