Beispiel #1
0
    def _func(self, conv):
        res = {}
        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return 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(_response.txt, "json")
                    self._message = err.to_json()
                except Exception:
                    res["content"] = _response.text
            else:
                res["content"] = _response.text
            res["url"] = _response.url
            res["http_status"] = _response.status_code
        elif _response.status_code in [300, 301, 302]:
            pass
        else:
            # might still be an error message
            msg = conv.events.last_item(EV_PROTOCOL_RESPONSE)
            if isinstance(msg, ErrorResponse):
                self._message = msg.to_json()
                self._status = self.status

        return res
Beispiel #2
0
    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
Beispiel #3
0
    def _func(self, conv):
        res = {}
        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return 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(_response.txt, "json")
                    self._message = err.to_json()
                except Exception:
                    res["content"] = _response.text
            else:
                res["content"] = _response.text
            res["url"] = _response.url
            res["http_status"] = _response.status_code
        elif _response.status_code in [300, 301, 302]:
            pass
        else:
            # might still be an error message
            msg = conv.events.last_item(EV_PROTOCOL_RESPONSE)
            if isinstance(msg, ErrorResponse):
                self._message = msg.to_json()
                self._status = self.status

        return res
Beispiel #4
0
    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 a redirect"
                self._status = CRITICAL
                return res
        except (KeyError, AttributeError):
            self._message = "Expected a 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 an error message"
                self._status = CRITICAL
        else:
            self._message = "Expected an error message"
            self._status = CRITICAL

        return res
Beispiel #5
0
    def do_put(self, path, info):
        """
        UPDATE: PUT /{collection}/{id}

        """

        _name = self.resource_name(path)
        try:
            f = open(_name, "w")
        except IOError:
            return ErrorResponse(error="not_allowed")

        head, tail = os.path.split(_name)

        try:
            _ji = json.loads(info)
        except ValueError:
            return ErrorResponse(error="not_json")

        try:
            assert _ji["_id"] == tail
        except KeyError:
            _ji["_id"] = tail
        except AssertionError:
            return ErrorResponse(error="not_allowed")

        f.write(json.dumps(_ji))
        f.close()
        return Response(json.dumps({"_id": tail}),
                        headers=[("Location",
                                  "%s/%s" % (self.baseurl, self.url(_name)))])
Beispiel #6
0
    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 a redirect"
                self._status = CRITICAL
                return res
        except (KeyError, AttributeError):
            self._message = "Expected a 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 an error message"
                self._status = CRITICAL
        else:
            self._message = "Expected an error message"
            self._status = CRITICAL

        return res
Beispiel #7
0
    def _func(self, conv):
        res = {}
        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return res

        try:
            _content = last_raw_response(conv)
        except NoSuchEvent:
            return res

        if _response.status_code == 400:
            err = ErrorResponse().deserialize(_content, "json")
            err.verify()
            res["content"] = err.to_json()
            conv.events.store(EV_PROTOCOL_RESPONSE, err)
        elif _response.status_code in [301, 302, 303]:
            pass
        elif _response.status_code in SUCCESSFUL:
            err = ErrorResponse().deserialize(_content, "json")
            err.verify()
            res["content"] = err.to_json()
            conv.events.store(EV_PROTOCOL_RESPONSE, err)
        else:
            self._message = "Expected a 400 error message"
            self._status = CRITICAL

        return res
Beispiel #8
0
    def test_parse_error_resp(self):
        err = ErrorResponse(
            error="invalid_request",
            error_description="Something was missing",
            error_uri="http://example.com/error_message.html",
        )
        jerr = err.to_json()
        uerr = err.to_urlencoded()

        self.client.parse_response(AccessTokenResponse, info=jerr)
        self.client.parse_response(AccessTokenResponse,
                                   info=uerr,
                                   sformat="urlencoded")

        with pytest.raises(ResponseError):
            self.client.parse_response(AccessTokenResponse,
                                       info=jerr,
                                       sformat="urlencoded")

        with pytest.raises(DecodeError):
            self.client.parse_response(AccessTokenResponse, info=uerr)

        with pytest.raises(FormatError):
            self.client.parse_response(
                AccessTokenResponse,
                info=jerr,
                sformat="focus"  # type: ignore
            )
Beispiel #9
0
    def _func(self, conv):
        res = {}

        response = conv.events.last_item(EV_HTTP_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
Beispiel #10
0
    def _func(self, conv):
        _response = conv.events.last_item(EV_HTTP_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 a redirect"
                self._status = CRITICAL
                return res
            env_id = conv.events.store(EV_RESPONSE, query)
        except (KeyError, AttributeError):
            self._message = "Expected a 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.events.store(EV_PROTOCOL_RESPONSE, err, env_id)
            except MissingRequiredAttribute:
                self._message = "Expected an error message"
                self._status = CRITICAL
        else:
            self._message = "Expected an error message"
            self._status = CRITICAL

        return res
Beispiel #11
0
    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
Beispiel #12
0
    def handle_registration_info(self, response):
        if response.status_code == 200:
            resp = RegistrationResponse().deserialize(response.text, "json")
            self.store_registration_info(resp)
        else:
            err = ErrorResponse().deserialize(response.text, "json")
            raise PyoidcError("Registration failed: %s" % err.get_json())

        return resp
Beispiel #13
0
    def handle_registration_info(self, response):
        if response.status_code == 200:
            resp = RegistrationResponse().deserialize(response.text, "json")
            self.store_registration_info(resp)
        else:
            err = ErrorResponse().deserialize(response.text, "json")
            raise PyoidcError("Registration failed: %s" % err.get_json())

        return resp
Beispiel #14
0
    def parse_request_response(self,
                               reqresp,
                               response,
                               body_type,
                               state="",
                               verify=True,
                               **kwargs):

        if reqresp.status_code in SUCCESSFUL:
            body_type = verify_header(reqresp, body_type)
        elif reqresp.status_code in [302, 303]:  # redirect
            return reqresp
        elif reqresp.status_code == 500:
            logger.error("(%d) %s" %
                         (reqresp.status_code, sanitize(reqresp.text)))
            raise ParseError("ERROR: Something went wrong: %s" % reqresp.text)
        elif reqresp.status_code in [400, 401]:
            # expecting an error response
            if issubclass(response, ErrorResponse):
                pass
        else:
            logger.error("(%d) %s" %
                         (reqresp.status_code, sanitize(reqresp.text)))
            raise HttpError("HTTP ERROR: %s [%s] on %s" %
                            (reqresp.text, reqresp.status_code, reqresp.url))

        if response:
            if body_type == 'txt':
                # no meaning trying to parse unstructured text
                return reqresp.text
            if not verify:
                # AymRod: skip parsing
                return reqresp.text
            else:
                return self.parse_response(response, reqresp.text, body_type,
                                           state, **kwargs)

        # could be an error response
        if reqresp.status_code in [200, 400, 401]:
            if body_type == 'txt':
                body_type = 'urlencoded'
            try:
                err = ErrorResponse().deserialize(reqresp.message,
                                                  method=body_type)
                try:
                    err.verify()
                except PyoidcError:
                    pass
                else:
                    return err
            except Exception:
                pass

        return reqresp
Beispiel #15
0
    def test_omit(self):
        err = ErrorResponse(error="invalid_request",
                            error_description="Something was missing",
                            error_uri="http://example.com/error_message.html")

        ue_str = err.to_urlencoded()
        del err["error_uri"]
        ueo_str = err.to_urlencoded()

        assert ue_str != ueo_str
        assert "error_message" not in ueo_str
        assert "error_message" in ue_str
Beispiel #16
0
    def test_omit(self):
        err = ErrorResponse(error="invalid_request",
                            error_description="Something was missing",
                            error_uri="http://example.com/error_message.html")

        ue_str = err.to_urlencoded()
        del err["error_uri"]
        ueo_str = err.to_urlencoded()

        assert ue_str != ueo_str
        assert "error_message" not in ueo_str
        assert "error_message" in ue_str
Beispiel #17
0
    def handle_registration_info(self, response):
        if response.status_code == 200:
            resp = RegistrationResponse().deserialize(response.text, "json")
            self.registration_response = resp
            self.client_secret = resp["client_secret"]
            self.client_id = resp["client_id"]
            self.registration_expires = resp["client_secret_expires_at"]
            self.registration_access_token = resp["registration_access_token"]
        else:
            err = ErrorResponse().deserialize(response.text, "json")
            raise PyoidcError("Registration failed: %s" % err.get_json())

        return resp
Beispiel #18
0
    def _func(self, environ):
        _response = environ["response"]
        _content = environ["content"]

        res = {}
        if _response.status_code >= 400 :
            if "application/json" in _response.headers["content-type"]:
                try:
                    err = ErrorResponse().deserialize(_content, "json")
                    err.verify()
                    res["content"] = err.to_json()
                    res["temp"] = err
                except Exception:
                    res["content"] = _content
            else:
                res["content"] = _content
        else:
            # might still be an error message
            try:
                err = ErrorResponse().deserialize(_content, "json")
                err.verify()
                res["content"] = err.to_json()
            except Exception:
                self._message = "Expected error message"
                self._status = CRITICAL

            res["url"] = environ["url"]

        return res
Beispiel #19
0
    def _func(self, environ):
        _response = environ["response"]
        _content = environ["content"]
        res = {}
        if _response.status_code == 400 :
            err = ErrorResponse().deserialize(_content, "json")
            err.verify()
            res["content"] = err.to_json()
            environ["item"].append(err)
        else:
            self._message = "Expected a 400 error message"
            self._status = CRITICAL

        return res
Beispiel #20
0
    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
Beispiel #21
0
    def _func(self, conv):
        res = {}
        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return res

        try:
            _content = last_raw_response(conv)
        except NoSuchEvent:
            return res

        if _response.status_code == 400:
            err = ErrorResponse().deserialize(_content, "json")
            err.verify()
            res["content"] = err.to_json()
            conv.events.store(EV_PROTOCOL_RESPONSE, err)
        elif _response.status_code in [301, 302, 303]:
            pass
        elif _response.status_code in SUCCESSFUL:
            err = ErrorResponse().deserialize(_content, "json")
            err.verify()
            res["content"] = err.to_json()
            conv.events.store(EV_PROTOCOL_RESPONSE, err)
        else:
            self._message = "Expected a 400 error message"
            self._status = CRITICAL

        return res
Beispiel #22
0
def exception_to_error_mesg(excep):
    if isinstance(excep, PyoidcError):
        if excep.content_type:
            if isinstance(excep.args, tuple):
                resp = BadRequest(excep.args[0], content=excep.content_type)
            else:
                resp = BadRequest(excep.args, content=excep.content_type)
        else:
            resp = BadRequest()
    else:
        err = ErrorResponse(error='service_error',
                            error_description='{}:{}'.format(
                                excep.__class__.__name__, excep.args))
        resp = BadRequest(err.to_json(), content='application/json')
    return resp
Beispiel #23
0
    def _func(self, environ):
        _response = environ["response"]

        res = {}
        query = _response.headers["location"].split("?")[1]
        if _response.status_code == 302 :
            err = ErrorResponse().deserialize(query, "urlencoded")
            err.verify()
            res["content"] = err.to_json()
            environ["item"].append(err)
        else:
            self._message = "Expected error message"
            self._status = CRITICAL

        return res
Beispiel #24
0
    def do_get(self, path):
        """
        GET /{collection}/{id}
        """

        _name = self.resource_name(path)
        if os.path.isfile(_name):
            try:
                data = open(_name, "r").read()
            except IOError:
                return ErrorResponse(error="not_available")
            else:
                return Response(data)
        else:
            return ErrorResponse(error="not_allowed")
Beispiel #25
0
    def client_info(self, client_id):
        _cinfo = self.cdb[client_id].copy()
        if not valid_client_info(_cinfo):
            err = ErrorResponse(error="invalid_client",
                                error_description="Invalid client secret")
            return BadRequest(err.to_json(), content="application/json")

        try:
            _cinfo["redirect_uris"] = self._tuples_to_uris(
                _cinfo["redirect_uris"])
        except KeyError:
            pass

        msg = ClientInfoResponse(**_cinfo)
        return Response(msg.to_json(), content="application/json")
Beispiel #26
0
    def client_info(self, client_id):
        _cinfo = self.cdb[client_id].copy()
        if not valid_client_info(_cinfo):
            err = ErrorResponse(
                error="invalid_client", error_description="Invalid client secret"
            )
            return BadRequest(err.to_json(), content="application/json")

        try:
            _cinfo["redirect_uris"] = self._tuples_to_uris(_cinfo["redirect_uris"])
        except KeyError:
            pass

        msg = self.server.message_factory.get_response_type("update_endpoint")(**_cinfo)
        return Response(msg.to_json(), content="application/json")
Beispiel #27
0
def exception_to_error_mesg(excep):
    if isinstance(excep, PyoidcError):
        if excep.content_type:
            if isinstance(excep.args, tuple):
                resp = BadRequest(excep.args[0], content=excep.content_type)
            else:
                resp = BadRequest(excep.args, content=excep.content_type)
        else:
            resp = BadRequest()
    else:
        err = ErrorResponse(error='service_error',
                            error_description='{}:{}'.format(
                                excep.__class__.__name__, excep.args))
        resp = BadRequest(err.to_json(), content='application/json')
    return resp
Beispiel #28
0
    def _func(self, conv):
        _response = conv.last_response
        _content = conv.last_content
        _client = conv.client
        res = {}
        if _response.status_code == 400:
            err = ErrorResponse().deserialize(_content, "json")
            err.verify()
            if err["error"] in ["consent_required", "interaction_required"]:
                # This is OK
                res["content"] = err.to_json()
                conv.protocol_response.append((err, _content))
            else:
                self._message = "Not an error I expected"
                self._status = CRITICAL
        elif _response.status_code in [301, 302]:
            _loc = _response.headers["location"]
            callback = False
            for url in _client.redirect_uris:
                if _loc.startswith(url):
                    callback = True
                    break

            if not callback:
                self._message = "Not valid to not redirect back to RP"
                self._status = ERROR
                return res

            if "?" in _loc:
                _query = _loc.split("?")[1]
            elif "#" in _loc:
                _query = _loc.split("#")[1]
            else:  # ???
                self._message = "Expected info in the redirect"
                self._status = CRITICAL
                return res
            try:
                err = ErrorResponse().deserialize(_query, "urlencoded")
                err.verify()
                if err["error"] in ["consent_required", "interaction_required",
                                    "login_required"]:
                    # This is OK
                    res["content"] = err.to_json()
                    conv.protocol_response.append((err, _query))
                else:
                    self._message = "Not an error I expected '%s'" % err[
                        "error"]
                    self._status = CRITICAL
            except:
                resp = AuthorizationResponse().deserialize(_query, "urlencoded")
                resp.verify()
                res["content"] = resp.to_json()
                conv.protocol_response.append((resp, _query))
        else:  # should not get anything else
            self._message = "Not an response I expected"
            self._status = CRITICAL

        return res
Beispiel #29
0
    def client_info(self, client_id):
        _cinfo = self.cdb[client_id].copy()
        if not valid_client_info(_cinfo):
            err = ErrorResponse(
                error="invalid_client",
                error_description="Invalid client secret")
            return BadRequest(err.to_json(), content="application/json")

        try:
            _cinfo["redirect_uris"] = self._tuples_to_uris(
                _cinfo["redirect_uris"])
        except KeyError:
            pass

        msg = ClientInfoResponse(**_cinfo)
        return Response(msg.to_json(), content="application/json")
Beispiel #30
0
    def handle_registration_info(self, response):
        if response.status_code in SUCCESSFUL:
            resp = self.message_factory.get_response_type(
                "registration_endpoint"
            )().deserialize(response.text, "json")
            self.store_response(resp, response.text)
            self.store_registration_info(resp)
        else:
            resp = ErrorResponse().deserialize(response.text, "json")
            try:
                resp.verify()
                self.store_response(resp, response.text)
            except Exception:
                raise PyoidcError("Registration failed: {}".format(response.text))

        return resp
Beispiel #31
0
    def register(self, url, operation="register", application_type="web",
                 **kwargs):
        req = RegistrationRequest(operation=operation,
                                  application_type=application_type)

        if operation == "update":
            req["client_id"] = self.client_id
            req["client_secret"] = self.client_secret

        for prop in req.parameters():
            if prop in ["operation", "client_id", "client_secret"]:
                continue

            try:
                req[prop] = kwargs[prop]
            except KeyError:
                try:
                    req[prop] = self.behaviour[prop]
                except KeyError:
                    pass

        if "redirect_uris" not in req:
            try:
                req["redirect_uris"] = self.redirect_uris
            except AttributeError:
                raise MissingRequiredAttribute("redirect_uris")

        headers = {"content-type": "application/x-www-form-urlencoded"}

        if operation == "client_update":
            headers["Authorization"] = "Bearer %s" % self.registration_access_token

        rsp = self.http_request(url, "POST", data=req.to_urlencoded(),
                                headers=headers)

        if rsp.status_code == 200:
            resp = RegistrationResponse().deserialize(rsp.text, "json")
            self.client_secret = resp["client_secret"]
            self.client_id = resp["client_id"]
            self.registration_expires = resp["expires_at"]
            self.registration_access_token = resp["registration_access_token"]
        else:
            err = ErrorResponse().deserialize(rsp.text, "json")
            raise Exception("Registration failed: %s" % err.get_json())

        return resp
Beispiel #32
0
def test_parse_access_token_response():
    client = Client()

    at = AccessTokenResponse(access_token="SlAV32hkKG",
                             token_type="Bearer",
                             refresh_token="8xLOxBtZp8",
                             expires_in=3600)

    atj = at.to_json()

    ATR = AccessTokenResponse
    atr = client.parse_response(ATR, info=atj)

    assert _eq(atr.keys(),
               ['access_token', 'token_type', 'expires_in', 'refresh_token'])

    uec = at.to_urlencoded()
    raises(ValueError, 'client.parse_response(ATR, info=uec)')

    uatr = client.parse_response(ATR, info=uec, sformat="urlencoded")
    assert _eq(uatr.keys(),
               ['access_token', 'token_type', 'expires_in', 'refresh_token'])

    huec = "%s?%s" % ("https://example.com/token", uec)

    uatr = client.parse_response(ATR, info=huec, sformat="urlencoded")
    assert _eq(uatr.keys(),
               ['access_token', 'token_type', 'expires_in', 'refresh_token'])

    err = ErrorResponse(error="invalid_request",
                        error_description="Something was missing",
                        error_uri="http://example.com/error_message.html")

    jerr = err.to_json()
    uerr = err.to_urlencoded()

    _ = client.parse_response(ATR, info=jerr)
    _ = client.parse_response(ATR, info=uerr, sformat="urlencoded")

    raises(Exception,
           'client.parse_response(ATR, info=jerr, sformat="urlencoded")')

    raises(Exception, "client.parse_response(ATR, info=uerr)")

    raises(Exception, 'client.parse_response(ATR, info=jerr, sformat="focus")')
Beispiel #33
0
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):
        res = {}
        # did I get one, should only be one
        try:
            _ = get_protocol_response(conv, ErrorResponse)[0]
        except ValueError:
            pass
        else:
            return res

        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return {}

        if _response.status_code >= 400:
            content_type = _response.headers["content-type"]
            _content = _response.text
            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()
                except Exception:
                    res["content"] = _content
            else:
                res["content"] = _content
        elif _response.status_code in [300, 301, 302, 303]:
            pass
        else:
            # Should never get here
            self._message = 'Not an error message ??'
            self._status = WARNING

        return res
Beispiel #34
0
    def parse_request_response(self, reqresp, response, body_type, state="",
                               **kwargs):

        if reqresp.status_code in SUCCESSFUL:
            body_type = verify_header(reqresp, body_type)
        elif reqresp.status_code in [302, 303]:  # redirect
            return reqresp
        elif reqresp.status_code == 500:
            logger.error("(%d) %s" % (reqresp.status_code,
                                      sanitize(reqresp.text)))
            raise ParseError("ERROR: Something went wrong: %s" % reqresp.text)
        elif reqresp.status_code in [400, 401]:
            # expecting an error response
            if issubclass(response, ErrorResponse):
                pass
        else:
            logger.error("(%d) %s" % (reqresp.status_code,
                                      sanitize(reqresp.text)))
            raise HttpError("HTTP ERROR: %s [%s] on %s" % (
                reqresp.text, reqresp.status_code, reqresp.url))

        if response:
            if body_type == 'txt':
                # no meaning trying to parse unstructured text
                return reqresp.text
            return self.parse_response(response, reqresp.text, body_type,
                                       state, **kwargs)

        # could be an error response
        if reqresp.status_code in [200, 400, 401]:
            if body_type == 'txt':
                body_type = 'urlencoded'
            try:
                err = ErrorResponse().deserialize(reqresp.message,
                                                  method=body_type)
                try:
                    err.verify()
                except PyoidcError:
                    pass
                else:
                    return err
            except Exception:
                pass

        return reqresp
Beispiel #35
0
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):
        res = {}
        # did I get one, should only be one
        try:
            _ = get_protocol_response(conv, ErrorResponse)[0]
        except ValueError:
            pass
        else:
            return res

        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return {}

        if _response.status_code >= 400:
            content_type = _response.headers["content-type"]
            _content = _response.text
            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()
                except Exception:
                    res["content"] = _content
            else:
                res["content"] = _content
        elif _response.status_code in [300, 301, 302, 303]:
            pass
        else:
            # Should never get here
            self._message = 'Not an error message ??'
            self._status = WARNING

        return res
Beispiel #36
0
    def _func(self, conv):
        res = {}

        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return res

        if _response.status_code == 400:
            err = ErrorResponse().deserialize(_response.text, "json")
            try:
                err.verify()
            except MissingRequiredAttribute:
                try:
                    self._status = self._kwargs["status"]
                except KeyError:
                    self._status = ERROR
                self._message = "Expected an error message"
            else:
                res["content"] = err.to_json()
        elif _response.status_code in [301, 302, 303]:
            pass
        elif _response.status_code < 300:
            _content = conv.events.last_item(EV_RESPONSE)
            err = ErrorResponse().deserialize(_content, "json")
            try:
                err.verify()
            except MissingRequiredAttribute:
                try:
                    self._status = self._kwargs["status"]
                except KeyError:
                    self._status = ERROR
                self._message = "Expected an error message"
            else:
                res["content"] = err.to_json()
            conv.events.store(EV_PROTOCOL_RESPONSE, err)
        else:
            self._message = "Expected an error message"
            try:
                self._status = self._kwargs["status"]
            except KeyError:
                self._status = CRITICAL

        return res
Beispiel #37
0
def test_parse_access_token_response():
    client = Client()

    at = AccessTokenResponse(access_token="SlAV32hkKG", token_type="Bearer",
                             refresh_token="8xLOxBtZp8", expires_in=3600)

    atj = at.to_json()

    ATR = AccessTokenResponse
    atr = client.parse_response(ATR, info=atj)

    assert _eq(atr.keys(), ['access_token', 'token_type', 'expires_in',
                            'refresh_token'])

    uec = at.to_urlencoded()
    raises(ValueError, 'client.parse_response(ATR, info=uec)')

    uatr = client.parse_response(ATR, info=uec, sformat="urlencoded")
    assert _eq(uatr.keys(), ['access_token', 'token_type', 'expires_in',
                             'refresh_token'])

    huec = "%s?%s" % ("https://example.com/token", uec)

    uatr = client.parse_response(ATR, info=huec, sformat="urlencoded")
    assert _eq(uatr.keys(), ['access_token', 'token_type', 'expires_in',
                             'refresh_token'])

    err = ErrorResponse(error="invalid_request",
                        error_description="Something was missing",
                        error_uri="http://example.com/error_message.html")

    jerr = err.to_json()
    uerr = err.to_urlencoded()

    _ = client.parse_response(ATR, info=jerr)
    _ = client.parse_response(ATR, info=uerr, sformat="urlencoded")

    raises(Exception,
           'client.parse_response(ATR, info=jerr, sformat="urlencoded")')

    raises(Exception, "client.parse_response(ATR, info=uerr)")

    raises(Exception,
           'client.parse_response(ATR, info=jerr, sformat="focus")')
Beispiel #38
0
    def test_parse_error_resp(self):
        err = ErrorResponse(error="invalid_request",
                            error_description="Something was missing",
                            error_uri="http://example.com/error_message.html")
        jerr = err.to_json()
        uerr = err.to_urlencoded()

        _ = self.client.parse_response(AccessTokenResponse, info=jerr)
        _ = self.client.parse_response(AccessTokenResponse, info=uerr,
                                       sformat="urlencoded")

        with pytest.raises(ResponseError):
            self.client.parse_response(AccessTokenResponse, info=jerr, sformat="urlencoded")

        with pytest.raises(ValueError):
            self.client.parse_response(AccessTokenResponse, info=uerr)

        with pytest.raises(FormatError):
            self.client.parse_response(AccessTokenResponse, info=jerr, sformat="focus")
Beispiel #39
0
    def do_delete(self, path):
        """
        DELETE /{collection}/{id}
        """

        if os.path.exists(self.resource_name(path)):
            os.remove(self.resource_name(path))
            return NoContent("")
        else:
            return ErrorResponse(error="not_available")
Beispiel #40
0
    def _func(self, environ):
        res = {}

        response = environ["response"]
        if response.status_code == 302:
            _query = response.headers["location"].split("?")[1]
            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
Beispiel #41
0
    def register(self, server, type="client_associate", **kwargs):
        req = RegistrationRequest(type=type)

        if type == "client_update" or type == "rotate_secret":
            req["client_id"] = self.client_id
            req["client_secret"] = self.client_secret

        for prop in req.parameters():
            if prop in ["type", "client_id", "client_secret"]:
                continue

            try:
                val = getattr(self, prop)
                if val:
                    req[prop] = val
            except Exception:
                val = None

            if not val:
                try:
                    req[prop] = kwargs[prop]
                except KeyError:
                    pass

        headers = {"content-type": "application/x-www-form-urlencoded"}
        rsp = self.http_request(server, "POST", data=req.to_urlencoded(),
                                headers=headers)

        if rsp.status_code == 200:
            if type == "client_associate" or type == "rotate_secret":
                rr = RegistrationResponseCARS()
            else:
                rr = RegistrationResponseCU()

            resp = rr.deserialize(rsp.text, "json")
            self.client_secret = resp["client_secret"]
            self.client_id = resp["client_id"]
            self.registration_expires = resp["expires_at"]
        else:
            err = ErrorResponse().deserialize(rsp.text, "json")
            raise Exception("Registration failed: %s" % err.get_json())

        return resp
Beispiel #42
0
    def _func(self, conv):
        res = {}
        # did I get one, should only be one
        try:
            instance, _ = get_protocol_response(conv, ErrorResponse)[0]
        except ValueError:
            pass
        else:
            return res

        _response = conv.last_response
        _content = conv.last_content

        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()
                except Exception:
                    res["content"] = _content
            else:
                res["content"] = _content
        elif _response.status_code in [300, 301, 302, 303]:
            pass
        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 an error message"
                self._status = CRITICAL

            res["url"] = conv.position

        return res
Beispiel #43
0
    def do(self, path, environ, permission=None, user=""):
        """

        """
        method = environ["REQUEST_METHOD"]

        if method == "GET":
            if "QUERY_STRING" in environ and environ["QUERY_STRING"]:
                method = "QUERY"

        # Verify that the permission is sufficient
        allowed = False
        if user:
            _pat = "%s%s" % (self.base, user)
            if path.startswith(_pat) or path == _pat:
                allowed = True
        elif permission and self.check_permission(permission, method):
            allowed = True

        if not allowed:
            return ErrorResponse(error="Unauthorized")

        if method in ["PUT", "POST", "PATCH"]:
            info = get_post(environ)
        else:
            info = ""

        if method == "GET":
            return self.do_get(path)
        elif method == "QUERY":
            return self.do_query(path, environ["QUERY_STRING"])
        elif method == "DELETE":
            return self.do_delete(path)
        elif method == "PUT":
            return self.do_put(path, info)
        elif method == "POST":
            return self.do_post(path, info, user)
        elif method == "PATCH":
            return self.do_patch(path, info)
        else:
            return ErrorResponse(error="unsupported_method")
Beispiel #44
0
    def _func(self, conv):
        res = {}
        # did I get one, should only be one
        try:
            instance, _ = get_protocol_response(conv, ErrorResponse)[0]
        except ValueError:
            pass
        else:
            return res

        _response = conv.events.last_item(EV_HTTP_RESPONSE)
        _content = conv.last_content

        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()
                except Exception:
                    res["content"] = _content
            else:
                res["content"] = _content
        elif _response.status_code in [300, 301, 302, 303]:
            pass
        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 an error message"
                self._status = CRITICAL

            res["url"] = conv.position

        return res
Beispiel #45
0
    def do_post(self, path, info, user):
        """
        POST /{collection}
        """

        _name = self.resource_name(path)
        try:
            index = self.index[user]
        except KeyError:
            index = 1
            self.index[user] = 1
        else:
            index += 1
            self.index[user] = index

        _name += "/%d" % index

        try:
            _ji = json.loads(info)
        except ValueError:
            return ErrorResponse(error="not_json")

        try:
            f = open(_name, "w")
        except IOError as err:
            head, tail = os.path.split(_name)
            # try to create
            os.mkdir(head)
            try:
                f = open(_name, "w")
            except IOError:
                return ErrorResponse(error="not_allowed")

        _ji["_id"] = index
        f.write(json.dumps(_ji))
        f.close()

        return Response(json.dumps({"_id": index}),
                        headers=[("Location",
                                  "%s/%s" % (self.baseurl, self.url(_name)))])
Beispiel #46
0
    def _func(self, environ):
        _response = environ["response"]
        _content = environ["content"]

        res = {}
        if _response.status_code >= 400 :
            self._status = self.status
            self._message = self.msg
            if "application/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"] = environ["url"]
            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"] = environ["url"]

        return res
Beispiel #47
0
    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
Beispiel #48
0
    def _func(self, conv):
        _response = conv.last_response
        _content = conv.last_content
        res = {}
        if _response.status_code == 400:
            err = ErrorResponse().deserialize(_content, "json")
            try:
                err.verify()
            except MissingRequiredAttribute:
                try:
                    self._status = self._kwargs["status"]
                except KeyError:
                    self._status = ERROR
                self._message = "Expected an error message"
            else:
                res["content"] = err.to_json()
        elif _response.status_code in [301, 302, 303]:
            pass
        elif _response.status_code < 300:
            err = ErrorResponse().deserialize(_content, "json")
            try:
                err.verify()
            except MissingRequiredAttribute:
                try:
                    self._status = self._kwargs["status"]
                except KeyError:
                    self._status = ERROR
                self._message = "Expected an error message"
            else:
                res["content"] = err.to_json()
            conv.protocol_response.append((err, _content))
        else:
            self._message = "Expected an error message"
            try:
                self._status = self._kwargs["status"]
            except KeyError:
                self._status = CRITICAL

        return res
Beispiel #49
0
    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))
        elif _response.status_code in [301, 302, 303]:
            pass
        elif _response.status_code in SUCCESSFUL:
            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
Beispiel #50
0
    def _func(self, conv):
        _response = conv.events.last_item(EV_HTTP_RESPONSE)
        _content = conv.events.last_item(EV_RESPONSE)
        res = {}

        if _response.status_code == 400:
            err = ErrorResponse().deserialize(_content, "json")
            err.verify()
            res["content"] = err.to_json()
            conv.events.store(EV_PROTOCOL_RESPONSE, err)
        elif _response.status_code in [301, 302, 303]:
            pass
        elif _response.status_code in SUCCESSFUL:
            err = ErrorResponse().deserialize(_content, "json")
            err.verify()
            res["content"] = err.to_json()
            conv.events.store(EV_PROTOCOL_RESPONSE, err)
        else:
            self._message = "Expected a 400 error message"
            self._status = CRITICAL

        return res
Beispiel #51
0
    def _func(self, conv):
        res = {}

        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return res

        if _response.status_code not in [200, 300, 301, 302, 400, 401]:
            self._status = self.status
            self._message = self.msg
            if CONT_JSON in _response.headers["content-type"]:
                try:
                    err = ErrorResponse().deserialize(_response.txt, "json")
                    self._message = err.to_json()
                except Exception:
                    res["content"] = _response.text
            else:
                res["content"] = _response.text
            res["url"] = _response.url
            res["http_status"] = _response.status_code

        return res
    def test_end_session_endpoint_with_cookie_dual_login_wrong_client(self):
        self._code_auth()
        self._code_auth2()
        # The cookie states that a user has a session at a client and this
        # statement is false.
        cookie = self._create_cookie("username", "a1b2c3")

        resp = self.provider.end_session_endpoint(urlencode({"state":
                                                             "abcde"}),
                                                  cookie=cookie)

        assert isinstance(resp, Response)
        _err = ErrorResponse().from_json(resp.message)
        assert _err["error"] == "invalid_request"
Beispiel #53
0
    def _func(self, conv):
        res = {}

        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return res

        if _response.status_code not in [200, 300, 301, 302, 400, 401]:
            self._status = self.status
            self._message = self.msg
            if CONT_JSON in _response.headers["content-type"]:
                try:
                    err = ErrorResponse().deserialize(_response.txt, "json")
                    self._message = err.to_json()
                except Exception:
                    res["content"] = _response.text
            else:
                res["content"] = _response.text
            res["url"] = _response.url
            res["http_status"] = _response.status_code

        return res
Beispiel #54
0
    def _func(self, conv):
        res = {}
        # did I get one, should only be one
        try:
            _ = get_protocol_response(conv, ErrorResponse)[0]
        except ValueError:
            pass
        else:
            return res

        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return {}

        if _response.status_code >= 400:
            content_type = _response.headers["content-type"]
            _content = _response.text
            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()
                except Exception:
                    res["content"] = _content
            else:
                res["content"] = _content
        elif _response.status_code in [300, 301, 302, 303]:
            pass
        else:
            # Should never get here
            self._message = 'Not an error message ??'
            self._status = WARNING

        return res
Beispiel #55
0
    def handle_registration_info(self, response):
        if response.status_code in SUCCESSFUL:
            resp = ClientInfoResponse().deserialize(response.text, "json")
            self.store_response(resp, response.text)
            self.store_registration_info(resp)
        else:
            resp = ErrorResponse().deserialize(response.text, "json")
            try:
                resp.verify()
                self.store_response(resp, response.text)
            except Exception:
                raise PyoidcError('Registration failed: {}'.format(
                    response.text))

        return resp
    def test_end_session_endpoint_with_wrong_post_logout_redirect_uri(self):
        self._code_auth()
        cookie = self._create_cookie("username", "number5")

        post_logout_redirect_uri = "https://www.example.com/logout"
        resp = self.provider.end_session_endpoint(
            urlencode({
                "post_logout_redirect_uri": post_logout_redirect_uri,
                "state": "abcde"
            }),
            cookie=cookie,
        )

        assert isinstance(resp, Response)
        _err = ErrorResponse().from_json(resp.message)
        assert _err["error"] == "invalid_request"
Beispiel #57
0
    def _func(self, conv):
        res = {}

        try:
            _response = last_http_response(conv)
        except NoSuchEvent:
            return res

        if _response.status_code == 400:
            err = ErrorResponse().deserialize(_response.text, "json")
            try:
                err.verify()
            except MissingRequiredAttribute:
                try:
                    self._status = self._kwargs["status"]
                except KeyError:
                    self._status = ERROR
                self._message = "Expected an error message"
            else:
                res["content"] = err.to_json()
        elif _response.status_code in [301, 302, 303]:
            pass
        elif _response.status_code < 300:
            _content = conv.events.last_item(EV_RESPONSE)
            err = ErrorResponse().deserialize(_content, "json")
            try:
                err.verify()
            except MissingRequiredAttribute:
                try:
                    self._status = self._kwargs["status"]
                except KeyError:
                    self._status = ERROR
                self._message = "Expected an error message"
            else:
                res["content"] = err.to_json()
            conv.events.store(EV_PROTOCOL_RESPONSE, err)
        else:
            self._message = "Expected an error message"
            try:
                self._status = self._kwargs["status"]
            except KeyError:
                self._status = CRITICAL

        return res
Beispiel #58
0
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):
        res = {}
        # did I get one, should only be one
        try:
            instance, _ = get_protocol_response(conv, ErrorResponse)[0]
        except ValueError:
            pass
        else:
            return res

        _response = conv.last_response
        _content = conv.last_content

        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()
                except Exception:
                    res["content"] = _content
            else:
                res["content"] = _content
        elif _response.status_code in [300, 301, 302, 303]:
            pass
        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 an error message"
                self._status = CRITICAL

            res["url"] = conv.position

        return res
Beispiel #59
0
    def _func(self, conv):
        _response = conv.last_response
        _content = conv.last_content
        res = {}
        if _response.status_code == 400:
            err = ErrorResponse().deserialize(_content, "json")
            try:
                err.verify()
            except MissingRequiredAttribute:
                try:
                    self._status = self._kwargs["status"]
                except KeyError:
                    self._status = ERROR
                self._message = "Expected an error message"
            else:
                res["content"] = err.to_json()
        elif _response.status_code in [301, 302, 303]:
            pass
        elif _response.status_code < 300:
            err = ErrorResponse().deserialize(_content, "json")
            try:
                err.verify()
            except MissingRequiredAttribute:
                try:
                    self._status = self._kwargs["status"]
                except KeyError:
                    self._status = ERROR
                self._message = "Expected an error message"
            else:
                res["content"] = err.to_json()
            conv.protocol_response.append((err, _content))
        else:
            self._message = "Expected an error message"
            try:
                self._status = self._kwargs["status"]
            except KeyError:
                self._status = CRITICAL

        return res