def _func(self, conv): res = {} response = conv.last_response if response.status_code == 302: _loc = response.headers["location"] if "?" in _loc: _query = _loc.split("?")[1] elif "#" in _loc: _query = _loc.split("#")[1] else: self._message = "Faulty error message" self._status = ERROR return try: err = ErrorResponse().deserialize(_query, "urlencoded") err.verify() #res["temp"] = err res["message"] = err.to_dict() except Exception: self._message = "Faulty error message" self._status = ERROR else: self._message = "Expected a redirect with an error message" self._status = ERROR return res
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)
def do_user_info_request(self, method="POST", state="", scope="openid", request="openid", **kwargs): kwargs["request"] = request path, body, method, h_args = self.user_info_request(method, state, scope, **kwargs) logger.debug( "[do_user_info_request] PATH:{} BODY:{} H_ARGS: {}".format(path, body, h_args)) if self.events: self.events.store('Request', {'body': body}) self.events.store('request_url', path) self.events.store('request_http_args', h_args) try: resp = self.http_request(path, method, data=body, **h_args) except MissingRequiredAttribute: raise if resp.status_code == 200: try: assert "application/json" in resp.headers["content-type"] sformat = "json" except AssertionError: assert "application/jwt" in resp.headers["content-type"] sformat = "jwt" elif resp.status_code == 500: raise PyoidcError("ERROR: Something went wrong: %s" % resp.text) elif resp.status_code == 401: try: www_auth_header=resp.headers["WWW-Authenticate"] res = ErrorResponse(error="invalid_token", error_description="Server returned 401 Unauthorized. WWW-Authenticate header:{}".format(www_auth_header)) except KeyError: #no www-authenticate header. https://tools.ietf.org/html/rfc6750#section-3 reads: #the resource server MUST include the HTTP "WWW-Authenticate" response header field res = ErrorResponse(error="invalid_token", error_description="Server returned 401 Unauthorized without a WWW-Authenticate header which is required as per https://tools.ietf.org/html/rfc6750#section-3") self.store_response(res, resp.text) return res elif 400 <= resp.status_code < 500: # the response text might be a OIDC message try: res = ErrorResponse().from_json(resp.text) except Exception: raise RequestError(resp.text) else: self.store_response(res, resp.text) return res else: raise PyoidcError("ERROR: Something went wrong [%s]: %s" % ( resp.status_code, resp.text)) try: _schema = kwargs["user_info_schema"] except KeyError: _schema = OpenIDSchema logger.debug("Reponse text: '{}'".format(resp.text)) _txt = resp.text if sformat == "json": res = _schema().from_json(txt=_txt) else: verify = kwargs.get('verify', True) res = _schema().from_jwt(_txt, keyjar=self.keyjar, sender=self.provider_info["issuer"], verify=verify) if 'error' in res: # Error response res = UserInfoErrorResponse(**res.to_dict()) # TODO verify issuer:sub against what's returned in the ID Token self.store_response(res, _txt) return res
def do_user_info_request(self, method="POST", state="", scope="openid", request="openid", **kwargs): kwargs["request"] = request path, body, method, h_args = self.user_info_request( method, state, scope, **kwargs) logger.debug( "[do_user_info_request] PATH:{} BODY:{} H_ARGS: {}".format( path, body, h_args)) if self.events: self.events.store('Request', {'body': body}) self.events.store('request_url', path) self.events.store('request_http_args', h_args) try: resp = self.http_request(path, method, data=body, **h_args) except MissingRequiredAttribute: raise if resp.status_code == 200: try: assert "application/json" in resp.headers["content-type"] sformat = "json" except AssertionError: assert "application/jwt" in resp.headers["content-type"] sformat = "jwt" elif resp.status_code == 500: raise PyoidcError("ERROR: Something went wrong: %s" % resp.text) elif resp.status_code == 401: try: www_auth_header = resp.headers["WWW-Authenticate"] res = ErrorResponse( error="invalid_token", error_description= "Server returned 401 Unauthorized. WWW-Authenticate header:{}" .format(www_auth_header)) except KeyError: #no www-authenticate header. https://tools.ietf.org/html/rfc6750#section-3 reads: #the resource server MUST include the HTTP "WWW-Authenticate" response header field res = ErrorResponse( error="invalid_token", error_description= "Server returned 401 Unauthorized without a WWW-Authenticate header which is required as per https://tools.ietf.org/html/rfc6750#section-3" ) self.store_response(res, resp.text) return res elif 400 <= resp.status_code < 500: # the response text might be a OIDC message try: res = ErrorResponse().from_json(resp.text) except Exception: raise RequestError(resp.text) else: self.store_response(res, resp.text) return res else: raise PyoidcError("ERROR: Something went wrong [%s]: %s" % (resp.status_code, resp.text)) try: _schema = kwargs["user_info_schema"] except KeyError: _schema = OpenIDSchema logger.debug("Reponse text: '{}'".format(resp.text)) _txt = resp.text if sformat == "json": res = _schema().from_json(txt=_txt) else: verify = kwargs.get('verify', True) res = _schema().from_jwt(_txt, keyjar=self.keyjar, sender=self.provider_info["issuer"], verify=verify) if 'error' in res: # Error response res = UserInfoErrorResponse(**res.to_dict()) # TODO verify issuer:sub against what's returned in the ID Token self.store_response(res, _txt) return res
def do_user_info_request(self, method="POST", state="", scope="openid", request="openid", **kwargs): kwargs["request"] = request path, body, method, h_args = self.user_info_request( method, state, scope, **kwargs) logger.debug( "[do_user_info_request] PATH:{} BODY:{} H_ARGS: {}".format( path, body, h_args)) if self.events: self.events.store('Request', {'body': body}) self.events.store('request_url', path) self.events.store('request_http_args', h_args) try: resp = self.http_request(path, method, data=body, **h_args) except MissingRequiredAttribute: raise if resp.status_code == 200: try: assert "application/json" in resp.headers["content-type"] sformat = "json" except AssertionError: assert "application/jwt" in resp.headers["content-type"] sformat = "jwt" elif resp.status_code == 500: raise PyoidcError("ERROR: Something went wrong: %s" % resp.text) elif 400 <= resp.status_code < 500: # the response text might be a OIDC message try: res = ErrorResponse().from_json(resp.text) except Exception: raise RequestError(resp.text) else: self.store_response(res, resp.text) return res else: raise PyoidcError("ERROR: Something went wrong [%s]: %s" % (resp.status_code, resp.text)) try: _schema = kwargs["user_info_schema"] except KeyError: _schema = OpenIDSchema logger.debug("Reponse text: '{}'".format(resp.text)) _txt = resp.text if sformat == "json": res = _schema().from_json(txt=_txt) else: verify = kwargs.get('verify', True) res = _schema().from_jwt(_txt, keyjar=self.keyjar, sender=self.provider_info["issuer"], verify=verify) if 'error' in res: # Error response res = UserInfoErrorResponse(**res.to_dict()) # TODO verify issuer:sub against what's returned in the ID Token self.store_response(res, _txt) return res