7
7
import com .fasterxml .jackson .databind .node .JsonNodeType ;
8
8
import com .fasterxml .jackson .databind .node .ObjectNode ;
9
9
import io .hyperfoil .tools .horreum .api .SortDirection ;
10
+ import io .hyperfoil .tools .horreum .api .alerting .Change ;
10
11
import io .hyperfoil .tools .horreum .api .data .Access ;
11
12
import io .hyperfoil .tools .horreum .api .data .ExportedLabelValues ;
12
13
import io .hyperfoil .tools .horreum .api .data .Fingerprints ;
41
42
import jakarta .enterprise .context .ApplicationScoped ;
42
43
import jakarta .inject .Inject ;
43
44
import jakarta .persistence .EntityManager ;
45
+ import jakarta .persistence .NoResultException ;
44
46
import jakarta .persistence .PersistenceException ;
45
47
import jakarta .persistence .Tuple ;
46
48
import jakarta .transaction .TransactionManager ;
@@ -91,6 +93,7 @@ public class TestServiceImpl implements TestService {
91
93
protected static final String LABEL_ORDER_STOP = "combined.stop" ;
92
94
protected static final String LABEL_ORDER_JSONPATH = "jsonb_path_query(combined.values,CAST( :orderBy as jsonpath))" ;
93
95
96
+ private static final String COUNT_TEST_BY_ID_QUERY = "SELECT count(id) FROM test WHERE id = ?1" ;
94
97
protected static final String LABEL_VALUES_QUERY = """
95
98
WITH
96
99
combined as (
@@ -183,6 +186,19 @@ public Test getByNameOrId(String input){
183
186
return TestMapper .from (test );
184
187
}
185
188
189
+ /**
190
+ * Checks whether the provided id belongs to an existing test and if the user can access it
191
+ * the security check is performed by triggering the RLS at database level
192
+ * @param id test ID
193
+ */
194
+ @ WithRoles
195
+ @ Transactional
196
+ protected boolean checkTestExists (int id ) {
197
+ return 0 != em .createQuery (COUNT_TEST_BY_ID_QUERY , Long .class )
198
+ .setParameter (1 , id )
199
+ .getSingleResult ();
200
+ }
201
+
186
202
@ WithRoles (extras = Roles .HORREUM_SYSTEM )
187
203
public TestDAO ensureTestExists (String testNameOrId , String token ){
188
204
TestDAO test ;// = TestMapper.to(getByNameOrId(input)); //why does getByNameOrId not work to create the DAO?
@@ -572,8 +588,7 @@ public void updateFolder(int id, String folder) {
572
588
@ SuppressWarnings ("unchecked" )
573
589
@ Override
574
590
public List <Fingerprints > listFingerprints (int testId ) {
575
- Test test = get (testId ,null );
576
- if (test == null ){
591
+ if (!checkTestExists (testId )){
577
592
throw ServiceException .serverError ("Cannot find test " +testId );
578
593
}
579
594
return Fingerprints .parse ( em .createNativeQuery ("""
@@ -582,7 +597,7 @@ public List<Fingerprints> listFingerprints(int testId) {
582
597
JOIN dataset ON dataset.id = dataset_id
583
598
WHERE dataset.testid = ?1
584
599
""" )
585
- .setParameter (1 , test . id )
600
+ .setParameter (1 , testId )
586
601
.unwrap (NativeQuery .class ).addScalar ("fingerprint" , JsonBinaryType .INSTANCE )
587
602
.getResultList ());
588
603
}
@@ -721,8 +736,7 @@ protected static FilterDef getFilterDef(String filter, Instant before, Instant a
721
736
@ WithRoles
722
737
@ Override
723
738
public List <ExportedLabelValues > labelValues (int testId , String filter , String before , String after , boolean filtering , boolean metrics , String sort , String direction , int limit , int page , List <String > include , List <String > exclude , boolean multiFilter ) {
724
- Test test = get (testId ,null );
725
- if (test == null ){
739
+ if (!checkTestExists (testId )){
726
740
throw ServiceException .serverError ("Cannot find test " +testId );
727
741
}
728
742
Object filterObject = Util .getFilterObject (filter );
@@ -785,7 +799,7 @@ public List<ExportedLabelValues> labelValues(int testId, String filter, String b
785
799
.replace ("ORDER_PLACEHOLDER" ,orderSql );
786
800
787
801
NativeQuery query = ((NativeQuery ) em .createNativeQuery (sql ))
788
- .setParameter ("testId" , test . id )
802
+ .setParameter ("testId" , testId )
789
803
.setParameter ("filteringLabels" , filtering )
790
804
.setParameter ("metricLabels" , metrics )
791
805
;
@@ -924,15 +938,14 @@ public void recalculateDatasets(int testId) {
924
938
@ Override
925
939
@ WithRoles
926
940
public RecalculationStatus getRecalculationStatus (int testId ) {
927
- Test test = get (testId ,null );
928
- if (test == null ){
941
+ if (!checkTestExists (testId )){
929
942
throw ServiceException .serverError ("Cannot find test " +testId );
930
943
}
931
- RecalculationStatus status = recalculations .get (test . id );
944
+ RecalculationStatus status = recalculations .get (testId );
932
945
if (status == null ) {
933
- status = new RecalculationStatus (RunDAO .count ("testid = ?1 AND trashed = false" , test . id ));
946
+ status = new RecalculationStatus (RunDAO .count ("testid = ?1 AND trashed = false" , testId ));
934
947
status .finished = status .totalRuns ;
935
- status .datasets = DatasetDAO .count ("testid" , test . id );
948
+ status .datasets = DatasetDAO .count ("testid" , testId );
936
949
}
937
950
return status ;
938
951
}
0 commit comments