Skip to content

Commit f5dab81

Browse files
committed
feat: update to use new Delphi issue schema
1 parent 44427a9 commit f5dab81

9 files changed

+158
-88
lines changed

apps/labrinth/.sqlx/query-0080a101c9ae040adbaadf9e46fbc457a08e70dcde320c6852074819e41f8ad9.json

Lines changed: 0 additions & 24 deletions
This file was deleted.

apps/labrinth/.sqlx/query-26a43c77d3c1e875889141d209f01763de4c51bd16c100549261b11c5a4142b8.json

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/labrinth/.sqlx/query-c7c72cf1f98cbc2b647ab840bdfadf1de8aaf214b32a2aab299a0d87fd2dc453.json

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/labrinth/.sqlx/query-f2054ae7dcc89b21ed6b2f04526de1e7cddd68ac956143bef994104280a8dc07.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/labrinth/migrations/20250810155316_delphi-reports.sql

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CREATE TYPE delphi_report_severity AS ENUM ('low', 'medium', 'high', 'severe');
1+
CREATE TYPE delphi_severity AS ENUM ('low', 'medium', 'high', 'severe');
22

33
CREATE TYPE delphi_report_issue_status AS ENUM ('pending', 'approved', 'rejected');
44

@@ -11,7 +11,7 @@ CREATE TABLE delphi_reports (
1111
delphi_version INTEGER NOT NULL,
1212
artifact_url VARCHAR(2048) NOT NULL,
1313
created TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL,
14-
severity DELPHI_REPORT_SEVERITY NOT NULL,
14+
severity DELPHI_SEVERITY NOT NULL,
1515
UNIQUE (file_id, delphi_version)
1616
);
1717
CREATE INDEX delphi_version ON delphi_reports (delphi_version);
@@ -29,16 +29,18 @@ CREATE TABLE delphi_report_issues (
2929
);
3030
CREATE INDEX delphi_report_issue_by_status_and_type ON delphi_report_issues (status, issue_type);
3131

32-
-- A Java class affected by a Delphi report issue. Every affected
33-
-- Java class belongs to a specific issue, and an issue can have zero,
34-
-- one, or more affected classes. (Some issues may be artifact-wide,
32+
-- The details of a Delphi report issue, which contain data about a
33+
-- Java class affected by it. Every Delphi report issue details object
34+
-- belongs to a specific issue, and an issue can have zero, one, or
35+
-- more details attached to it. (Some issues may be artifact-wide,
3536
-- or otherwise not really specific to any particular class.)
36-
CREATE TABLE delphi_report_issue_java_classes (
37+
CREATE TABLE delphi_report_issue_details (
3738
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
3839
issue_id BIGINT NOT NULL REFERENCES delphi_report_issues (id)
3940
ON DELETE CASCADE
4041
ON UPDATE CASCADE,
4142
internal_class_name TEXT NOT NULL,
4243
decompiled_source TEXT,
43-
UNIQUE (issue_id, internal_class_name)
44+
data JSONB NOT NULL,
45+
severity DELPHI_SEVERITY NOT NULL
4446
);

apps/labrinth/src/database/models/delphi_report_item.rs

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
use std::{
2+
collections::HashMap,
23
fmt::{self, Display, Formatter},
34
ops::Deref,
45
};
56

67
use chrono::{DateTime, Utc};
78
use serde::{Deserialize, Serialize};
9+
use sqlx::types::Json;
810

911
use crate::database::models::{
10-
DBFileId, DBProjectId, DatabaseError, DelphiReportId, DelphiReportIssueId,
11-
DelphiReportIssueJavaClassId,
12+
DBFileId, DBProjectId, DatabaseError, DelphiReportId,
13+
DelphiReportIssueDetailsId, DelphiReportIssueId,
1214
};
1315

1416
/// A Delphi malware analysis report for a project version file.
@@ -25,7 +27,7 @@ pub struct DBDelphiReport {
2527
pub delphi_version: i32,
2628
pub artifact_url: String,
2729
pub created: DateTime<Utc>,
28-
pub severity: DelphiReportSeverity,
30+
pub severity: DelphiSeverity,
2931
}
3032

3133
impl DBDelphiReport {
@@ -44,20 +46,20 @@ impl DBDelphiReport {
4446
self.file_id as Option<DBFileId>,
4547
self.delphi_version,
4648
self.artifact_url,
47-
self.severity as DelphiReportSeverity,
49+
self.severity as DelphiSeverity,
4850
)
4951
.fetch_one(&mut **transaction)
5052
.await?))
5153
}
5254
}
5355

54-
/// A severity level for a Delphi report.
56+
/// A severity level reported by Delphi.
5557
#[derive(
5658
Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq, Hash, sqlx::Type,
5759
)]
5860
#[serde(rename_all = "UPPERCASE")]
59-
#[sqlx(type_name = "delphi_report_severity", rename_all = "snake_case")]
60-
pub enum DelphiReportSeverity {
61+
#[sqlx(type_name = "delphi_severity", rename_all = "snake_case")]
62+
pub enum DelphiSeverity {
6163
Low,
6264
Medium,
6365
High,
@@ -122,7 +124,7 @@ impl Display for DelphiReportListOrder {
122124
pub struct DelphiReportIssueResult {
123125
pub issue: DBDelphiReportIssue,
124126
pub report: DBDelphiReport,
125-
pub java_classes: Vec<DBDelphiReportIssueJavaClass>,
127+
pub details: Vec<DBDelphiReportIssueDetails>,
126128
pub project_id: Option<DBProjectId>,
127129
pub project_published: Option<DateTime<Utc>>,
128130
}
@@ -164,11 +166,11 @@ impl DBDelphiReportIssue {
164166
issue_type,
165167
delphi_report_issues.status AS "status: DelphiReportIssueStatus",
166168
167-
file_id, delphi_version, artifact_url, created, severity AS "severity: DelphiReportSeverity",
168-
json_array(SELECT to_jsonb(delphi_report_issue_java_classes)
169-
FROM delphi_report_issue_java_classes
169+
file_id, delphi_version, artifact_url, created, severity AS "severity: DelphiSeverity",
170+
json_array(SELECT to_jsonb(delphi_report_issue_details)
171+
FROM delphi_report_issue_details
170172
WHERE issue_id = delphi_report_issues.id
171-
) AS "classes: sqlx::types::Json<Vec<DBDelphiReportIssueJavaClass>>",
173+
) AS "details: sqlx::types::Json<Vec<DBDelphiReportIssueDetails>>",
172174
versions.mod_id AS "project_id?", mods.published AS "project_published?"
173175
FROM delphi_report_issues
174176
INNER JOIN delphi_reports ON delphi_reports.id = report_id
@@ -182,8 +184,8 @@ impl DBDelphiReportIssue {
182184
CASE WHEN $3 = 'created_asc' THEN delphi_reports.created ELSE TO_TIMESTAMP(0) END ASC,
183185
CASE WHEN $3 = 'created_desc' THEN delphi_reports.created ELSE TO_TIMESTAMP(0) END DESC,
184186
CASE WHEN $3 = 'pending_status_first' THEN delphi_report_issues.status ELSE 'pending'::delphi_report_issue_status END ASC,
185-
CASE WHEN $3 = 'severity_asc' THEN delphi_reports.severity ELSE 'low'::delphi_report_severity END ASC,
186-
CASE WHEN $3 = 'severity_desc' THEN delphi_reports.severity ELSE 'low'::delphi_report_severity END DESC
187+
CASE WHEN $3 = 'severity_asc' THEN delphi_reports.severity ELSE 'low'::delphi_severity END ASC,
188+
CASE WHEN $3 = 'severity_desc' THEN delphi_reports.severity ELSE 'low'::delphi_severity END DESC
187189
OFFSET $5
188190
LIMIT $4
189191
"#,
@@ -208,10 +210,10 @@ impl DBDelphiReportIssue {
208210
created: row.created,
209211
severity: row.severity,
210212
},
211-
java_classes: row
212-
.classes
213+
details: row
214+
.details
213215
.into_iter()
214-
.flat_map(|class_list| class_list.0)
216+
.flat_map(|details_list| details_list.0)
215217
.collect(),
216218
project_id: row.project_id.map(DBProjectId),
217219
project_published: row.project_published,
@@ -221,37 +223,54 @@ impl DBDelphiReportIssue {
221223
}
222224
}
223225

224-
/// A Java class affected by a Delphi report issue. Every affected
225-
/// Java class belongs to a specific issue, and an issue can have zero,
226-
/// one, or more affected classes. (Some issues may be artifact-wide,
226+
/// The details of a Delphi report issue, which contain data about a
227+
/// Java class affected by it. Every Delphi report issue details object
228+
/// belongs to a specific issue, and an issue can have zero, one, or
229+
/// more details attached to it. (Some issues may be artifact-wide,
227230
/// or otherwise not really specific to any particular class.)
228231
#[derive(Debug, Deserialize, Serialize)]
229-
pub struct DBDelphiReportIssueJavaClass {
230-
pub id: DelphiReportIssueJavaClassId,
232+
pub struct DBDelphiReportIssueDetails {
233+
pub id: DelphiReportIssueDetailsId,
231234
pub issue_id: DelphiReportIssueId,
232235
pub internal_class_name: InternalJavaClassName,
233236
pub decompiled_source: Option<DecompiledJavaClassSource>,
237+
pub data: Json<HashMap<String, serde_json::Value>>,
238+
pub severity: DelphiSeverity,
234239
}
235240

236-
impl DBDelphiReportIssueJavaClass {
237-
pub async fn upsert(
241+
impl DBDelphiReportIssueDetails {
242+
pub async fn insert(
238243
&self,
239244
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
240-
) -> Result<DelphiReportIssueJavaClassId, DatabaseError> {
241-
Ok(DelphiReportIssueJavaClassId(sqlx::query_scalar!(
245+
) -> Result<DelphiReportIssueDetailsId, DatabaseError> {
246+
Ok(DelphiReportIssueDetailsId(sqlx::query_scalar!(
242247
"
243-
INSERT INTO delphi_report_issue_java_classes (issue_id, internal_class_name, decompiled_source)
244-
VALUES ($1, $2, $3)
245-
ON CONFLICT (issue_id, internal_class_name) DO UPDATE SET decompiled_source = $3
248+
INSERT INTO delphi_report_issue_details (issue_id, internal_class_name, decompiled_source, data, severity)
249+
VALUES ($1, $2, $3, $4, $5)
246250
RETURNING id
247251
",
248252
self.issue_id as DelphiReportIssueId,
249253
self.internal_class_name.0,
250254
self.decompiled_source.as_ref().map(|decompiled_source| &decompiled_source.0),
255+
&self.data as &Json<HashMap<String, serde_json::Value>>,
256+
self.severity as DelphiSeverity,
251257
)
252258
.fetch_one(&mut **transaction)
253259
.await?))
254260
}
261+
262+
pub async fn remove_all_by_issue_id(
263+
issue_id: DelphiReportIssueId,
264+
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
265+
) -> Result<u64, DatabaseError> {
266+
Ok(sqlx::query!(
267+
"DELETE FROM delphi_report_issue_details WHERE issue_id = $1",
268+
issue_id as DelphiReportIssueId,
269+
)
270+
.execute(&mut **transaction)
271+
.await?
272+
.rows_affected())
273+
}
255274
}
256275

257276
/// A [Java class name] with dots replaced by forward slashes (/).

apps/labrinth/src/database/models/ids.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,4 +281,4 @@ id_type!(ReportTypeId as i32);
281281
id_type!(StatusId as i32);
282282
id_type!(DelphiReportId as i64);
283283
id_type!(DelphiReportIssueId as i64);
284-
id_type!(DelphiReportIssueJavaClassId as i64);
284+
id_type!(DelphiReportIssueDetailsId as i64);

0 commit comments

Comments
 (0)