Пример #1
0
async def restart(request):
    if 'config' not in request.json:
        raise InvalidUsage('Body must contain "config" key')
    if request.json['config'] not in ['original', 'current']:
        raise InvalidUsage(
            'Body "config" key must have value "original" or "current"')
    run_on_master_thread_when_idle(
        request['session'].end,
        restart=True,
        use_current_config=request.json['config'] == 'current')
    return _status_ok_response()
Пример #2
0
async def create_idea(request, *args, **kwargs):
    if request.json is not None:
        idea, errors = IdeaSchema().load(request.json)
        if errors is not None and len(errors) > 0:
            raise InvalidUsage(errors)
        else:
            id = idea.save()
            idea = Idea.load_by_id(id)
    else:
        raise InvalidUsage("Missing JSON body")

    return response.json(IdeaSchema().dump(idea).data, status=201)
Пример #3
0
def _get_connection(request, id, create_if_not_made):
    if 'uid' not in request.json:
        raise InvalidUsage('Requires "uid" field in JSON body')

    source = request['session'].uid_to_block(request.json['uid'])
    if source is None:
        raise InvalidUsage('No such item "%s"' % request.json['uid'])

    connection = _get_mixer(request, id).connection_for_source(source, create_if_not_made=create_if_not_made)
    if not connection and create_if_not_made is True:
        raise InvalidUsage('Unable to connect "%s" to mixer %d' % (request.json['uid'], id))
    return connection, request.json
Пример #4
0
    def add(self, methods, handler, stream=False):
        if stream:
            handler.is_stream = stream
        for method in methods:
            if method not in HTTP_METHODS:
                raise InvalidUsage(
                    "{} is not a valid HTTP method.".format(method))

            if method in self.handlers:
                raise InvalidUsage(
                    "Method {} is already registered.".format(method))
            self.handlers[method] = handler
Пример #5
0
async def processRun(request, authenticatedUser):
    def substitute(s):
        return s.format(user=authenticatedUser.name)

    reqData = request.json
    actionToken = reqData.get('action', None)
    command = reqData.get('command', None)
    # client-defined extra data, forwarded to start notification
    extraData = reqData.get('extraData', None)
    token = reqData.get('token', None)
    isAction = bool(actionToken)
    isCommand = bool(command)

    user = None
    if isAction and isCommand:
        # cannot have both at the same time
        raise InvalidUsage('make_up_your_mind')
    elif isAction:
        action = await getAction(actionToken)
        args = action.arguments
        authId = args['user']
        user = await User.get_or_none(authId=authId)
        command = list(map(substitute, args['command']))
    elif isCommand:
        # use current user instead
        user = authenticatedUser

    if not user:
        # not connected to any authorized user
        raise Forbidden('forbidden')
    else:
        processes = perUserProcesses[authenticatedUser]

        if token in processes:
            raise InvalidUsage('process_exists')
        elif not token:
            raise InvalidUsage('missing_token')

        p = WebsocketProcess(token,
                             user,
                             broadcastFunc=partial(broadcast,
                                                   authenticatedUser),
                             command=command,
                             extraData=extraData)
        try:
            await p.run()
            processes[token] = p
            return jsonResponse({'status': 'ok', 'token': token})
        except asyncssh.misc.PermissionDenied:
            raise Forbidden('locked_out')
        except TermsNotAccepted:
            raise Forbidden('terms_of_service')
Пример #6
0
def process_paste(paste, paste_id, fallback_charset = None):
    if isinstance(paste, bytes): paste = decode(paste, fallback_charset)
    elif paste is None: raise InvalidUsage("Malformed request (no paste found)")
    elif paste[0] == "\uFEFF": paste = paste[1:]  # Remove Unicode BOM
    paste = paste.replace("\r\n", "\n")
    if not paste.strip(): raise InvalidUsage("Empty paste (no data found)")
    if not paste.endswith("\n"): paste += "\n"
    if paste_id:
        paste_id = "".join([c for c in paste_id.replace(" ", "_") if re.match(r'[-_\w\.]', c)])
    if not paste_id or len(paste_id) < 3:
        ext = next((e for e, r in matchers if r.search(paste)), ".txt")
        paste_id = PronounceableWord().length(6, 15) + ext
    return paste_id, dict(text=paste, html=prettyprint(paste, paste_id))
Пример #7
0
async def get_body(request, id):
    '''
    Returns the body (image contents) of a JPEG output
    '''
    output = _get_output(request, id)
    if type(output) != ImageOutput:
        raise InvalidUsage('Output is not an image')

    try:
        return await sanic.response.file_stream(
            output.props['location'], headers={'Cache-Control': 'max-age=1'})
    except FileNotFoundError:
        raise InvalidUsage('No such body')
async def get_jogging_weekly_report(request, *args, **kwargs):
    user_from_token = retrieve_user(request, args, kwargs)
    if user_from_token is None:
        raise InvalidUsage("invalid parameter (maybe expired?)")

    page = int(request.args["page"][0]) if "page" in request.args else 0
    limit = int(request.args["count"][0]) if "count" in request.args else 10

    if page < 0 or limit <= 0:
        raise InvalidUsage("invalid paging (page >= 0 and count > 0)")

    user_id = retrieve_user(request, args, kwargs).user_id
    rc = jogging_weekly_report(user_id, page, limit)
    return response.json(rc, status=200)
Пример #9
0
    async def login(cls,
                    email=None,
                    password=None,
                    *,
                    is_anonymous=False,
                    **kwargs):
        user = None
        if not is_anonymous:
            if not email:
                raise InvalidUsage("Missing field 'email' in request's body.")
            if not password:
                raise InvalidUsage(
                    "Missing field 'password' in request's body.")

            password = hash_password(password)
            try:
                user = await cls.get(email=email, password=password, **kwargs)
            except NotFound:
                pass

            if not user:
                raise LoginFailureError()

            # Invalidate the staff if he is disabled
            if "role_id" in user and user["disabled"]:
                raise Unauthorized(
                    "Your account have been disabled. Please contact your supervisor."
                )
        else:  # Anonymous login
            kwargs["is_anonymous"] = True
            user = await cls.add(**kwargs)

        # Only store minimum info for user
        fields = {
            "id",
            "full_name",
            "display_name",
            "name",
            "email",
            "role_id",
            "organisation_id",
            "is_anonymous",
            "disabled",
        }
        for key in list(user.keys()):
            if key not in fields:
                user.pop(key, None)

        return user
Пример #10
0
    async def modify(cls, get_kwargs, update_kwargs):
        model_id = get_kwargs.get("id")
        if not model_id:
            raise InvalidUsage("Missing field 'id' in query parameter")

        payload = await get_one(cls, id=model_id)
        if not payload:
            raise_not_found_exception(cls, id=model_id)
        try:
            data = await update_one(payload, **update_kwargs)
        except (UniqueViolationError, DuplicatedError):
            raise InvalidUsage("The {} already exists".format(
                cls.__tablename__))

        return serialize_to_dict(data)
Пример #11
0
def validate_required_params(param_list, *params):
    args = {}
    for param in list(params):
        if param not in param_list:
            raise InvalidUsage(
                f'Parameter "{param}" was missing from the request')

        arg = param_list[param]
        if len(arg) == 0:
            raise InvalidUsage(
                f'Parameter "{param}" had no data associated with it')

        args[param] = arg

    return args
Пример #12
0
 def validate_request(self, request):
     if not request.body and self.body_required:
         raise InvalidUsage("empty body")
     if self.json_required:
         for k in self.json_required:
             if k not in loads(request.body):
                 raise InvalidUsage(f"{k} not in body")
     if self.type_check:
         for k in self.type_check.keys():
             try:
                 self.type_check[k](request.get(k))
             except TypeError:
                 raise InvalidUsage(
                     f"{request.get(k)}'s type must be {self.type_check[k]}"
                 )
Пример #13
0
def validate_post_request(request: Request, fields: [str]) -> dict:
    '''
    Throws InvalidUsage exception if any given field is missing
    in the request body or URL arguments (in this order).
    '''
    error_message = 'Invalid request format. Mandatory fields are missing: {}'
    if not request.json and not request.args:
        raise InvalidUsage(error_message.format(repr(fields)))
    for source in [request.json, request.args]:
        if source:
            missing = [field for field in fields if field not in source]
            if len(missing):
                raise InvalidUsage(error_message.format(repr(missing)))
            else:
                return strip_list(source)
Пример #14
0
async def msg_create(request: Request):
    # Примечание:
    # реквест обрабатывается через form, а не json, поэтому check_request для обработки данных не применяется
    if request.cookies.get('Authorization') is None:
        raise Unauthorized('You need to be authorized')
    if 'message' not in request.form.keys():
        raise InvalidUsage('message info is missing')
    if 'recipient' not in request.form.keys():
        raise InvalidUsage('recipient info is missing')

    user = await check_request(request, list(), True)
    recipient = await User.find(user_login=request.form.get('recipient'))

    if 'reply_id' in request.form:
        reply_msg = await Msg.find(msg_id=request.form.get('reply_id'))
        if user.id not in (reply_msg.recipient_id, reply_msg.sender_id):
            raise Forbidden('You have not permission to reply this message')
        reply_msg = reply_msg.id
    else:
        reply_msg = None

    # Добавление картинки к сообщению
    upload_file = request.files.get('photo')
    if upload_file:
        if MAX_FILE_SIZE < len(upload_file.body):
            raise InvalidUsage(
                f'Photo size must be less than {MAX_FILE_SIZE} bytes')
        if imghdr.what(None, upload_file.body) == 'jpeg': file_type = 'jpg'
        elif imghdr.what(None, upload_file.body) == 'png': file_type = 'png'
        elif imghdr.what(None, upload_file.body) == 'gif': file_type = 'gif'
        else: raise InvalidUsage('Photo must be .jpg, .png or .gif')

        upload = await Upload.save_upload(user_id=user.id, file_type=file_type)
        async with aiofiles.open(f'{UPLOAD_DIR}\\{upload.id}.{file_type}',
                                 'wb') as f:
            await f.write(upload_file.body)
        await f.close()
        msg = await Msg.send(message=request.form.get('message'),
                             recipient_id=recipient.id,
                             sender_id=user.id,
                             upload_id=upload.id,
                             reply_id=reply_msg)
    else:
        msg = await Msg.send(message=request.form.get('message'),
                             recipient_id=recipient.id,
                             sender_id=user.id,
                             reply_id=reply_msg)
    return json(await msg.dump())
Пример #15
0
async def delete_snapshot(request, machine_id, snapshot_id):
    with data.Connection.use() as conn:
        machine_ro = data.Machine.get_one({'_id': machine_id}, conn=conn)
        if snapshot_id not in machine_ro.snapshots:
            raise InvalidUsage(
                f'Machine \'{machine_id}\' does not have snapshot \'{snapshot_id}\'!'
            )

        new_request = data.Request(type=data.RequestType.DELETE_SNAPSHOT)
        new_request.machine = machine_id
        new_request.subject_id = snapshot_id
        new_request.save(conn=conn)

        # enqueue snapshot deletion
        data.Action(type='other', request=new_request.id).save(conn=conn)

        return sanic.response.json(
            {
                "responses": [{
                    "type": "request_id",
                    "request_id": new_request.id,
                    "is_last": True
                }]
            },
            status=200)
Пример #16
0
async def get_tails(request, rr_id):
    """
    Get tails file pertaining to input revocation registry identifier.

    :param request: Sanic request structure
    :param rr_id: rev reg id for revocation registry to which tails file pertains
    :return: tails file, with tails hash as name
    """

    if not ok_rev_reg_id(rr_id):
        LOGGER.error('GET cited bad rev reg id %s', rr_id)
        raise InvalidUsage('GET cited bad rev reg id {}'.format(rr_id))

    dir_tails = pjoin(dirname(dirname(abspath(__file__))), 'tails')
    dir_cd_id = Tails.dir(dir_tails, rr_id)

    if not isdir(dir_cd_id):
        LOGGER.error('GET cited rev reg id %s for which tails file dir %s not present', rr_id, dir_cd_id)
        raise NotFound('GET cited rev reg id {} for which tails file dir {} not present'.format(rr_id, dir_cd_id))

    path_tails = Tails.linked(dir_tails, rr_id)
    if not path_tails:
        LOGGER.error('GET cited rev reg id %s for which tails file not present', rr_id)
        raise NotFound('GET cited rev reg id {} for which tails file not present'.format(rr_id))

    LOGGER.info('Fulfilling download GET request for tails file %s associated with rev reg id %s', path_tails, rr_id)
    return await response.file(path_tails, filename=basename(path_tails))
Пример #17
0
async def transcribe_with_http(request) -> HTTPResponse:
    """ Transcription route using HTTP. """

    current_app = request.app

    # The audio to be transcribed
    audio = request.files.get('audio')

    # The hot-words with their boosts to be used for transcribing the audio
    data = request.form

    all_hot_words = []
    if data:
        all_hot_words = stt_engine.add_hot_words(data)
    if not audio:
        raise InvalidUsage('Audio not provided')
    inference_start = perf_counter()

    # Running the transcription
    text = await current_app.loop.run_in_executor(
        executor, lambda: stt_engine.run(audio.body))
    inference_end = perf_counter() - inference_start

    # Logging on the prompt the outcome of the transcription process
    logger.info(
        '----------------------------------------------------------------------------'
    )
    logger.info(json.dumps(SttResponse(text, inference_end).__dict__))
    logger.info(
        '----------------------------------------------------------------------------'
    )

    # Explicitly erasing a hot-word from the language model (even though they are removed when the request is done)
    stt_engine.erase_hot_word(all_hot_words)
    return sanic_json(SttResponse(text, inference_end).__dict__)
Пример #18
0
    async def websocket_handshake(self, request):
        # let the websockets package do the handshake with the client
        headers = []

        def get_header(k):
            return request.headers.get(k, '')

        def set_header(k, v):
            headers.append((k, v))

        try:
            key = handshake.check_request(get_header)
            handshake.build_response(set_header, key)
        except InvalidHandshake:
            raise InvalidUsage('Invalid websocket request')

        # write the 101 response back to the client
        rv = b'HTTP/1.1 101 Switching Protocols\r\n'
        for k, v in headers:
            rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n'
        rv += b'\r\n'
        request.transport.write(rv)

        # hook up the websocket protocol
        self.websocket = WebSocketCommonProtocol(
            max_size=self.websocket_max_size,
            max_queue=self.websocket_max_queue)
        self.websocket.connection_made(request.transport)
        return self.websocket
Пример #19
0
def get_query_arg(req: Request, key, default=None):
    try:
        return req.args[key][0]
    except KeyError:
        if default is not None:
            return default
        raise InvalidUsage("missing argument '%s'." % key)
Пример #20
0
async def turn_on_handler(
    request: Request,
    ip_address: str,
    phone_id: str,
    device_id: str,
    device_password: str,
) -> HTTPResponse:
    """Use for handling requests to /switcher/turn_on.

    Args:
      request: ``sanic``'s request object.
      ip_address: the local ip address.
      phone_id: the extracted phone id.
      device_id: the extracted device id.
      device_password: the extracted device password.

    Raises:
      sanic.exceptions.InvalidUsage: when timer is no 1-180 minutes.
      sanic.exceptions.ServerError: when encounterd any error.

    Returns:
      Json object represnting the request status.

      More information is available in the ``Usage`` section.

    Note:
      Accepts arguments as json body or query parameters.

    """
    try:
        minutes = None  # type: Optional[str]
        if request.args and consts.PARAM_MINUTES in request.args:
            minutes = request.args[consts.PARAM_MINUTES][0]
        elif request.json and consts.PARAM_MINUTES in request.json:
            minutes = str(request.json[consts.PARAM_MINUTES])
        if minutes and (int(minutes) < 1 or int(minutes) > 180):
            logger.info("Invalid usage, timer requested is %s", minutes)
            raise InvalidUsage("Can only accept timer for 1 to 180 minutes.",
                               400)
        async with SwitcherV2Api(
                get_running_loop(),
                ip_address,
                phone_id,
                device_id,
                device_password,
        ) as swapi:
            if minutes:
                response = await swapi.control_device(COMMAND_ON, minutes)
            else:
                response = await swapi.control_device(COMMAND_ON)

        if (response
                and response.msg_type == messages.ResponseMessageType.CONTROL):
            return json({consts.KEY_SUCCESSFUL: response.successful})
        return json({
            consts.KEY_SUCCESSFUL: False,
            consts.KEY_MESSAGE: "Failed turning on the device.",
        })
    except ExceptionSet as exc:
        raise ServerError("Failed turning on the device.", 500) from exc
Пример #21
0
 def _get_user_from_database(self, session: str):
     user = self.db.fetchone_query(
         f"SELECT * FROM users WHERE session_id='{session}'")
     if not user:
         raise InvalidUsage('Could not validate session')
     self._validate_user_session(user['user_id'])
     return user
Пример #22
0
 async def patch(self, request):
     try:
         user_id = await get_user_id_by_request(request)
         data = request.json
         new_data = {}
         for k, v in data.items():
             if k not in self.fields:
                 continue
             new_data[k] = v
         for k, v in new_data.items():
             if k in self.unique:
                 res = await self.user_model.check_unique_simple_field(k, v)
                 if res is False:
                     raise InvalidUsage("{} 已被使用".format(v))
         # name need update to follow and friend collection
         doc = await self.user_model.update_by_id(user_id, new_data)
         if not doc:
             return response.json(response_package("500", {"error_id": str(user_id)}))
         for k, v in new_data.items():
             if k in self.update_to_friend_follow:
                 await update_server.update_name(k, v, user_id, self.follower_model, self.friends_model, app,
                                                 self.user_model)
         data = await UserReadModel(data=doc, status="").to_dict()
         return response.json(response_package("200", data))
     except TimeoutError as e:
         return response.json(response_package("999", {"e": str(e)}))
Пример #23
0
async def sign_up(request: Request):
    """
    Sign up
    @param request:
    @return:
    """
    try:
        params = SignUpPostSchema().load(request.json)
    except ValidationError as ex:
        raise InvalidUsage(ex.messages)
    user_repo = UserRepository(request.app.db_client)
    user = user_repo.find_by_email(params["email"])
    if user:
        raise InvalidUsage("User already exists", 422)
    user = user_repo.create(params["email"], params["password"])
    return json(user)
Пример #24
0
    def load_input(self, request):
        if self.url_model:
            try:
                url_model = self.url_model(request.args)
                url_model.validate()
            except BaseError as ex:
                raise InvalidUsage(f'Error in data: {ex.to_primitive()}')
            self.url_params = url_model.to_native()

        if self.body_model:
            try:
                body_model = self.body_model(request.json, strict=True)
                body_model.validate()
            except BaseError as ex:
                raise InvalidUsage(f'Error in data: {ex.to_primitive()}')
            self.body_params = body_model.to_native()
Пример #25
0
def get_form_param(req, key, default=None):
    try:
        return req.form[key][0]
    except KeyError:
        if default is not None:
            return default
        raise InvalidUsage("missing parameter '%s'." % key)
    def get_type_filters(self, list_type: ListType) -> List[TypeFilter]:
        """
        Returns requested type filters or the defaults for the desired ListType
        :param list_type:
        :return:
        """
        if hasattr(self, "json") and isinstance(self.json, dict):
            type_filters_raw = self.json.get("filter", None)

            if type_filters_raw is not None:
                if isinstance(type_filters_raw, str):
                    type_filters_raw = loads(type_filters_raw)

                if not isinstance(type_filters_raw, list):
                    type_filters_raw = [type_filters_raw]

                try:
                    type_filters: List[
                        TypeFilter] = AvailableTypeFilters.from_string_list(
                            type_filters_raw)
                    return type_filters
                except UnknownTypeFilter as e:
                    # Import logger here to prevent circular dependency on module import
                    message = "Received unknown type filter: '{0}'".format(
                        e.unknown_type_filter)
                    logger.error(self.request_id, message, exc_info=e)
                    raise InvalidUsage(message)

        return list_type.to_type_filters()
Пример #27
0
async def list_tails(request, ident):
    """
    List tails files by corresponding rev reg ids: all, by rev reg id, by cred def id, or by issuer DID.

    :param request: Sanic request structure
    :param ident: 'all' for no filter; rev reg id, cred def id, or issuer DID to filter by any such identifier
    :return: JSON array of rev reg ids corresponding to tails files available
    """

    rv = []
    dir_tails = pjoin(dirname(dirname(abspath(__file__))), 'tails')

    if ident == 'all':  # list everything: 'all' is not valid base58 so it can't be any case below
        rv = [basename(link) for link in Tails.links(dir_tails)]
    elif ok_rev_reg_id(ident) and Tails.linked(dir_tails, ident):  # it's a rev reg id
        rv = [ident]
    elif ok_cred_def_id(ident):  # it's a cred def id (starts with issuer DID)
        rv = [basename(link) for link in Tails.links(dir_tails, ident.split(':')[0])
            if rev_reg_id2cred_def_id(basename(link)) == ident]
    elif ok_did(ident):  # it's an issuer DID
        rv = [basename(link) for link in Tails.links(dir_tails, ident)]
    else:
        LOGGER.error("Token %s must be 'all', rev reg id, cred def id, or issuer DID", ident)
        raise InvalidUsage("Token {} must be 'all', rev reg id, cred def id, or issuer DID".format(ident))

    LOGGER.info('Fulfilling GET request listing tails files on filter %s', ident)
    return response.json(rv)
Пример #28
0
async def update_idea(request, id, *args, **kwargs):
    if request.json is not None:
        idea, errors = IdeaSchema().load(request.json)
        if errors is not None and len(errors) > 0:
            raise InvalidUsage(errors)
        else:
            idea.id = id

            if not idea.exists():
                raise InvalidUsage("idea does not exist")
            idea.update()
            idea = Idea.load_by_id(id)
    else:
        raise InvalidUsage("Missing JSON body")

    return response.json(IdeaSchema().dump(idea).data, status=200)
Пример #29
0
    def data_received(self, data):
        # Check for the request itself getting too large and exceeding
        # memory limits
        self._total_request_size += len(data)
        if self._total_request_size > self.request_max_size:
            exception = PayloadTooLarge('Payload Too Large')
            self.write_error(exception)

        # Create parser if this is the first time we're receiving data
        if self.parser is None:
            assert self.request is None
            self.headers = []
            self.parser = HttpRequestParser(self)

        # requests count
        self.state['requests_count'] = self.state['requests_count'] + 1

        # Parse request chunk or close connection
        try:
            self.parser.feed_data(data)
        except HttpParserError:
            message = 'Bad Request'
            if self._debug:
                message += '\n' + traceback.format_exc()
            exception = InvalidUsage(message)
            self.write_error(exception)
Пример #30
0
 def get(self, request, id):
     '''Fetch a cat given its identifier'''
     raise InvalidUsage("Text Exception", status_code=405)
     for cat in CATS:
         if cat['id'] == id:
             return cat
     api.abort(404)