@@ -24,6 +24,7 @@ use tokio::sync::Mutex;
2424use crate :: {
2525 handlers:: http:: { modal:: utils:: rbac_utils:: get_metadata, rbac:: RBACError } ,
2626 rbac:: {
27+ map:: roles,
2728 user:: { self , User as ParseableUser } ,
2829 Users ,
2930 } ,
@@ -73,38 +74,6 @@ pub async fn delete_user(username: web::Path<String>) -> Result<impl Responder,
7374 Ok ( format ! ( "deleted user: {username}" ) )
7475}
7576
76- // // Handler PUT /user/{username}/roles => Put roles for user
77- // // Put roles for given user
78- // pub async fn put_role(
79- // username: web::Path<String>,
80- // role: web::Json<HashSet<String>>,
81- // ) -> Result<String, RBACError> {
82- // let username = username.into_inner();
83- // let role = role.into_inner();
84-
85- // if !Users.contains(&username) {
86- // return Err(RBACError::UserDoesNotExist);
87- // };
88- // // update parseable.json first
89- // let mut metadata = get_metadata().await?;
90- // if let Some(user) = metadata
91- // .users
92- // .iter_mut()
93- // .find(|user| user.username() == username)
94- // {
95- // user.roles.clone_from(&role);
96- // } else {
97- // // should be unreachable given state is always consistent
98- // return Err(RBACError::UserDoesNotExist);
99- // }
100-
101- // let _ = storage::put_staging_metadata(&metadata);
102- // // update in mem table
103- // Users.add_roles(&username.clone(), role.clone());
104-
105- // Ok(format!("Roles updated successfully for {username}"))
106- // }
107-
10877// Handler PATCH /user/{username}/role/sync/add => Add roles to a user
10978pub async fn add_roles_to_user (
11079 username : web:: Path < String > ,
@@ -116,6 +85,19 @@ pub async fn add_roles_to_user(
11685 if !Users . contains ( & username) {
11786 return Err ( RBACError :: UserDoesNotExist ) ;
11887 } ;
88+
89+ // check if all roles exist
90+ let mut non_existent_roles = Vec :: new ( ) ;
91+ roles_to_add. iter ( ) . for_each ( |r| {
92+ if roles ( ) . get ( r) . is_none ( ) {
93+ non_existent_roles. push ( r. clone ( ) ) ;
94+ }
95+ } ) ;
96+
97+ if !non_existent_roles. is_empty ( ) {
98+ return Err ( RBACError :: RolesDoNotExist ( non_existent_roles) ) ;
99+ }
100+
119101 // update parseable.json first
120102 let mut metadata = get_metadata ( ) . await ?;
121103 if let Some ( user) = metadata
@@ -147,6 +129,30 @@ pub async fn remove_roles_from_user(
147129 if !Users . contains ( & username) {
148130 return Err ( RBACError :: UserDoesNotExist ) ;
149131 } ;
132+
133+ // check if all roles exist
134+ let mut non_existent_roles = Vec :: new ( ) ;
135+ roles_to_remove. iter ( ) . for_each ( |r| {
136+ if roles ( ) . get ( r) . is_none ( ) {
137+ non_existent_roles. push ( r. clone ( ) ) ;
138+ }
139+ } ) ;
140+
141+ if !non_existent_roles. is_empty ( ) {
142+ return Err ( RBACError :: RolesDoNotExist ( non_existent_roles) ) ;
143+ }
144+
145+ // check that user actually has these roles
146+ let user_roles: HashSet < String > = HashSet :: from_iter ( Users . get_role ( & username) ) ;
147+ let roles_not_with_user: HashSet < String > =
148+ HashSet :: from_iter ( roles_to_remove. difference ( & user_roles) . cloned ( ) ) ;
149+
150+ if !roles_not_with_user. is_empty ( ) {
151+ return Err ( RBACError :: RolesNotAssigned ( Vec :: from_iter (
152+ roles_not_with_user,
153+ ) ) ) ;
154+ }
155+
150156 // update parseable.json first
151157 let mut metadata = get_metadata ( ) . await ?;
152158 if let Some ( user) = metadata
0 commit comments