fix(asset): insert_assets 由程序权威赋 task_id + service/endpoint 补建 subdomain/root_domain
- insert_assets 不再把 task_id 暴露给模型/依赖模型传:schema 去掉 task_id,handler 直接用 SetTaskID 设的 t.taskID,避免模型漏传/错传导致资产未归任务或归错任务。 - UpsertHTTPService/UpsertOtherService/UpsertEndpoint 新增 side effect linkHostAssets:把 host 反向登记为独立 root_domain + subdomain 资产(非 apex、非 IP 才建 subdomain);endpoint 原来无任何 side effect,现补建 root_domain/subdomain/IP。 Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
e01b659097
commit
1025938dd9
2 files changed
+29
-13
No files matched your search
@@ -79,7 +79,7 @@ func (t *ToolSet) insertAssets() actool.CoreTool {
|
||||
"auth/technologies/params 都是【追加合并】(append),不会覆盖原有值。\n"+
|
||||
"返回:{results:[{index,id,type}], errors:[{index,error}]}",
|
||||
obj(map[string]any{
|
||||
"task_id": intp("任务 id(可选,用于关联 task_ids)"),
|
||||
// task_id 不暴露给模型:worker 归属哪个 task 由程序经 SetTaskID 权威赋值(见 handler)。
|
||||
"assets": map[string]any{
|
||||
"type": "array",
|
||||
"description": "资产数组,每个元素对应一条资产记录",
|
||||
@@ -158,16 +158,13 @@ func (t *ToolSet) insertAssets() actool.CoreTool {
|
||||
}
|
||||
var a struct {
|
||||
Assets []assetInputItem `json:"assets"`
|
||||
TaskID int64 `json:"task_id"`
|
||||
}
|
||||
if err := json.Unmarshal(in, &a); err != nil {
|
||||
return actool.Errorf("invalid input: " + err.Error()), nil
|
||||
}
|
||||
// use ToolSet.taskID as fallback
|
||||
taskID := a.TaskID
|
||||
if taskID == 0 {
|
||||
taskID = t.taskID
|
||||
}
|
||||
// task_id 由程序权威赋值(worker: SetTaskID),不接受模型传入——避免模型漏传/错传
|
||||
// 导致资产未归任务或归错任务。无任务上下文的调用方(auto/pentest/chat)其 t.taskID=0。
|
||||
taskID := t.taskID
|
||||
|
||||
type result struct {
|
||||
Index int `json:"index"`
|
||||
|
||||
+25
-6
@@ -628,8 +628,8 @@ RETURNING id`,
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// side effects
|
||||
_, _ = s.UpsertRootDomain(UpsertRootDomainReq{Domain: rootDomain, TaskID: req.TaskID})
|
||||
// side effects: register root_domain + subdomain as their own assets too
|
||||
s.linkHostAssets(domain, rootDomain, req.TaskID)
|
||||
if req.IP != "" {
|
||||
var boundDomains []string
|
||||
if domain != "" {
|
||||
@@ -760,12 +760,22 @@ RETURNING id`,
|
||||
TaskID: req.TaskID,
|
||||
})
|
||||
}
|
||||
if rootDomain != "" {
|
||||
_, _ = s.UpsertRootDomain(UpsertRootDomainReq{Domain: rootDomain, TaskID: req.TaskID})
|
||||
}
|
||||
s.linkHostAssets(domain, rootDomain, req.TaskID)
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// linkHostAssets ensures a service/endpoint's host is also registered as its own
|
||||
// root_domain and (when it's a real subdomain, not the apex or an IP) subdomain
|
||||
// asset — so those asset types stay populated and can anchor task scope. Best-effort.
|
||||
func (s *AssetStore) linkHostAssets(domain, rootDomain string, taskID int64) {
|
||||
if rootDomain != "" {
|
||||
_, _ = s.UpsertRootDomain(UpsertRootDomainReq{Domain: rootDomain, TaskID: taskID})
|
||||
}
|
||||
if domain != "" && domain != rootDomain && net.ParseIP(domain) == nil {
|
||||
_, _ = s.UpsertSubdomain(UpsertSubdomainReq{Domain: domain, TaskID: taskID})
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// UpsertEndpoint
|
||||
// =====================================================================
|
||||
@@ -852,7 +862,16 @@ RETURNING id`,
|
||||
normURL, method, domainVal, ipVal, nullableInt(port), rootDomainVal,
|
||||
paramsJSON, companyID, taskIDs, csegVal,
|
||||
).Scan(&id)
|
||||
return id, err
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// side effects: endpoint previously registered none — register its host as
|
||||
// root_domain + subdomain(+IP) so those asset types get populated too.
|
||||
s.linkHostAssets(domain, rootDomain, req.TaskID)
|
||||
if req.IP != "" {
|
||||
_, _ = s.UpsertIP(UpsertIPReq{IP: req.IP, TaskID: req.TaskID})
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
|
||||
Reference in new issue
Block a user