10
10
import org .dependencytrack .proto .policy .v1 .Component ;
11
11
import org .dependencytrack .proto .policy .v1 .License ;
12
12
import org .dependencytrack .proto .policy .v1 .Project ;
13
+ import org .dependencytrack .proto .policy .v1 .VersionDistance ;
13
14
import org .dependencytrack .proto .policy .v1 .Vulnerability ;
14
- import org .dependencytrack .util .VersionDistance ;
15
15
import org .jdbi .v3 .core .Handle ;
16
16
import org .jdbi .v3 .core .mapper .reflect .ConstructorMapper ;
17
17
import org .jdbi .v3 .core .statement .Query ;
46
46
import static org .dependencytrack .persistence .jdbi .JdbiFactory .jdbi ;
47
47
import static org .dependencytrack .policy .cel .definition .CelPolicyTypes .TYPE_COMPONENT ;
48
48
import static org .dependencytrack .policy .cel .definition .CelPolicyTypes .TYPE_PROJECT ;
49
+ import static org .dependencytrack .policy .cel .definition .CelPolicyTypes .TYPE_VERSION_DISTANCE ;
49
50
50
51
public class CelCommonPolicyLibrary implements Library {
51
52
@@ -117,7 +118,7 @@ public List<EnvOption> getCompileOptions() {
117
118
FUNC_COMPARE_VERSION_DISTANCE ,
118
119
Decls .newInstanceOverload (
119
120
"matches_version_distance_bool" ,
120
- List .of (TYPE_COMPONENT , Decls .String , Decls . String ),
121
+ List .of (TYPE_COMPONENT , Decls .String , TYPE_VERSION_DISTANCE ),
121
122
Decls .Bool
122
123
)
123
124
)
@@ -129,7 +130,8 @@ public List<EnvOption> getCompileOptions() {
129
130
Project .getDefaultInstance (),
130
131
Project .Property .getDefaultInstance (),
131
132
Vulnerability .getDefaultInstance (),
132
- Vulnerability .Alias .getDefaultInstance ()
133
+ Vulnerability .Alias .getDefaultInstance (),
134
+ VersionDistance .getDefaultInstance ()
133
135
)
134
136
);
135
137
}
@@ -163,20 +165,27 @@ public List<ProgramOption> getProgramOptions() {
163
165
}
164
166
165
167
private static Val matchesVersionDistanceFunc (Val ... vals ) {
166
- var basicCheckResult = basicCheck (vals );
167
- if ((basicCheckResult instanceof BoolT && basicCheckResult .value () == Types .boolOf (false )) || basicCheckResult instanceof Err ) {
168
- return basicCheckResult ;
169
- }
170
- var component = (Component ) vals [0 ].value ();
171
- var value = (String ) vals [2 ].value ();
172
- var comparator = (String ) vals [1 ].value ();
173
- if (!component .hasLatestVersion ()) {
174
- return Err .newErr ("Requested component does not have latest version information" , component );
168
+ try {
169
+ var basicCheckResult = basicVersionDistanceCheck (vals );
170
+ if ((basicCheckResult instanceof BoolT && basicCheckResult .value () == Types .boolOf (false )) || basicCheckResult instanceof Err ) {
171
+ return basicCheckResult ;
172
+ }
173
+ var component = (Component ) vals [0 ].value ();
174
+ var comparator = (String ) vals [1 ].value ();
175
+ var value = (VersionDistance ) vals [2 ].value ();
176
+ if (!component .hasLatestVersion ()) {
177
+ return Err .newErr ("Requested component does not have latest version information" , component );
178
+ }
179
+ return Types .boolOf (matchesVersionDistance (component , comparator , value ));
180
+ }catch (Exception ex ) {
181
+ LOGGER .warn ("""
182
+ %s: Was unable to parse dynamic message for version distance policy;
183
+ Unable to resolve, returning false""" .formatted (FUNC_COMPARE_VERSION_DISTANCE ));
184
+ return Types .boolOf (false );
175
185
}
176
- return Types .boolOf (matchesVersionDistance (component , comparator , value ));
177
186
}
178
187
179
- private static boolean matchesVersionDistance (Component component , String comparator , String value ) {
188
+ private static boolean matchesVersionDistance (Component component , String comparator , VersionDistance value ) {
180
189
String comparatorComputed = switch (comparator ) {
181
190
case "NUMERIC_GREATER_THAN" , ">" -> "NUMERIC_GREATER_THAN" ;
182
191
case "NUMERIC_GREATER_THAN_OR_EQUAL" , ">=" -> "NUMERIC_GREATER_THAN_OR_EQUAL" ;
@@ -192,9 +201,9 @@ private static boolean matchesVersionDistance(Component component, String compar
192
201
Unable to resolve, returning false""" .formatted (FUNC_COMPARE_VERSION_DISTANCE , comparator ));
193
202
return false ;
194
203
}
195
- final VersionDistance versionDistance ;
204
+ final org . dependencytrack . model . VersionDistance versionDistance ;
196
205
try {
197
- versionDistance = VersionDistance .getVersionDistance (component .getVersion (), component .getLatestVersion ());
206
+ versionDistance = org . dependencytrack . model . VersionDistance .getVersionDistance (component .getVersion (), component .getLatestVersion ());
198
207
} catch (RuntimeException e ) {
199
208
LOGGER .warn ("""
200
209
%s: Failed to compute version distance for component %s (UUID: %s), \
@@ -207,7 +216,7 @@ private static boolean matchesVersionDistance(Component component, String compar
207
216
final var celQm = new CelPolicyQueryManager (qm )) {
208
217
isDirectDependency = celQm .isDirectDependency (component );
209
218
}
210
- return isDirectDependency && VersionDistance .evaluate (value , comparatorComputed , versionDistance );
219
+ return isDirectDependency && org . dependencytrack . model . VersionDistance .evaluate (value , comparatorComputed , versionDistance );
211
220
}
212
221
213
222
private static Val dependsOnFunc (final Val lhs , final Val rhs ) {
@@ -289,11 +298,28 @@ private static Val isComponentOldFunc(Val... vals) {
289
298
return Types .boolOf (isComponentOld (component , comparator , dateValue ));
290
299
}
291
300
292
- private static Val basicCheck (Val ... vals ) {
301
+ private static Val basicVersionDistanceCheck (Val ... vals ) {
302
+
293
303
if (vals .length != 3 ) {
294
304
return Types .boolOf (false );
295
305
}
296
- if (vals [0 ].value () == null || vals [1 ].value () == null || vals [2 ].value () == null ) {
306
+ Val [] subVals = {vals [0 ], vals [1 ]};
307
+ Val basicCheckResult = basicPartsCheck (subVals );
308
+ if ((basicCheckResult instanceof BoolT && basicCheckResult .value ().equals (Types .boolOf (false ))) || basicCheckResult instanceof Err ) {
309
+ return basicCheckResult ;
310
+ }
311
+
312
+ if (!(vals [2 ].value () instanceof VersionDistance )) {
313
+ return Err .maybeNoSuchOverloadErr (vals [2 ]);
314
+ }
315
+ return Types .boolOf (true );
316
+ }
317
+
318
+ private static Val basicPartsCheck (Val ... vals ) {
319
+ if (vals .length != 2 ) {
320
+ return Types .boolOf (false );
321
+ }
322
+ if (vals [0 ].value () == null || vals [1 ].value () == null ) {
297
323
return Types .boolOf (false );
298
324
}
299
325
@@ -304,10 +330,6 @@ private static Val basicCheck(Val... vals) {
304
330
return Err .maybeNoSuchOverloadErr (vals [1 ]);
305
331
}
306
332
307
- if (!(vals [2 ].value () instanceof String )) {
308
- return Err .maybeNoSuchOverloadErr (vals [2 ]);
309
- }
310
-
311
333
if (!component .hasPurl ()) {
312
334
return Err .newErr ("Provided component does not have a purl" , vals [0 ]);
313
335
}
@@ -321,6 +343,23 @@ private static Val basicCheck(Val... vals) {
321
343
return Types .boolOf (true );
322
344
}
323
345
346
+ private static Val basicCheck (Val ... vals ) {
347
+ if (vals .length != 3 ) {
348
+ return Types .boolOf (false );
349
+ }
350
+ Val [] subVals = {vals [0 ], vals [1 ]};
351
+ Val basicCheckResult = basicPartsCheck (subVals );
352
+ if ((basicCheckResult instanceof BoolT && basicCheckResult .value ().equals (Types .boolOf (false ))) || basicCheckResult instanceof Err ) {
353
+ return basicCheckResult ;
354
+ }
355
+
356
+ if (!(vals [2 ].value () instanceof String )) {
357
+ return Err .maybeNoSuchOverloadErr (vals [2 ]);
358
+ }
359
+
360
+ return Types .boolOf (true );
361
+ }
362
+
324
363
private static boolean dependsOn (final Project project , final Component component ) {
325
364
if (project .getUuid ().isBlank ()) {
326
365
// Need a UUID for our starting point.
0 commit comments