Skip to content

Commit 1cb7808

Browse files
committed
feat(backend): finding analysis functionality
1 parent 5133cfb commit 1cb7808

30 files changed

+2509
-78
lines changed

backend/src/main/java/io/reliza/common/CommonVariables.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,8 @@ public enum TableName {
403403
USER_GROUPS("user_groups"),
404404
VARIANTS("variants"),
405405
VCS_REPOSITORIES("vcs_repositories"),
406-
VERSION_ASSIGNMENTS("version_assignments")
406+
VERSION_ASSIGNMENTS("version_assignments"),
407+
VULN_ANALYSIS("vuln_analysis")
407408
;
408409

409410
private String name;

backend/src/main/java/io/reliza/common/Utils.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,4 +600,36 @@ public static SeveritySourceDto createSeveritySourceDto(String vulnId, Vulnerabi
600600

601601
return new SeveritySourceDto(source, severity);
602602
}
603+
604+
/**
605+
* Minimizes a PURL by stripping all qualifiers while keeping the core components
606+
* (type, namespace, name, version, subpath).
607+
*
608+
* @param purl The PURL string to minimize
609+
* @return Minimized PURL string without qualifiers, or null if input is null or invalid
610+
*/
611+
public static String minimizePurl(String purl) {
612+
if (purl == null || purl.isEmpty()) {
613+
return null;
614+
}
615+
616+
try {
617+
// Parse the PURL
618+
PackageURL packageUrl = new PackageURL(purl);
619+
620+
// Build a new PURL with the same components but without qualifiers
621+
PackageURLBuilder builder = PackageURLBuilder.aPackageURL()
622+
.withType(packageUrl.getType())
623+
.withNamespace(packageUrl.getNamespace())
624+
.withName(packageUrl.getName())
625+
.withVersion(packageUrl.getVersion())
626+
.withSubpath(packageUrl.getSubpath());
627+
// Note: Not setting qualifiers - they will be empty
628+
629+
return builder.build().toString();
630+
} catch (MalformedPackageURLException e) {
631+
log.warn("Failed to parse PURL for minimization: {}", purl, e);
632+
return null;
633+
}
634+
}
603635
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Copyright Reliza Incorporated. 2019 - 2025. Licensed under the terms of AGPL-3.0-only.
3+
*/
4+
5+
package io.reliza.model;
6+
7+
/**
8+
* Analysis justification enum based on CycloneDX 1.7 specification
9+
* https://cyclonedx.org/docs/1.7/json/#vulnerabilities_items_analysis_justification
10+
*/
11+
public enum AnalysisJustification {
12+
CODE_NOT_PRESENT,
13+
CODE_NOT_REACHABLE,
14+
REQUIRES_CONFIGURATION,
15+
REQUIRES_DEPENDENCY,
16+
REQUIRES_ENVIRONMENT,
17+
PROTECTED_BY_COMPILER,
18+
PROTECTED_AT_RUNTIME,
19+
PROTECTED_AT_PERIMETER,
20+
PROTECTED_BY_MITIGATING_CONTROL
21+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Copyright Reliza Incorporated. 2019 - 2025. Licensed under the terms of AGPL-3.0-only.
3+
*/
4+
5+
package io.reliza.model;
6+
7+
public enum AnalysisScope {
8+
ORG,
9+
RESOURCE_GROUP,
10+
COMPONENT,
11+
BRANCH,
12+
RELEASE
13+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright Reliza Incorporated. 2019 - 2025. Licensed under the terms of AGPL-3.0-only.
3+
*/
4+
5+
package io.reliza.model;
6+
7+
public enum AnalysisState {
8+
EXPLOITABLE,
9+
IN_TRIAGE,
10+
FALSE_POSITIVE,
11+
NOT_AFFECTED
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Copyright Reliza Incorporated. 2019 - 2025. Licensed under the terms of AGPL-3.0-only.
3+
*/
4+
5+
package io.reliza.model;
6+
7+
public enum FindingType {
8+
VULNERABILITY,
9+
VIOLATION,
10+
WEAKNESS
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Copyright Reliza Incorporated. 2019 - 2025. Licensed under the terms of AGPL-3.0-only.
3+
*/
4+
5+
package io.reliza.model;
6+
7+
public enum LocationType {
8+
PURL,
9+
CODE_POINT
10+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/**
2+
* Copyright Reliza Incorporated. 2019 - 2025. Licensed under the terms of AGPL-3.0-only.
3+
*/
4+
5+
package io.reliza.model;
6+
7+
import java.io.Serializable;
8+
import java.time.ZonedDateTime;
9+
import java.util.Map;
10+
import java.util.UUID;
11+
12+
import jakarta.persistence.Column;
13+
import jakarta.persistence.Entity;
14+
import jakarta.persistence.Id;
15+
import jakarta.persistence.Table;
16+
17+
import org.hibernate.annotations.Type;
18+
19+
import io.hypersistence.utils.hibernate.type.json.JsonBinaryType;
20+
21+
@Entity
22+
@Table(schema=ModelProperties.DB_SCHEMA, name="vuln_analysis")
23+
public class VulnAnalysis implements Serializable, RelizaEntity {
24+
private static final long serialVersionUID = 234735;
25+
26+
@Id
27+
private UUID uuid = UUID.randomUUID();
28+
29+
@Column(nullable = false)
30+
private int revision=0;
31+
32+
@Column(nullable = false)
33+
private int schemaVersion=0;
34+
35+
@Column(nullable = false)
36+
private ZonedDateTime createdDate = ZonedDateTime.now();
37+
38+
@Column(nullable = false)
39+
private ZonedDateTime lastUpdatedDate = ZonedDateTime.now();
40+
41+
@Type(JsonBinaryType.class)
42+
@Column(columnDefinition = ModelProperties.JSONB)
43+
private Map<String,Object> recordData;
44+
45+
@Override
46+
public UUID getUuid() {
47+
return uuid;
48+
}
49+
50+
public void setUuid(UUID uuid) {
51+
this.uuid = uuid;
52+
}
53+
54+
@Override
55+
public int getRevision() {
56+
return revision;
57+
}
58+
59+
public void setRevision(int revision) {
60+
this.revision = revision;
61+
}
62+
63+
@Override
64+
public ZonedDateTime getCreatedDate() {
65+
return createdDate;
66+
}
67+
68+
public void setCreatedDate(ZonedDateTime createdDate) {
69+
this.createdDate = createdDate;
70+
}
71+
72+
@Override
73+
public ZonedDateTime getLastUpdatedDate() {
74+
return lastUpdatedDate;
75+
}
76+
77+
public void setLastUpdatedDate(ZonedDateTime lastUpdatedDate) {
78+
this.lastUpdatedDate = lastUpdatedDate;
79+
}
80+
81+
@Override
82+
public Map<String, Object> getRecordData() {
83+
return recordData;
84+
}
85+
86+
@Override
87+
public void setRecordData(Map<String, Object> recordData) {
88+
this.recordData = recordData;
89+
}
90+
91+
@Override
92+
public int getSchemaVersion() {
93+
return schemaVersion;
94+
}
95+
96+
public void setSchemaVersion(int schemaVersion) {
97+
this.schemaVersion = schemaVersion;
98+
}
99+
}

0 commit comments

Comments
 (0)