Skip to content

Commit 21c90f2

Browse files
committed
feat: Add table for storing vulnerability resolution definitions
Signed-off-by: Johanna Lamppu <[email protected]>
1 parent 7fe4fb7 commit 21c90f2

File tree

4 files changed

+237
-0
lines changed

4 files changed

+237
-0
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright (C) 2025 The ORT Server Authors (See <https://github.com/eclipse-apoapsis/ort-server/blob/main/NOTICE>)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
* License-Filename: LICENSE
18+
*/
19+
20+
package org.eclipse.apoapsis.ortserver.dao.tables
21+
22+
import org.eclipse.apoapsis.ortserver.dao.repositories.repository.RepositoriesTable
23+
import org.eclipse.apoapsis.ortserver.dao.utils.jsonb
24+
import org.eclipse.apoapsis.ortserver.model.ChangeEventEntityType
25+
import org.eclipse.apoapsis.ortserver.model.RepositoryId
26+
import org.eclipse.apoapsis.ortserver.model.VulnerabilityResolutionDefinition
27+
import org.eclipse.apoapsis.ortserver.model.VulnerabilityResolutionReason
28+
import org.eclipse.apoapsis.ortserver.model.util.OptionalValue
29+
30+
import org.jetbrains.exposed.dao.id.LongIdTable
31+
import org.jetbrains.exposed.sql.ResultRow
32+
import org.jetbrains.exposed.sql.insertAndGetId
33+
import org.jetbrains.exposed.sql.update
34+
35+
/**
36+
* A table to store definitions of vulnerability resolutions.
37+
*/
38+
object VulnerabilityResolutionDefinitionsTable : LongIdTable("vulnerability_resolution_definitions") {
39+
val repositoryId = reference("repository_id", RepositoriesTable)
40+
41+
val contextRunId = long("context_run_id")
42+
val idMatchers = jsonb<List<String>>("id_matchers")
43+
val reason = text("reason")
44+
val comment = text("comment")
45+
val archived = bool("archived").default(false)
46+
47+
fun insert(
48+
hierarchyId: RepositoryId,
49+
runIdInput: Long,
50+
idMatchersInput: List<String>,
51+
reasonInput: VulnerabilityResolutionReason,
52+
commentInput: String
53+
): Long {
54+
return insertAndGetId {
55+
it[repositoryId] = hierarchyId.value
56+
it[contextRunId] = runIdInput
57+
it[idMatchers] = idMatchersInput
58+
it[reason] = reasonInput.name
59+
it[comment] = commentInput
60+
}.value
61+
}
62+
63+
fun get(definitionId: Long): VulnerabilityResolutionDefinition {
64+
return select(columns)
65+
.where { id eq definitionId }
66+
.single()
67+
.toVulnerabilityResolutionDefinition()
68+
}
69+
70+
fun getOrNull(definitionId: Long): VulnerabilityResolutionDefinition? {
71+
val row = select(columns)
72+
.where { id eq definitionId }
73+
.singleOrNull() ?: return null
74+
75+
return row.toVulnerabilityResolutionDefinition()
76+
}
77+
78+
fun updateDefinition(
79+
definitionId: Long,
80+
idMatchersInput: OptionalValue<List<String>> = OptionalValue.Absent,
81+
reasonInput: OptionalValue<VulnerabilityResolutionReason> = OptionalValue.Absent,
82+
commentInput: OptionalValue<String> = OptionalValue.Absent,
83+
archivedInput: OptionalValue<Boolean> = OptionalValue.Absent
84+
) {
85+
update({ id eq definitionId }) { stmt ->
86+
idMatchersInput.ifPresent { stmt[idMatchers] = it }
87+
reasonInput.ifPresent { stmt[reason] = it.name }
88+
commentInput.ifPresent { stmt[comment] = it }
89+
archivedInput.ifPresent { stmt[archived] = it }
90+
}
91+
}
92+
93+
fun ResultRow.toVulnerabilityResolutionDefinition() = VulnerabilityResolutionDefinition(
94+
this[id].value,
95+
RepositoryId(this[repositoryId].value),
96+
this[idMatchers],
97+
VulnerabilityResolutionReason.valueOf(this[reason]),
98+
this[comment],
99+
this[archived],
100+
ChangeLogTable.getAllByEntityTypeAndId(
101+
ChangeEventEntityType.VULNERABILITY_RESOLUTION_DEFINITION,
102+
this[id].value.toString()
103+
)
104+
)
105+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
CREATE TABLE vulnerability_resolution_definitions
2+
(
3+
id bigserial PRIMARY KEY,
4+
repository_id bigint REFERENCES repositories NOT NULL,
5+
context_run_id bigint NOT NULL,
6+
id_matchers jsonb NOT NULL,
7+
reason text NOT NULL,
8+
comment text NOT NULL,
9+
archived boolean DEFAULT FALSE NOT NULL
10+
);
11+
12+
CREATE INDEX IF NOT EXISTS idx_vulnerability_resolution_definitions_repository_id
13+
ON vulnerability_resolution_definitions(repository_id);
14+
15+
CREATE INDEX IF NOT EXISTS idx_vulnerability_resolution_definitions_context_run_id
16+
ON vulnerability_resolution_definitions(context_run_id);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (C) 2025 The ORT Server Authors (See <https://github.com/eclipse-apoapsis/ort-server/blob/main/NOTICE>)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
* License-Filename: LICENSE
18+
*/
19+
20+
package org.eclipse.apoapsis.ortserver.model
21+
22+
/*
23+
* A data class representing a vulnerability resolution definition.
24+
*/
25+
data class VulnerabilityResolutionDefinition(
26+
/** The unique identifier of the vulnerability resolution definition. */
27+
val id: Long,
28+
29+
/**
30+
* The ID of the hierarchy to which this vulnerability resolution definition is scoped to. In the initial
31+
* implementation this is always the repository level.
32+
*/
33+
val hierarchyId: RepositoryId,
34+
35+
/** The list of vulnerability ID matchers (regular expressions) to match the ids of the vulnerability to resolve. */
36+
val idMatchers: List<String>,
37+
38+
/** The reason why the vulnerability is resolved. */
39+
val reason: VulnerabilityResolutionReason,
40+
41+
/** A comment to further explain why the [reason] is applicable here. */
42+
val comment: String,
43+
44+
/** Whether the vulnerability resolution definition is archived. */
45+
val archived: Boolean,
46+
47+
/** The list of change events associated with this vulnerability resolution definition. */
48+
val changes: List<ChangeEvent>
49+
)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (C) 2025 The ORT Server Authors (See <https://github.com/eclipse-apoapsis/ort-server/blob/main/NOTICE>)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
* License-Filename: LICENSE
18+
*/
19+
20+
package org.eclipse.apoapsis.ortserver.model
21+
22+
/**
23+
* Possible reasons for resolving an [Vulnerability] using a [VulnerabilityResolution].
24+
*/
25+
enum class VulnerabilityResolutionReason {
26+
/**
27+
* No remediation is available for this vulnerability, e.g., because it requires a change to be made
28+
* by a third party that is not responsive.
29+
*/
30+
CANT_FIX_VULNERABILITY,
31+
32+
/**
33+
* The code in which the vulnerability was found is neither invoked in the project's code nor indirectly
34+
* via another open source component.
35+
*/
36+
INEFFECTIVE_VULNERABILITY,
37+
38+
/**
39+
* The vulnerability is irrelevant due to a tooling or database mismatch, e.g., the package version used
40+
* does not match the version for which the vulnerability provider has reported a vulnerability.
41+
*/
42+
INVALID_MATCH_VULNERABILITY,
43+
44+
/**
45+
* The vulnerability is valid but has been mitigated, e.g., measures have been taken to ensure
46+
* this vulnerability can not be exploited.
47+
*/
48+
MITIGATED_VULNERABILITY,
49+
50+
/**
51+
* The vulnerability was reported, and got a CVE assigned. However, the CVE was later deemed to not be a
52+
* vulnerability.
53+
*/
54+
NOT_A_VULNERABILITY,
55+
56+
/**
57+
* This vulnerability will never be fixed, e.g., because the package which is affected is orphaned,
58+
* declared end-of-life, or otherwise deprecated.
59+
*/
60+
WILL_NOT_FIX_VULNERABILITY,
61+
62+
/**
63+
* The vulnerability is valid but a temporary workaround has been put in place to avoid exposure
64+
* to the vulnerability.
65+
*/
66+
WORKAROUND_FOR_VULNERABILITY
67+
}

0 commit comments

Comments
 (0)