Skip to content

fix: 修改接口联调问题 --story=135517916 - #836

Merged
dengyh merged 5 commits into
TencentBlueKing:developfrom
guohelu:develop_0728
Jul 29, 2026
Merged

fix: 修改接口联调问题 --story=135517916#836
dengyh merged 5 commits into
TencentBlueKing:developfrom
guohelu:develop_0728

Conversation

@guohelu

@guohelu guohelu commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review 总结

本 PR 主要新增了批量删除模板接口、模板/任务列表的标签过滤功能、标签列表的 include_children 参数,并清理了旧的 sdk_label 相关 API 资源。文档和 api-resources.yml 已同步更新。

主要问题:

  • ⚠️ get_task_list 未对远程调用结果做成功判断即访问嵌套字段,可能导致 500
  • ⚠️ get_template_listidlabel 同时传入时 id__in 会被覆盖
  • BatchDeleteTemplateSerializer 缺少 max_length 限制
  • batch_delete_template 错误信息建议使用 ugettext_lazy

整体代码结构清晰,权限配置合理(apigw default backend + appVerifiedRequired),文档同步完整。

Comment thread bkflow/apigw/views/get_task_list.py Outdated
client = TaskComponentClient(space_id=space_id)
result = client.task_list(data=data)
label_ids = []
for item in result["data"]["results"]:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ 此处直接访问 result["data"]["results"],未检查 result.get("result") 是否为 True。若 client.task_list 返回错误响应(如下游超时),会触发 KeyError 导致 500。建议加 if not result.get("result"): return result 提前返回。

Comment thread bkflow/apigw/views/get_template_list.py Outdated
template_ids_subquery = TemplateLabelRelation.objects.filter(label_id__in=label_ids).values_list(
"template_id", flat=True
)
filter_kwargs["id__in"] = Subquery(template_ids_subquery)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ 当请求同时传入 idlabel 参数时,两者都会设置 filter_kwargs["id__in"],后处理的会覆盖前者。建议对 id 筛选和 label 筛选使用不同的 queryset filter 策略(如分开 .filter() 调用),或检测冲突取交集。



class BatchDeleteTemplateSerializer(serializers.Serializer):
template_ids = serializers.ListField(help_text=_("模板ID列表"), required=True, child=serializers.IntegerField())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template_ids 缺少 max_length 限制,恶意调用方可传入超大列表导致 DB 压力。建议参考项目中 task_id_list 的做法,添加 max_length=50(或合理上限)。

failed_data["root_template_info"] = dict(sub_root_map)

if failed_data:
return {"result": False, "data": failed_data, "code": err_code.VALIDATION_ERROR.code, "message": "模板被引用,无法删除"}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✨ 硬编码中文错误信息 "模板被引用,无法删除" 建议使用 ugettext_lazy("模板被引用,无法删除") 保持国际化一致性。

trigger_ids = Trigger.objects.filter(template_id__in=template_ids).values_list("id", flat=True)
Trigger.objects.batch_delete_by_ids(space_id=space_id, trigger_ids=list(trigger_ids))
TemplateLabelRelation.objects.filter(template_id__in=template_ids).delete()
except Exception as e:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ 捕获裸 Exception 并直接返回 str(e) 可能泄露内部实现细节(如 DB 表名、SQL 片段)。建议添加日志记录完整异常栈,对外只返回通用错误提示。

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review 总结(增量)

本次增量审查针对新推送的提交。之前报告的部分问题已修复,但 get_task_list 中的条件判断逻辑出现了新的严重 bug。

已解决的问题:

  • get_template_listidlabel 同时传入时 id__in 覆盖问题已通过链式 .filter() 解决
  • batch_delete_template 错误信息已使用 ugettext_lazy

新发现问题:

  • 🚨 get_task_listif not result.get("result") 条件反转,导致成功时跳过标签富化、失败时访问不存在的字段触发 500
  • ⚠️ get_label_ids_by_names 新增 space_id 过滤后遗漏默认标签(space_id=-1
  • BatchDeleteTemplateSerializer.template_ids 仍缺少 max_length 限制

Comment thread bkflow/apigw/views/get_task_list.py Outdated

client = TaskComponentClient(space_id=space_id)
result = client.task_list(data=data)
if not result.get("result"):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 条件反转:if not result.get("result") 表示调用失败时才进入标签富化逻辑,成功时反而跳过。应改为 if result.get("result")。当前逻辑在失败响应上访问 result["data"]["results"] 会触发 KeyError 导致 500。

Comment thread bkflow/label/models.py Outdated
for keyword in labels:
q_objects |= Q(name__icontains=keyword)
label_ids = list(Label.objects.filter(q_objects).values_list("id", flat=True))
label_ids = list(Label.objects.filter(q_objects, space_id=space_id).values_list("id", flat=True))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ 新增 space_id=space_id 过滤后,默认标签(space_id=-1)将无法被匹配到。参考 label/views.py:52 的做法,建议改为 space_id__in=[-1, space_id],与项目中其他标签查询的语义保持一致。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 此问题已在最新提交 b481b06 中解决,现在使用 space_id__in=[-1, space_id] 过滤。



class BatchDeleteTemplateSerializer(serializers.Serializer):
template_ids = serializers.ListField(help_text=_("模板ID列表"), required=True, child=serializers.IntegerField())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template_ids 仍缺少 max_length 限制,恶意调用方可传入超大列表导致 DB 压力。建议添加 max_length=50(或合理上限)。

@codecov-commenter

codecov-commenter commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 44.53782% with 66 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.60%. Comparing base (0b4016d) to head (4da513d).
⚠️ Report is 18 commits behind head on develop.

Files with missing lines Patch % Lines
bkflow/apigw/views/batch_delete_template.py 30.43% 48 Missing ⚠️
bkflow/apigw/views/get_template_list.py 12.50% 14 Missing ⚠️
bkflow/apigw/views/get_task_list.py 75.00% 3 Missing ⚠️
bkflow/template/serializers/template.py 66.66% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #836      +/-   ##
===========================================
- Coverage    83.83%   83.60%   -0.24%     
===========================================
  Files          323      324       +1     
  Lines        20617    20722     +105     
===========================================
+ Hits         17285    17324      +39     
- Misses        3332     3398      +66     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review 总结(增量)

本次针对最新提交 4d3b922 的增量审查。

已解决的问题:

  • get_task_listif not result.get("result") 条件反转 bug 已修复为 if result.get("result")

仍未解决的问题(已在先前评论中指出,不重复报告):

  • get_label_ids_by_names 使用 space_id=space_id 遗漏默认标签(space_id=-1
  • BatchDeleteTemplateSerializer.template_ids 缺少 max_length 限制

新发现问题:

  • ⚠️ bkflow/interface/task/view.py:70:与 apigw/views/get_task_list.py 相同的问题——未检查 result.get("result") 即访问 result["data"]["results"]apigw 侧已在本 PR 中修复(加了 if result.get("result"): 保护),建议此处也做相同处理,避免下游超时时 KeyError 导致 500。

整体来看,本次提交正确修复了关键的条件反转 bug,标签富化逻辑现在可以正常工作。

query_params = request.query_params.copy()
labels = request.query_params.get("label", "")
label_ids = Label.get_label_ids_by_names(labels)
label_ids = Label.get_label_ids_by_names(labels, space_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ 本方法在下方 line 70 直接访问 result["data"]["results"] 未做成功判断。apigw/views/get_task_list.py 已在本 PR 中修复(加了 if result.get("result"): 保护),建议此处也做相同处理,避免下游超时时 KeyError 导致 500。

Comment on lines +96 to +104
with transaction.atomic():
Template.objects.filter(space_id=space_id, id__in=template_ids, is_deleted=False).update(is_deleted=True)
clear_result = clear_scope_webhooks([str(tid) for tid in template_ids])
if not clear_result["result"]:
message = clear_result["message"]
raise Exception(message)
trigger_ids = Trigger.objects.filter(template_id__in=template_ids).values_list("id", flat=True)
Trigger.objects.batch_delete_by_ids(space_id=space_id, trigger_ids=list(trigger_ids))
TemplateLabelRelation.objects.filter(template_id__in=template_ids).delete()

@dengyh dengyh Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template_ids 未校验归属空间:只有 Template 软删带了 space_id 过滤,clear_scope_webhooks、Trigger 删除、TemplateLabelRelation.delete() 都只按 template_id 过滤。空间 A 的 app 传入空间 B 的 template_ids 时,B 的模板删不掉,但它的 Webhook / 周期触发器 / 标签关联会被删,接口仍返回 result: True(实测 Template 更新 0 行、标签关联删除 1 行)。上面引用检查里的 Template.objects.filter(id__in=all_needed_template_ids) 同样缺空间过滤,会带出其它空间的模板名。

建议先收敛出本空间的 id 再执行清理:

valid_ids = set(Template.objects.filter(space_id=space_id, id__in=template_ids, is_deleted=False).values_list("id", flat=True))
if set(template_ids) - valid_ids:
    return {"result": False, "code": err_code.VALIDATION_ERROR.code, "message": _("模板不存在或不属于当前空间")}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 此问题已在最新提交 b481b06 中解决。现在先收敛 valid_ids(校验归属空间),后续所有操作(DecisionTable、Trigger、TemplateLabelRelation、clear_scope_webhooks)均基于 valid_ids 执行,不再存在跨空间误操作风险。

Comment thread bkflow/label/models.py Outdated
for keyword in labels:
q_objects |= Q(name__icontains=keyword)
label_ids = list(Label.objects.filter(q_objects).values_list("id", flat=True))
label_ids = list(Label.objects.filter(q_objects, space_id=space_id).values_list("id", flat=True))

@dengyh dengyh Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space_id=space_id 会排除默认标签(space_id=-1),但列表侧用的是 space_id__in=[-1, space_id]get_label_list.py:30label/views.py:52)——默认标签列表里可见,按名字却筛不到。叠加本 PR 把空结果改成 filter(id__in=[]),按默认标签筛选模板会从「返回全部」变成「返回空列表」。

建议:Label.objects.filter(q_objects, space_id__in=[-1, space_id])

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review 总结(增量)

本次针对最新提交 b481b06 的增量审查。

已解决的问题:

  • get_label_ids_by_namesspace_id 过滤已修复为 space_id__in=[-1, space_id],默认标签现在可被正确匹配
  • batch_delete_template 跨空间安全问题已修复:新增 valid_ids 归属校验,所有子操作均使用 valid_ids + space_id 过滤

新发现问题:

  • 🚨 bkflow/label/models.py:177s.strip 缺少括号,应为 s.strip()。方法引用恒为 truthy,导致空字符串不会被过滤,后续会以空串构建 Q(name__icontains="") 匹配所有标签

仍未解决的问题(已在先前评论中指出,不重复报告):

  • interface/task/view.py:70 未做 result.get("result") 成功判断
  • batch_delete_templateraise Exception(message) 可能泄露内部信息
  • BatchDeleteTemplateSerializer.template_ids 缺少 max_length 限制

Comment thread bkflow/label/models.py Outdated
def get_label_ids_by_names(names, space_id):
"""通过标签名称列表获取对应的标签ID列表"""
labels = [s.strip() for s in re.split(r"[,\s]+", names) if s.strip()]
labels = [s.strip() for s in re.split(r"[,\s]+", names) if s.strip]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 s.strip 缺少括号,应为 s.strip()。方法引用(bound method)恒为 truthy,不会过滤掉空字符串,导致空串进入 Q(name__icontains="") 匹配所有标签——标签筛选将完全失效。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 此问题已在最新提交 4da513d 中解决,s.strip 已修正为 s.strip()

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review 总结(增量)

本次针对最新提交 4da513d 的增量审查。

已解决的问题:

  • bkflow/label/models.py:177s.strip 缺少括号的 bug 已修复为 s.strip(),标签过滤功能现在可以正确工作

仍未解决的问题(已在先前评论中指出,不重复报告):

  • interface/task/view.py:70 未做 result.get("result") 成功判断即访问嵌套字段
  • BatchDeleteTemplateSerializer.template_ids 缺少 max_length 限制
  • batch_delete_templateraise Exception(message) 可能泄露内部信息

本次无新发现问题。 最新提交精准修复了先前报告的 Critical 级别 bug,代码变更正确且最小化。

@dengyh
dengyh merged commit a0bdfb7 into TencentBlueKing:develop Jul 29, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants