Esempio n. 1
0
    def parse_federation_registration(self, resp, issuer):
        """
        Receives a dynamic client registration response, verifies the
        signature and parses the compounded metadata statement.
        If only one federation are mentioned in the response then the name
        of that federation are stored in the *federation* attribute and
        the flattened response is handled in the normal pyoidc way.
        If there are more then one federation involved then the decision
        on which to use has to be made higher up, hence the list of
        :py:class:`fedoidc.operator.LessOrEqual` instances are stored in the
        attribute *registration_federations*
        
        :param resp: A MetadataStatement instance or a dictionary
        :param issuer: Issuer ID
        """
        ms_list = self.federation_entity.get_metadata_statement(
            resp, cls=ClientMetadataStatement)

        if not ms_list:  # No metadata statement that I can use
            raise RegistrationError('No trusted metadata')

        # response is a list of registration infos

        # At this point in time I may not know within which
        # federation I'll be working.
        if len(ms_list) == 1:
            ms = ms_list[0]
            _trusted_claims = ms.protected_claims()
            if not _trusted_claims:
                raise fedoidc.NoTrustedClaims()
            self.store_registration_info(_trusted_claims)
            self.federation = ms.fo
            self.redirect_uris = self.registration_response['redirect_uris']
        else:
            self.registration_federations = ms_list
Esempio n. 2
0
    def verify(self, **kwargs):
        if "initiate_login_uri" in self and not self[
                "initiate_login_uri"].startswith("https:"):
            raise RegistrationError("initiate_login_uri is not https")

        if "redirect_uris" in self:
            for uri in self["redirect_uris"]:
                if urlparse(uri).fragment:
                    raise InvalidRedirectUri(
                        "redirect_uri contains fragment: %s" % uri)

        for uri in ["client_uri", "logo_uri", "tos_uri", "policy_uri"]:
            if uri in self:
                try:
                    resp = requests.request("GET",
                                            str(self[uri]),
                                            allow_redirects=True,
                                            verify=False)
                except requests.ConnectionError:
                    raise MissingPage(self[uri])

                if resp.status_code not in SUCCESSFUL:
                    raise MissingPage(self[uri])

        try:
            ss = self["software_statement"]
        except KeyError:
            pass
        else:
            _ss = []
            for _s in ss:
                _ss.append(unpack_software_statement(_s, "", kwargs["keyjar"]))
            self["__software_statement"] = _ss

        return super(RegistrationRequest, self).verify(**kwargs)
Esempio n. 3
0
    def handle_response(self, response, issuer, func, response_cls):
        """
        Handle a request response. Depending on which type of response 
        it is different functions *func* will be used to handle it.
        If something went wrong an exception will be raised.
        
        :param response: A requests.request response 
        :param issuer: who was the request sent to
        :param func: A function to use for handling a correct response
        :param response_cls: The response should match this class
        """
        err_msg = 'Got error response: {}'
        unk_msg = 'Unknown response: {}'

        if response.status_code in [200, 201]:
            resp = response_cls().deserialize(response.text, "json")

            # Some implementations sends back a 200 with an error message inside
            if resp.verify():  # got a proper response
                func(resp, issuer)
            else:
                resp = ErrorResponse().deserialize(response.text, "json")
                if resp.verify():
                    logger.error(err_msg.format(sanitize(resp.to_json())))
                    if self.events:
                        self.events.store('protocol response', resp)
                    raise RegistrationError(resp.to_dict())
                else:  # Something else
                    logger.error(unk_msg.format(sanitize(response.text)))
                    raise RegistrationError(response.text)
        else:
            try:
                resp = ErrorResponse().deserialize(response.text, "json")
            except _decode_err:
                logger.error(unk_msg.format(sanitize(response.text)))
                raise RegistrationError(response.text)

            if resp.verify():
                logger.error(err_msg.format(sanitize(resp.to_json())))
                if self.events:
                    self.events.store('protocol response', resp)
                raise RegistrationError(resp.to_dict())
            else:  # Something else
                logger.error(unk_msg.format(sanitize(response.text)))
                raise RegistrationError(response.text)
Esempio n. 4
0
    def verify(self, **kwargs):
        if "initiate_login_uri" in self and not self[
                "initiate_login_uri"].startswith("https:"):
            raise RegistrationError('initiate_login_uri is not https')

        if "redirect_uris" in self:
            for uri in self["redirect_uris"]:
                if urlparse(uri).fragment:
                    raise InvalidRedirectUri(
                        "redirect_uri contains fragment: %s" % uri)

        for uri in ["client_uri", "logo_uri", "tos_uri", "policy_uri"]:
            if uri in self:
                try:
                    resp = requests.request("GET",
                                            str(self[uri]),
                                            allow_redirects=True,
                                            verify=False)
                except requests.ConnectionError:
                    raise MissingPage(self[uri])

                if resp.status_code not in SUCCESSFUL:
                    raise MissingPage(self[uri])

        # if "grant_types" in self and "response_types" in self:
        #     for typ in self["grant_types"]:
        #         if typ == "authorization_code":
        #             assert "code" in self["response_types"]
        #         elif typ == "implicit":
        #             assert "token" in self["response_types"]

        try:
            ss = self['software_statement']
        except KeyError:
            pass
        else:
            # need to get the client keys before I can verify any signature
            # kj = kwargs['keyjar']
            # The case where jwks_uri is used
            # try:
            #     kj.add(,self['jwks_uri'])
            _ss = []
            for _s in ss:
                _ss.append(unpack_software_statement(_s, '', kwargs['keyjar']))
            self['__software_statement'] = _ss

        return super(RegistrationRequest, self).verify(**kwargs)
Esempio n. 5
0
    def handle_registration_info(self, response):
        err_msg = 'Got error response: {}'
        unk_msg = 'Unknown response: {}'
        if response.status_code in [200, 201]:
            resp = RegistrationResponse().deserialize(response.text, "json")
            # Some implementations sends back a 200 with an error message inside
            if resp.verify():  # got a proper registration response
                resp = self.get_metadata_statement(resp)
                if resp is None: # No metadata statement that I can use
                    raise RegistrationError('No trusted metadata')
                self.store_response(resp, response.text)
                self.store_registration_info(resp)
            else:
                resp = ErrorResponse().deserialize(response.text, "json")
                if resp.verify():
                    logger.error(err_msg.format(sanitize(resp.to_json())))
                    if self.events:
                        self.events.store('protocol response', resp)
                    raise RegistrationError(resp.to_dict())
                else:  # Something else
                    logger.error(unk_msg.format(sanitize(response.text)))
                    raise RegistrationError(response.text)
        else:
            try:
                resp = ErrorResponse().deserialize(response.text, "json")
            except _decode_err:
                logger.error(unk_msg.format(sanitize(response.text)))
                raise RegistrationError(response.text)

            if resp.verify():
                logger.error(err_msg.format(sanitize(resp.to_json())))
                if self.events:
                    self.events.store('protocol response', resp)
                raise RegistrationError(resp.to_dict())
            else:  # Something else
                logger.error(unk_msg.format(sanitize(response.text)))
                raise RegistrationError(response.text)

        return resp