@@ -625,6 +625,90 @@ mod tests {
625625 Ok ( ( ) )
626626 }
627627
628+ #[ actix_web:: test]
629+ async fn test_repo_permissions ( ) -> Result < ( ) > {
630+ // Initialize the app
631+ let path = TmpDir :: new ( "test_repo_permissions" ) . await ?;
632+
633+ // Initialize backend2 first (this will be the creator of the group/repo)
634+ let store2 = iroh_blobs:: store:: fs:: Store :: load ( path. to_path_buf ( ) . join ( "iroh2" ) ) . await ?;
635+ let ( veilid_api2, update_rx2) = save_dweb_backend:: common:: init_veilid (
636+ path. to_path_buf ( ) . join ( "test2" ) . as_path ( ) ,
637+ "test2" . to_string ( ) ,
638+ )
639+ . await ?;
640+ let backend2 = save_dweb_backend:: backend:: Backend :: from_dependencies (
641+ & path. to_path_buf ( ) ,
642+ veilid_api2. clone ( ) ,
643+ update_rx2,
644+ store2,
645+ )
646+ . await
647+ . unwrap ( ) ;
648+
649+ // Initialize the main backend (this will join the group)
650+ BACKEND . get_or_init ( || init_backend ( path. to_path_buf ( ) . as_path ( ) ) ) ;
651+ {
652+ let backend = get_backend ( ) . await ?;
653+ backend. start ( ) . await . expect ( "Backend failed to start" ) ;
654+ }
655+
656+ // Create group and repo in backend2 (creator)
657+ let mut group = backend2. create_group ( ) . await ?;
658+ let join_url = group. get_url ( ) ;
659+ group. set_name ( TEST_GROUP_NAME ) . await ?;
660+
661+ let repo = group. create_repo ( ) . await ?;
662+ repo. set_name ( TEST_GROUP_NAME ) . await ?;
663+
664+ // Verify creator has write access
665+ let creator_repo: SnowbirdRepo = repo. clone ( ) . into ( ) ;
666+ assert ! ( creator_repo. can_write, "Creator should have write access" ) ;
667+
668+ // Join the group with the main backend
669+ {
670+ let backend = get_backend ( ) . await ?;
671+ backend. join_from_url ( join_url. as_str ( ) ) . await ?;
672+ }
673+
674+ let app = test:: init_service (
675+ App :: new ( )
676+ . service ( status)
677+ . service ( web:: scope ( "/api" ) . service ( groups:: scope ( ) ) ) ,
678+ )
679+ . await ;
680+
681+ // Get the repo info through the API for the joined backend
682+ let get_repo_req = test:: TestRequest :: get ( )
683+ . uri ( & format ! (
684+ "/api/groups/{}/repos/{}" ,
685+ group. id( ) . to_string( ) ,
686+ repo. id( ) . to_string( )
687+ ) )
688+ . to_request ( ) ;
689+ let joined_repo: SnowbirdRepo = test:: call_and_read_body_json ( & app, get_repo_req) . await ;
690+
691+ // Verify joined backend has read-only access
692+ assert ! ( !joined_repo. can_write, "Joined backend should have read-only access" ) ;
693+
694+ // List repos to verify permissions are consistent
695+ let list_repos_req = test:: TestRequest :: get ( )
696+ . uri ( & format ! ( "/api/groups/{}/repos" , group. id( ) . to_string( ) ) )
697+ . to_request ( ) ;
698+ let repos_response: ReposResponse = test:: call_and_read_body_json ( & app, list_repos_req) . await ;
699+
700+ assert_eq ! ( repos_response. repos. len( ) , 1 , "Should see one repo" ) ;
701+ assert ! ( !repos_response. repos[ 0 ] . can_write, "Listed repo should show read-only access" ) ;
702+
703+ // Clean up
704+ backend2. stop ( ) . await ?;
705+ {
706+ let backend = get_backend ( ) . await ?;
707+ backend. stop ( ) . await . expect ( "Backend failed to stop" ) ;
708+ }
709+ tokio:: time:: sleep ( Duration :: from_secs ( 2 ) ) . await ;
710+ veilid_api2. shutdown ( ) . await ;
711+
628712 Ok ( ( ) )
629713 }
630714}
0 commit comments