def _func(self, conv): _response = conv.last_response _content = conv.last_content res = {} if _response.status_code >= 400: self._status = self.status self._message = self.msg if CONT_JSON in _response.headers["content-type"]: try: err = ErrorResponse().deserialize(_content, "json") self._message = err.to_json() except Exception: res["content"] = _content else: res["content"] = _content res["url"] = conv.position res["http_status"] = _response.status_code else: # might still be an error message try: err = ErrorResponse().deserialize(_content, "json") err.verify() self._message = err.to_json() self._status = self.status except Exception: pass res["url"] = conv.position return res
def _func(self, conv): _response = conv.last_response res = {} try: _loc = _response.headers["location"] if "?" in _loc: query = _loc.split("?")[1] elif "#" in _loc: query = _loc.split("#")[1] else: # ??? self._message = "Expected redirect" self._status = CRITICAL return res except (KeyError, AttributeError): self._message = "Expected redirect" self._status = CRITICAL return res if _response.status_code == 302: err = ErrorResponse().deserialize(query, "urlencoded") try: err.verify() res["content"] = err.to_json() conv.protocol_response.append((err, query)) except MissingRequiredAttribute: self._message = "Expected error message" self._status = CRITICAL else: self._message = "Expected error message" self._status = CRITICAL 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 handle_registration_info(self, response): if response.status_code in [200, 201]: resp = ClientInfoResponse().deserialize(response.text, "json") self.store_registration_info(resp) else: err = ErrorResponse().deserialize(response.text, "json") raise PyoidcError("Registration failed: %s" % err.to_json()) return resp
def handle_registration_info(self, response): if response.status_code in SUCCESSFUL: resp = ClientInfoResponse().deserialize(response.text, "json") self.store_registration_info(resp) else: err = ErrorResponse().deserialize(response.text, "json") raise PyoidcError("Registration failed: %s" % err.to_json()) return resp
class CheckErrorResponse(ExpectedError): """ Checks that the HTTP response status is outside the 200 or 300 range or that an JSON encoded error message has been received """ cid = "check-error-response" msg = "OP error" def _func(self, conv): _response = conv.last_response _content = conv.last_content res = {} if _response.status_code >= 400: content_type = _response.headers["content-type"] if content_type is None: res["content"] = _content elif CONT_JSON in content_type: try: self.err = ErrorResponse().deserialize(_content, "json") self.err.verify() res["content"] = self.err.to_json() #res["temp"] = err except Exception: res["content"] = _content else: res["content"] = _content else: # might still be an error message try: self.err = ErrorResponse().deserialize(_content, "json") self.err.verify() res["content"] = self.err.to_json() except Exception: self._message = "Expected error message" self._status = CRITICAL res["url"] = conv.position return res
def _func(self, conv): _response = conv.last_response _content = conv.last_content res = {} if _response.status_code == 400: err = ErrorResponse().deserialize(_content, "json") err.verify() res["content"] = err.to_json() conv.protocol_response.append((err, _content)) else: self._message = "Expected a 400 error message" self._status = CRITICAL return res
def authorization(self, **kwargs): if cherrypy.request.method == "OPTIONS": cherrypy_cors.preflight( allowed_methods=["GET"], origins='*', allowed_headers=['Authorization', 'content-type']) else: logger.debug('AuthorizationRequest') try: args = {'cookie': cherrypy.request.headers['Cookie']} except KeyError: args = {} try: _claims = json.loads(kwargs['claims']) except json.JSONDecodeError: try: _claims = json.loads( kwargs['claims'].replace("\'", '"').replace('True', 'true')) except json.JSONDecodeError: _err = ErrorResponse( error="invalid_request", error_description="Invalid claims value" ) raise cherrypy.HTTPError(400, as_bytes(_err.to_json())) else: kwargs['claims'] = _claims except KeyError: pass else: kwargs['claims'] = _claims try: resp = self.op.authorization_endpoint(kwargs, **args) except Exception as err: raise cherrypy.HTTPError(message=err) else: return conv_response(resp)
def auth_init(self, request, request_class=AuthorizationRequest): """ :param request: The AuthorizationRequest :return: """ logger.debug("Request: '%s'" % sanitize(request)) # Same serialization used for GET and POST try: areq = self.server.parse_authorization_request( request=request_class, query=request) except (MissingRequiredValue, MissingRequiredAttribute, AuthzError) as err: logger.debug("%s" % err) areq = request_class() areq.lax = True if isinstance(request, dict): areq.from_dict(request) else: areq.deserialize(request, "urlencoded") try: redirect_uri = self.get_redirect_uri(areq) except (RedirectURIError, ParameterError, UnknownClient) as err: return error_response("invalid_request", "%s" % err) try: _rtype = areq["response_type"] except KeyError: _rtype = ["code"] try: _state = areq["state"] except KeyError: _state = '' return redirect_authz_error("invalid_request", redirect_uri, "%s" % err, _state, _rtype) except KeyError: areq = request_class().deserialize(request, "urlencoded") # verify the redirect_uri try: self.get_redirect_uri(areq) except (RedirectURIError, ParameterError) as err: return error_response("invalid_request", "%s" % err) except Exception as err: message = traceback.format_exception(*sys.exc_info()) logger.error(message) logger.debug("Bad request: %s (%s)" % (err, err.__class__.__name__)) err = ErrorResponse(error='invalid_request', error_description=str(err)) return BadRequest(err.to_json(), content='application/json') if not areq: logger.debug("No AuthzRequest") return error_response("invalid_request", "Can not parse AuthzRequest") areq = self.filter_request(areq) if self.events: self.events.store('Protocol request', areq) try: _cinfo = self.cdb[areq['client_id']] except KeyError: logger.error( 'Client ID ({}) not in client database'.format( areq['client_id'])) return error_response('unauthorized_client', 'unknown client') else: try: _registered = [set(rt.split(' ')) for rt in _cinfo['response_types']] except KeyError: # If no response_type is registered by the client then we'll # code which it the default according to the OIDC spec. _registered = [{'code'}] _wanted = set(areq["response_type"]) if _wanted not in _registered: return error_response("invalid_request", "Trying to use unregistered response_typ") logger.debug("AuthzRequest: %s" % (sanitize(areq.to_dict()),)) try: redirect_uri = self.get_redirect_uri(areq) except (RedirectURIError, ParameterError, UnknownClient) as err: return error_response("invalid_request", "{}:{}".format(err.__class__.__name__, err)) try: keyjar = self.keyjar except AttributeError: keyjar = "" try: # verify that the request message is correct areq.verify(keyjar=keyjar, opponent_id=areq["client_id"]) except (MissingRequiredAttribute, ValueError, MissingRequiredValue) as err: return redirect_authz_error("invalid_request", redirect_uri, "%s" % err) return {"areq": areq, "redirect_uri": redirect_uri}