@@ -48,7 +48,7 @@ pub async fn post_user(
4848 let _ = storage:: put_staging_metadata ( & metadata) ;
4949 let created_role = user. roles . clone ( ) ;
5050 Users . put_user ( user. clone ( ) ) ;
51- Users . put_role ( & username, created_role. clone ( ) ) ;
51+ Users . add_roles ( & username, created_role. clone ( ) ) ;
5252 }
5353
5454 Ok ( generated_password)
@@ -73,14 +73,45 @@ pub async fn delete_user(username: web::Path<String>) -> Result<impl Responder,
7373 Ok ( format ! ( "deleted user: {username}" ) )
7474}
7575
76- // Handler PUT /user/{username}/roles => Put roles for user
77- // Put roles for given user
78- pub async fn put_role (
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+
108+ // Handler PATCH /user/{username}/role/sync/add => Add roles to a user
109+ pub async fn add_roles_to_user (
79110 username : web:: Path < String > ,
80- role : web:: Json < HashSet < String > > ,
111+ roles_to_add : web:: Json < HashSet < String > > ,
81112) -> Result < String , RBACError > {
82113 let username = username. into_inner ( ) ;
83- let role = role . into_inner ( ) ;
114+ let roles_to_add = roles_to_add . into_inner ( ) ;
84115
85116 if !Users . contains ( & username) {
86117 return Err ( RBACError :: UserDoesNotExist ) ;
@@ -92,15 +123,48 @@ pub async fn put_role(
92123 . iter_mut ( )
93124 . find ( |user| user. username ( ) == username)
94125 {
95- user. roles . clone_from ( & role ) ;
126+ user. roles . extend ( roles_to_add . clone ( ) ) ;
96127 } else {
97128 // should be unreachable given state is always consistent
98129 return Err ( RBACError :: UserDoesNotExist ) ;
99130 }
100131
101132 let _ = storage:: put_staging_metadata ( & metadata) ;
102133 // update in mem table
103- Users . put_role ( & username. clone ( ) , role. clone ( ) ) ;
134+ Users . add_roles ( & username. clone ( ) , roles_to_add. clone ( ) ) ;
135+
136+ Ok ( format ! ( "Roles updated successfully for {username}" ) )
137+ }
138+
139+ // Handler PATCH /user/{username}/role/sync/add => Add roles to a user
140+ pub async fn remove_roles_from_user (
141+ username : web:: Path < String > ,
142+ roles_to_remove : web:: Json < HashSet < String > > ,
143+ ) -> Result < String , RBACError > {
144+ let username = username. into_inner ( ) ;
145+ let roles_to_remove = roles_to_remove. into_inner ( ) ;
146+
147+ if !Users . contains ( & username) {
148+ return Err ( RBACError :: UserDoesNotExist ) ;
149+ } ;
150+ // update parseable.json first
151+ let mut metadata = get_metadata ( ) . await ?;
152+ if let Some ( user) = metadata
153+ . users
154+ . iter_mut ( )
155+ . find ( |user| user. username ( ) == username)
156+ {
157+ let diff: HashSet < String > =
158+ HashSet :: from_iter ( user. roles . difference ( & roles_to_remove) . cloned ( ) ) ;
159+ user. roles = diff;
160+ } else {
161+ // should be unreachable given state is always consistent
162+ return Err ( RBACError :: UserDoesNotExist ) ;
163+ }
164+
165+ let _ = storage:: put_staging_metadata ( & metadata) ;
166+ // update in mem table
167+ Users . remove_roles ( & username. clone ( ) , roles_to_remove. clone ( ) ) ;
104168
105169 Ok ( format ! ( "Roles updated successfully for {username}" ) )
106170}
0 commit comments