From c204e00ebcfc182b1e4a46e2f94c869d7be934fe Mon Sep 17 00:00:00 2001 From: aecsocket <43144841+aecsocket@users.noreply.github.com> Date: Wed, 19 Aug 2026 15:56:47 +0900 Subject: [PATCH] add sibling traces --- .../moderation/technical-review/rules.vue | 2 + ...2ad488032235981bc118532ad1094701eae2d.json | 120 +++++++++++++++++ ...3526bf321a861f42b59c9b21c6f50196d3158.json | 124 +++++++++++++++++ ...65fd5165d02ebcc0f8454554cbd870e4ddb42.json | 120 ----------------- ...04666378d1d24981ab8113badded16fb63413.json | 118 ---------------- ...ba93c7016b2a6f18aa4f22ea57f604d82c1da.json | 114 ---------------- ...306aad5e2d79f1bb4bf144d48933f7fa1ee83.json | 126 ++++++++++++++++++ .../moderation/tech_review/rules_scan.rs | 72 +++++++++- .../api-client/src/modules/labrinth/types.ts | 19 +-- 9 files changed, 454 insertions(+), 361 deletions(-) create mode 100644 apps/labrinth/.sqlx/query-448ba47493dc3b83b33ce83316c2ad488032235981bc118532ad1094701eae2d.json create mode 100644 apps/labrinth/.sqlx/query-6cbc61717a4ac5dd6d1b07137643526bf321a861f42b59c9b21c6f50196d3158.json delete mode 100644 apps/labrinth/.sqlx/query-7e7e2e9f67158b94eb62834cbfd65fd5165d02ebcc0f8454554cbd870e4ddb42.json delete mode 100644 apps/labrinth/.sqlx/query-8537362d9c11e437ada9ce97bb604666378d1d24981ab8113badded16fb63413.json delete mode 100644 apps/labrinth/.sqlx/query-b536d7870ba77ace55e309938c3ba93c7016b2a6f18aa4f22ea57f604d82c1da.json create mode 100644 apps/labrinth/.sqlx/query-e8ea2268b7d3e4ec1741bfc0312306aad5e2d79f1bb4bf144d48933f7fa1ee83.json diff --git a/apps/frontend/src/pages/moderation/technical-review/rules.vue b/apps/frontend/src/pages/moderation/technical-review/rules.vue index 325e29cc44..71120d0725 100644 --- a/apps/frontend/src/pages/moderation/technical-review/rules.vue +++ b/apps/frontend/src/pages/moderation/technical-review/rules.vue @@ -460,6 +460,7 @@ const TEST_INPUTS: Labrinth.TechReview.Internal.RuleInput[] = [ symbol_count: 42, }, }, + sibling_traces: [], scan: { delphi_version: 17, }, @@ -494,6 +495,7 @@ const TEST_INPUTS: Labrinth.TechReview.Internal.RuleInput[] = [ host: 'telemetry.example.com', }, }, + sibling_traces: [], scan: { delphi_version: 18, }, diff --git a/apps/labrinth/.sqlx/query-448ba47493dc3b83b33ce83316c2ad488032235981bc118532ad1094701eae2d.json b/apps/labrinth/.sqlx/query-448ba47493dc3b83b33ce83316c2ad488032235981bc118532ad1094701eae2d.json new file mode 100644 index 0000000000..750071379b --- /dev/null +++ b/apps/labrinth/.sqlx/query-448ba47493dc3b83b33ce83316c2ad488032235981bc118532ad1094701eae2d.json @@ -0,0 +1,120 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n detail.key,\n issue.issue_type,\n detail.severity AS \"severity: DelphiSeverity\",\n detail.jar,\n detail.file_path,\n detail.data AS \"data: Json>\",\n COALESCE(sibling_traces.traces, '[]'::jsonb)\n AS \"sibling_traces!: Json>\",\n report.delphi_version,\n file.size AS \"size?\",\n file.id AS \"file_id?\",\n version.id AS \"version_id?\",\n version.mod_id AS \"project_id?\",\n COALESCE(version_metadata.project_types, ARRAY[]::text[])\n AS \"project_types!: Vec\",\n COALESCE(version_metadata.loaders, ARRAY[]::text[])\n AS \"loaders!: Vec\",\n COALESCE(file_hashes.hashes, '{}'::jsonb)\n AS \"hashes!: Json>\"\n FROM delphi_report_issue_details detail\n INNER JOIN delphi_report_issues issue ON issue.id = detail.issue_id\n INNER JOIN delphi_reports report ON report.id = issue.report_id\n LEFT JOIN LATERAL (\n SELECT\n jsonb_agg(\n jsonb_build_object(\n 'key', sibling_detail.key,\n 'issue_type', sibling_issue.issue_type,\n 'severity', sibling_detail.severity,\n 'jar', sibling_detail.jar,\n 'file_path', sibling_detail.file_path,\n 'data', sibling_detail.data\n )\n ORDER BY sibling_detail.id\n ) AS traces\n FROM delphi_report_issues sibling_issue\n INNER JOIN delphi_report_issue_details sibling_detail\n ON sibling_detail.issue_id = sibling_issue.id\n WHERE sibling_issue.report_id = issue.report_id\n AND sibling_detail.id != detail.id\n ) sibling_traces ON TRUE\n LEFT JOIN files file ON file.id = report.file_id\n LEFT JOIN versions version ON version.id = file.version_id\n LEFT JOIN LATERAL (\n SELECT\n ARRAY_AGG(\n DISTINCT project_type.name::text\n ORDER BY project_type.name::text\n ) FILTER (WHERE project_type.name IS NOT NULL)\n AS project_types,\n ARRAY_AGG(\n DISTINCT loader.loader\n ORDER BY loader.loader\n ) AS loaders\n FROM loaders_versions loader_version\n INNER JOIN loaders loader\n ON loader.id = loader_version.loader_id\n LEFT JOIN loaders_project_types loader_project_type\n ON loader_project_type.joining_loader_id = loader_version.loader_id\n LEFT JOIN project_types project_type\n ON project_type.id = loader_project_type.joining_project_type_id\n WHERE loader_version.version_id = version.id\n ) version_metadata ON TRUE\n LEFT JOIN LATERAL (\n SELECT\n jsonb_object_agg(algorithm, encode(hash, 'hex')) AS hashes\n FROM hashes\n WHERE hashes.file_id = file.id\n ) file_hashes ON TRUE\n WHERE detail.id = $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "key", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "issue_type", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "severity: DelphiSeverity", + "type_info": { + "Custom": { + "name": "delphi_severity", + "kind": { + "Enum": [ + "hidden", + "low", + "medium", + "high", + "severe", + "malware" + ] + } + } + } + }, + { + "ordinal": 3, + "name": "jar", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "file_path", + "type_info": "Text" + }, + { + "ordinal": 5, + "name": "data: Json>", + "type_info": "Jsonb" + }, + { + "ordinal": 6, + "name": "sibling_traces!: Json>", + "type_info": "Jsonb" + }, + { + "ordinal": 7, + "name": "delphi_version", + "type_info": "Int4" + }, + { + "ordinal": 8, + "name": "size?", + "type_info": "Int4" + }, + { + "ordinal": 9, + "name": "file_id?", + "type_info": "Int8" + }, + { + "ordinal": 10, + "name": "version_id?", + "type_info": "Int8" + }, + { + "ordinal": 11, + "name": "project_id?", + "type_info": "Int8" + }, + { + "ordinal": 12, + "name": "project_types!: Vec", + "type_info": "TextArray" + }, + { + "ordinal": 13, + "name": "loaders!: Vec", + "type_info": "VarcharArray" + }, + { + "ordinal": 14, + "name": "hashes!: Json>", + "type_info": "Jsonb" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + false, + false, + true, + false, + false, + null, + false, + false, + false, + false, + false, + null, + null, + null + ] + }, + "hash": "448ba47493dc3b83b33ce83316c2ad488032235981bc118532ad1094701eae2d" +} diff --git a/apps/labrinth/.sqlx/query-6cbc61717a4ac5dd6d1b07137643526bf321a861f42b59c9b21c6f50196d3158.json b/apps/labrinth/.sqlx/query-6cbc61717a4ac5dd6d1b07137643526bf321a861f42b59c9b21c6f50196d3158.json new file mode 100644 index 0000000000..674e9196aa --- /dev/null +++ b/apps/labrinth/.sqlx/query-6cbc61717a4ac5dd6d1b07137643526bf321a861f42b59c9b21c6f50196d3158.json @@ -0,0 +1,124 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n detail.id,\n detail.key,\n issue.issue_type,\n detail.severity AS \"severity: DelphiSeverity\",\n detail.jar,\n detail.file_path,\n detail.data AS \"data: Json>\",\n COALESCE(sibling_traces.traces, '[]'::jsonb)\n AS \"sibling_traces!: Json>\",\n report.delphi_version,\n file.size AS \"size?\",\n file.id AS \"file_id?\",\n version.id AS \"version_id?\",\n version.mod_id AS \"project_id?\",\n COALESCE(version_metadata.project_types, ARRAY[]::text[])\n AS \"project_types!: Vec\",\n COALESCE(version_metadata.loaders, ARRAY[]::text[])\n AS \"loaders!: Vec\",\n COALESCE(file_hashes.hashes, '{}'::jsonb)\n AS \"hashes!: Json>\"\n FROM delphi_report_issue_details detail\n INNER JOIN delphi_report_issues issue ON issue.id = detail.issue_id\n INNER JOIN delphi_reports report ON report.id = issue.report_id\n LEFT JOIN LATERAL (\n SELECT\n jsonb_agg(\n jsonb_build_object(\n 'key', sibling_detail.key,\n 'issue_type', sibling_issue.issue_type,\n 'severity', sibling_detail.severity,\n 'jar', sibling_detail.jar,\n 'file_path', sibling_detail.file_path,\n 'data', sibling_detail.data\n )\n ORDER BY sibling_detail.id\n ) AS traces\n FROM delphi_report_issues sibling_issue\n INNER JOIN delphi_report_issue_details sibling_detail\n ON sibling_detail.issue_id = sibling_issue.id\n WHERE sibling_issue.report_id = issue.report_id\n AND sibling_detail.id != detail.id\n ) sibling_traces ON TRUE\n LEFT JOIN files file ON file.id = report.file_id\n LEFT JOIN versions version ON version.id = file.version_id\n LEFT JOIN (\n SELECT\n loader_version.version_id,\n ARRAY_AGG(\n DISTINCT project_type.name::text\n ORDER BY project_type.name::text\n ) FILTER (WHERE project_type.name IS NOT NULL)\n AS project_types,\n ARRAY_AGG(\n DISTINCT loader.loader\n ORDER BY loader.loader\n ) AS loaders\n FROM loaders_versions loader_version\n INNER JOIN loaders loader\n ON loader.id = loader_version.loader_id\n LEFT JOIN loaders_project_types loader_project_type\n ON loader_project_type.joining_loader_id = loader_version.loader_id\n LEFT JOIN project_types project_type\n ON project_type.id = loader_project_type.joining_project_type_id\n GROUP BY loader_version.version_id\n ) version_metadata\n ON version_metadata.version_id = version.id\n LEFT JOIN (\n SELECT\n file_id,\n jsonb_object_agg(algorithm, encode(hash, 'hex')) AS hashes\n FROM hashes\n GROUP BY file_id\n ) file_hashes ON file_hashes.file_id = file.id\n ORDER BY detail.id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "key", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "issue_type", + "type_info": "Text" + }, + { + "ordinal": 3, + "name": "severity: DelphiSeverity", + "type_info": { + "Custom": { + "name": "delphi_severity", + "kind": { + "Enum": [ + "hidden", + "low", + "medium", + "high", + "severe", + "malware" + ] + } + } + } + }, + { + "ordinal": 4, + "name": "jar", + "type_info": "Text" + }, + { + "ordinal": 5, + "name": "file_path", + "type_info": "Text" + }, + { + "ordinal": 6, + "name": "data: Json>", + "type_info": "Jsonb" + }, + { + "ordinal": 7, + "name": "sibling_traces!: Json>", + "type_info": "Jsonb" + }, + { + "ordinal": 8, + "name": "delphi_version", + "type_info": "Int4" + }, + { + "ordinal": 9, + "name": "size?", + "type_info": "Int4" + }, + { + "ordinal": 10, + "name": "file_id?", + "type_info": "Int8" + }, + { + "ordinal": 11, + "name": "version_id?", + "type_info": "Int8" + }, + { + "ordinal": 12, + "name": "project_id?", + "type_info": "Int8" + }, + { + "ordinal": 13, + "name": "project_types!: Vec", + "type_info": "TextArray" + }, + { + "ordinal": 14, + "name": "loaders!: Vec", + "type_info": "VarcharArray" + }, + { + "ordinal": 15, + "name": "hashes!: Json>", + "type_info": "Jsonb" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + false, + false, + false, + true, + false, + false, + null, + false, + false, + false, + false, + false, + null, + null, + null + ] + }, + "hash": "6cbc61717a4ac5dd6d1b07137643526bf321a861f42b59c9b21c6f50196d3158" +} diff --git a/apps/labrinth/.sqlx/query-7e7e2e9f67158b94eb62834cbfd65fd5165d02ebcc0f8454554cbd870e4ddb42.json b/apps/labrinth/.sqlx/query-7e7e2e9f67158b94eb62834cbfd65fd5165d02ebcc0f8454554cbd870e4ddb42.json deleted file mode 100644 index 14a9377c81..0000000000 --- a/apps/labrinth/.sqlx/query-7e7e2e9f67158b94eb62834cbfd65fd5165d02ebcc0f8454554cbd870e4ddb42.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n detail.id,\n detail.key,\n issue.issue_type,\n detail.severity AS \"severity: DelphiSeverity\",\n detail.jar,\n detail.file_path,\n detail.data AS \"data: Json>\",\n report.delphi_version,\n file.size AS \"size?\",\n file.id AS \"file_id?\",\n version.id AS \"version_id?\",\n version.mod_id AS \"project_id?\",\n COALESCE(version_metadata.project_types, ARRAY[]::text[])\n AS \"project_types!: Vec\",\n COALESCE(version_metadata.loaders, ARRAY[]::text[])\n AS \"loaders!: Vec\",\n COALESCE(file_hashes.hashes, '{}'::jsonb)\n AS \"hashes!: Json>\"\n FROM delphi_report_issue_details detail\n INNER JOIN delphi_report_issues issue ON issue.id = detail.issue_id\n INNER JOIN delphi_reports report ON report.id = issue.report_id\n LEFT JOIN files file ON file.id = report.file_id\n LEFT JOIN versions version ON version.id = file.version_id\n LEFT JOIN LATERAL (\n SELECT\n ARRAY_AGG(\n DISTINCT project_type.name::text\n ORDER BY project_type.name::text\n ) FILTER (WHERE project_type.name IS NOT NULL)\n AS project_types,\n ARRAY_AGG(\n DISTINCT loader.loader\n ORDER BY loader.loader\n ) AS loaders\n FROM loaders_versions loader_version\n INNER JOIN loaders loader\n ON loader.id = loader_version.loader_id\n LEFT JOIN loaders_project_types loader_project_type\n ON loader_project_type.joining_loader_id = loader_version.loader_id\n LEFT JOIN project_types project_type\n ON project_type.id = loader_project_type.joining_project_type_id\n WHERE loader_version.version_id = version.id\n ) version_metadata ON TRUE\n LEFT JOIN LATERAL (\n SELECT\n jsonb_object_agg(algorithm, encode(hash, 'hex')) AS hashes\n FROM hashes\n WHERE hashes.file_id = file.id\n ) file_hashes ON TRUE\n WHERE detail.id = ANY($1::bigint[])\n ORDER BY detail.id\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "key", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "issue_type", - "type_info": "Text" - }, - { - "ordinal": 3, - "name": "severity: DelphiSeverity", - "type_info": { - "Custom": { - "name": "delphi_severity", - "kind": { - "Enum": [ - "hidden", - "low", - "medium", - "high", - "severe", - "malware" - ] - } - } - } - }, - { - "ordinal": 4, - "name": "jar", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "file_path", - "type_info": "Text" - }, - { - "ordinal": 6, - "name": "data: Json>", - "type_info": "Jsonb" - }, - { - "ordinal": 7, - "name": "delphi_version", - "type_info": "Int4" - }, - { - "ordinal": 8, - "name": "size?", - "type_info": "Int4" - }, - { - "ordinal": 9, - "name": "file_id?", - "type_info": "Int8" - }, - { - "ordinal": 10, - "name": "version_id?", - "type_info": "Int8" - }, - { - "ordinal": 11, - "name": "project_id?", - "type_info": "Int8" - }, - { - "ordinal": 12, - "name": "project_types!: Vec", - "type_info": "TextArray" - }, - { - "ordinal": 13, - "name": "loaders!: Vec", - "type_info": "VarcharArray" - }, - { - "ordinal": 14, - "name": "hashes!: Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Int8Array" - ] - }, - "nullable": [ - false, - false, - false, - false, - true, - false, - false, - false, - true, - true, - true, - true, - null, - null, - null - ] - }, - "hash": "7e7e2e9f67158b94eb62834cbfd65fd5165d02ebcc0f8454554cbd870e4ddb42" -} diff --git a/apps/labrinth/.sqlx/query-8537362d9c11e437ada9ce97bb604666378d1d24981ab8113badded16fb63413.json b/apps/labrinth/.sqlx/query-8537362d9c11e437ada9ce97bb604666378d1d24981ab8113badded16fb63413.json deleted file mode 100644 index 1102be54f7..0000000000 --- a/apps/labrinth/.sqlx/query-8537362d9c11e437ada9ce97bb604666378d1d24981ab8113badded16fb63413.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n detail.id,\n detail.key,\n issue.issue_type,\n detail.severity AS \"severity: DelphiSeverity\",\n detail.jar,\n detail.file_path,\n detail.data AS \"data: Json>\",\n report.delphi_version,\n file.size AS \"size?\",\n file.id AS \"file_id?\",\n version.id AS \"version_id?\",\n version.mod_id AS \"project_id?\",\n COALESCE(version_metadata.project_types, ARRAY[]::text[])\n AS \"project_types!: Vec\",\n COALESCE(version_metadata.loaders, ARRAY[]::text[])\n AS \"loaders!: Vec\",\n COALESCE(file_hashes.hashes, '{}'::jsonb)\n AS \"hashes!: Json>\"\n FROM delphi_report_issue_details detail\n INNER JOIN delphi_report_issues issue ON issue.id = detail.issue_id\n INNER JOIN delphi_reports report ON report.id = issue.report_id\n LEFT JOIN files file ON file.id = report.file_id\n LEFT JOIN versions version ON version.id = file.version_id\n LEFT JOIN (\n SELECT\n loader_version.version_id,\n ARRAY_AGG(\n DISTINCT project_type.name::text\n ORDER BY project_type.name::text\n ) FILTER (WHERE project_type.name IS NOT NULL)\n AS project_types,\n ARRAY_AGG(\n DISTINCT loader.loader\n ORDER BY loader.loader\n ) AS loaders\n FROM loaders_versions loader_version\n INNER JOIN loaders loader\n ON loader.id = loader_version.loader_id\n LEFT JOIN loaders_project_types loader_project_type\n ON loader_project_type.joining_loader_id = loader_version.loader_id\n LEFT JOIN project_types project_type\n ON project_type.id = loader_project_type.joining_project_type_id\n GROUP BY loader_version.version_id\n ) version_metadata\n ON version_metadata.version_id = version.id\n LEFT JOIN (\n SELECT\n file_id,\n jsonb_object_agg(algorithm, encode(hash, 'hex')) AS hashes\n FROM hashes\n GROUP BY file_id\n ) file_hashes ON file_hashes.file_id = file.id\n ORDER BY detail.id\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "key", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "issue_type", - "type_info": "Text" - }, - { - "ordinal": 3, - "name": "severity: DelphiSeverity", - "type_info": { - "Custom": { - "name": "delphi_severity", - "kind": { - "Enum": [ - "hidden", - "low", - "medium", - "high", - "severe", - "malware" - ] - } - } - } - }, - { - "ordinal": 4, - "name": "jar", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "file_path", - "type_info": "Text" - }, - { - "ordinal": 6, - "name": "data: Json>", - "type_info": "Jsonb" - }, - { - "ordinal": 7, - "name": "delphi_version", - "type_info": "Int4" - }, - { - "ordinal": 8, - "name": "size?", - "type_info": "Int4" - }, - { - "ordinal": 9, - "name": "file_id?", - "type_info": "Int8" - }, - { - "ordinal": 10, - "name": "version_id?", - "type_info": "Int8" - }, - { - "ordinal": 11, - "name": "project_id?", - "type_info": "Int8" - }, - { - "ordinal": 12, - "name": "project_types!: Vec", - "type_info": "TextArray" - }, - { - "ordinal": 13, - "name": "loaders!: Vec", - "type_info": "VarcharArray" - }, - { - "ordinal": 14, - "name": "hashes!: Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false, - false, - false, - false, - true, - false, - false, - false, - false, - false, - false, - false, - null, - null, - null - ] - }, - "hash": "8537362d9c11e437ada9ce97bb604666378d1d24981ab8113badded16fb63413" -} diff --git a/apps/labrinth/.sqlx/query-b536d7870ba77ace55e309938c3ba93c7016b2a6f18aa4f22ea57f604d82c1da.json b/apps/labrinth/.sqlx/query-b536d7870ba77ace55e309938c3ba93c7016b2a6f18aa4f22ea57f604d82c1da.json deleted file mode 100644 index 1d7013755a..0000000000 --- a/apps/labrinth/.sqlx/query-b536d7870ba77ace55e309938c3ba93c7016b2a6f18aa4f22ea57f604d82c1da.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n detail.key,\n issue.issue_type,\n detail.severity AS \"severity: DelphiSeverity\",\n detail.jar,\n detail.file_path,\n detail.data AS \"data: Json>\",\n report.delphi_version,\n file.size AS \"size?\",\n file.id AS \"file_id?\",\n version.id AS \"version_id?\",\n version.mod_id AS \"project_id?\",\n COALESCE(version_metadata.project_types, ARRAY[]::text[])\n AS \"project_types!: Vec\",\n COALESCE(version_metadata.loaders, ARRAY[]::text[])\n AS \"loaders!: Vec\",\n COALESCE(file_hashes.hashes, '{}'::jsonb)\n AS \"hashes!: Json>\"\n FROM delphi_report_issue_details detail\n INNER JOIN delphi_report_issues issue ON issue.id = detail.issue_id\n INNER JOIN delphi_reports report ON report.id = issue.report_id\n LEFT JOIN files file ON file.id = report.file_id\n LEFT JOIN versions version ON version.id = file.version_id\n LEFT JOIN LATERAL (\n SELECT\n ARRAY_AGG(\n DISTINCT project_type.name::text\n ORDER BY project_type.name::text\n ) FILTER (WHERE project_type.name IS NOT NULL)\n AS project_types,\n ARRAY_AGG(\n DISTINCT loader.loader\n ORDER BY loader.loader\n ) AS loaders\n FROM loaders_versions loader_version\n INNER JOIN loaders loader\n ON loader.id = loader_version.loader_id\n LEFT JOIN loaders_project_types loader_project_type\n ON loader_project_type.joining_loader_id = loader_version.loader_id\n LEFT JOIN project_types project_type\n ON project_type.id = loader_project_type.joining_project_type_id\n WHERE loader_version.version_id = version.id\n ) version_metadata ON TRUE\n LEFT JOIN LATERAL (\n SELECT\n jsonb_object_agg(algorithm, encode(hash, 'hex')) AS hashes\n FROM hashes\n WHERE hashes.file_id = file.id\n ) file_hashes ON TRUE\n WHERE detail.id = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "key", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "issue_type", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "severity: DelphiSeverity", - "type_info": { - "Custom": { - "name": "delphi_severity", - "kind": { - "Enum": [ - "hidden", - "low", - "medium", - "high", - "severe", - "malware" - ] - } - } - } - }, - { - "ordinal": 3, - "name": "jar", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "file_path", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "data: Json>", - "type_info": "Jsonb" - }, - { - "ordinal": 6, - "name": "delphi_version", - "type_info": "Int4" - }, - { - "ordinal": 7, - "name": "size?", - "type_info": "Int4" - }, - { - "ordinal": 8, - "name": "file_id?", - "type_info": "Int8" - }, - { - "ordinal": 9, - "name": "version_id?", - "type_info": "Int8" - }, - { - "ordinal": 10, - "name": "project_id?", - "type_info": "Int8" - }, - { - "ordinal": 11, - "name": "project_types!: Vec", - "type_info": "TextArray" - }, - { - "ordinal": 12, - "name": "loaders!: Vec", - "type_info": "VarcharArray" - }, - { - "ordinal": 13, - "name": "hashes!: Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - false, - false, - true, - false, - false, - false, - false, - false, - false, - false, - null, - null, - null - ] - }, - "hash": "b536d7870ba77ace55e309938c3ba93c7016b2a6f18aa4f22ea57f604d82c1da" -} diff --git a/apps/labrinth/.sqlx/query-e8ea2268b7d3e4ec1741bfc0312306aad5e2d79f1bb4bf144d48933f7fa1ee83.json b/apps/labrinth/.sqlx/query-e8ea2268b7d3e4ec1741bfc0312306aad5e2d79f1bb4bf144d48933f7fa1ee83.json new file mode 100644 index 0000000000..1a7cc4ae34 --- /dev/null +++ b/apps/labrinth/.sqlx/query-e8ea2268b7d3e4ec1741bfc0312306aad5e2d79f1bb4bf144d48933f7fa1ee83.json @@ -0,0 +1,126 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n detail.id,\n detail.key,\n issue.issue_type,\n detail.severity AS \"severity: DelphiSeverity\",\n detail.jar,\n detail.file_path,\n detail.data AS \"data: Json>\",\n COALESCE(sibling_traces.traces, '[]'::jsonb)\n AS \"sibling_traces!: Json>\",\n report.delphi_version,\n file.size AS \"size?\",\n file.id AS \"file_id?\",\n version.id AS \"version_id?\",\n version.mod_id AS \"project_id?\",\n COALESCE(version_metadata.project_types, ARRAY[]::text[])\n AS \"project_types!: Vec\",\n COALESCE(version_metadata.loaders, ARRAY[]::text[])\n AS \"loaders!: Vec\",\n COALESCE(file_hashes.hashes, '{}'::jsonb)\n AS \"hashes!: Json>\"\n FROM delphi_report_issue_details detail\n INNER JOIN delphi_report_issues issue ON issue.id = detail.issue_id\n INNER JOIN delphi_reports report ON report.id = issue.report_id\n LEFT JOIN LATERAL (\n SELECT\n jsonb_agg(\n jsonb_build_object(\n 'key', sibling_detail.key,\n 'issue_type', sibling_issue.issue_type,\n 'severity', sibling_detail.severity,\n 'jar', sibling_detail.jar,\n 'file_path', sibling_detail.file_path,\n 'data', sibling_detail.data\n )\n ORDER BY sibling_detail.id\n ) AS traces\n FROM delphi_report_issues sibling_issue\n INNER JOIN delphi_report_issue_details sibling_detail\n ON sibling_detail.issue_id = sibling_issue.id\n WHERE sibling_issue.report_id = issue.report_id\n AND sibling_detail.id != detail.id\n ) sibling_traces ON TRUE\n LEFT JOIN files file ON file.id = report.file_id\n LEFT JOIN versions version ON version.id = file.version_id\n LEFT JOIN LATERAL (\n SELECT\n ARRAY_AGG(\n DISTINCT project_type.name::text\n ORDER BY project_type.name::text\n ) FILTER (WHERE project_type.name IS NOT NULL)\n AS project_types,\n ARRAY_AGG(\n DISTINCT loader.loader\n ORDER BY loader.loader\n ) AS loaders\n FROM loaders_versions loader_version\n INNER JOIN loaders loader\n ON loader.id = loader_version.loader_id\n LEFT JOIN loaders_project_types loader_project_type\n ON loader_project_type.joining_loader_id = loader_version.loader_id\n LEFT JOIN project_types project_type\n ON project_type.id = loader_project_type.joining_project_type_id\n WHERE loader_version.version_id = version.id\n ) version_metadata ON TRUE\n LEFT JOIN LATERAL (\n SELECT\n jsonb_object_agg(algorithm, encode(hash, 'hex')) AS hashes\n FROM hashes\n WHERE hashes.file_id = file.id\n ) file_hashes ON TRUE\n WHERE detail.id = ANY($1::bigint[])\n ORDER BY detail.id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "key", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "issue_type", + "type_info": "Text" + }, + { + "ordinal": 3, + "name": "severity: DelphiSeverity", + "type_info": { + "Custom": { + "name": "delphi_severity", + "kind": { + "Enum": [ + "hidden", + "low", + "medium", + "high", + "severe", + "malware" + ] + } + } + } + }, + { + "ordinal": 4, + "name": "jar", + "type_info": "Text" + }, + { + "ordinal": 5, + "name": "file_path", + "type_info": "Text" + }, + { + "ordinal": 6, + "name": "data: Json>", + "type_info": "Jsonb" + }, + { + "ordinal": 7, + "name": "sibling_traces!: Json>", + "type_info": "Jsonb" + }, + { + "ordinal": 8, + "name": "delphi_version", + "type_info": "Int4" + }, + { + "ordinal": 9, + "name": "size?", + "type_info": "Int4" + }, + { + "ordinal": 10, + "name": "file_id?", + "type_info": "Int8" + }, + { + "ordinal": 11, + "name": "version_id?", + "type_info": "Int8" + }, + { + "ordinal": 12, + "name": "project_id?", + "type_info": "Int8" + }, + { + "ordinal": 13, + "name": "project_types!: Vec", + "type_info": "TextArray" + }, + { + "ordinal": 14, + "name": "loaders!: Vec", + "type_info": "VarcharArray" + }, + { + "ordinal": 15, + "name": "hashes!: Json>", + "type_info": "Jsonb" + } + ], + "parameters": { + "Left": [ + "Int8Array" + ] + }, + "nullable": [ + false, + false, + false, + false, + true, + false, + false, + null, + false, + true, + true, + true, + true, + null, + null, + null + ] + }, + "hash": "e8ea2268b7d3e4ec1741bfc0312306aad5e2d79f1bb4bf144d48933f7fa1ee83" +} diff --git a/apps/labrinth/src/routes/internal/moderation/tech_review/rules_scan.rs b/apps/labrinth/src/routes/internal/moderation/tech_review/rules_scan.rs index f1571f11d9..a8b3ed3766 100644 --- a/apps/labrinth/src/routes/internal/moderation/tech_review/rules_scan.rs +++ b/apps/labrinth/src/routes/internal/moderation/tech_review/rules_scan.rs @@ -57,6 +57,7 @@ struct RuleScanErrorEvent<'a> { pub struct RuleInput { pub schema_version: u32, pub trace: RuleTrace, + pub sibling_traces: Vec, pub scan: RuleScan, pub artifact: RuleArtifact, pub project: RuleProject, @@ -64,7 +65,7 @@ pub struct RuleInput { pub file: RuleFile, } -#[derive(Deserialize, Serialize, utoipa::ToSchema)] +#[derive(Debug, Deserialize, Serialize, utoipa::ToSchema)] pub struct RuleTrace { pub key: String, pub issue_type: String, @@ -208,6 +209,8 @@ pub async fn get_detail_rule_input( detail.jar, detail.file_path, detail.data AS "data: Json>", + COALESCE(sibling_traces.traces, '[]'::jsonb) + AS "sibling_traces!: Json>", report.delphi_version, file.size AS "size?", file.id AS "file_id?", @@ -222,6 +225,25 @@ pub async fn get_detail_rule_input( FROM delphi_report_issue_details detail INNER JOIN delphi_report_issues issue ON issue.id = detail.issue_id INNER JOIN delphi_reports report ON report.id = issue.report_id + LEFT JOIN LATERAL ( + SELECT + jsonb_agg( + jsonb_build_object( + 'key', sibling_detail.key, + 'issue_type', sibling_issue.issue_type, + 'severity', sibling_detail.severity, + 'jar', sibling_detail.jar, + 'file_path', sibling_detail.file_path, + 'data', sibling_detail.data + ) + ORDER BY sibling_detail.id + ) AS traces + FROM delphi_report_issues sibling_issue + INNER JOIN delphi_report_issue_details sibling_detail + ON sibling_detail.issue_id = sibling_issue.id + WHERE sibling_issue.report_id = issue.report_id + AND sibling_detail.id != detail.id + ) sibling_traces ON TRUE LEFT JOIN files file ON file.id = report.file_id LEFT JOIN versions version ON version.id = file.version_id LEFT JOIN LATERAL ( @@ -269,6 +291,7 @@ pub async fn get_detail_rule_input( file_path: detail.file_path, data: detail.data.0, }, + sibling_traces: detail.sibling_traces.0, scan: RuleScan { delphi_version: detail.delphi_version, }, @@ -443,6 +466,8 @@ async fn run_scan( detail.jar, detail.file_path, detail.data AS "data: Json>", + COALESCE(sibling_traces.traces, '[]'::jsonb) + AS "sibling_traces!: Json>", report.delphi_version, file.size AS "size?", file.id AS "file_id?", @@ -457,6 +482,25 @@ async fn run_scan( FROM delphi_report_issue_details detail INNER JOIN delphi_report_issues issue ON issue.id = detail.issue_id INNER JOIN delphi_reports report ON report.id = issue.report_id + LEFT JOIN LATERAL ( + SELECT + jsonb_agg( + jsonb_build_object( + 'key', sibling_detail.key, + 'issue_type', sibling_issue.issue_type, + 'severity', sibling_detail.severity, + 'jar', sibling_detail.jar, + 'file_path', sibling_detail.file_path, + 'data', sibling_detail.data + ) + ORDER BY sibling_detail.id + ) AS traces + FROM delphi_report_issues sibling_issue + INNER JOIN delphi_report_issue_details sibling_detail + ON sibling_detail.issue_id = sibling_issue.id + WHERE sibling_issue.report_id = issue.report_id + AND sibling_detail.id != detail.id + ) sibling_traces ON TRUE LEFT JOIN files file ON file.id = report.file_id LEFT JOIN versions version ON version.id = file.version_id LEFT JOIN ( @@ -523,6 +567,7 @@ async fn run_scan( file_path: detail.file_path, data: detail.data.0, }, + sibling_traces: detail.sibling_traces.0, scan: RuleScan { delphi_version: detail.delphi_version, }, @@ -719,6 +764,8 @@ pub(crate) async fn materialize_current_rule_effects( detail.jar, detail.file_path, detail.data AS "data: Json>", + COALESCE(sibling_traces.traces, '[]'::jsonb) + AS "sibling_traces!: Json>", report.delphi_version, file.size AS "size?", file.id AS "file_id?", @@ -733,6 +780,25 @@ pub(crate) async fn materialize_current_rule_effects( FROM delphi_report_issue_details detail INNER JOIN delphi_report_issues issue ON issue.id = detail.issue_id INNER JOIN delphi_reports report ON report.id = issue.report_id + LEFT JOIN LATERAL ( + SELECT + jsonb_agg( + jsonb_build_object( + 'key', sibling_detail.key, + 'issue_type', sibling_issue.issue_type, + 'severity', sibling_detail.severity, + 'jar', sibling_detail.jar, + 'file_path', sibling_detail.file_path, + 'data', sibling_detail.data + ) + ORDER BY sibling_detail.id + ) AS traces + FROM delphi_report_issues sibling_issue + INNER JOIN delphi_report_issue_details sibling_detail + ON sibling_detail.issue_id = sibling_issue.id + WHERE sibling_issue.report_id = issue.report_id + AND sibling_detail.id != detail.id + ) sibling_traces ON TRUE LEFT JOIN files file ON file.id = report.file_id LEFT JOIN versions version ON version.id = file.version_id LEFT JOIN LATERAL ( @@ -782,6 +848,7 @@ pub(crate) async fn materialize_current_rule_effects( file_path: detail.file_path, data: detail.data.0, }, + sibling_traces: detail.sibling_traces.0, scan: RuleScan { delphi_version: detail.delphi_version, }, @@ -938,6 +1005,9 @@ fn evaluate_rule_inner( context .add_variable("trace", &input.trace) .wrap_err("failed to add `trace` to cel context")?; + context + .add_variable("sibling_traces", &input.sibling_traces) + .wrap_err("failed to add `sibling_traces` to cel context")?; context .add_variable("scan", &input.scan) .wrap_err("failed to add `scan` to cel context")?; diff --git a/packages/api-client/src/modules/labrinth/types.ts b/packages/api-client/src/modules/labrinth/types.ts index 18713f53b8..b71ad57819 100644 --- a/packages/api-client/src/modules/labrinth/types.ts +++ b/packages/api-client/src/modules/labrinth/types.ts @@ -2398,14 +2398,8 @@ export namespace Labrinth { export type RuleInput = { schema_version: number - trace: { - key: string - issue_type: string - severity: DelphiSeverity - jar: string | null - file_path: string - data: Record - } + trace: RuleTrace + sibling_traces: RuleTrace[] scan: { delphi_version: number } @@ -2426,6 +2420,15 @@ export namespace Labrinth { } } + export type RuleTrace = { + key: string + issue_type: string + severity: DelphiSeverity + jar: string | null + file_path: string + data: Record + } + export type TestDelphiRuleResponse = { effects: Array }