Esempio n. 1
0
 async def _driveToken(self, request: Request):
     data = await request.post()
     if data.get('redirect_uri') not in [
             "http://localhost:{}/drive/authorize".format(self._port),
             'urn:ietf:wg:oauth:2.0:oob'
     ]:
         raise HTTPUnauthorized()
     if data.get('grant_type') != 'authorization_code':
         raise HTTPUnauthorized()
     if not self._checkClientIdandSecret(data.get('client_id'),
                                         data.get('client_secret')):
         raise HTTPUnauthorized()
     if data.get('code') != self._drive_auth_code:
         raise HTTPUnauthorized()
     self.generateNewRefreshToken()
     return json_response({
         'access_token':
         self._auth_token,
         'refresh_token':
         self._refresh_token,
         'client_id':
         data.get('client_id'),
         'client_secret':
         self.config.get(Setting.DEFAULT_DRIVE_CLIENT_SECRET),
         'token_expiry':
         self.timeToRfc3339String(self._time.now()),
     })
Esempio n. 2
0
 async def _oAuth2Authorize(self, request: Request):
     query = request.query
     if query.get('client_id') != self.config.get(
             Setting.DEFAULT_DRIVE_CLIENT_ID) and query.get(
                 'client_id') != self._custom_drive_client_id:
         raise HTTPUnauthorized()
     if query.get('scope') != 'https://www.googleapis.com/auth/drive.file':
         raise HTTPUnauthorized()
     if query.get('response_type') != 'code':
         raise HTTPUnauthorized()
     if query.get('include_granted_scopes') != 'true':
         raise HTTPUnauthorized()
     if query.get('access_type') != 'offline':
         raise HTTPUnauthorized()
     if 'state' not in query:
         raise HTTPUnauthorized()
     if 'redirect_uri' not in query:
         raise HTTPUnauthorized()
     if query.get('prompt') != 'consent':
         raise HTTPUnauthorized()
     if query.get('redirect_uri') == 'urn:ietf:wg:oauth:2.0:oob':
         return json_response({"code": self._drive_auth_code})
     url = URL(query.get('redirect_uri')).with_query({
         'code':
         self._drive_auth_code,
         'state':
         query.get('state')
     })
     raise HTTPSeeOther(str(url))
Esempio n. 3
0
async def check_api_permissions(request, permissions):
    try:
        if await api_auth(request, list(permissions)):
            return True
        else:
            return False
    except HTTPUnauthorized:
        reason = "No user with this api key/session found"
        raise HTTPUnauthorized(
            reason=reason,
            body=dumps({
                "Ok": False,
                "Error": reason,
                "status_code": 401
            }),
            content_type="application/json",
        )
    except HTTPForbidden:
        reason = f"Insufficient permissions. Permissions required: {list(permissions)}"
        raise HTTPForbidden(
            reason=reason,
            body=dumps({
                "Ok": False,
                "Error": reason,
                "status_code": 403
            }),
            content_type="application/json",
        )
Esempio n. 4
0
 async def _verifyHeader(self, request) -> bool:
     if request.headers.get("X-Supervisor-Token", None) == self._auth_token:
         return
     if request.headers.get("Authorization",
                            None) == "Bearer " + self._auth_token:
         return
     raise HTTPUnauthorized()
    async def driveRefreshToken(self, request: Request):
        params = await request.post()
        if not self.checkClientIdandSecret(params['client_id'], params['client_secret']):
            raise HTTPUnauthorized()
        if params['refresh_token'] != self.getSetting('drive_refresh_token'):
            raise HTTPUnauthorized()
        if params['grant_type'] != 'refresh_token':
            raise HTTPUnauthorized()

        self.generateNewAccessToken()

        return json_response({
            'access_token': self.settings['drive_auth_token'],
            'expires_in': 3600,
            'token_type': 'doesn\'t matter'
        })
Esempio n. 6
0
async def users_login_get(request: Request) -> Response:
    session_maker = request.app['db_session_manager']
    if 'X-Login' not in request.headers:
        return HTTPUnauthorized()
    if not request.headers['X-Login'] == request.match_info['login']:
        return HTTPForbidden()
    session: Session = session_maker()
    try:
        user = session.query(Users).filter_by(
            login=request.match_info['login']).first()

        if not user:
            return HTTPNotFound()

        params = request.rel_url.query.get('output')
        if params:
            output = [x.strip() for x in params.split(',')]
            user_serialized = UsersSchema(only=output).dump(user)
        else:
            user_serialized = UsersSchema().dump(user)

        return Response(body=json.dumps(user_serialized),
                        headers={'content-type': 'application/json'})

    finally:
        session.close()
Esempio n. 7
0
 async def validate_token(self, token, permissions=[], raise_error=False):
     logger.debug(
         f"validating a token{' for permissions' + permissions if permissions != [] else ''}. Token: {token}"
     )
     user = await find_user_by_token(self.app, token, ["permissions", "username"])
     packed = self.branca.decode(token)
     payload = msgpack.loads(packed, raw=False)
     logger.debug(f"decoded token: {payload}")
     if user == None:
         if raise_error:
             raise HTTPUnauthorized()
         return False
     user_permission_set = set(user.get("permissions", []))
     if not set(payload.get("permissions", [])).issubset(user_permission_set):
         payload["permissions"] = filter(
             lambda permission: permission in user_permission_set,
             payload["permissions"],
         )
     if (
         # check if token has all requested permissions
         not set(permissions).issubset(set(payload.get("permissions", [])))
         # check if user has all requested permissions
         or not set(permissions).issubset(user_permission_set)
     ):
         if raise_error:
             raise HTTPForbidden()
         return False
     logger.debug("Token is valid")
     return True
Esempio n. 8
0
    async def post(request):
        """
        Handle REST API requests to "/api/logout"

        First of all, we check that request contains an "Authorization" header with
        some value, if not - we can't logout user that is not logged in, return an error JSON response.
        Else, if the JWT token exists, we need to decode it to remove the key from the Redis cache
        database. If everything is ok, the user successfully logged out.

        :param request: POST request in JSON representation
        :return: JSON response
        """
        jwt_token = request.headers.get("Authorization")
        if not jwt_token:
            return HTTPUnauthorized()
        try:
            jwt_token = jwt_token.split(" ")[1]
            payload = decode_token(jwt_token)
            if check_cache(payload) is False:
                raise ValueError("Token is not active")
            username = payload.get("name")
            cache.delitem(username)
        except ValueError as not_active:
            return Responses.error(str(not_active))
        except Exception:
            return Responses.error("Token revocation error")
        finally:
            return Responses.success("Successfully logged out")
Esempio n. 9
0
async def statistic_receiver(request: Request):

    auth = request.headers.get('Authorization')

    if not auth:
        raise HTTPUnauthorized()

    secret = auth.replace("Bearer ", '')

    if secret != SECRET:
        raise HTTPForbidden()

    payload = msgpack.unpackb(await request.read(), encoding='utf-8')

    if not isinstance(payload, list):
        raise HTTPBadRequest()

    for metric in payload:
        try:
            name, ts_value = metric
            ts, value = ts_value
            ts = float(ts)
            assert isinstance(value, (int, float, type(None)))
        except:
            log.exception("Invalid data in %r", metric)
            raise HTTPBadRequest()

        QUEUE.append((name, value, ts))

    return Response(content_type='text/plain', status=HTTPStatus.ACCEPTED)
Esempio n. 10
0
async def auth_middleware(request: Request, handler) -> str:
    auth_token = request.headers.get('auth')

    if request.path in public_api_paths or token_is_valid(auth_token):
        return await handler(request)
    else:
        raise HTTPUnauthorized()
Esempio n. 11
0
            async def wrapped(request):
                # set the area property inside the request object
                try:
                    user = request.user
                except AttributeError:
                    # the user of this method is not using it in the intended way
                    raise RuntimeError(
                        "The 'user' property is not set in the request object."
                        "Use the {0}.auth decorator after a '{0}' decorator".
                        format(area_name))
                if not user or user.authenticated is False:
                    raise HTTPUnauthorized()

                if roles and not user.has_any_role(roles):
                    raise HTTPUnauthorized()
                return await f(request)
Esempio n. 12
0
async def verify_authn_challenge(request, ctx: AppConfig,
                                 session: AuthnSession):
    if not session.pending_challenge:
        raise HTTPBadRequest()

    challenge_response =\
        AuthnChallengeResponseRequest.unmarshal_request(await request.json())

    if challenge_response.challenge_id != session.pending_challenge.challenge_id:
        raise ValueError("invalid challenge")

    session.pending_challenge.attempts += 1
    session.changed()
    if session.pending_challenge.attempts > security.MaxVerificationChallengeAttempts:
        session.invalidate()
        raise HTTPForbidden(text="Too many invalid attempts")

    otp_types = [AuthnChallengeType.Email, AuthnChallengeType.SMS]
    if session.pending_challenge.challenge_type in otp_types:
        if challenge_response.passcode != session.pending_challenge.secret:
            raise HTTPUnauthorized(text="Incorrect passcode")
    elif session.pending_challenge.challenge_type is AuthnChallengeType.Password:
        async with op.session(ctx) as ss:
            result = await op.authn.\
                authenticate_user(
                    user_profile_id=session.user_profile_id,
                    password=challenge_response.passcode).\
                execute(ss)
            if not result:
                raise HTTPUnauthorized(text="Incorrect passcode")
    else:
        raise HTTPBadRequest()

    session.clear_pending_challenge()
    async with op.session(ctx) as ss:
        u = await op.user_profile.\
            get_user_profile(user_profile_id=session.user_profile_id).\
            execute(ss)
    if session.required_challenges:
        session.next_challenge_for_user(u)
        return HTTPAccepted(), session.pending_challenge.get_view('public')

    session.authenticated = True
    session.set_role(u.role)
    session.remove_capabilities(Capability.Authenticate)
    return HTTPOk()
 async def _checkDriveHeaders(self, request: Request):
     if self.drive_sleep > 0:
         await asyncio.sleep(self.drive_sleep)
     self._checkDriveError(request)
     if request.headers.get(
             "Authorization",
             "") != "Bearer " + self.getSetting('drive_auth_token'):
         raise HTTPUnauthorized()
Esempio n. 14
0
    async def get(self, request: Request):
        """Handle for GPSLogger message received as GET."""
        hass = request.app['hass']
        data = request.query

        if self._password is not None:
            authenticated = CONF_API_PASSWORD in data and compare_digest(
                self._password, data[CONF_API_PASSWORD])
            if not authenticated:
                raise HTTPUnauthorized()

        if 'latitude' not in data or 'longitude' not in data:
            return ('Latitude and longitude not specified.',
                    HTTP_UNPROCESSABLE_ENTITY)

        if 'device' not in data:
            _LOGGER.error("Device id not specified")
            return ('Device id not specified.', HTTP_UNPROCESSABLE_ENTITY)

        device = data['device'].replace('-', '')
        gps_location = (data['latitude'], data['longitude'])
        accuracy = 200
        battery = -1
        zone_state = async_active_zone(self.hass, float(data['latitude']),
                                       float(data['longitude']), 300)
        if self._ignore_home and zone_state != None and zone_state.entity_id == zone.ENTITY_ID_HOME:
            _LOGGER.warn("drop a gps event, because it near home")
            return

        if 'accuracy' in data:
            accuracy = int(float(data['accuracy']))
        if 'battery' in data:
            battery = float(data['battery'])

        attrs = {}
        if 'speed' in data:
            attrs['speed'] = float(data['speed'])
        if 'direction' in data:
            attrs['direction'] = float(data['direction'])
        if 'altitude' in data:
            attrs['altitude'] = float(data['altitude'])
        if 'provider' in data:
            attrs['provider'] = data['provider']
        if 'activity' in data:
            attrs['activity'] = data['activity']
#{{{dylan
        attrs['update_at'] = int(round(time.time() * 1000))
        #}}}

        hass.async_add_job(
            self.async_see(dev_id=device,
                           gps=gps_location,
                           battery=battery,
                           gps_accuracy=accuracy,
                           attributes=attrs))

        return 'Setting location for {}'.format(device)
Esempio n. 15
0
async def aiohttp_error_middleware(request, handler):
    try:
        response = await handler(request)
        return response
    except BotActionNotImplementedError:
        raise HTTPNotImplemented()
    except PermissionError:
        raise HTTPUnauthorized()
    except KeyError:
        raise HTTPNotFound()
    except Exception:
        raise HTTPInternalServerError()
Esempio n. 16
0
async def auth_required(request) -> str:
    # Only expiration date is validated here,
    # since authenticity of client cert is validated on the TLS level
    # If request is not secure return early with empty identity. ACL provider will catch
    # request as unauthorized due to empty client identity.
    if not request.secure:
        return ""
    if await _validate_cert_date(request):
        identity = await _extract_identity(request)
        request["identity"] = identity
        return identity
    raise HTTPUnauthorized()
Esempio n. 17
0
    async def authenticate(self, request):
        token = re.sub('^Basic *', '', request.headers.get(
            'Authorization', '')) or 'x'
        try:
            _, password = base64.b64decode(token).decode().split(':', 1)
        except (ValueError, UnicodeDecodeError):
            password = ''

        if not secrets.compare_digest(password,
                                      self.settings.admin_basic_auth_password):
            raise HTTPUnauthorized(text='Invalid basic auth',
                                   headers={'WWW-Authenticate': 'Basic'})
Esempio n. 18
0
    async def get(self, request: Request):
        """Handle for GPSLogger message received as GET."""
        hass = request.app['hass']
        data = request.query

        if self._password is not None:
            authenticated = CONF_API_PASSWORD in data and compare_digest(
                self._password,
                data[CONF_API_PASSWORD]
            )
            if not authenticated:
                raise HTTPUnauthorized()

        if 'latitude' not in data or 'longitude' not in data:
            return ('Latitude and longitude not specified.',
                    HTTP_UNPROCESSABLE_ENTITY)

        if 'device' not in data:
            _LOGGER.error("Device id not specified")
            return ('Device id not specified.',
                    HTTP_UNPROCESSABLE_ENTITY)

        device = data['device'].replace('-', '')
        gps_location = (data['latitude'], data['longitude'])
        accuracy = 200
        battery = -1

        if 'accuracy' in data:
            accuracy = int(float(data['accuracy']))
        if 'battery' in data:
            battery = float(data['battery'])

        attrs = {}
        if 'speed' in data:
            attrs['speed'] = float(data['speed'])
        if 'direction' in data:
            attrs['direction'] = float(data['direction'])
        if 'altitude' in data:
            attrs['altitude'] = float(data['altitude'])
        if 'provider' in data:
            attrs['provider'] = data['provider']
        if 'activity' in data:
            attrs['activity'] = data['activity']

        hass.async_add_job(self.async_see(
            dev_id=device,
            gps=gps_location, battery=battery,
            gps_accuracy=accuracy,
            attributes=attrs
        ))

        return 'Setting location for {}'.format(device)
Esempio n. 19
0
async def delete_entries(request):
    if not compare_digest(request.match_info['token'],
                          request.app['settings'].update_token):
        raise HTTPUnauthorized(text='invalid token\n')

    async with request.app['db'].acquire() as conn:
        entries_before = await conn.fetchval('SELECT COUNT(*) from entries')
        logger.info('entries before: %d', entries_before)
        await conn.execute('DELETE FROM entries')

    return Response(
        text=f'all entries deleted, entries before: {entries_before}',
        content_type='text/plain')
Esempio n. 20
0
async def api(request):
    """Check headers for authorization, load JSON/query data and return as JSON."""
    if not request.headers.get('authorization'):
        raise HTTPUnauthorized()

    return json_response({
        'params': {
            'user': int(request.match_info['user']),
            'record': int(request.match_info['record']),
        },
        'query': dict(request.query),
        'data': await request.json(),
    })
Esempio n. 21
0
    def middleware(request):
        if 'AUTHORIZATION' not in request.headers:
            raise HTTPUnauthorized(
                    headers={'WWW-Authenticate': 'Basic realm="flowpanel"'}
            )
        else:
            auth, loginpassword = request.headers['AUTHORIZATION'].split(" ", 2)
            assert auth == "Basic"
            login, password = b64decode(loginpassword).decode('utf-8').split(':', 2)
            # FIXME, validate the password
            request[USER_KEY] = login

        return (yield from handler(request))
Esempio n. 22
0
    async def validate_token(self, token, permissions=None, raise_error=False):
        """Validate if token is valid and has the requested permissions.

        Parameters
        ----------
        token : str
            The token to be validated
        permissions : list(str), default=None
            The permissions that the token must have access to.
        raise_error : bool, default=False
            If True, raise an error if the token is invalid, otherwise just return False
        Returns
        -------
        bool
            True if the token is valid and has the requested permissions, False otherwise
        """
        permissions = permissions if permissions else []
        logger.debug(
            "validating a token%s. Token: %s",
            " for permissions" + permissions if permissions != [] else "",
            token,
        )
        user = await find_user_by_token(self.app, token,
                                        ["permissions", "username"])
        packed = self.branca.decode(token)
        payload = msgpack.loads(packed, raw=False)
        logger.debug("decoded token: %s", payload)
        if user is None:
            if raise_error:
                raise HTTPUnauthorized()
            return False
        user_permission_set = set(user.get("permissions", []))
        if not set(payload.get("permissions",
                               [])).issubset(user_permission_set):
            payload["permissions"] = filter(
                lambda permission: permission in user_permission_set,
                payload["permissions"],
            )
        if (
                # check if token has all requested permissions
                not set(permissions).issubset(
                    set(payload.get("permissions", [])))
                # check if user has all requested permissions
                or not set(permissions).issubset(user_permission_set)):
            if raise_error:
                raise HTTPForbidden()
            return False
        logger.debug("Token is valid")
        return True
async def aiohttp_error_middleware(request, handler):
    try:
        response = await handler(request)
        return response
    except BotActionNotImplementedError:
        raise HTTPNotImplemented()
    except NotImplementedError:
        raise HTTPNotImplemented()
    except PermissionError:
        raise HTTPUnauthorized()
    except KeyError:
        raise HTTPNotFound()
    except HTTPError as error:
        # In the case the integration adapter raises a specific HTTPError
        raise error
    except Exception:
        raise HTTPInternalServerError()
Esempio n. 24
0
async def login(request):

    next_url = request.query.get('next', '/')
    LOG.debug('next URL: %s', next_url)

    request_session = await get_session(request)
    access_token = request_session.get('access_token')
    if access_token:
        # Redirect only if the token is valid
        await get_user_info_and_redirect(access_token, next_url,
                                         request_session)

    # Otherwise, we don't have a token (yet)
    # A redirect response will be raised
    await do_login(request, request_session, next_url)

    # If we reach here, we have an invalid token, even after creating it
    raise HTTPUnauthorized(reason='Failed to obtain access token.')
    async def _http_authenticate_request(self, request: Request) -> bool:
        # pylint: disable=no-member
        try:
            if not await self._credential_provider.is_authentication_disabled(
            ):
                auth_header = request.headers.get(self._AUTH_HEADER_NAME)
                channel_id = request.headers.get(self._CHANNEL_ID_HEADER_NAME)

                if not auth_header:
                    await self._write_unauthorized_response(
                        self._AUTH_HEADER_NAME)
                    return False
                if not channel_id:
                    await self._write_unauthorized_response(
                        self._CHANNEL_ID_HEADER_NAME)
                    return False

                claims_identity = await JwtTokenValidation.validate_auth_header(
                    auth_header,
                    self._credential_provider,
                    self._channel_provider,
                    channel_id,
                )

                if not claims_identity.is_authenticated:
                    raise HTTPUnauthorized()

                self._credentials = (
                    self._credentials
                    or await self._BotFrameworkAdapter__get_app_credentials(
                        self.settings.app_id,
                        AuthenticationConstants.
                        TO_CHANNEL_FROM_BOT_OAUTH_SCOPE,
                    ))

                # Add ServiceURL to the cache of trusted sites in order to allow token refreshing.
                self._credentials.trust_service_url(
                    claims_identity.claims.get(
                        AuthenticationConstants.SERVICE_URL_CLAIM))
                self.claims_identity = claims_identity
            return True
        except Exception as error:
            raise error
Esempio n. 26
0
    async def wrapped(*args, **kwargs):
        if middlewares.request_property is ...:
            raise RuntimeError('Incorrect usage of decorator.'
                               'Please initialize middleware first')
        request = args[-1]

        if isinstance(request, View):
            request = request.request

        if not isinstance(request, BaseRequest):  # pragma: no cover
            raise RuntimeError(
                'Incorrect usage of decorator.'
                'Expect web.BaseRequest as an argument')

        if not request.get(middlewares.request_property):
            raise HTTPUnauthorized(reason='Authorization required')

        session_id = (await get_from_cache(request.app['cache'], key=request['token']))
        if not session_id or session_id.decode('utf8') != request.cookies.get('sessionID'):
            raise HTTPForbidden(reason='Session has expired')

        return await func(*args, **kwargs)
Esempio n. 27
0
    async def post(self) -> Response:
        """Authorize route function."""
        db = self.request.app["db"]
        try:
            body = await self.request.json()
        except json.decoder.JSONDecodeError as e:
            raise HTTPBadRequest(reason="Invalid data in request body.") from e

        # Process:
        try:
            await AuthorizationService.authorize(db, body.get("token", None),
                                                 body.get("roles", None))
        except (
                InvalidTokenException,
                InvalidInputException,
                IncompleteTokenException,
        ) as e:
            logging.debug(traceback.format_exc())
            raise HTTPUnauthorized(reason=str(e)) from e
        except (UserNotAuthorizedException, InconsistentTokenException) as e:
            raise HTTPForbidden(reason=str(e)) from e

        return Response(status=204)
Esempio n. 28
0
async def init_authn_session(request, ctx: AppConfig, session: AuthnSession):
    sr = InitiateAuthnSessionRequest.unmarshal_request(await request.json())

    async with op.session(ctx) as ss:
        if sr.principal_type is AuthnPrincipalType.Email:
            u = await op.user_profile.get_user_profile(
                email_address=sr.principal_name).execute(ss)
            session.require_challenge(AuthnChallengeType.Email)
        elif sr.principal_type is AuthnPrincipalType.Phone:
            u = await op.user_profile.get_user_profile(
                phone_number=sr.principal_name).execute(ss)
            session.require_challenge(AuthnChallengeType.SMS)
        else:
            raise ValueError(sr.principal_type)

    if u is None:
        raise HTTPUnauthorized()

    session.user_profile_id = u.user_profile_id
    if u.role in {UserRole.Superuser, UserRole.Manager, UserRole.Creator}:
        session.require_challenge(AuthnChallengeType.Password)

    session.add_capabilities(Capability.Authenticate)
    return HTTPOk()
    async def _connect_web_socket(self, bot: Bot, request: Request,
                                  ws_response: WebSocketResponse):
        if not request:
            raise TypeError("request can't be None")
        if ws_response is None:
            raise TypeError("ws_response can't be None")

        if not bot:
            raise TypeError(
                f"'bot: {bot.__class__.__name__}' argument can't be None")

        if not ws_response.can_prepare(request):
            raise HTTPBadRequest(text="Upgrade to WebSocket is required.")

        if not await self._http_authenticate_request(request):
            raise HTTPUnauthorized(text="Request authentication failed.")

        try:
            await ws_response.prepare(request)

            bf_web_socket = AiohttpWebSocket(ws_response)

            request_handler = StreamingRequestHandler(bot, self, bf_web_socket)

            if self.request_handlers is None:
                self.request_handlers = []

            self.request_handlers.append(request_handler)

            await request_handler.listen()
        except Exception as error:
            import traceback  # pylint: disable=import-outside-toplevel

            traceback.print_exc()
            raise Exception(
                f"Unable to create transport server. Error: {str(error)}")
Esempio n. 30
0
async def update(request):
    if not compare_digest(request.match_info['token'],
                          request.app['settings'].update_token):
        raise HTTPUnauthorized(text='invalid token\n')
    r = StreamResponse()
    r.content_type = 'text/html'
    await r.prepare(request)
    divider = '>'
    if 'html' in request.headers.get('Accept', ''):
        divider = '>'
        await r.write(STREAM_HEAD)

    async def log(msg):
        logger.info(msg)
        try:
            await r.write(
                f'{datetime.now():%H:%M:%S} {divider} {msg}\n'.encode())
        except RuntimeError as e:
            logger.warning('unable to write to response: %s', e)

    start, finish = int(request.match_info['start']), int(
        request.match_info['finish'])
    await update_index(start, finish, request.app['db'], log)
    return r