Exemple #1
0
    def validate_response(self, response: ResponseParser):
        # Check it came from the right place
        if self.entity_id != response.issuer:
            raise CannotHandleAssertion(
                f'Entity ID mismatch {self.entity_id} != {response.issuer}')

        if response.conditions is not None:
            # Validate the NotBefore/NotOnOrAfter tags
            now = utcnow()
            not_before = response.conditions.get('NotBefore')
            not_on_or_after = response.conditions.get('NotOnOrAfter')
            try:
                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

            # 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):
                raise CannotHandleAssertion(
                    "No valid AudienceRestriction found")
    def make_response(self, request) -> XmlTemplate:
        """
        Process the request and make a :class:`~.xml_render.ResponseTemplate`.
        """
        self.validate_request(request)
        self.validate_user()

        issue_instant = utcnow()
        assertion = self.format_assertion(self.build_assertion(request, issue_instant))
        response = self.format_response(self.build_response(request, issue_instant), assertion)
        return response
Exemple #3
0
 def get_authn_request(
     self,
     template=AuthnRequest,
     **parameters,
 ):
     """
     Make a AuthnRequest to send to this IdP.
     """
     return template({
         'REQUEST_ID': get_random_id(),
         'ISSUE_INSTANT': self.format_datetime(utcnow()),
         'DESTINATION': self.get_idp_sso_url(),
         'ISSUER': self.sp.get_sp_entity_id(),
         'ACS_URL': self.get_sp_acs_url(),
         **parameters,
     })
Exemple #4
0
    def test_just_right(self):
        now = utcnow()
        self.login(self.user)

        with freezegun.freeze_time(now) as frozen:
            authn_request = self._make_authn_request()

            # step forwards a bit for transmission time
            frozen.tick(delta=datetime.timedelta(seconds=30))

            authn_response = self._process_authn_request(authn_request)

            # step forwards a bit for transmission times
            frozen.tick(delta=datetime.timedelta(seconds=30))

            auth_data = self._process_authn_response(authn_response)
            assert auth_data.nameid == self.user.email
Exemple #5
0
    def test_too_late(self):
        now = utcnow()
        self.login(self.user)

        with freezegun.freeze_time(now) as frozen:
            authn_request = self._make_authn_request()

            # step forwards a bit for transmission time
            frozen.tick(delta=datetime.timedelta(seconds=30))

            authn_response = self._process_authn_request(authn_request)

            # step backwards a bunch
            frozen.tick(delta=datetime.timedelta(minutes=25))

            with pytest.raises(CannotHandleAssertion, match='NotOnOrAfter'):
                self._process_authn_response(authn_response)
Exemple #6
0
 def get_logout_request(
     self,
     auth_data: AuthData,
     template: XmlTemplate = LogoutRequest,
     **parameters,
 ):
     """
     Make a LogoutRequest for the authenticated user to send to this IdP.
     """
     return template({
         'REQUEST_ID': get_random_id(),
         'ISSUE_INSTANT': self.format_datetime(utcnow()),
         'DESTINATION': self.get_idp_slo_url(),
         'ISSUER': self.sp.get_sp_entity_id(),
         'SUBJECT': auth_data.nameid,
         'SUBJECT_FORMAT': auth_data.nameid_format,
         **parameters,
     })