Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎨完善工具与规则展示相关逻辑与接口 #601

Merged
merged 1 commit into from
Sep 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scripts/deploy/tca_docker_compose.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ function init_main() {
python manage.py createcachetable; \
python manage.py initializedb_open; \
python manage.py initialize_exclude_paths; \
python manage.py loadlibs all --dirname open_source_toollib --ignore-auth; \
python manage.py loadcheckers all --dirname open_source; \
python manage.py loadpackages all --dirname open_source_package;
"
Expand Down
1 change: 1 addition & 0 deletions scripts/server/init_data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ function init_main_data() {
python manage.py initializedb_open
python manage.py initialize_exclude_paths
LOG_INFO "[TCAServer] Init checker config..."
python manage.py loadlibs all --dirname open_source_toollib --ignore-auth >/dev/null
python manage.py loadcheckers all --dirname open_source >/dev/null
python manage.py loadpackages all --dirname open_source_package >/dev/null
LOG_INFO "Init checkertool and checkerpackage successfully"
Expand Down
2 changes: 2 additions & 0 deletions server/projects/main/apps/job/api_urls/v2_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@
# 前缀 /api/v2/jobs/
urlpatterns = [
path("", apis.JobListApiView.as_view(), name="apiv2_job_list"),
path("<int:job_id>/cancel/", apis.JobCancelApiView.as_view(),
name="apiv2_job_cancel"),
path("tasks/", apis.TaskListApiView.as_view(), name="apiv2_task_list"),
]
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
apis.CheckRuleListAPIView.as_view()),
path("allrules/<int:checkrule_id>/",
apis.CheckRuleDetailAPIView.as_view()),
path("allrules/byname/",
apis.CheckRuleDetailByNameAPIView.as_view()),
path("checkprofile/", include(checkprofile_urlpatterns)),
path("checkprofile/checkpackages/", include(checkpackage_urlpatterns)),
]
2 changes: 2 additions & 0 deletions server/projects/main/apps/scan_conf/api_urls/v3_scheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
apis.CheckRuleListAPIView.as_view()),
path("allrules/<int:checkrule_id>/",
apis.CheckRuleDetailAPIView.as_view()),
path("allrules/byname/",
apis.CheckRuleDetailByNameAPIView.as_view()),
path("checkprofile/", include(checkprofile_urlpatterns)),
path("checkprofile/checkpackages/", include(checkpackage_urlpatterns)),
]
42 changes: 40 additions & 2 deletions server/projects/main/apps/scan_conf/apis/v3/scheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from rest_framework import generics, status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import ParseError, NotFound

# 项目内
from apps.scan_conf import models
Expand Down Expand Up @@ -202,16 +203,23 @@ class ScanSchemeCheckProfileRuleCreateAPIView(ScanSchemeCheckProfileRuleBatch):
```python
{
"checkrules": [x], # int, 规则id
"checktool": xx # int, 工具id,可选,如果存在checktool, 则一键添加该工具所有规则,忽略 checkrules
}
```
"""
serializer_class = serializers.CheckPackageRuleAddSerializer

def post(self, request, *args, **kwargs):
serializer, checkpackage, tool_key = self.get_and_check_batch_data(request)
checktool = serializer.validated_data.get("checktool")
checkrules = serializer.validated_data.get("checkrules")
err_message = CheckPackageManager.add_rules(checkpackage, checkrules, request.user, tool_key=tool_key)
message = "已成功添加规则"
if checktool:
CheckPackageManager.add_checktool_rules(checkpackage, checktool, request.user, tool_key=tool_key)
err_message = []
message = "已成功添加工具规则"
else:
err_message = CheckPackageManager.add_rules(checkpackage, checkrules, request.user, tool_key=tool_key)
message = "已成功添加规则"
return Response({
"detail": message,
"err_message": err_message
Expand Down Expand Up @@ -390,3 +398,33 @@ class CheckRuleDetailAPIView(generics.RetrieveAPIView, V3GetModelMixinAPIView):
def get_queryset(self):
tool_key = CheckToolManager.get_tool_key(org=self.get_org())
return CheckRuleManager.filter_pkg_usable(tool_keys=[tool_key])


class CheckRuleDetailByNameAPIView(generics.RetrieveAPIView, V3GetModelMixinAPIView):
"""分析方案-规则配置-有权限使用的规则详情接口,根据工具、规则名称获取规则详情

### get
应用场景:根据工具name和规则real_name获取规则详情

```python
{
checktool_name: '工具真实名称',
checkrule_real_name: '规则真实名称
}
```
"""
permission_classes = [SchemeDefaultPermission]
serializer_class = serializers.CheckRuleSerializer

def get_object(self):
query_params = self.request.query_params
checktool_name = query_params.get("checktool_name")
checkrule_real_name = query_params.get("checkrule_real_name")
if not checktool_name or not checkrule_real_name:
raise ParseError("checktool_name、checkrule_real_name参数必填")
tool_key = CheckToolManager.get_tool_key(org=self.get_org())
checkrule = CheckRuleManager.filter_pkg_usable(tool_keys=[tool_key]) \
.filter(checktool__name=checktool_name, real_name=checkrule_real_name).first()
if checkrule:
return checkrule
raise NotFound("没有找到该规则")
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.1.14 on 2022-09-05 15:34

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('scan_conf', '0003_auto_20220518_1055'),
]

operations = [
migrations.AlterField(
model_name='language',
name='name',
field=models.CharField(choices=[('cpp', 'C/C++'), ('java', 'Java'), ('js', 'JavaScript'), ('oc', 'Objective-C'), ('php', 'PHP'), ('python', 'Python'), ('cs', 'C#'), ('ruby', 'Ruby'), ('kotlin', 'Kotlin'), ('Go', 'Go'), ('Lua', 'Lua'), ('swift', 'Swift'), ('html', 'Html'), ('css', 'Css'), ('ts', 'TypeScript'), ('scala', 'Scala'), ('visualbasic', 'Visual Basic'), ('plsql', 'PL/SQL'), ('cobol', 'COBOL'), ('abap', 'ABAP'), ('tsql', 'T-SQL'), ('flex', 'Flex'), ('rpg', 'RPG'), ('apex', 'Apex'), ('pli', 'PL/I'), ('xml', 'XML'), ('dart', 'Dart'), ('shell', 'Shell'), ('protobuf', 'Protocol Buffers'), ('sql', 'SQL'), ('wasm', 'WebAssembly'), ('rust', 'Rust')], help_text='程序语言', max_length=32, null=True),
),
]
12 changes: 2 additions & 10 deletions server/projects/main/apps/scan_conf/models/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,6 @@ def __str__(self):
return "packagemap-%s-%s" % (self.checkpackage_id, self.checkrule_id)



def get_checkprofile_admins(checkprofile):
"""获取规则集admins,开源版规则集无单独权限
"""
return []


class CheckProfile(CDBaseModel):
"""规则集表
"""
Expand Down Expand Up @@ -216,10 +209,9 @@ def get_checkrules(self):
return (official_pms | custom_pms).distinct()

def get_admins(self):
"""由于规则集依附代码库admin权限,因此该方法获取规则集+对应代码库的admins
开源版规则集无单独的权限
"""获取规则集admins,开源版规则集无单独权限
"""
return get_checkprofile_admins(self)
return []

def get_custom_checkpackage_content(self):
"""自定义规则包内容
Expand Down
20 changes: 20 additions & 0 deletions server/projects/main/apps/scan_conf/serializers/base/pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,26 @@ class CheckProfilePackageAddSerializer(serializers.Serializer):
many=True)


class CheckPackageRuleAddSerializer(serializers.Serializer):
"""用于规则包批量添加规则序列化
"""
checkrules = serializers.ListField(
child=serializers.PrimaryKeyRelatedField(queryset=models.CheckRule.objects.all()),
required=False, allow_null=True, help_text="规则列表"
)
checktool = serializers.PrimaryKeyRelatedField(
queryset=models.CheckTool.objects.all(),
required=False, allow_null=True, help_text="工具"
)

def validate(self, attrs):
checkrules = attrs.get("checkrules")
checktool = attrs.get("checktool")
if not checktool and not checkrules:
raise serializers.ValidationError({"cd_error": "请传入checkrules或checktool"})
return attrs


class CheckPackageRuleUpdateSerializer(serializers.Serializer):
"""用于规则包批量更新规则严重级别、规则参数、状态等序列化
"""
Expand Down
36 changes: 16 additions & 20 deletions server/projects/main/apps/scan_conf/serializers/base/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

# 项目内
from apps.scan_conf import models
from apps.base.serializers import CDBaseModelSerializer, OnlySuperAdminReadField
from apps.base.serializers import CDBaseModelSerializer

logger = logging.getLogger(__name__)

Expand All @@ -29,30 +29,26 @@ class Meta:
fields = ["desc_type", "desc"]


class CheckToolSimpleSerializer(serializers.ModelSerializer):
"""工具简单序列化
class CheckRuleSimpleSerializer(serializers.ModelSerializer):
"""规则简单序列化,用于仅展示规则简要信息,不包含工具信息
"""
display_name = serializers.SerializerMethodField()
scope = serializers.SerializerMethodField()
name = OnlySuperAdminReadField()
category_name = serializers.CharField(source="get_category_display")
severity_name = serializers.CharField(source="get_severity_display")
languages = serializers.SlugRelatedField(help_text="适用语言", slug_field="name", many=True, read_only=True)

def get_display_name(self, checktool):
"""获取工具展示名称
"""
request = self.context.get("request")
user = request.user if request else None
return checktool.get_show_name(user=user)
class Meta:
model = models.CheckRule
fields = ["id", "real_name", "display_name", "rule_title", "severity", "severity_name",
"category", "category_name", "rule_params", "solution", "languages", "disable"]

def get_scope(self, checktool):
"""公有True/私有False工具
"""
if checktool.is_public():
return models.CheckTool.ScopeEnum.PUBLIC
return models.CheckTool.ScopeEnum.PRIVATE

class CheckRuleToolSimpleSerializer(serializers.ModelSerializer):
"""规则的工具简单序列化,用于在规则中序列化显示其工具简要信息
"""

class Meta:
model = models.CheckTool
fields = ["id", "name", "display_name", "scope", "status", "show_display_name", "build_flag"]
fields = ["id", "display_name", "build_flag", "status"]


class CheckRuleSerializer(CDBaseModelSerializer):
Expand All @@ -71,7 +67,7 @@ class SelectStateTypeEnum:
queryset=models.Language.objects.all())
category_name = serializers.CharField(source="get_category_display", read_only=True)
severity_name = serializers.CharField(source="get_severity_display", read_only=True)
checktool = CheckToolSimpleSerializer(read_only=True)
checktool = CheckRuleToolSimpleSerializer(read_only=True)
select_state = serializers.SerializerMethodField()

def get_select_state(self, checkrule):
Expand Down
10 changes: 5 additions & 5 deletions server/projects/main/apps/scan_conf/serializers/v3/pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
# 项目内
from apps.scan_conf import models
from apps.scan_conf.serializers import base
from apps.scan_conf.serializers.v3.rule import CheckRuleSimpleSerializer, CheckRuleToolSimpleSerializer
from apps.base.serializers import CDBaseModelSerializer
from .rule import CheckRuleSimpleSerializer

logger = logging.getLogger(__name__)

Expand All @@ -28,11 +28,10 @@ class CheckProfilePackageAddSerializer(base.CheckProfilePackageAddSerializer):
pass


class CheckPackageRuleAddSerializer(serializers.Serializer):
class CheckPackageRuleAddSerializer(base.CheckPackageRuleAddSerializer):
"""用于规则包批量添加规则序列化
"""
checkrules = serializers.ListField(child=serializers.PrimaryKeyRelatedField(
queryset=models.CheckRule.objects.all()), help_text="规则列表")
pass


class CheckPackageRuleUpdateSerializer(base.CheckPackageRuleUpdateSerializer):
Expand Down Expand Up @@ -90,7 +89,8 @@ class ScanSchemePackageMapSerializer(serializers.ModelSerializer):
"""分析方案-规则配置-规则包与规则的映射序列化
"""
checkrule = CheckRuleSimpleSerializer(read_only=True)
checktool = CheckRuleToolSimpleSerializer(read_only=True)

class Meta:
model = models.PackageMap
exclude = ["checktool"]
fields = "__all__"
29 changes: 14 additions & 15 deletions server/projects/main/apps/scan_conf/serializers/v3/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from rest_framework import serializers

# 项目内
from apps.scan_conf import models
from apps.scan_conf.serializers import base
from apps.scan_conf.core import CheckRuleManager

Expand All @@ -27,29 +26,29 @@ class CheckRuleDescSerializer(base.CheckRuleDescSerializer):
pass


class CheckRuleSimpleSerializer(serializers.ModelSerializer):
"""规则简单序列化
class CheckRuleSimpleSerializer(base.CheckRuleSimpleSerializer):
"""规则简单序列化,用于仅展示规则简要信息,包含规则所属团队信息
"""
category_name = serializers.CharField(source="get_category_display")
severity_name = serializers.CharField(source="get_severity_display")
languages = serializers.SlugRelatedField(help_text="适用语言", slug_field="name", many=True, read_only=True)
org_detail = serializers.SerializerMethodField()

def get_org_detail(self, checkrule):
return CheckRuleManager.get_org_detail(checkrule)

class Meta(base.CheckRuleSimpleSerializer.Meta):
fields = base.CheckRuleSimpleSerializer.Meta.fields + ["org_detail"]

class Meta:
model = models.CheckRule
fields = ["id", "category_name", "severity_name", "display_name", "category", "severity",
"rule_params", "rule_title", "disable", "languages", "solution", "org_detail"]

class CheckRuleToolSimpleSerializer(base.CheckRuleToolSimpleSerializer):
"""规则的工具简单序列化,用于在规则中序列化显示其工具简要信息
"""
pass


class CheckRuleSerializer(CheckRuleSimpleSerializer):
"""规则详情序列化
"""规则详情序列化,用于展示规则的详细信息,包含规则详情和工具信息
"""
checkruledesc = CheckRuleDescSerializer(help_text="规则描述")
checktool = CheckRuleToolSimpleSerializer(read_only=True)

class Meta:
model = models.CheckRule
fields = ["id", "category_name", "severity_name", "display_name", "real_name", "category", "severity",
"rule_params", "rule_title", "disable", "languages", "solution", "org_detail", "checkruledesc"]
class Meta(CheckRuleSimpleSerializer.Meta):
fields = CheckRuleSimpleSerializer.Meta.fields + ["checkruledesc", "checktool"]