Пример #1
0
 def not_found(self):
     """Called if no URL matches."""
     resp = NotFound()
     return resp(self.environ, self.start_response)
Пример #2
0
    def application(self, environ, start_response):
        """
        :param environ: The HTTP application environment
        :param start_response: The application to run when the handling of the
            request is done
        :return: The response as a list of lines
        """

        path = environ.get('PATH_INFO', '').lstrip('/')
        response_encoder = ResponseEncoder(environ=environ,
                                           start_response=start_response)
        parameters = parse_qs(environ["QUERY_STRING"])

        session_info = {
            "addr": get_client_address(environ),
            'cookie': environ.get("HTTP_COOKIE", ''),
            'path': path,
            'parameters': parameters
        }

        jlog = JLog(LOGGER, session_info['addr'])
        jlog.info(session_info)

        if path == "robots.txt":
            return static(environ, start_response, "static/robots.txt")

        if path.startswith("static/"):
            return static(environ, start_response, path)
        elif path.startswith("tar/"):
            return static(environ, start_response, path)
        elif path.startswith("log"):
            return display_log(path, environ, start_response, lookup=LOOKUP)
        elif path.startswith('clear/'):
            return clear_log(path, environ, start_response, lookup=LOOKUP)
        elif path.startswith('mktar/'):
            return make_tar(path, environ, start_response, lookup=LOOKUP)
        elif path.startswith("_static/"):
            return static(environ, start_response, path)
        elif path.startswith("jwks.json"):
            try:
                mode, endpoint = extract_mode(self.op_args["baseurl"])
                events = Events()
                events.store('Init',
                             '===========================================')
                op, path, jlog.id = self.op_setup(environ, mode, events,
                                                  self.test_conf, endpoint)
                jwks = op.generate_jwks(mode)
                resp = Response(jwks,
                                headers=[('Content-Type', 'application/json')])
                return resp(environ, start_response)
            except KeyError:
                # Try to load from static file
                return static(environ, start_response, "static/jwks.json")

        events = Events()
        events.store('Init', '===========================================')

        if path == "test_list":
            return rp_test_list(environ, start_response)
        elif path == "":
            return registration(environ, start_response)
        elif path == "generate_client_credentials":
            client_id, client_secret = generate_static_client_credentials(
                parameters)
            return response_encoder.return_json(
                json.dumps({"client_id": client_id,
                            "client_secret": client_secret}))
        elif path == "3rd_party_init_login":
            return rp_support_3rd_party_init_login(environ, start_response)

        # path should be <oper_id>/<test_id>/<endpoint>
        try:
            mode = parse_path(path)
        except ValueError:
            resp = BadRequest('Illegal path')
            return resp(environ, start_response)

        try:
            endpoint = mode['endpoint']
        except KeyError:
            _info = {'error': 'No endpoint', 'mode': mode}
            events.store(EV_FAULT, _info)
            jlog.error(_info)
            resp = BadRequest('Illegal path')
            return resp(environ, start_response)

        if endpoint == ".well-known/webfinger":
            session_info['endpoint'] = endpoint
            try:
                _p = urlparse(parameters["resource"][0])
            except KeyError:
                events.store(EV_FAULT,
                             FailedOperation('webfinger',
                                             'No resource defined'))
                jlog.error({'reason': 'No resource defined'})
                resp = ServiceError("No resource defined")
                return resp(environ, start_response)

            if _p.scheme in ["http", "https"]:
                events.store(EV_REQUEST,
                             Operation(name='webfinger', type='url',
                                       path=_p.path))
                mode = parse_path(_p.path)
            elif _p.scheme == "acct":
                _l, _ = _p.path.split('@')

                _a = _l.split('.')
                if len(_a) == 2:
                    _oper_id = _a[0]
                    _test_id = _a[1]
                elif len(_a) > 2:
                    _oper_id = ".".join(_a[:-1])
                    _test_id = _a[-1]
                else:
                    _oper_id = _a[0]
                    _test_id = 'default'

                mode.update({'oper_id': _oper_id, 'test_id': _test_id})
                events.store(EV_REQUEST,
                             Operation(name='webfinger', type='acct',
                                       oper_id=_oper_id, test_id=_test_id))
            else:
                _msg = "Unknown scheme: {}".format(_p.scheme)
                events.events(EV_FAULT, FailedOperation('webfinger', _msg))
                jlog.error({'reason': _msg})
                resp = ServiceError(_msg)
                return resp(environ, start_response)
        elif endpoint == "claim":
            authz = environ["HTTP_AUTHORIZATION"]
            _ev = Operation('claim')
            try:
                assert authz.startswith("Bearer")
            except AssertionError:
                resp = BadRequest()
            else:
                _ev.authz = authz
                events.store(EV_REQUEST, _ev)
                tok = authz[7:]
                # mode, endpoint = extract_mode(self.op_args["baseurl"])
                _op, _, sid = self.op_setup(environ, mode, events,
                                            self.test_conf, endpoint)
                try:
                    _claims = _op.claim_access_token[tok]
                except KeyError:
                    resp = BadRequest()
                else:
                    del _op.claim_access_token[tok]
                    _info = Message(**_claims)
                    jwt_key = _op.keyjar.get_signing_key()
                    resp = Response(_info.to_jwt(key=jwt_key,
                                                 algorithm="RS256"),
                                    content='application/jwt')
            return resp(environ, start_response)

        if mode:
            session_info.update(mode)
            jlog.id = mode['oper_id']

        try:
            _op, path, jlog.id = self.op_setup(environ, mode, events,
                                               self.test_conf,
                                               endpoint)
        except UnknownTestID as err:
            resp = BadRequest('Unknown test ID: {}'.format(err.args[0]))
            return resp(environ, start_response)

        session_info["op"] = _op
        session_info["path"] = path
        session_info['test_conf'] = self.test_conf[session_info['test_id']]

        for regex, callback in URLS:
            match = re.search(regex, endpoint)
            if match is not None:
                _op = HTTPRequest(endpoint=endpoint,
                                  method=environ["REQUEST_METHOD"])
                try:
                    _op.authz = environ["HTTP_AUTHORIZATION"]
                except KeyError:
                    pass
                events.store(EV_HTTP_REQUEST, _op)
                try:
                    environ['oic.url_args'] = match.groups()[0]
                except IndexError:
                    environ['oic.url_args'] = endpoint

                jlog.info({'callback': callback.__name__})
                try:
                    return callback(environ, start_response, session_info,
                                    events, op_arg=self.op_args, jlog=jlog)
                except Exception as err:
                    print("%s" % err)
                    message = traceback.format_exception(*sys.exc_info())
                    print(message)
                    events.store(EV_EXCEPTION, err)
                    LOGGER.exception("%s" % err)
                    resp = ServiceError("%s" % err)
                    return resp(environ, start_response)

        LOGGER.debug("unknown page: '{}'".format(endpoint))
        events.store(EV_FAULT, 'No such page: {}'.format(endpoint))
        resp = NotFound("Couldn't find the side you asked for!")
        return resp(environ, start_response)
Пример #3
0
    def resource_set_registration_endpoint_(self,
                                            entity,
                                            path,
                                            method,
                                            client_id,
                                            body="",
                                            if_match="",
                                            **kwargs):
        """
        The endpoint at which the resource server handles resource sets
        descriptions.

        :param entity: The entity that controls the resource set
        :param path:
        :param method: HTTP method
        :param body: The resource set registration message
        :paran client_id: Which client I'm talking to
        :param if_match: The HTTP If-Match header if any
        :param kwargs: possible other arguments
        :returns: A Response instance
        """

        # path should be /resource_set/{rsid} or /resource_set
        # Path may or may not start with '/'
        if path.startswith("/"):
            assert path[1:].startswith(RSR_PATH)
            rsid = path[PLEN + 1:]
        else:
            assert path.startswith(RSR_PATH)
            rsid = path[PLEN:]

        if rsid.startswith("/"):
            rsid = rsid[1:]

        _user = safe_name(entity, client_id)
        logger.debug("handling resource set belonging to '%s'" % _user)
        #  self.resource_set.set_collection(_user)
        if method == "POST":  # create
            args = {"oid": _user, "data": body}
            func = self.resource_set.create
        elif method == "PUT":  # update
            args = {
                "oid": _user,
                "data": body,
                "rsid": rsid,
                # "if_match": if_match
            }
            func = self.resource_set.update
        elif method == "GET":
            args = {"oid": _user}
            if not rsid:  # List
                func = self.resource_set.list
            else:  # Read
                func = self.resource_set.read
                args["rsid"] = rsid
        elif method == "DELETE":
            args = {"rsid": rsid, "oid": _user}
            func = self.resource_set.delete
        else:
            return BadRequest("Message error")

        logger.debug("operation: %s" % func)
        logger.debug("operation args: %s" % (args, ))
        try:
            body = func(**args)
        except MessageException as err:
            _err = ErrorResponse(error="invalid_request",
                                 error_description=str(err))
            response = BadRequest(_err.to_json(), content="application/json")
        except UnknownObject:
            _err = ErrorResponse(error="not_found")
            response = NotFound(_err.to_json(), content="application/json")
        else:
            response = None
            if isinstance(body, ErrorResponse):
                pass
            else:
                if func == self.resource_set.delete:
                    # As a side effect all permissions assigned that references
                    # this resource set should be deleted
                    self.permit.delete_permit_by_resource_id(entity, rsid)
                    response = NoContent()
                elif func == self.resource_set.create:
                    _etag = self.resource_set.etag[body["_id"]]
                    response = Created(body.to_json(),
                                       content="application/json",
                                       headers=[("ETag", _etag),
                                                ("Location", "/{}/{}".format(
                                                    RSR_PATH, body["_id"]))])
                elif func == self.resource_set.update:
                    _etag = self.resource_set.etag[body["_id"]]
                    response = NoContent(content="application/json",
                                         headers=[("ETag", _etag)])
                elif func == self.resource_set.list:
                    response = Response(json.dumps(body))

            if not response:
                response = Response(body.to_json(), content="application/json")

        return response
Пример #4
0
            resp = None
            try:
                func = AUTHZSRV.service(prepath)
            except Exception, err:
                pass
            else:
                if func:
                    try:
                        resp = wrap(func, prepath, get_args(environ))
                    except Exception, err:
                        resp = ServiceError("%s" % err)

    if isinstance(resp, Response):
        pass
    else:
        resp = NotFound(path)

    return resp(environ, start_response, **argv)


# -----------------------------------------------------------------------------

AUTHZ = Implicit("PERMISSION")
CDB = {}

PASSWD = {
    "alice": "krall",
    "hans": "thetake",
    "user": "******",
    "https://sp.example.org/": "code"
}
Пример #5
0
def application(environ, start_response):
    """
    :param environ: The HTTP application environment
    :param start_response: The application to run when the handling of the
        request is done
    :return: The response as a list of lines
    """
    global OAS
    session = environ['beaker.session']
    path = environ.get('PATH_INFO', '').lstrip('/')
    response_encoder = ResponseEncoder(environ=environ,
                                       start_response=start_response)
    parameters = parse_qs(environ["QUERY_STRING"])

    if path == "robots.txt":
        return static(environ, start_response, "static/robots.txt")

    if path.startswith("static/"):
        return static(environ, start_response, path)
    elif path.startswith("log"):
        return display_log(environ, start_response)
    elif path.startswith("_static/"):
        return static(environ, start_response, path)
    
    trace = Trace()

    if path == "test_list":
        return rp_test_list(environ, start_response)
    elif path == "":
        return registration(environ, start_response)
    elif path == "generate_client_credentials":
        client_id, client_secret = generate_static_client_credentials(parameters)
        return response_encoder.return_json(
            json.dumps({"client_id": client_id,
                        "client_secret": client_secret}))
    elif path == "claim":
        _oas = session["op"]
        authz = environ["HTTP_AUTHORIZATION"]
        try:
            assert authz.startswith("Bearer")
        except AssertionError:
            resp = BadRequest()
        else:
            tok = authz[7:]
            try:
                _claims = _oas.claim_access_token[tok]
            except KeyError:
                resp = BadRequest()
            else:
                del _oas.claim_access_token[tok]
                resp = Response(json.dumps(_claims), content='application/json')
        return resp(environ, start_response)

    mode, endpoint = extract_mode(path)

    if endpoint == ".well-known/webfinger":
        _p = urlparse(parameters["resource"][0])
        if _p.scheme in ["http", "https"]:
            mode = {"test_id": _p.path[1:]}
        elif _p.scheme == "acct":
            _l, _ = _p.path.split('@')
            mode = {"test_id": _l}
        else:
            resp = ServiceError("Unknown scheme: {}".format(_p.scheme))
            return resp(environ, start_response)

    if mode:
        session["test_id"] = mode["test_id"]

    if "op" not in session:
        session["op"] = setup_op(mode, COM_ARGS, OP_ARG)
        session["mode_path"] = mode2path(mode)
    else:  # may be a new mode
        _path = mode2path(mode)
        if session["mode_path"] != _path:
            session["op"] = setup_op(mode, COM_ARGS, OP_ARG)
            session["mode_path"] = _path

    for regex, callback in URLS:
        match = re.search(regex, endpoint)
        if match is not None:
            trace.request("PATH: %s" % endpoint)
            trace.request("METHOD: %s" % environ["REQUEST_METHOD"])
            try:
                trace.request(
                    "HTTP_AUTHORIZATION: %s" % environ["HTTP_AUTHORIZATION"])
            except KeyError:
                pass

            try:
                environ['oic.url_args'] = match.groups()[0]
            except IndexError:
                environ['oic.url_args'] = endpoint

            LOGGER.info("callback: %s" % callback)
            try:
                return callback(environ, start_response, session, trace)
            except Exception as err:
                print >> sys.stderr, "%s" % err
                message = traceback.format_exception(*sys.exc_info())
                print >> sys.stderr, message
                LOGGER.exception("%s" % err)
                resp = ServiceError("%s" % err)
                return resp(environ, start_response)

    LOGGER.debug("unknown side: %s" % endpoint)
    resp = NotFound("Couldn't find the side you asked for!")
    return resp(environ, start_response)