From fcc274d67907ca87dd7e124c794e8ea7a03b0776 Mon Sep 17 00:00:00 2001 From: GareArc Date: Tue, 22 Apr 2025 02:54:30 -0400 Subject: [PATCH] fix: add filter in installedapp list api --- api/controllers/console/explore/error.py | 6 +++++ .../console/explore/installed_app.py | 27 +++++++++++++++++-- api/controllers/console/explore/wraps.py | 3 ++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/api/controllers/console/explore/error.py b/api/controllers/console/explore/error.py index 18221b7797..1e05ff4206 100644 --- a/api/controllers/console/explore/error.py +++ b/api/controllers/console/explore/error.py @@ -23,3 +23,9 @@ class AppSuggestedQuestionsAfterAnswerDisabledError(BaseHTTPException): error_code = "app_suggested_questions_after_answer_disabled" description = "Function Suggested questions after answer disabled." code = 403 + + +class AppAccessDeniedError(BaseHTTPException): + error_code = "access_denied" + description = "App access denied." + code = 403 diff --git a/api/controllers/console/explore/installed_app.py b/api/controllers/console/explore/installed_app.py index 86550b2bdf..f533389378 100644 --- a/api/controllers/console/explore/installed_app.py +++ b/api/controllers/console/explore/installed_app.py @@ -1,20 +1,26 @@ +import logging from datetime import UTC, datetime from typing import Any from flask import request from flask_login import current_user # type: ignore -from flask_restful import Resource, inputs, marshal_with, reqparse # type: ignore +from flask_restful import (Resource, inputs, marshal_with, # type: ignore + reqparse) from sqlalchemy import and_ from werkzeug.exceptions import BadRequest, Forbidden, NotFound from controllers.console import api from controllers.console.explore.wraps import InstalledAppResource -from controllers.console.wraps import account_initialization_required, cloud_edition_billing_resource_check +from controllers.console.wraps import (account_initialization_required, + cloud_edition_billing_resource_check) from extensions.ext_database import db from fields.installed_app_fields import installed_app_list_fields from libs.login import login_required from models import App, InstalledApp, RecommendedApp from services.account_service import TenantService +from services.app_service import AppService +from services.enterprise.enterprise_service import EnterpriseService +from services.feature_service import FeatureService class InstalledAppsListApi(Resource): @@ -48,6 +54,23 @@ class InstalledAppsListApi(Resource): for installed_app in installed_apps if installed_app.app is not None ] + + # filter out apps that user doesn't have access to + if FeatureService.get_system_features().webapp_auth.enabled: + user_id = current_user.id + res = [] + for installed_app in installed_app_list: + app_code = AppService.get_app_code_by_id(str(installed_app["app"].id)) + if EnterpriseService.WebAppAuth.is_user_allowed_to_access_webapp( + user_id=user_id, + app_code=app_code, + ): + res.append(installed_app) + installed_app_list = res + logging.info( + f"installed_app_list: {installed_app_list}, user_id: {user_id}" + ) + installed_app_list.sort( key=lambda app: ( -app["is_pinned"], diff --git a/api/controllers/console/explore/wraps.py b/api/controllers/console/explore/wraps.py index 4fbf4092fd..548343a258 100644 --- a/api/controllers/console/explore/wraps.py +++ b/api/controllers/console/explore/wraps.py @@ -5,6 +5,7 @@ from flask_login import current_user # type: ignore from flask_restful import Resource # type: ignore from werkzeug.exceptions import NotFound +from controllers.console.explore.error import AppAccessDeniedError from controllers.console.wraps import account_initialization_required from extensions.ext_database import db from libs.login import login_required @@ -67,7 +68,7 @@ def user_allowed_to_access_app(view=None): ) logging.info(f"res: {res}") if not res: - raise ValueError("User not allowed to access this app") + raise AppAccessDeniedError() return view(installed_app, *args, **kwargs)