@@ -9,16 +9,19 @@ use crate::integration_tests::instances::{
9
9
} ;
10
10
use chrono:: Utc ;
11
11
use dropshot:: test_util:: ClientTestContext ;
12
- use dropshot:: ResultsPage ;
12
+ use dropshot:: { HttpErrorResponseBody , ResultsPage } ;
13
13
use http:: { Method , StatusCode } ;
14
+ use nexus_auth:: authn:: USER_TEST_UNPRIVILEGED ;
15
+ use nexus_db_queries:: db:: identity:: Asset ;
14
16
use nexus_test_utils:: background:: activate_background_task;
15
17
use nexus_test_utils:: http_testing:: { AuthnMode , NexusRequest , RequestBuilder } ;
16
18
use nexus_test_utils:: resource_helpers:: {
17
19
create_default_ip_pool, create_disk, create_instance, create_project,
18
- object_create_error, objects_list_page_authz, DiskTest ,
20
+ grant_iam , object_create_error, objects_list_page_authz, DiskTest ,
19
21
} ;
20
22
use nexus_test_utils:: ControlPlaneTestContext ;
21
23
use nexus_test_utils_macros:: nexus_test;
24
+ use nexus_types:: external_api:: shared:: ProjectRole ;
22
25
use nexus_types:: external_api:: views:: OxqlQueryResult ;
23
26
use nexus_types:: silo:: DEFAULT_SILO_ID ;
24
27
use omicron_test_utils:: dev:: poll:: { wait_for_condition, CondCheckError } ;
@@ -637,8 +640,44 @@ async fn test_project_timeseries_query(
637
640
object_create_error ( client, url, & body, StatusCode :: NOT_FOUND ) . await ;
638
641
assert_eq ! ( result. message, "not found: project with name \" nonexistent\" " ) ;
639
642
640
- // try a project in your silo that you can't read
641
- // try a project in another silo
643
+ // unprivileged user gets 404 on project that exists, but which they can't read
644
+ let url = "/v1/timeseries/query/project/project1" ;
645
+ let body = nexus_types:: external_api:: params:: TimeseriesQuery {
646
+ query : q1. to_string ( ) ,
647
+ } ;
648
+
649
+ let request = RequestBuilder :: new ( client, Method :: POST , url)
650
+ . body ( Some ( & body) )
651
+ . expect_status ( Some ( StatusCode :: NOT_FOUND ) ) ;
652
+ let result = NexusRequest :: new ( request)
653
+ . authn_as ( AuthnMode :: UnprivilegedUser )
654
+ . execute ( )
655
+ . await
656
+ . unwrap ( )
657
+ . parsed_body :: < HttpErrorResponseBody > ( )
658
+ . unwrap ( ) ;
659
+ assert_eq ! ( result. message, "not found: project with name \" project1\" " ) ;
660
+
661
+ // now grant the user access to that project only
662
+ grant_iam (
663
+ client,
664
+ "/v1/projects/project1" ,
665
+ ProjectRole :: Viewer ,
666
+ USER_TEST_UNPRIVILEGED . id ( ) ,
667
+ AuthnMode :: PrivilegedUser ,
668
+ )
669
+ . await ;
670
+
671
+ // now they can access the timeseries. how cool is that
672
+ let request = RequestBuilder :: new ( client, Method :: POST , url)
673
+ . body ( Some ( & body) )
674
+ . expect_status ( Some ( StatusCode :: OK ) ) ;
675
+ let result = NexusRequest :: new ( request)
676
+ . authn_as ( AuthnMode :: UnprivilegedUser )
677
+ . execute_and_parse_unwrap :: < OxqlQueryResult > ( )
678
+ . await ;
679
+ assert_eq ! ( result. tables. len( ) , 1 ) ;
680
+ assert_eq ! ( result. tables[ 0 ] . timeseries( ) . len( ) , 1 ) ;
642
681
}
643
682
644
683
#[ nexus_test]
0 commit comments