Beispiel #1
0
def _assert_if_none_match(request: web.Request, etag: T.Union[None, bool, str],
                          require: bool):
    # The If-None-Match: header is used in two scenarios:
    # 1. GET requests by a caching client. In this case, the client will
    #    normally provide a list of (cached) ETags.
    # 2. PUT requests, where the client intends to create a new resource and
    #    wants to avoid overwriting an existing resource. In this case, the
    #    client will normally provide only the asterisk "*" character.
    etags = _parse_if_header(request, 'If-None-Match')
    if require and etags is None:
        raise web.HTTPPreconditionRequired(text='If-None-Match')
    if etags is None or etag is False or etag is None:
        return
    if etags is _STAR:
        raise web.HTTPPreconditionFailed()
    # From here on, we know that etags is a set of strings.
    if etag is True:
        raise web.HTTPPreconditionFailed(
            text="Resource doesn't support ETags.")
    # From here on, we know that etag is a string:
    if etag in etags:
        if request.method in {'GET', 'HEAD'}:
            raise web.HTTPNotModified()
        else:
            raise web.HTTPPreconditionFailed()
Beispiel #2
0
def _assert_if_match(request: web.Request, etag: T.Union[None, bool, str],
                     require: bool):
    # The If-Match: header is commonly used in non-safe HTTP requests to prevent
    # lost update problems.
    etags = _parse_if_header(request, 'If-Match')

    if etags is None:
        if require:
            raise web.HTTPPreconditionRequired(text='If-Match')
        return
    if etags is _STAR:
        if etag is None or etag is False:
            raise web.HTTPPreconditionFailed()
        if etag is True or require is False:
            return
        raise web.HTTPPreconditionRequired(
            text='If-Match: * is too generic for this resource.')
    # From here on, `etags` can only be a set().
    if etag is True or etag is False:
        raise web.HTTPPreconditionFailed(
            text="Resource doesn't support If-Match header.")
    # From here on, `etag` can only be `None` or a valid ETag string:
    if etag is None:
        raise web.HTTPNotFound()
    if etag not in etags:
        raise web.HTTPPreconditionFailed()
Beispiel #3
0
    async def put(self):
        if_match = self.request.headers.get('if-match', '')
        if_none_match = self.request.headers.get('if-none-match', '')
        if if_match == '' and if_none_match == '':
            raise web.HTTPPreconditionRequired()
        assert_preconditions(self.request, await self.etag())
        if not re.match(r'application/(?:hal\+)?json(?:$|;)',
                        self.request.content_type):
            raise web.HTTPUnsupportedMediaType()
        try:
            request_body_json = json_loads(await self.request.text())
        except:
            raise web.HTTPBadRequest()
        # self.request.app['swagger'].validate_definition('Account', request_body_json)
        existing_roles = set(
            self.request.app['config']['authz_admin']['roles'].keys())
        try:
            roles = request_body_json['_links']['role']
            assert isinstance(roles, list)
        except:
            raise web.HTTPBadRequest(
                text="No '#/_links/role' array in request.") from None
        new_roles = set()
        try:
            for link_object in roles:
                role = web.URL(link_object['href']).name
                assert role in existing_roles
                new_roles.add(role)
        except:
            raise web.HTTPBadRequest(
                text=
                "Not all roles are valid HALJSON link objects to an existing role."
            ) from None

        if await self.data() is None:
            try:
                log_id = await database.create_account(self.request,
                                                       self['account'],
                                                       new_roles)
            except database.PreconditionFailed:
                raise web.HTTPPreconditionFailed() from None
            status = 201
            headers = {
                'Location': self.rel_url.raw_path,
                'ETag': etag_from_int(log_id)
            }
        else:
            try:
                log_id = await database.update_account(self.request, self,
                                                       new_roles)
            except database.PreconditionFailed:
                raise web.HTTPPreconditionFailed() from None
            status = 204
            headers = {'ETag': etag_from_int(log_id)}
        return web.Response(status=status, headers=headers)
Beispiel #4
0
def _assert_if_none_match(request: web.Request, etag: T.Union[None, bool, str],
                          allow_weak: bool) -> bool:
    # language=rst
    """

    Todo:
        Evert lammerts schreef: Documenteren. Ik vind _assert_if_none_match niet
        makkelijk te lezen zonder docs voor de parameters. Bv: etag heeft als
        type None, bool, of str. En if etag is True: PreconditionFailed. Die
        semantiek is vast logisch in context maar niet op zichzelf.

    The If-None-Match: header is used in two scenarios:

    1.   GET requests by a caching client. In this case, the client will
         normally provide a list of (cached) ETags.
    2.   PUT requests, where the client intends to create a new resource and
         wants to avoid overwriting an existing resource. In this case, the
         client will normally provide only the asterisk "*" character.

    Returns:
        bool: indicates if an ``If-None-Match`` header was provided.

    Raises:
        web.HTTPBadRequest:
            If the request header is syntactically incorrect.
        web.HTTPPreconditionRequired:
            If parameter `require` is ``True`` and no precondition was provided
            by the client.
        web.HTTPPreconditionFailed:
            If the precondition failed and the request is *unsafe*.
        web.HTTPNotModified:
            If the precondition failed and the request is *safe*.

    """
    etags = _parse_if_header(request, _IF_NONE_MATCH)

    if etags is None:
        # if require and request.method in unsafe_methods:
        #     raise web.HTTPPreconditionRequired(text=_IF_NONE_MATCH)
        return False
    if etag is False or etag is None:
        return True
    if etags is _STAR:
        raise web.HTTPPreconditionFailed(text=_IF_NONE_MATCH)
    # From here on, we know that etags is a set of strings.
    if etag is True:
        raise web.HTTPPreconditionFailed(text="Resource doesn't have an ETag.")
    # From here on, we know that etag is a string:
    if _match_etags(etag, etags, allow_weak):
        if request.method in {hdrs.METH_GET, hdrs.METH_HEAD}:
            raise web.HTTPNotModified()
        else:
            raise web.HTTPPreconditionFailed(text=_IF_NONE_MATCH)
    return True
Beispiel #5
0
def _assert_if_match(request: web.Request, etag: T.Union[None, bool, str],
                     deny_asterisk: bool, allow_weak: bool) -> bool:
    # language=rst
    """Assert ETag validity in the ``If-Match`` header.

    Returns:
        bool: indicates if an ``If-Match`` header with at least one ETag was
              provided.

    Raises:
        web.HTTPPreconditionRequired:
            If parameter `require` is ``True`` and no precondition was provided
            by the client.
        web.HTTPBadRequest: Either

            -   the request header is syntactically incorrect, or
            -   parameter `deny_star` is ``True`` and the client provided an
                asterisk instead of a valid ETag.
        web.HTTPPreconditionFailed:

    """
    etags = _parse_if_header(request, _IF_MATCH)

    if etags is None:
        # if require and request.method in unsafe_methods:
        #     raise web.HTTPPreconditionRequired(
        #         text=_IF_MATCH
        #     )
        return False
    if etags is _STAR:
        if deny_asterisk:
            raise web.HTTPBadRequest(
                text=
                "If-Match: * is not allowed for this request. Use a specific ETag instead."
            )
        if etag is None or etag is False:
            raise web.HTTPPreconditionFailed(text=_IF_MATCH)
        return False
    # From here on, `etags` can only be a set().
    if etag is True:
        raise web.HTTPPreconditionFailed(text="Resource doesn't have an ETag.")
    if (etag is True  # the resource exists, but doesn't have a specific ETag
            or etag is False  # the resource doesn't exist
            or etag is None  # the resource doesn't exist
            # the resource has a different ETag:
            or not _match_etags(etag, etags, allow_weak)):
        raise web.HTTPPreconditionFailed(text=_IF_MATCH)
    return True
Beispiel #6
0
async def error_middleware(request, handler):
    resp = web.HTTPInternalServerError()
    try:
        resp = await handler(request)
    except web.HTTPException as ex:
        resp = ex
    except:
        traceback.print_exc()
        resp = web.HTTPInternalServerError()
    if resp is None or resp.status < 400:
        return resp
    if resp.status == 403:
        raise web.HTTPForbidden(text='( ・∀・)つ=≡≡ξ)Д`) 403')
    if resp.status == 404:
        raise web.HTTPNotFound(text='(゚ペ) 404')
    if resp.status == 412:
        raise web.HTTPPreconditionFailed(text='Not started yet. 412')
    if resp.status < 500:
        raise web.HTTPBadRequest(text='¯\_༼ ಥ ‿ ಥ ༽_/¯ 500')
    if resp.status == 503:
        raise web.HTTPServiceUnavailable(
            text=''
            'Congrats\n'
            'You might have crashed the server.\n'
            'There is no flag on this server now.\n'
            '(σ゚∀゚)σ゚∀゚)σ゚∀゚)σ\n'
            '(σ゚∀゚)σ゚∀゚)σ゚∀゚)σ\n'
            '(σ゚∀゚)σ゚∀゚)σ゚∀゚)σ\n'
            '(σ゚∀゚)σ゚∀゚)σ゚∀゚)σ\n'
            '\n'
            'Please contact admin if you stop all your exploits\n'
            'but the problem still exists in the next round.\n')
    raise web.HTTPInternalServerError(text='((((;゚Д゚))) wtf')
async def switch_workspace(request):
    overwrite_to = request.headers.get('Overwrite', '')
    request.is_overwritten = False
    all_workspaces = [overwrite_to]

    try:
        calling_workspace = None
        if overwrite_to:
            with suppress(AttributeError):
                all_workspaces = request.session.workspaces

            if overwrite_to not in all_workspaces:
                raise web.HTTPPreconditionFailed(
                    reason='Workspace not found or outside of scope')

            with suppress(AttributeError):
                calling_workspace = request.session.workspace
                request.is_overwritten = True
                request.session._session_ctxt['workspace'] = overwrite_to

        for before_handler in request.app.config.before_request_hooks:
            await before_handler(request)
        yield request

    finally:
        if calling_workspace:
            # session exists AND Overwrite header has been used
            request.session._session_ctxt['workspace'] = calling_workspace
        for after_handler in request.app.config.after_request_hooks:
            await after_handler(request)
Beispiel #8
0
def abort(code):
    if code == 400: return web.HTTPBadRequest()
    elif code == 401: return web.HTTPUnauthorized()
    elif code == 402: return web.HTTPPaymentRequired()
    elif code == 403: return web.HTTPForbidden()
    elif code == 404: return web.HTTPNotFound()
    elif code == 405: return web.HTTPMethodNotAllowed()
    elif code == 406: return web.HTTPNotAcceptable()
    elif code == 407: return web.HTTPProxyAuthenticationRequired()
    elif code == 408: return web.HTTPRequestTimeout()
    elif code == 409: return web.HTTPConflict()
    elif code == 410: return web.HTTPGone()
    elif code == 411: return web.HTTPLengthRequired()
    elif code == 412: return web.HTTPPreconditionFailed()
    elif code == 413: return web.HTTPRequestEntityTooLarge()
    elif code == 414: return web.HTTPRequestURITooLong()
    elif code == 415: return web.HTTPUnsupportedMediaType()
    elif code == 416: return web.HTTPRequestRangeNotSatisfiable()
    elif code == 417: return web.HTTPExpectationFailed()
    elif code == 421: return web.HTTPMisdirectedRequest()
    elif code == 422: return web.HTTPUnprocessableEntity()
    elif code == 424: return web.HTTPFailedDependency()
    elif code == 426: return web.HTTPUpgradeRequired()
    elif code == 428: return web.HTTPPreconditionRequired()
    elif code == 429: return web.HTTPTooManyRequests()
    elif code == 431: return web.HTTPRequestHeaderFieldsTooLarge()
    elif code == 451: return web.HTTPUnavailableForLegalReasons()
    else: return web.HTTPBadRequest()
Beispiel #9
0
 async def delete(self) -> web.Response:
     assert_preconditions(self.request,
                          await self.etag(),
                          require_if_match=True)
     try:
         await database.delete_account(self.request, self)
     except database.PreconditionFailed:
         raise web.HTTPPreconditionFailed() from None
     return web.Response(status=204)
async def login(request):
    query = request.rel_url.query
    param_list = ['email', 'password']
    if all(param in query.keys() for param in param_list):
        try:
            email, password = str(query['email']), str(query['password'])
        except:
            raise web.HTTPPreconditionFailed(
                text='Неправильные значения параметров')
        res = await AuthMS.make_request('login',
                                        data={
                                            'email': email,
                                            'password': password
                                        })
        res_dict = json.loads(res)
        if res_dict['status'] == 'error':
            raise web.HTTPBadRequest(body=res)
    else:
        raise web.HTTPPreconditionFailed(text='Неправльные параметры')
    return web.Response(text=res)
async def search(request):
    query = request.rel_url.query
    param_list = ['q', 'limit', 'offset']
    if all(param in query.keys() for param in param_list):
        try:
            q, limit, offset = str(query['q']), int(query['limit']), int(
                query['offset'])
            if limit > 100:
                raise web.HTTPPreconditionFailed(
                    text='Неправильные значения параметров')
        except:
            raise web.HTTPPreconditionFailed(
                text='Неправильные значения параметров')
        res = await CrawlerMS.make_request('search',
                                           data={
                                               'q': q,
                                               'limit': limit,
                                               'offset': offset
                                           })
    else:
        raise web.HTTPPreconditionFailed(text='Неправльные параметры')
    return web.Response(text=res)
async def index(request):
    query = request.rel_url.query

    if 'X-Token' in request.headers:
        token = request.headers['X-Token']
        try:
            domain = str(query['domain'])
        except:
            raise web.HTTPPreconditionFailed(
                text='Неправильные значения параметров')
        res = await CrawlerMS.make_request('index',
                                           data={
                                               'domain': domain,
                                               'token': token
                                           })
        return web.Response(text=res)
    else:
        raise web.HTTPForbidden(text='forbidden')
Beispiel #13
0
async def chat_websocket(request):
    session = await get_session(request)
    userid = session['userid']
    username = session['name']
    convid = request.app['db'].get_user(userid)['curconv']
    if not convid:
        raise web.HTTPPreconditionFailed()
    userdata = {'userid': userid, 'username': username, 'convid': convid}

    ws = web.WebSocketResponse()
    await ws.prepare(request)

    CONV_CONNECTIONS[convid].add(ws)
    ALL_CONNECTIONS.add(ws)
    try:
        async for msg in ws:
            dispatch_message(request, ws, msg, userdata)
    finally:
        CONV_CONNECTIONS[convid].remove(ws)
        ALL_CONNECTIONS.remove(ws)
    return ws
Beispiel #14
0
 def error(self,
           request: web.Request = None,
           response: dict = {},
           exception: Exception = None,
           state: int = 400,
           headers: dict = {},
           **kwargs) -> web.Response:
     # TODO: process the exception object
     response_obj = {"status": "Failed"}
     if not request:
         request = self.request
     if exception:
         response_obj["reason"] = str(exception)
     args = {**kwargs}
     if isinstance(response, dict):
         response_obj = {**response_obj, **response}
         args["content_type"] = "application/json"
         args["text"] = json.dumps(response_obj)
     else:
         args["body"] = response
     # defining the error
     if state == 400:  # bad request
         obj = web.HTTPBadRequest(**args)
     elif state == 401:  # unauthorized
         obj = web.HTTPUnauthorized(**args)
     elif state == 403:  # forbidden
         obj = web.HTTPForbidden(**args)
     elif state == 404:  # not found
         obj = web.HTTPNotFound(**args)
     elif state == 406:
         obj = web.HTTPNotAcceptable(**args)
     elif state == 412:
         obj = web.HTTPPreconditionFailed(**args)
     elif state == 428:
         obj = web.HTTPPreconditionRequired(**args)
     else:
         obj = web.HTTPBadRequest(**args)
     for header, value in headers.items():
         obj.headers[header] = value
     return obj
 async def resolve(self, request):
     raise web.HTTPPreconditionFailed()
Beispiel #16
0
async def put(request: web.Request):
    hooks = request.app.hooks
    scopes = request.authz_scopes

    is_redact_only = 'CAT/W' not in scopes

    # Grab the document from the request body and canonicalize it.
    try:
        doc = await request.json()
    except json.decoder.JSONDecodeError:
        raise web.HTTPBadRequest(text='invalid json')
    doc['ams:modifiedby'] = request.authz_subject
    canonical_doc = await hooks.mds_canonicalize(app=request.app, data=doc)

    if is_redact_only and canonical_doc['ams:status'] == 'beschikbaar':
        raise web.HTTPForbidden()

    # Make sure the docid in the path corresponds to the ids given in the
    # document, if any. The assumption is that request.path (which corresponds
    # to the path part of the incoming HTTP request) is the path as seen by
    # the client. This is not necessarily true.
    doc_id = request.match_info['dataset']

    # Let the metadata plugin grab the full-text search representation
    searchable_text = await hooks.mds_full_text_search_representation(
        data=canonical_doc)

    # Figure out the mode (insert / update) of the request.
    etag_if_match = conditional.parse_if_header(request,
                                                conditional.HEADER_IF_MATCH)
    etag_if_none_match = conditional.parse_if_header(
        request, conditional.HEADER_IF_NONE_MATCH)
    # Can't accept a value in both headers
    if etag_if_match is not None and etag_if_none_match is not None:
        raise web.HTTPBadRequest(
            body='Endpoint supports either If-Match or If-None-Match in a '
            'single request, not both')

    # If-Match: {etag, ...} is for updates
    if etag_if_match is not None:
        if etag_if_match == '*':
            raise web.HTTPBadRequest(
                body='Endpoint does not support If-Match: *. Must provide one '
                'or more Etags.')
        try:
            old_doc, _etag = await hooks.storage_retrieve(app=request.app,
                                                          docid=doc_id,
                                                          etags=None)
        except KeyError:
            _logger.exception('precondition failed')
            raise web.HTTPPreconditionFailed()
        canonical_doc = await hooks.mds_before_storage(app=request.app,
                                                       data=canonical_doc,
                                                       old_data=old_doc)
        try:
            new_etag = await hooks.storage_update(
                app=request.app,
                docid=doc_id,
                doc=canonical_doc,
                searchable_text=searchable_text,
                etags=etag_if_match,
                iso_639_1_code="nl")
        except ValueError:
            _logger.exception('precondition failed')
            raise web.HTTPPreconditionFailed()
        await notify_data_changed(request.app)
        retval = web.Response(status=204, headers={'Etag': new_etag})

    else:
        # If-None-Match: * is for creates
        if etag_if_none_match != '*':
            raise web.HTTPBadRequest(
                body='For inserts of new documents, provide If-None-Match: *')
        canonical_doc = await hooks.mds_before_storage(app=request.app,
                                                       data=canonical_doc)
        try:
            new_etag = await hooks.storage_create(
                app=request.app,
                docid=doc_id,
                doc=canonical_doc,
                searchable_text=searchable_text,
                iso_639_1_code="nl")
        except KeyError:
            _logger.exception('precondition failed')
            raise web.HTTPPreconditionFailed()
        await notify_data_changed(request.app)
        retval = web.Response(status=201,
                              headers={'Etag': new_etag},
                              content_type='text/plain')

    return retval
 def function27(self, arg236):
     raise web.HTTPPreconditionFailed()
Beispiel #18
0
def check_flag():
    if round < 0:
        raise web.HTTPPreconditionFailed()
    if flag is None or key is None:
        raise web.HTTPServiceUnavailable()