Skip to content

Commit

Permalink
fix: 修改权限问题 #7626
Browse files Browse the repository at this point in the history
  • Loading branch information
guohelu committed Dec 11, 2024
1 parent 5877bb6 commit 48aa0d9
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 99 deletions.
2 changes: 2 additions & 0 deletions config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -890,3 +890,5 @@ def check_engine_admin_permission(request, *args, **kwargs):
ENABLE_TEMPLATE_MARKET = env.ENABLE_TEMPLATE_MARKET
# 流程商店 API 地址
TEMPLATE_MARKET_API_URL = env.TEMPLATE_MARKET_API_URL
# 共享流程最大数量
MAX_NUMBER_SHARED_PROCESSES = env.MAX_NUMBER_SHARED_PROCESSES
2 changes: 2 additions & 0 deletions env.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,5 @@
ENABLE_TEMPLATE_MARKET = False if os.getenv("ENABLE_TEMPLATE_MARKET") is None else True
# 流程商店 API 地址
TEMPLATE_MARKET_API_URL = os.getenv("TEMPLATE_MARKET_API_URL", "")
# 共享流程最大数量
MAX_NUMBER_SHARED_PROCESSES = int(os.getenv("MAX_NUMBER_SHARED_PROCESSES", 10))
2 changes: 1 addition & 1 deletion gcloud/apigw/management/commands/data/api-resources.yml
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ paths:
default:
description: ''
x-bk-apigateway-resource:
isPublic: true
isPublic: false
allowApplyPermission: true
matchSubpath: false
backend:
Expand Down
5 changes: 3 additions & 2 deletions gcloud/apigw/validators/copy_template_across_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def validate(self, request, *args, **kwargs):
if not valid:
return valid, err

if not json.loads(request.body).get("new_project_id") or not json.loads(request.body).get("template_id"):
return False, "new_project_id and template_id is required"
data = json.loads(request.body)
if not data.get("new_project_id") or not data.get("template_id"):
return False, "new_project_id and template_id are required"

return True, ""
8 changes: 4 additions & 4 deletions gcloud/contrib/template_market/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


@admin.register(models.TemplateSharedRecord)
class TemplateMarketAdmin(admin.ModelAdmin):
list_display = ["project_id", "template_id", "scene_instance_id", "creator", "create_at", "extra_info"]
list_filter = ["project_id", "creator", "create_at"]
search_fields = ["project_id", "template_id", "scene_instance_id", "creator"]
class TemplateSharedRecordAdmin(admin.ModelAdmin):
list_display = ["scene_shared_id", "project_id", "templates", "creator", "create_at", "update_at", "extra_info"]
list_filter = ["project_id", "creator", "create_at", "update_at"]
search_fields = ["scene_shared_id", "project_id", "creator"]
7 changes: 4 additions & 3 deletions gcloud/contrib/template_market/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 3.2.15 on 2024-12-10 02:27
# Generated by Django 3.2.15 on 2024-12-11 13:46

from django.db import migrations, models

Expand All @@ -14,11 +14,12 @@ class Migration(migrations.Migration):
name="TemplateSharedRecord",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("scene_shared_id", models.IntegerField(help_text="共享实例id", verbose_name="共享实例id")),
("project_id", models.IntegerField(default=-1, help_text="项目 ID", verbose_name="项目 ID")),
("template_id", models.IntegerField(help_text="模版 ID", verbose_name="模版 ID")),
("scene_instance_id", models.IntegerField(db_index=True, help_text="场景实例 ID", verbose_name="场景实例 ID")),
("templates", models.JSONField(help_text="模板 ID 列表", verbose_name="模板 ID 列表")),
("creator", models.CharField(default="", max_length=32, verbose_name="创建者")),
("create_at", models.DateTimeField(auto_now_add=True, verbose_name="创建时间")),
("update_at", models.DateTimeField(auto_now=True, verbose_name="更新时间")),
("extra_info", models.JSONField(blank=True, null=True, verbose_name="额外信息")),
],
options={
Expand Down
21 changes: 3 additions & 18 deletions gcloud/contrib/template_market/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,19 @@
specific language governing permissions and limitations under the License.
"""


from django.db import models
from django.utils.translation import ugettext_lazy as _


class TemplateSharedRecord(models.Model):
scene_shared_id = models.IntegerField(_("共享实例id"), help_text="共享实例id")
project_id = models.IntegerField(_("项目 ID"), default=-1, help_text="项目 ID")
template_id = models.IntegerField(_("模版 ID"), help_text="模版 ID")
scene_instance_id = models.IntegerField(_("场景实例 ID"), db_index=True, help_text="场景实例 ID")
templates = models.JSONField(_("模板 ID 列表"), help_text="模板 ID 列表")
creator = models.CharField(_("创建者"), max_length=32, default="")
create_at = models.DateTimeField(_("创建时间"), auto_now_add=True)
update_at = models.DateTimeField(verbose_name=_("更新时间"), auto_now=True)
extra_info = models.JSONField(_("额外信息"), blank=True, null=True)

class Meta:
verbose_name = _("模板共享记录 TemplateSharedRecord")
verbose_name_plural = _("模板共享记录 TemplateSharedRecord")

@classmethod
def create(cls, project_id, template_id, scene_instance_id, creator="", extra_info=None):
if not scene_instance_id:
raise ValueError("场景实例 ID 不能为空")

instance = cls(
project_id=project_id,
template_id=template_id,
scene_instance_id=scene_instance_id,
creator=creator,
extra_info=extra_info,
)
instance.save()
return instance
29 changes: 22 additions & 7 deletions gcloud/contrib/template_market/permission.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,44 @@
"""
import logging

from django.db.models import Q
from rest_framework import permissions

from gcloud.conf import settings
from gcloud.contrib.template_market.models import TemplateSharedRecord
from gcloud.iam_auth import IAMMeta
from gcloud.iam_auth.utils import iam_multi_resource_auth_or_raise


class TemplatePreviewPermission(permissions.BasePermission):
def has_permission(self, request, view):
template_id = request.GET.get("template_id")
project_id = request.GET.get("project_id")

if not template_id or not project_id:
logging.warning("Missing required parameters.")
try:
template_id = int(request.GET.get("template_id"))
project_id = int(request.GET.get("project_id"))
except (TypeError, ValueError):
logging.warning("Missing or invalid required parameters.")
return False

record = TemplateSharedRecord.objects.filter(template_id=template_id, project_id=project_id).first()
record = TemplateSharedRecord.objects.filter(
Q(project_id=project_id) & Q(templates__contains=[template_id])
).first()
if record is None:
logging.warning("template_id {} does not exist.".format(template_id))
logging.warning("The specified template could not be found")
return False

return True


class SharedProcessTemplatePermission(permissions.BasePermission):
def has_permission(self, request, view):
username = request.user.username
serializer = view.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)

template_id_list = [template.get("id") for template in serializer.validated_data["templates"]]
if view.action in ["create", "partial_update"]:
iam_multi_resource_auth_or_raise(
username, IAMMeta.FLOW_EDIT_ACTION, template_id_list, "resources_list_for_flows"
)

return settings.ENABLE_TEMPLATE_MARKET
72 changes: 65 additions & 7 deletions gcloud/contrib/template_market/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
specific language governing permissions and limitations under the License.
"""
import json
import logging
from rest_framework import serializers

from gcloud.constants import DATETIME_FORMAT
from gcloud.contrib.template_market.models import TemplateSharedRecord


class TemplatePreviewSerializer(serializers.Serializer):
Expand All @@ -24,15 +26,71 @@ def get_pipeline_tree(self, obj):
return json.dumps(obj.pipeline_tree)


class TemplateSharedRecordSerializer(serializers.Serializer):
class TemplateProjectBaseSerializer(serializers.Serializer):
template_id = serializers.CharField(required=True, help_text="模板id")
project_id = serializers.CharField(required=True, help_text="项目id")
name = serializers.CharField(required=True, help_text="场景名称")
code = serializers.CharField(required=True, help_text="场景标识")
category = serializers.CharField(required=True, help_text="场景分类")
risk_level = serializers.IntegerField(required=True, help_text="风险级别")
labels = serializers.ListField(child=serializers.IntegerField(), required=True, help_text="场景标签列表")
usage_content = serializers.CharField(required=True, help_text="使用说明")


class TemplateSharedRecordSerializer(serializers.ModelSerializer):
project_id = serializers.CharField(required=True, max_length=32, help_text="项目id")
templates = serializers.ListField(required=True, help_text="关联的模板列表")
creator = serializers.CharField(required=False, max_length=32, help_text="创建者")
create_at = serializers.DateTimeField(required=False, help_text="创建时间", format=DATETIME_FORMAT)
update_at = serializers.DateTimeField(required=False, help_text="更新时间", format=DATETIME_FORMAT)
extra_info = serializers.JSONField(required=False, allow_null=True, help_text="额外信息")
id = serializers.IntegerField(required=False, help_text="共享实例id")
name = serializers.CharField(required=True, help_text="共享名称")
code = serializers.CharField(required=True, help_text="共享标识")
category = serializers.CharField(required=True, help_text="共享分类")
risk_level = serializers.IntegerField(required=True, help_text="风险级别")
usage_id = serializers.IntegerField(required=True, help_text="使用说明id")
labels = serializers.ListField(child=serializers.IntegerField(), required=True, help_text="共享标签列表")
usage_content = serializers.JSONField(required=True, help_text="使用说明")

class Meta:
model = TemplateSharedRecord
fields = [
"project_id",
"templates",
"creator",
"create_at",
"update_at",
"extra_info",
"labels",
"usage_content",
"id",
"name",
"code",
"category",
"risk_level",
"usage_id",
]

def convert_templates(self, templates):
return [template.get("id") for template in templates]

def create(self, validated_data):
try:
validated_data["templates"] = self.convert_templates(validated_data["templates"])
return TemplateSharedRecord.objects.create(
scene_shared_id=validated_data["id"],
project_id=validated_data["project_id"],
templates=validated_data["templates"],
creator=validated_data["creator"],
extra_info=validated_data["extra_info"],
)
except Exception:
logging.exception("Failed to create model sharing record")
raise Exception("Failed to create model sharing record")

def update(self, instance, validated_data):
try:
validated_data["templates"] = self.convert_templates(validated_data["templates"])
instance.project_id = validated_data["project_id"]
instance.templates = validated_data["templates"]
instance.creator = validated_data["creator"]
instance.extra_info = validated_data["extra_info"]
instance.save()
except Exception:
logging.exception("Failed to update model sharing record")
raise Exception("Failed to update model sharing record")
39 changes: 39 additions & 0 deletions gcloud/contrib/template_market/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
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 requests

from gcloud.conf import settings


class MarketAPIClient:
def __init__(self):
self.base_url = settings.TEMPLATE_MARKET_API_URL

def _get_url(self, endpoint):
return f"{self.base_url}{endpoint}"

def get_template_list(self):
url = self._get_url("/sre_scene/flow_template_scene/")
response = requests.get(url)
return response.json()

def create_template(self, data):
url = self._get_url("/sre_scene/flow_template_scene/")
response = requests.post(url, json=data)
return response.json()

def patch_template(self, data, scene_shared_id):
url = self._get_url(f"/sre_scene/flow_template_scene/{scene_shared_id}/")
response = requests.patch(url, json=data)
return response.json()
Loading

0 comments on commit 48aa0d9

Please sign in to comment.