diff --git a/config/default.py b/config/default.py index 911fe0b52e..20386f5bb9 100644 --- a/config/default.py +++ b/config/default.py @@ -831,3 +831,6 @@ def check_engine_admin_permission(request, *args, **kwargs): # 任务列表过滤失败任务最大天数 TASK_LIST_STATUS_FILTER_DAYS = env.BKPAAS_TASK_LIST_STATUS_FILTER_DAYS + +# 支持限制接口的 app +ALLOWED_LIMITED_API_APPS = env.ALLOWED_LIMITED_API_APPS diff --git a/env.py b/env.py index 85c1af5bf0..3ced6b6cdf 100644 --- a/env.py +++ b/env.py @@ -120,3 +120,6 @@ # 默认六个月 BKPAAS_TASK_LIST_STATUS_FILTER_DAYS = int(os.getenv("BKPAAS_TASK_LIST_STATUS_FILTER_DAYS", 180)) + +# 支持限制接口的 app +ALLOWED_LIMITED_API_APPS = [app for app in os.getenv("BKAPP_ALLOWED_LIMITED_API_APPS", "").split(",") if app] diff --git a/gcloud/apigw/decorators.py b/gcloud/apigw/decorators.py index eb0c7a15e4..e082adb00c 100644 --- a/gcloud/apigw/decorators.py +++ b/gcloud/apigw/decorators.py @@ -36,6 +36,11 @@ def check_white_apps(request): return app_whitelist.has(app_code) +def check_allowed_limited_api_apps(request): + app_code = getattr(request.app, settings.APIGW_MANAGER_APP_CODE_KEY) + return app_code in getattr(settings, "ALLOWED_LIMITED_API_APPS", []) + + def inject_user(request): user_model = get_user_model() @@ -57,6 +62,7 @@ def mark_request_whether_is_trust(view_func): @wraps(view_func) def wrapper(request, *args, **kwargs): setattr(request, "is_trust", check_white_apps(request)) + setattr(request, "allow_limited_apis", check_allowed_limited_api_apps(request)) try: inject_user(request) diff --git a/gcloud/apigw/views/import_project_template.py b/gcloud/apigw/views/import_project_template.py index 6654c19bd4..5bde3abd07 100644 --- a/gcloud/apigw/views/import_project_template.py +++ b/gcloud/apigw/views/import_project_template.py @@ -10,8 +10,6 @@ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ - - import ujson as json from apigw_manager.apigw.decorators import apigw_require from blueapps.account.decorators import login_exempt @@ -19,17 +17,12 @@ from django.views.decorators.http import require_POST from gcloud import err_code -from gcloud.apigw.decorators import ( - mark_request_whether_is_trust, - project_inject, - return_json_response, -) +from gcloud.apigw.decorators import mark_request_whether_is_trust, project_inject, return_json_response from gcloud.apigw.views.utils import logger +from gcloud.iam_auth import IAMMeta, get_iam_client, res_factory from gcloud.tasktmpl3.models import TaskTemplate -from gcloud.template_base.utils import ( - format_import_result_to_response_data, - read_encoded_template_data, -) +from gcloud.template_base.utils import format_import_result_to_response_data, read_encoded_template_data +from iam import Action, Request, Subject @login_exempt @@ -40,13 +33,28 @@ @project_inject @mark_request_whether_is_trust def import_project_template(request, project_id): - if not request.is_trust: + if not request.is_trust and not request.allow_limited_apis: return { "result": False, "message": "you have no permission to call this api.", "code": err_code.REQUEST_FORBIDDEN_INVALID.code, } + # 针对非trust请求,校验用户是否有权限 + if not request.is_trust and request.allow_limited_apis: + iam = get_iam_client() + subject = Subject("user", request.user.username) + create_action = Action(IAMMeta.FLOW_CREATE_ACTION) + project_resources = res_factory.resources_for_project(request.project.id) + create_request = Request(IAMMeta.SYSTEM_ID, subject, create_action, project_resources, {}) + allowed = iam.is_allowed(create_request) + if not allowed: + return { + "result": False, + "message": f"user {request.user.username} have no permission to call this api.", + "code": err_code.REQUEST_FORBIDDEN_INVALID.code, + } + try: req_data = json.loads(request.body) except Exception: @@ -71,7 +79,7 @@ def import_project_template(request, project_id): operator=request.user.username, ) except Exception as e: - logger.exception("[API] import common tempalte error: {}".format(e)) + logger.exception("[API] import template error: {}".format(e)) return { "result": False, "message": "invalid flow data or error occur, please contact administrator",