示例#1
0
def get_multi_dict_from_python_dict(resp_headers_dict: dict) -> MultiDictProxy:
    """Construct an :class:`aiohttp.MultiDictProxy` instance from a Python dictionary.

    Note: For now, this method is used for test only.

    .. note::

        Neither Python dictionary nor JSON supports multi-value key.  The response headers returned
        by `aiohttp` is of immutable type :class:`aiohttp.MultiDictProxy` while the one returned by
        `aiohttpretty` is of :class:`aiohttp.MultiDict`.

        WB tests use the :class:`aiohttp.MultiDict` type for both files and folders during modification
        and returns the :class:`aiohttp.MultiDictProxy` type to imitate the behavior of `aiohttp`.

    :param dict resp_headers_dict: the raw response headers dictionary
    :rtype: :class:`aiohttp.MultiDictProxy`
    """

    resp_headers = MultiDict(resp_headers_dict)
    google_hash = resp_headers.get('x-goog-hash', None)
    if google_hash:
        assert verify_raw_google_hash_header(google_hash)
        resp_headers.pop('x-goog-hash')
        google_hash_list = google_hash.split(',')
        for google_hash in google_hash_list:
            resp_headers.add('x-goog-hash', google_hash)

    return MultiDictProxy(resp_headers)
示例#2
0
文件: user_pass.py 项目: bigur/auth
    async def post(self) -> Response:
        request = self.request
        ctype = request.headers.get('content-type')

        logger.debug('Request Content-Type: %s', ctype)

        form: MultiDict

        if ctype == 'application/json':
            try:
                data: Any = await request.json()
                if not isinstance(data, dict):
                    raise ValueError('Invalid request type')
            except ValueError as e:
                logger.warning('Invalid request: %s', e)
                raise HTTPBadRequest(reason='Invalid request') from e
            else:
                form = MultiDict(cast(Dict, data))

        elif ctype == 'application/x-www-form-urlencoded':
            form = (await self.request.post()).copy()

        else:
            raise HTTPBadRequest(reason='Invalid content type')

        logger.debug('Form is: %s', form)

        accepts = parse_accept(request.headers.get('Accept'))
        response_ctype = choice_content_type(
            accepts, ['application/json', 'text/html', 'text/plain'])
        logger.debug('Content-type for response is: %s', response_ctype)

        error: Optional[str] = None
        error_description: Optional[str] = None

        if ('username' in form and 'password' in form):
            # Check incoming parameters
            username = str(form.pop('username')).strip()
            password = str(form.pop('password')).strip()

            # Check fields too long
            if (len(username) > FIELD_LENGTH or len(password) > FIELD_LENGTH):
                logger.warning(
                    'Recieve request with very long login/password field')
                raise HTTPBadRequest()

            # Ensure no redirect to external host
            next_uri = form.get('next')
            if next_uri:
                parsed = urlparse(next_uri)
                if parsed.scheme or parsed.netloc:
                    logger.warning('Trying to do external redirect')
                    raise HTTPBadRequest()

            # Finding user
            logger.debug('Try to find user %s in store', username)

            try:
                user = store.users.get_by_username(username)
            except KeyError:
                logger.warning('User %s not found', username)
                error = 'bigur_invalid_login'
                error_description = 'Invalid login or password'
            else:
                if user.verify_password(password):
                    # Login successful
                    logger.debug('Login for user %s successful', username)

                    if response_ctype == 'application/json':
                        response = json_response({'meta': {'status': 'ok'}})
                    else:
                        # No next parameter, no way to redirect
                        if not next_uri:
                            response = Response(text='Login successful')

                        # Redirecting
                        else:
                            response = Response(status=303,
                                                reason='See Other',
                                                charset='utf-8',
                                                headers={'Location': next_uri})

                    # Set cookie
                    self.set_cookie(self.request, response, user.id)

                    return response

                logger.warning('Password is incorrect for user %s', username)
                error = 'bigur_invalid_login'
                error_description = 'Invalid login or password'

        if response_ctype == 'application/json':
            return json_response({
                'meta': {
                    'status': 'error',
                    'error': error,
                    'message': error_description
                }
            })
        else:
            # Show form
            context = {
                'endpoint':
                self.request.app['config'].get(
                    'http_server.endpoints.login.path'),
                'query':
                form,
                'error':
                error,
                'error_description':
                error_description,
                'prefix':
                request.app['config'].get('http_server.static.prefix', '/')
            }
            return render_template('login_form.j2', self.request, context)