@@ -48,7 +48,7 @@ pub async fn post_user(
48
48
let _ = storage:: put_staging_metadata ( & metadata) ;
49
49
let created_role = user. roles . clone ( ) ;
50
50
Users . put_user ( user. clone ( ) ) ;
51
- Users . put_role ( & username, created_role. clone ( ) ) ;
51
+ Users . add_roles ( & username, created_role. clone ( ) ) ;
52
52
}
53
53
54
54
Ok ( generated_password)
@@ -73,14 +73,45 @@ pub async fn delete_user(username: web::Path<String>) -> Result<impl Responder,
73
73
Ok ( format ! ( "deleted user: {username}" ) )
74
74
}
75
75
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 (
79
110
username : web:: Path < String > ,
80
- role : web:: Json < HashSet < String > > ,
111
+ roles_to_add : web:: Json < HashSet < String > > ,
81
112
) -> Result < String , RBACError > {
82
113
let username = username. into_inner ( ) ;
83
- let role = role . into_inner ( ) ;
114
+ let roles_to_add = roles_to_add . into_inner ( ) ;
84
115
85
116
if !Users . contains ( & username) {
86
117
return Err ( RBACError :: UserDoesNotExist ) ;
@@ -92,15 +123,48 @@ pub async fn put_role(
92
123
. iter_mut ( )
93
124
. find ( |user| user. username ( ) == username)
94
125
{
95
- user. roles . clone_from ( & role ) ;
126
+ user. roles . extend ( roles_to_add . clone ( ) ) ;
96
127
} else {
97
128
// should be unreachable given state is always consistent
98
129
return Err ( RBACError :: UserDoesNotExist ) ;
99
130
}
100
131
101
132
let _ = storage:: put_staging_metadata ( & metadata) ;
102
133
// 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 ( ) ) ;
104
168
105
169
Ok ( format ! ( "Roles updated successfully for {username}" ) )
106
170
}
0 commit comments