summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Kanakarakis <ivan.kanak@gmail.com>2018-12-06 10:08:35 +0100
committerGitHub <noreply@github.com>2018-12-06 10:08:35 +0100
commitf671747aea352c981333f8b47aaf7a7329471297 (patch)
tree1c1bf23ed33962bb64afd4d9561676a93902261d
parent65b136e2c822d3b0e08e0b3c1dc121b6c7de646c (diff)
parent19b21e218f529db7434fb309314e4377c3db3898 (diff)
downloadpysaml2-f671747aea352c981333f8b47aaf7a7329471297.tar.gz
Merge pull request #577 from johanlundberg/non_standard_status_code
Handle non standard response error status codes
-rw-r--r--src/saml2/response.py43
-rw-r--r--tests/test_51_client.py33
2 files changed, 55 insertions, 21 deletions
diff --git a/src/saml2/response.py b/src/saml2/response.py
index 323e71e6..6d32e313 100644
--- a/src/saml2/response.py
+++ b/src/saml2/response.py
@@ -354,26 +354,29 @@ class StatusResponse(object):
return self._postamble()
def status_ok(self):
- if self.response.status:
- status = self.response.status
- logger.info("status: %s", status)
- if status.status_code.value != samlp.STATUS_SUCCESS:
- logger.info("Not successful operation: %s", status)
- if status.status_code.status_code:
- excep = STATUSCODE2EXCEPTION[
- status.status_code.status_code.value]
- else:
- excep = StatusError
- if status.status_message:
- msg = status.status_message.text
- else:
- try:
- msg = status.status_code.status_code.value
- except Exception:
- msg = "Unknown error"
- raise excep(
- "%s from %s" % (msg, status.status_code.value,))
- return True
+ status = self.response.status
+ logger.info("status: %s", status)
+
+ if not status or status.status_code.value == samlp.STATUS_SUCCESS:
+ return True
+
+ err_code = (
+ status.status_code.status_code.value
+ if status.status_code.status_code
+ else None
+ )
+ err_msg = (
+ status.status_message.text
+ if status.status_message
+ else err_code or "Unknown error"
+ )
+ err_cls = STATUSCODE2EXCEPTION.get(err_code, StatusError)
+
+ msg = "Unsuccessful operation: {status}\n{msg} from {code}".format(
+ status=status, msg=err_msg, code=err_code
+ )
+ logger.info(msg)
+ raise err_cls(msg)
def issue_instant_ok(self):
""" Check that the response was issued at a reasonable time """
diff --git a/tests/test_51_client.py b/tests/test_51_client.py
index 3dad6d9f..a56ef2cf 100644
--- a/tests/test_51_client.py
+++ b/tests/test_51_client.py
@@ -28,7 +28,7 @@ from saml2.extension.requested_attributes import RequestedAttribute
from saml2.authn_context import INTERNETPROTOCOLPASSWORD
from saml2.client import Saml2Client
from saml2.pack import parse_soap_enveloped_saml
-from saml2.response import LogoutResponse, StatusInvalidNameidPolicy
+from saml2.response import LogoutResponse, StatusInvalidNameidPolicy, StatusError
from saml2.saml import NAMEID_FORMAT_PERSISTENT, EncryptedAssertion, Advice
from saml2.saml import NAMEID_FORMAT_TRANSIENT
from saml2.saml import NameID
@@ -2325,6 +2325,37 @@ class TestClientNonAsciiAva:
resp_str, BINDING_HTTP_POST,
{"id1": "http://foo.example.com/service"})
+ def test_response_error_status_non_standard_status_code(self):
+ """ Test that the SP client can parse an authentication response
+ from an IdP that contains an error status."""
+
+ conf = config.SPConfig()
+ conf.load_file("server_conf")
+ client = Saml2Client(conf)
+
+ resp = self.server.create_error_response(
+ in_response_to="id1",
+ destination="http://lingon.catalogix.se:8087/",
+ info=('http://example.com/status/1.0/cancel', None),
+ )
+
+ # Cast the response to a string and encode it to mock up the payload
+ # the SP client is expected to receive via HTTP POST binding.
+ if six.PY2:
+ resp_str = encode_fn(str(resp))
+ else:
+ resp_str = encode_fn(bytes(str(resp), 'utf-8'))
+
+ # We do not need the client to verify a signature for this test.
+ client.want_assertions_signed = False
+ client.want_response_signed = False
+
+ # Parse the authentication error response
+ with raises(StatusError):
+ client.parse_authn_request_response(
+ resp_str, BINDING_HTTP_POST,
+ {"id1": "http://foo.example.com/service"})
+
def setup_verify_authn_response(self):
idp = "urn:mace:example.com:saml:roland:idp"
ava = {"givenName": ["Dave"], "sn": ["ConcepciĆ³n"],