示例#1
0
        async def request_wrapper(request: web.Request,
                                  **kwargs) -> Union[Callable, web.Response]:
            errors = {}

            if path_schema:
                try:
                    path = path_schema.load(dict(request.match_info))
                    request["path"] = path
                except ValidationError as e:
                    errors["path"] = e.messages

            if query_schema:
                try:
                    query = query_schema.load(dict(request.query))
                    request["query"] = query
                except ValidationError as e:
                    errors["query"] = e.messages

            if body_schema:
                try:
                    body = body_schema.load(await request.json())
                    request["body"] = body
                except JSONDecodeError as e:
                    raise web.HTTPUnsupportedMediaType()
                except ValidationError as e:
                    errors["body"] = e.messages

            if errors:
                validation_error_schema = HTTPValidationErrorSchema()
                data = validation_error_schema.dump({"detail": errors})
                raise web.HTTPUnprocessableEntity(
                    text=json.dumps(data), content_type="application/json")

            return await handler(request, **kwargs)
示例#2
0
    def _try_client_response(self, headers, parsed):
        """
        Sends a response back to the client based on Accept header
        Defaults to JSON
        """
        media_msg = 'The requested media type is unsupported'
        mime_type = None
        sub_type = None

        try:
            accept_types = headers['Accept']
            mime_type, sub_type, _, _ = parse_mimetype(accept_types)
        except KeyError:
            pass

        if mime_type == 'application' and sub_type == 'octet-stream':
            return web.Response(
                content_type='application/octet-stream',
                body=parsed.SerializeToString()
            )

        if ((mime_type in ['application', '*'] or mime_type is None)
                and (sub_type in ['json', '*'] or sub_type is None)):
            return web.Response(
                content_type='application/json',
                text=MessageToJson(parsed)
            )

        raise web.HTTPUnsupportedMediaType(reason=media_msg)
示例#3
0
async def http_error_handler(req: Request, handler: Callable) -> Response:
    """Middleware for handling exceptions received from the API methods.

    :param req: A request instance
    :param handler: A request handler
    :raises: Reformatted HTTP Exceptions
    :returns: Successful requests unaffected
    """
    try:
        response = await handler(req)
        return response
    except web.HTTPError as error:
        details = _json_exception(error.status, error, req.url)
        LOG.error(details)
        c_type = "application/problem+json"
        if error.status == 400:
            raise web.HTTPBadRequest(text=details, content_type=c_type)
        elif error.status == 401:
            raise web.HTTPUnauthorized(
                headers={"WWW-Authenticate": 'OAuth realm="/", charset="UTF-8"'}, text=details, content_type=c_type
            )
        elif error.status == 403:
            raise web.HTTPForbidden(text=details, content_type=c_type)
        elif error.status == 404:
            raise web.HTTPNotFound(text=details, content_type=c_type)
        elif error.status == 415:
            raise web.HTTPUnsupportedMediaType(text=details, content_type=c_type)
        elif error.status == 422:
            raise web.HTTPUnprocessableEntity(text=details, content_type=c_type)
        else:
            raise web.HTTPServerError()
示例#4
0
        async def wrapper(request):

            # Check media type
            if request.content_type != 'application/json':
                raise web.HTTPUnsupportedMediaType(
                    text=(
                        'Invalid Content-Type "{}". '
                        'Only "application/json" is supported.'
                    ).format(request.content_type)
                )

            # Parse JSON request
            body = await request.text()
            try:
                payload = loads(body)
            except ValueError:
                log.error('Invalid JSON payload:\n{}'.format(body))
                raise web.HTTPBadRequest(
                    text='Invalid JSON payload'
                )

            # Log request and responses
            log.info('Request:\n{}'.format(pformat(payload)))
            response = await handler(request, payload)
            log.info('Response:\n{}'.format(pformat(response)))

            # Convert dictionaries to JSON responses
            if isinstance(response, dict):
                return web.json_response(response)
            return response
示例#5
0
    def _try_client_response(headers, parsed):
        """
        Used by pre-spec /state and /batches routes
        Should be removed when routes are updated to spec
        """
        media_msg = 'The requested media type is unsupported'
        mime_type = None
        sub_type = None

        try:
            accept_types = headers['Accept']
            mime_type, sub_type, _, _ = parse_mimetype(accept_types)
        except KeyError:
            pass

        if mime_type == 'application' and sub_type == 'octet-stream':
            return web.Response(
                content_type='application/octet-stream',
                body=parsed.SerializeToString()
            )

        if ((mime_type in ['application', '*'] or mime_type is None)
                and (sub_type in ['json', '*'] or sub_type is None)):
            return web.Response(
                content_type='application/json',
                text=MessageToJson(parsed)
            )

        raise web.HTTPUnsupportedMediaType(reason=media_msg)
示例#6
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()
示例#7
0
 async def create_request(self, request):
     params = await request.post()
     wallet = self.daemon.wallet
     if 'amount_sat' not in params or not params['amount_sat'].isdigit():
         raise web.HTTPUnsupportedMediaType()
     amount = int(params['amount_sat'])
     message = params['message'] or "donation"
     payment_hash = await wallet.lnworker._add_invoice_coro(amount, message, 3600)
     key = payment_hash.hex()
     raise web.HTTPFound(self.root + '/pay?id=' + key)
示例#8
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)
示例#9
0
async def handle_post(request):
    if request.content_type != 'application/json':
        raise web.HTTPUnsupportedMediaType(
            text='Media type needs to be application/json')
    body_json = await request.json()
    resp_json = {
        key: value
        for key, value in body_json.items() if key.lower().startswith('a')
    }
    return web.Response(text=json.dumps(resp_json),
                        content_type='application/json')
示例#10
0
 async def create_request(self, request):
     raise NotImplementedError()  # FIXME code here is broken
     params = await request.post()
     wallet = self.wallet
     if 'amount_sat' not in params or not params['amount_sat'].isdigit():
         raise web.HTTPUnsupportedMediaType()
     amount = int(params['amount_sat'])
     message = params['message'] or "donation"
     payment_hash = wallet.lnworker.add_request(amount_sat=amount,
                                                message=message,
                                                expiry=3600)
     key = payment_hash.hex()
     raise web.HTTPFound(self.root + '/pay?id=' + key)
示例#11
0
    async def _format_data_to_update_and_add_to_db(self, schema_type: str,
                                                   accession_id: str,
                                                   data: str) -> str:
        """Raise not implemented.

        Patch update for XML not supported

        :param schema_type: Schema type of the object to replace.
        :param accession_id: Identifier of object to replace.
        :param data: Original xml content
        :raises: HTTPUnsupportedMediaType
        """
        reason = "XML patching is not possible."
        raise web.HTTPUnsupportedMediaType(reason=reason)
示例#12
0
async def handler(request: Request) -> Response:
    post = await request.post()
    if 'file' not in post:
        return web.HTTPBadRequest(text='No file in request')
    if not post['file'].content_type.startswith('image/'):
        return web.HTTPUnsupportedMediaType()
    filename = post['file'].filename
    file_stream = post['file'].file
    image = file_stream.read()
    with open(test_data_folder / filename, 'rb') as fp:
        image_original = fp.read()
    if len(image) == len(image_original) and image == image_original:
        return web.HTTPOk()
    return web.HTTPBadRequest(text='Original and received images do not match')
示例#13
0
async def login_post(request):
    try:
        data = await request.json()
    except JSONDecodeError:
        raise web.HTTPUnsupportedMediaType(text="Payload could not be parsed as JSON")

    if not check_required_keys(data, "user_name", "user_pass"):
        raise web.HTTPUnprocessableEntity(text="Payload missing required parameter(s)")

    user_name, user_pass = data["user_name"], data["user_pass"]

    user_dict = request.app["users"]

    if user_name not in user_dict or user_pass != user_dict[user_name]:
        raise web.HTTPUnauthorized(text="Invalid user name and/or password")

    return web.json_response({"token": "abcdefghijklmnopqrstuvwxyz"})
示例#14
0
    def unpublish_post(self, request):
        """De-register a service in the service directory

        :param request: incoming HTTP request
        :type request: aiohttp.Request
        :returns: A HTTP response
        :rtype: aiohttp.web.Response
        """
        content_handlers = {
            'application/json': services.Service.from_json,
            'application/xml': services.Service.from_xml,
        }
        try:
            handler = content_handlers[request.content_type]
        except KeyError:
            self.log.info('Unhandled Content-Type: %s', request.content_type)
            raise web.HTTPUnsupportedMediaType(
                reason='Unhandled Content-Type: %s' % request.content_type)

        try:
            text = yield from request.text()
            self.log.debug('Service text: %s', text)
            service = handler(text)
        except ValueError:
            # bad input
            raise web.HTTPBadRequest(reason='Invalid data, expected service')

        name = service.name
        if not name:
            # bad input
            raise web.HTTPBadRequest(reason='Missing service name')

        try:
            self._directory.unpublish(name=name)
        except self._directory.DoesNotExist:
            self.log.info('Service %s is not published', name)
            raise web.HTTPBadRequest(reason='Service %s is not published' %
                                     (name, ))
        self.log.info('Unpublish %s OK', name)
        payload = 'Unpublish OK'
        code = web.HTTPOk.status_code
        return web.Response(body=payload.encode('utf-8'),
                            status=code,
                            content_type='text/plain',
                            charset='utf-8')
示例#15
0
async def register_post(request):
    try:
        data = await request.json()
    except JSONDecodeError:
        raise web.HTTPUnsupportedMediaType(text="Payload is not JSON")

    if not check_required_keys(data, "user_name", "user_pass"):
        raise web.HTTPUnprocessableEntity(text="Payload missing required parameter(s)")

    user_name, user_pass = data["user_name"], data["user_pass"]

    user_dict = request.app["users"]

    if user_name in user_dict:
        raise web.HTTPUnprocessableEntity(text="User name already registered")

    user_dict[user_name] = user_pass

    raise web.HTTPCreated(text="User created")
示例#16
0
async def Event(request: web.Request) -> EventType:
    user_agent = request.headers.get('User-Agent', None)
    if not user_agent.startswith('GitHub-Hookshot/'):
        raise web.HTTPNotAcceptable(reason='User agent looks incorrect')
    content_type = request.headers.get('Content-Type', None)
    if not content_type == 'application/json':
        raise web.HTTPUnsupportedMediaType(reason='Not a JSON payload')
    payload = await request.json()
    event_type = request.headers.get('X-GitHub-Event', None)
    key = 'issue' if event_type == 'issues' else event_type
    return EventType(
        app=request.app,
        key=key,
        type=event_type,
        guid=request.headers.get('X-GitHub-Delivery', None),
        signature=request.headers.get('X-Hub-Signature', None),
        user_agent=user_agent,
        content_type=content_type,
        payload=payload,
        action=payload.get('action', None),
    )
示例#17
0
    async def patch_object(self, req: Request) -> Response:
        """Update metadata object in database.

        We do not support patch for XML.

        :param req: PATCH request
        :raises: HTTPUnauthorized if object is in published folder
        :returns: JSON response containing accessionId for submitted object
        """
        schema_type = req.match_info["schema"]
        accession_id = req.match_info["accessionId"]
        self._check_schema_exists(schema_type)
        collection = f"draft-{schema_type}" if req.path.startswith("/drafts") else schema_type

        db_client = req.app["db_client"]
        operator: Union[Operator, XMLOperator]
        if req.content_type == "multipart/form-data":
            reason = "XML patching is not possible."
            raise web.HTTPUnsupportedMediaType(reason=reason)
        else:
            content = await self._get_data(req)
            operator = Operator(db_client)

        await operator.check_exists(collection, accession_id)

        await self._handle_check_ownedby_user(req, collection, accession_id)

        folder_op = FolderOperator(db_client)
        exists, _, published = await folder_op.check_object_in_folder(collection, accession_id)
        if exists:
            if published:
                reason = "Published objects cannot be updated."
                LOG.error(reason)
                raise web.HTTPUnauthorized(reason=reason)

        accession_id = await operator.update_metadata_object(collection, accession_id, content)

        body = json.dumps({"accessionId": accession_id})
        LOG.info(f"PATCH object with accession ID {accession_id} in schema {collection} was successful.")
        return web.Response(body=body, status=200, content_type="application/json")
示例#18
0
    async def put_object(self, req: Request) -> Response:
        """Replace metadata object in database.

        For JSON request we don't allow replacing in the DB.

        :param req: PUT request
        :raises: HTTPUnsupportedMediaType if JSON replace is attempted
        :returns: JSON response containing accessionId for submitted object
        """
        schema_type = req.match_info["schema"]
        accession_id = req.match_info["accessionId"]
        self._check_schema_exists(schema_type)
        collection = f"draft-{schema_type}" if req.path.startswith("/drafts") else schema_type

        db_client = req.app["db_client"]
        content: Union[Dict, str]
        operator: Union[Operator, XMLOperator]
        if req.content_type == "multipart/form-data":
            files = await _extract_xml_upload(req, extract_one=True)
            content, _ = files[0]
            operator = XMLOperator(db_client)
        else:
            content = await self._get_data(req)
            if not req.path.startswith("/drafts"):
                reason = "Replacing objects only allowed for XML."
                LOG.error(reason)
                raise web.HTTPUnsupportedMediaType(reason=reason)
            operator = Operator(db_client)

        await operator.check_exists(collection, accession_id)

        await self._handle_check_ownedby_user(req, collection, accession_id)

        accession_id = await operator.replace_metadata_object(collection, accession_id, content)

        body = json.dumps({"accessionId": accession_id})
        LOG.info(f"PUT object with accession ID {accession_id} in schema {collection} was successful.")
        return web.Response(body=body, status=200, content_type="application/json")
示例#19
0
    async def handle_request(self, request: web.Request) -> web.Response:
        request_time = int(time() * 1000)
        try:
            # Check if the Content-Type and Accept headers both are presented
            # and contain 'application/json'

            if request.headers["Content-Type"] != "application/json":
                raise web.HTTPUnsupportedMediaType(
                    reason="Invalid Content-Type")
            if request.headers["Accept"] != "application/json":
                raise web.HTTPNotAcceptable(reason="Invalid Accept header")
        except KeyError as exp:
            reason = "{} header is required".format(exc_message(exp))
            raise web.HTTPNotAcceptable(reason=reason)

        try:
            request_data = await request.json()
        except json.JSONDecodeError:
            exp = JsonRpcError(Errors.PARSE_ERROR)
            self.log_request(request, request_time, "invalid", exp)
            return exp.http_response()

        try:
            if isinstance(request_data, list):
                response_data = await self.process_batch_rpc(request_data)
                self.log_request(request, request_time)
                return web.json_response(response_data)
            response_data = await self.process_single_rpc(request_data)
            self.log_request(request, request_time, request_data["method"])
            return web.json_response(response_data)
        except JsonRpcError as exp:
            exp.set_context(request_data)
            self.log_request(request, request_time,
                             request_data.get("method", "unknown/invalid"),
                             exp)
            return exp.http_response()
示例#20
0
文件: aiohttp.py 项目: dapper91/pjrpc
    async def _rpc_handle(
            self, http_request: web.Request,
            dispatcher: pjrpc.server.AsyncDispatcher) -> web.Response:
        """
        Handles JSON-RPC request.

        :param http_request: :py:class:`aiohttp.web.Response`
        :returns: :py:class:`aiohttp.web.Request`
        """

        if http_request.content_type not in pjrpc.common.REQUEST_CONTENT_TYPES:
            raise web.HTTPUnsupportedMediaType()

        try:
            request_text = await http_request.text()
        except UnicodeDecodeError as e:
            raise web.HTTPBadRequest() from e

        response_text = await dispatcher.dispatch(request_text,
                                                  context=http_request)
        if response_text is None:
            return web.Response()
        else:
            return web.json_response(text=response_text)
示例#21
0
def route(request):

    if request.content_type != "multipart/form-data":
        return web.HTTPBadRequest()

    query_parameters = request.rel_url.query
    if "token" in query_parameters:
        room = toolbox.token_verify(query_parameters["token"])
        if room is None:
            return web.HTTPBadRequest()
        elif not re.search(r'^\d{6}$', room):
            return web.HTTPBadRequest()
    else:
        return web.HTTPBadRequest()

    try:
        reader = yield from request.multipart()
    except:
        return web.HTTPBadRequest()

    data = yield from reader.next()

    photo_dir = os.path.join(request.app["photo_dir"], room)

    if os.path.exists(photo_dir) == 0:
        os.mkdir(photo_dir)

    temp_path = ''
    size = 0
    suffix = ''
    hash_calc = hashlib.md5()

    while True:
        try:
            chunk = yield from data.read_chunk()  # 8192 bytes by default
        except:
            return web.HTTPBadRequest()

        if not chunk:
            break

        if size == 0:

            if len(chunk) < 4:
                return web.HTTPUnsupportedMediaType(
                    reason="unsupported file type")

            # top_bytes = chunk[0:4].hex().upper()
            top_bytes = ''.join('{:02x}'.format(x) for x in chunk[0:4]).upper()

            if top_bytes[0:6] == 'FFD8FF':
                suffix = "jpg"
            elif top_bytes[0:8] == '89504E47':
                suffix = "png"
            elif top_bytes[0:8] == '47494638':
                suffix = "gif"
            else:
                return web.HTTPUnsupportedMediaType(
                    reason="unsupported file type")

            while True:
                temp_name = str(int(time.time())) + str(random.randint(
                    0, 9999)).zfill(4)
                temp_path = os.path.join(photo_dir, temp_name)
                if not os.path.exists(temp_path):
                    file = open(temp_path, 'wb')
                    break

        size = size + len(chunk)
        file.write(chunk)
        hash_calc.update(chunk)

        if size / 1048576 > 3:  # size limit 3MB
            file.close()
            os.remove(temp_path)
            return web.HTTPRequestEntityTooLarge(reason="file size overflow")

    file.close()
    hash_value = hash_calc.hexdigest()
    formal_name = hash_value + "." + suffix
    formal_path = os.path.join(photo_dir, formal_name)

    if os.path.exists(formal_path) != 0:
        os.remove(temp_path)
    else:
        os.rename(temp_path, formal_path)

    return web.Response(text=formal_name,
                        # headers={'Access-Control-Allow-Origin':'*'}
                        )
    async def post(self) -> web.Response:
        """Validate route function."""
        cache = self.request.app["cache"]

        logging.debug(
            f"Got following content-type-headers: {self.request.headers[hdrs.CONTENT_TYPE]}."
        )
        if "multipart/" not in self.request.headers[hdrs.CONTENT_TYPE].lower():
            raise web.HTTPUnsupportedMediaType(
                reason=
                f"multipart/* content type expected, got {hdrs.CONTENT_TYPE}.")

        # Iterate through each part of MultipartReader
        data_graph_url = None
        data_graph = None
        shapes_graph = None
        shapes_graph_url = None
        ontology_graph = None
        ontology_graph_url = None
        config = None
        data_graph_matrix = dict()
        shapes_graph_matrix = dict()
        async for part in (await self.request.multipart()):
            logging.debug(f"part.name {part.name}.")
            if Part(part.name) is Part.CONFIG:
                # Get config:
                config_json = await part.json()
                logging.debug(f"Got config: {config_json}.")
                if config_json:
                    config = _create_config(config_json)
                pass
            # Data graph, url:
            if Part(part.name) is Part.DATA_GRAPH_URL:
                # Get data graph from url:
                data_graph_url = (await part.read()).decode()
                logging.debug(
                    f"Got reference to data graph with url: {data_graph_url}.")
                data_graph_matrix[part.name] = data_graph_url
                pass
            # Data graph, file:
            if Part(part.name) is Part.DATA_GRAPH_FILE:
                # Process any files you uploaded
                logging.debug(
                    f"Got input data graph with filename: {part.filename}.")
                try:
                    data_graph = (await part.read()).decode()
                except ValueError:
                    raise web.HTTPBadRequest(
                        reason="Data graph file is not readable.") from None
                # logging.debug(f"Content of {part.filename}:\n{data_graph}.")
                if part.filename:
                    data_graph_matrix[part.name] = part.filename
                pass
            # Shapes graph, url:
            if Part(part.name) is Part.SHAPES_GRAPH_URL:
                # Get shapes graph from url:
                shapes_graph_url = (await part.read()).decode()
                logging.debug(
                    f"Got reference to shapes graph with url: {shapes_graph_url}."
                )
                shapes_graph_matrix[part.name] = shapes_graph_url
                pass
            # Shapes graph, file:
            if Part(part.name) is Part.SHAPES_GRAPH_FILE:
                # Process any files you uploaded
                logging.debug(
                    f"Got input shapes graph with filename: {part.filename}.")
                try:
                    shapes_graph = (await part.read()).decode()
                except ValueError:
                    raise web.HTTPBadRequest(
                        reason="Shapes graph file is not readable.") from None
                # logging.debug(f"Content of {part.filename}:\n{shapes_graph}.")
                if part.filename:
                    shapes_graph_matrix[part.name] = part.filename
                pass
            # Ontology graph, url:
            if Part(part.name) is Part.ONTOLOGY_GRAPH_URL:
                # Get ontology graph from url:
                ontology_graph_url = (await part.read()).decode()
                logging.debug(
                    f"Got reference to ontology graph with url: {ontology_graph_url}."
                )
                pass
            # Ontology graph, file:
            if Part(part.name) is Part.ONTOLOGY_GRAPH_FILE:
                # Process any files you uploaded
                logging.debug(
                    f"Got input ontology graph with filename: {part.filename}."
                )
                try:
                    ontology_graph = (await part.read()).decode()
                except ValueError:
                    raise web.HTTPBadRequest(
                        reason="Ontology graph file is not readable."
                    ) from None

        # check if we got any input:
        # validate data-graph input:
        if len(data_graph_matrix) == 0:
            raise web.HTTPBadRequest(reason="No data graph in input.")
        elif len(data_graph_matrix) > 1:
            logging.debug(f"Ambigious user input: {data_graph_matrix}.")
            raise web.HTTPBadRequest(reason="Multiple data graphs in input.")
        # validate shape-graph input:
        if len(shapes_graph_matrix) == 0:
            raise web.HTTPBadRequest(reason="No shapes graph in input.")
        elif len(shapes_graph_matrix) > 1:
            logging.debug(f"Ambigious user input: {shapes_graph_matrix}.")
            raise web.HTTPBadRequest(reason="Multiple shapes graphs in input.")

        # We have got data, now validate:
        try:
            # instantiate validator service:
            service = await ValidatorService.create(
                cache=cache,
                data_graph_url=data_graph_url,
                data_graph=data_graph,
                shapes_graph_url=shapes_graph_url,
                shapes_graph=shapes_graph,
                ontology_graph_url=ontology_graph_url,
                ontology_graph=ontology_graph,
                config=config,
            )
        except FetchError as e:
            logging.debug(traceback.format_exc())
            raise web.HTTPBadRequest(reason=str(e)) from None
        except SyntaxError as e:
            logging.debug(traceback.format_exc())
            raise web.HTTPBadRequest(reason=str(e)) from None

        # validate:
        (
            conforms,
            data_graph,
            ontology_graph,
            results_graph,
        ) = await service.validate(cache=cache)

        # Try to content-negotiate:
        logging.debug(
            f"Got following accept-headers: {self.request.headers[hdrs.ACCEPT]}."
        )
        content_type = "text/turtle"  # default
        if "*/*" in self.request.headers[hdrs.ACCEPT]:
            pass  # use default
        elif self.request.headers[
                hdrs.ACCEPT]:  # we try to serialize according to accept-header
            content_type = self.request.headers[hdrs.ACCEPT]
        response_graph = Graph()
        response_graph += results_graph
        response_graph += data_graph
        if config and config.include_expanded_triples is True:
            response_graph += ontology_graph
        try:
            return web.Response(
                body=response_graph.serialize(format=content_type),
                content_type=content_type,
            )
        except PluginException:  # rdflib raises PluginException, in this context imples 406
            logging.debug(traceback.format_exc())
            raise web.HTTPNotAcceptable() from None  # 406
示例#23
0
文件: app.py 项目: semtexzv/vmaas
 async def get_post_data(cls, request):
     """extract input JSON from POST request"""
     if request.headers.get(hdrs.CONTENT_TYPE, None) == 'application/json':
         return await request.json()
     raise web.HTTPUnsupportedMediaType(
         reason="Application/json media type is needed")
async def service_submission(request: web.Request):
    reader = MultipartReader.from_response(request)
    data = None
    filedata = None

    # Read multipart email
    while True:
        part = await reader.next()  # pylint: disable=not-callable
        if part is None:
            break
        if part.headers[hdrs.CONTENT_TYPE] == "application/json":
            data = await part.json()
            continue
        if part.headers[hdrs.CONTENT_TYPE] == "application/zip":
            filedata = await part.read(decode=True)
            # Validate max file size
            maxsize = 10 * 1024 * 1024  # 10MB
            actualsize = len(filedata)
            if actualsize > maxsize:
                raise web.HTTPRequestEntityTooLarge(maxsize, actualsize)
            filename = part.filename
            continue
        raise web.HTTPUnsupportedMediaType(
            reason=f"One part had an unexpected type: {part.headers[hdrs.CONTENT_TYPE]}"
        )

    # data (dict) and file (bytearray) have the necessary information to compose the email
    support_email_address = request.app[APP_CONFIG_KEY]["smtp"]["sender"]
    is_real_usage = any(
        env in os.environ.get("SWARM_STACK_NAME", "")
        for env in ("production", "staging")
    )
    db = get_storage(request.app)
    user = await db.get_user({"id": request[RQT_USERID_KEY]})
    user_email = user.get("email")
    if not is_real_usage:
        support_email_address = user_email

    try:
        # NOTE: temporarily internal import to avoid render_and_send_mail to be interpreted as handler
        # TODO: Move outside when get_handlers_from_namespace is fixed
        from .login.utils import render_and_send_mail

        attachments = [("metadata.json", json.dumps(data, indent=4))]
        if filedata:
            attachments.append((filename, filedata))
        # send email
        await render_and_send_mail(
            request,
            to=support_email_address,
            template=common_themed(EMAIL_TEMPLATE_NAME),
            context={
                "user": user_email,
                "data": json2html.convert(
                    json=json.dumps(data), table_attributes='class="pure-table"'
                ),
                "subject": "TEST: " * (not is_real_usage) + "New service submission",
            },
            attachments=attachments,
        )
    except Exception as exc:
        log.exception("Error while sending the 'new service submission' mail.")
        raise web.HTTPServiceUnavailable() from exc

    raise web.HTTPNoContent(content_type="application/json")