Пример #1
0
    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")
Пример #2
0
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
Пример #3
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,
    )
Пример #4
0
 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))
Пример #5
0
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()
Пример #6
0
 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
Пример #7
0
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)
Пример #8
0
 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)
Пример #9
0
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
Пример #10
0
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)
Пример #11
0
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")
Пример #12
0
    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
Пример #13
0
 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
Пример #14
0
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
    )
Пример #15
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.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)
Пример #16
0
 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
Пример #17
0
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",
    }
Пример #18
0
 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))
Пример #19
0
async def get_current_token(request: Request):
    _, token = await utils.AuthDependency()(request,
                                            SecurityScopes(),
                                            return_token=True)
    return token