def test_check_authorization(self): self.clear_lru_cache() security_scopes = SecurityScopes(["resources:get"]) token_data = check_authorization(security_scopes, self.infinite_resources_get_token) self.assertEqual( token_data, TokenData(scopes=security_scopes.scopes, user_name="test")) security_scopes = SecurityScopes(["resources:put"]) with self.assertRaises(HTTPException) as he: check_authorization(security_scopes, self.infinite_resources_get_token) self.assertEqual(he.exception.status_code, status.HTTP_401_UNAUTHORIZED) self.assertEqual(he.exception.detail, "Not enough permissions") token_data = check_authorization( security_scopes, self.infinite_resources_get_update_token) self.assertEqual( token_data, TokenData(scopes=["resources:get", "resources:put"], user_name="test"), ) security_scopes = SecurityScopes() check_authorization(security_scopes, self.infinite_resources_get_token) with self.assertRaises(HTTPException) as he: check_authorization(security_scopes, "1234567890abdcef") self.assertEqual(he.exception.status_code, status.HTTP_401_UNAUTHORIZED) self.assertEqual(he.exception.detail, "Could not validate credentials")
async def products_count( request: Request, store: Optional[int] = None, category: Optional[str] = "", min_price: Optional[Decimal] = None, max_price: Optional[Decimal] = None, sale: Optional[bool] = False, ): query = models.Product.query if sale: query = (query.select_from( models.Product.join(models.DiscountxProduct).join( models.Discount)).having( func.count(models.DiscountxProduct.product_id) > 0).where( models.Discount.end_date > utils.now())) if store is None: user = await utils.AuthDependency()(request, SecurityScopes( ["product_management"])) query = query.where(models.Product.user_id == user.id) else: query = query.where(models.Product.store_id == store) if category and category != "all": query = query.where(models.Product.category == category) if min_price is not None: query = query.where(models.Product.price >= min_price) if max_price is not None: query = query.where(models.Product.price <= max_price) return await (query.with_only_columns([ db.db.func.count(distinct(models.Product.id)) ]).order_by(None).gino.scalar()) or 0
async def get_products( request: Request, pagination: pagination.Pagination = Depends(), store: Optional[int] = None, category: Optional[str] = "", min_price: Optional[Decimal] = None, max_price: Optional[Decimal] = None, sale: Optional[bool] = False, ): try: user = await utils.AuthDependency()(request, SecurityScopes( ["product_management"])) except HTTPException: if store is None: raise user = None return await pagination.paginate( models.Product, user.id if user else None, store, category, min_price, max_price, sale, postprocess=crud.products_add_related, )
async def on_connect(self, websocket, **kwargs): await websocket.accept() self.channel_name = secrets.token_urlsafe(32) self.access_token = None self.user = None try: self.object_id = int(websocket.path_params["model_id"]) if self.REQUIRE_AUTH: self.access_token = websocket.query_params["token"] except (ValueError, KeyError): await websocket.close(code=WS_1008_POLICY_VIOLATION) return if self.REQUIRE_AUTH: try: self.user = await utils.authorization.AuthDependency( token=self.access_token )(None, SecurityScopes([f"{self.NAME}_management"])) except HTTPException: await websocket.close(code=WS_1008_POLICY_VIOLATION) return self.object = await utils.database.get_object(self.MODEL, self.object_id, self.user, raise_exception=False) if not self.object: await websocket.close(code=WS_1008_POLICY_VIOLATION) return if await self.maybe_exit_early(websocket): return self.subscriber, self.channel = await utils.redis.make_subscriber( f"{self.NAME}:{self.object_id}") settings.loop.create_task(self.poll_subs(websocket))
async def test_get_current_access(init_test_db, token_data, scope, expected_access, exception): # Create a token for the access we'll want to retrieve if isinstance(token_data, str): token = token_data else: _data = {"sub": str(token_data['id']), "scopes": token_data['scope'].split()} token = await security.create_access_token(_data) # Check that we retrieve the correct access if exception: with pytest.raises(HTTPException): access = await deps.get_current_access(SecurityScopes([scope]), token=token) else: access = await deps.get_current_access(SecurityScopes([scope]), token=token) if isinstance(expected_access, int): assert access.dict() == AccessRead(**ACCESS_TABLE[expected_access]).dict()
async def post( model: create_model, # type: ignore, request: Request, ): try: user = await auth_dependency(request, SecurityScopes(scopes["post"])) except HTTPException: if post_auth: raise user = None try: if custom_methods.get("post"): obj = await custom_methods["post"](model, user) else: obj = await orm_model.create(**model.dict()) # type: ignore except ( asyncpg.exceptions.UniqueViolationError, asyncpg.exceptions.NotNullViolationError, asyncpg.exceptions.ForeignKeyViolationError, ) as e: raise HTTPException(422, e.message) if background_tasks_mapping.get("post"): background_tasks_mapping["post"].send(obj.id) return obj
async def get_server_settings(request: Request, ssh_settings: Optional[ schemes.SSHSettings] = None): if not ssh_settings: await utils.AuthDependency()(request, SecurityScopes(["server_management"])) ssh_settings = settings.SSH_SETTINGS return ssh_ext.collect_server_settings(ssh_settings)
async def get_one(self, model_id: int, request: Request): try: user = await self.auth_dependency(request, SecurityScopes(self.scopes["get_one"])) except HTTPException: if self.get_one_auth: raise user = None return await self._get_one(model_id, user)
async def get_services(request: Request): try: user = await utils.AuthDependency()(request, SecurityScopes( ["server_management"])) except HTTPException: user = None return tor_ext.TorService.services_dict if user else tor_ext.TorService.anonymous_services_dict
async def get_services(request: Request): try: user = await utils.authorization.AuthDependency()( request, SecurityScopes(["server_management"])) except HTTPException: user = None key = "services_dict" if user else "anonymous_services_dict" async with utils.redis.wait_for_redis(): return await tor_ext.get_data(key, {}, json_decode=True)
async def authenticate_request(request, scopes=[]): try: await utils.AuthDependency()(request, SecurityScopes(scopes)) except HTTPException: if scopes: raise allow_anonymous_configurator = (await utils.get_setting( schemes.Policy)).allow_anonymous_configurator if not allow_anonymous_configurator: raise HTTPException(422, "Anonymous configurator access disallowed")
def test_check_authorization_jwt_error(self, mocked_jwt): mocked_jwt.decode.side_effect = JWTError with self.assertRaises(HTTPException) as he: check_authorization(SecurityScopes(), self.infinite_resources_get_token) self.assertEqual(he.exception.status_code, status.HTTP_401_UNAUTHORIZED) self.assertEqual(he.exception.detail, "Could not validate credentials") mocked_jwt.decode.side_effect = None
async def post(model: self.create_model, request: Request, background_tasks: BackgroundTasks): try: user = await self.auth_dependency(request, SecurityScopes(self.scopes["post"])) except HTTPException: if self.post_auth: raise user = None with safe_db_write(): if self.custom_methods.get("post"): obj = await self.custom_methods["post"](model, user) else: obj = await self.orm_model.create(**model.dict()) # type: ignore # pragma: no cover if self.background_tasks_mapping.get("post"): background_tasks.add_task(self.background_tasks_mapping["post"], obj.id) return obj
async def products_count( request: Request, pagination: pagination.Pagination = Depends(), store: Optional[int] = None, category: Optional[str] = "", min_price: Optional[Decimal] = None, max_price: Optional[Decimal] = None, sale: Optional[bool] = False, ): user = None if store is None: user = await utils.authorization.AuthDependency()(request, SecurityScopes(["product_management"])) return await utils.database.paginate_object( models.Product, pagination, user, store, category, min_price, max_price, sale, count_only=True )
async def get_products( request: Request, pagination: pagination.Pagination = Depends(), store: Optional[int] = None, category: Optional[str] = "", min_price: Optional[Decimal] = None, max_price: Optional[Decimal] = None, sale: Optional[bool] = False, ): try: user = await utils.authorization.AuthDependency()(request, SecurityScopes(["product_management"])) except HTTPException: if store is None: raise user = None return await utils.database.paginate_object(models.Product, pagination, user, store, category, min_price, max_price, sale)
async def post(model: self.create_model, request: Request): try: user = await self.auth_dependency( request, SecurityScopes(self.scopes["post"])) except HTTPException: if self.post_auth: raise user = None if self.custom_methods.get("post"): obj = await self.custom_methods["post"](model, user) else: obj = await utils.database.create_object( self.orm_model, model, user) if self.background_tasks_mapping.get("post"): await events.event_handler.publish( self.background_tasks_mapping["post"], {"id": obj.id}) return obj
async def create_token( request: Request, token_data: Optional[ schemes.HTTPCreateLoginToken] = schemes.HTTPCreateLoginToken(), ): token = None try: user, token = await utils.AuthDependency()(request, SecurityScopes(), return_token=True) except HTTPException: user, status = await utils.authenticate_user(token_data.email, token_data.password) if not user: raise HTTPException(401, { "message": "Unauthorized", "status": status }) token_data = token_data.dict() strict = token_data.pop("strict") if "server_management" in token_data[ "permissions"] and not user.is_superuser: if strict: raise HTTPException( 422, "This application requires access to server settings") token_data["permissions"].remove("server_management") if token and "full_control" not in token.permissions: for permission in token_data["permissions"]: if permission not in token.permissions: raise HTTPException(403, "Not enough permissions") token = await models.Token.create( **schemes.CreateDBToken(user_id=user.id, **token_data).dict()) return { **schemes.Token.from_orm(token).dict(), "access_token": token.id, "token_type": "bearer", }
async def on_connect(self, websocket, **kwargs): await websocket.accept() self.channel_name = secrets.token_urlsafe(32) try: self.wallet_id = int(websocket.path_params["model_id"]) self.access_token = websocket.query_params["token"] except (ValueError, KeyError): await websocket.close(code=WS_1008_POLICY_VIOLATION) return try: self.user = await utils.AuthDependency(token=self.access_token)( None, SecurityScopes(["wallet_management"])) except HTTPException: await websocket.close(code=WS_1008_POLICY_VIOLATION) return self.wallet = (await models.Wallet.query.where( models.Wallet.id == self.wallet_id ).where(models.Wallet.user_id == self.user.id).gino.first()) if not self.wallet: await websocket.close(code=WS_1008_POLICY_VIOLATION) return self.subscriber, self.channel = await utils.make_subscriber( f"wallet:{self.wallet_id}") settings.loop.create_task(self.poll_subs(websocket))
async def get_current_token(request: Request): _, token = await utils.AuthDependency()(request, SecurityScopes(), return_token=True) return token