@@ -9,6 +9,7 @@ use crate::models::group_join_request::GroupJoinRequestRepository;
99use crate :: response:: group:: { GroupResponse , GroupsResponse } ;
1010use crate :: response:: shared:: User ;
1111use crate :: response:: Enrich ;
12+ use crate :: security:: StaticSecurity ;
1213use crate :: security:: { IsGranted , SecurityAction } ;
1314use crate :: AppState ;
1415use actix_web:: delete;
@@ -280,3 +281,42 @@ pub async fn remove_user(
280281 GroupRepository :: update_group ( group, conn) ;
281282 Ok ( HttpResponse :: Ok ( ) . finish ( ) )
282283}
284+
285+ /// Endpoint to leave a specific group as student
286+ #[ post( "/groups/{id}/leave" ) ]
287+ pub async fn leave_group (
288+ data : web:: Data < AppState > ,
289+ user : web:: ReqData < UserData > ,
290+ path : web:: Path < ( i32 , ) > ,
291+ ) -> Result < HttpResponse , ApiError > {
292+ let conn = & mut data. db . db . get ( ) . unwrap ( ) ;
293+ let path_data = path. into_inner ( ) ;
294+
295+ let mut group = GroupRepository :: get_by_id ( path_data. 0 , conn) . ok_or ( ApiError :: BadRequest {
296+ message : "No access to group" . to_string ( ) ,
297+ } ) ?;
298+
299+ if !group. is_granted ( SecurityAction :: Read , & user) {
300+ return Err ( ApiError :: Forbidden {
301+ message : "You are not allowed to leave this group" . to_string ( ) ,
302+ } ) ;
303+ }
304+
305+ if !StaticSecurity :: is_granted ( crate :: security:: StaticSecurityAction :: IsStudent , & user) {
306+ return Err ( ApiError :: Forbidden {
307+ message : "You are not a student and not able to leave this group" . to_string ( ) ,
308+ } ) ;
309+ }
310+
311+ // TODO: When switching to more scalabe approach, consider adding membership verification here
312+ // This is not nessesary for application security but would be a little extra
313+
314+ group. members = group
315+ . members
316+ . iter ( )
317+ . filter ( |m| m. is_some ( ) && m. unwrap ( ) != user. user_id )
318+ . copied ( )
319+ . collect ( ) ;
320+ GroupRepository :: update_group ( group, conn) ;
321+ Ok ( HttpResponse :: Ok ( ) . finish ( ) )
322+ }
0 commit comments