def test_get_parse_stderr_error_should_not_happen(self):
        msg = 'FAILURE'
        fake_proc = fudge.Fake('proc')
        stderr = StringIO(msg)
        fake_proc.has_attr(stderr=stderr)
        fake_proc.has_attr(returncode=0)

        msg = assert_raises(
            SignatureVerifier.SignatureVerifierError,
            SignatureVerifier._parse_stderr,
            fake_proc
            )

        eq(str(msg),
           ('There was a problem validating the response: XMLSec exited with '
            + 'code 0 but did not return OK when verifying the  SAML response.'
            )
           )
    def test_get_parse_stderr_error(self):
        msg = 'FAILURE'
        fake_proc = fudge.Fake('proc')
        stderr = StringIO(msg)
        fake_proc.has_attr(stderr=stderr)
        fake_proc.has_attr(returncode=1)

        msg = assert_raises(
            SignatureVerifier.SignatureVerifierError,
            SignatureVerifier._parse_stderr,
            fake_proc
            )

        eq(str(msg),
           ('There was a problem validating the response: XMLSec returned error '
            + 'code 1. Please check your certficate.'
            ),
           )
    def test_is_valid_current_time_on_or_after(self):
        encoded_response = base64.b64encode(test_response)
        res = Response(
            response=encoded_response,
            signature=None,
            )

        def fake_clock():
            return datetime(2004, 12, 05, 9, 30, 45, 462796)
        msg = assert_raises(
            ResponseValidationError,
            res.is_valid,
            _clock=fake_clock,
            )

        eq(str(msg),
           ('There was a problem validating the response: Current time is '
            + 'on or after NotOnOrAfter condition'
            ),
           )
    def test_is_valid_not_on_or_after_missing(self):
        response = """<samlp:Response
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   ID="identifier_2"
   InResponseTo="identifier_1"
   Version="2.0"
   IssueInstant="2004-12-05T09:22:05Z"
   Destination="https://sp.example.com/SAML2/SSO/POST">
   <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
   <samlp:Status>
     <samlp:StatusCode
       Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
   </samlp:Status>
   <saml:Assertion
     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
     ID="identifier_3"
     Version="2.0"
     IssueInstant="2004-12-05T09:22:05Z">
     <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
     <ds:Signature
       xmlns:ds="http://www.w3.org/2000/09/xmldsig#">foo signature</ds:Signature>
     <saml:Subject>
       <saml:NameID
         Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">
         3f7b3dcf-1674-4ecd-92c8-1544f346baf8
       </saml:NameID>
       <saml:SubjectConfirmation
         Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
         <saml:SubjectConfirmationData
           InResponseTo="identifier_1"
           Recipient="https://sp.example.com/SAML2/SSO/POST"
           NotOnOrAfter="2004-12-05T09:27:05Z"/>
       </saml:SubjectConfirmation>
     </saml:Subject>
     <saml:Conditions
       NotBefore="2004-12-05T09:27:05Z">
       <saml:AudienceRestriction>
         <saml:Audience>https://sp.example.com/SAML2</saml:Audience>
       </saml:AudienceRestriction>
     </saml:Conditions>
     <saml:AuthnStatement
       AuthnInstant="2004-12-05T09:22:00Z"
       SessionIndex="identifier_3">
       <saml:AuthnContext>
         <saml:AuthnContextClassRef>
           urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
        </saml:AuthnContextClassRef>
       </saml:AuthnContext>
     </saml:AuthnStatement>
   </saml:Assertion>
 </samlp:Response>
"""
        encoded_response = base64.b64encode(response)
        res = Response(
            response=encoded_response,
            signature=None,
            )
        msg = assert_raises(
            ResponseConditionError,
            res.is_valid,
            )

        eq(str(msg),
           ('There was a problem validating a condition: Did not find '
            + 'NotOnOrAfter condition'
            ),
           )
    def test_get_name_id_none(self):
        response = """<samlp:Response
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   ID="identifier_2"
   InResponseTo="identifier_1"
   Version="2.0"
   IssueInstant="2004-12-05T09:22:05Z"
   Destination="https://sp.example.com/SAML2/SSO/POST">
   <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
   <samlp:Status>
     <samlp:StatusCode
       Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
   </samlp:Status>
   <saml:Assertion
     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
     ID="identifier_3"
     Version="2.0"
     IssueInstant="2004-12-05T09:22:05Z">
     <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
     <ds:Signature
       xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
     <saml:Subject>
       <saml:SubjectConfirmation
         Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
         <saml:SubjectConfirmationData
           InResponseTo="identifier_1"
           Recipient="https://sp.example.com/SAML2/SSO/POST"
           NotOnOrAfter="2004-12-05T09:27:05Z"/>
       </saml:SubjectConfirmation>
     </saml:Subject>
     <saml:Conditions
       NotBefore="2004-12-05T09:17:05Z"
       NotOnOrAfter="2004-12-05T09:27:05Z">
       <saml:AudienceRestriction>
         <saml:Audience>https://sp.example.com/SAML2</saml:Audience>
       </saml:AudienceRestriction>
     </saml:Conditions>
     <saml:AuthnStatement
       AuthnInstant="2004-12-05T09:22:00Z"
       SessionIndex="identifier_3">
       <saml:AuthnContext>
         <saml:AuthnContextClassRef>
           urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
        </saml:AuthnContextClassRef>
       </saml:AuthnContext>
     </saml:AuthnStatement>
   </saml:Assertion>
 </samlp:Response>
"""
        encoded_response = base64.b64encode(response)
        res = Response(
            response=encoded_response,
            signature=None,
            )
        msg = assert_raises(
            ResponseNameIDError,
            res._get_name_id,
            )

        eq(
            str(msg),
            ('There was a problem getting the name ID: Did not find a name '
             + 'ID'
             ),
            )