Add DELETE /family/{id} route
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
				
			|||||||
use crate::constants::StaticConstraints;
 | 
					use crate::constants::StaticConstraints;
 | 
				
			||||||
use crate::controllers::HttpResult;
 | 
					use crate::controllers::HttpResult;
 | 
				
			||||||
use crate::extractors::family_extractor::FamilyInPath;
 | 
					use crate::extractors::family_extractor::{FamilyInPath, FamilyInPathWithAdminMembership};
 | 
				
			||||||
use crate::services::login_token_service::LoginToken;
 | 
					use crate::services::login_token_service::LoginToken;
 | 
				
			||||||
use crate::services::rate_limiter_service::RatedAction;
 | 
					use crate::services::rate_limiter_service::RatedAction;
 | 
				
			||||||
use crate::services::{families_service, rate_limiter_service};
 | 
					use crate::services::{families_service, rate_limiter_service};
 | 
				
			||||||
@@ -86,6 +86,14 @@ pub async fn leave(f: FamilyInPath) -> HttpResult {
 | 
				
			|||||||
    Ok(HttpResponse::Accepted().finish())
 | 
					    Ok(HttpResponse::Accepted().finish())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Delete a family
 | 
				
			||||||
 | 
					pub async fn delete(f: FamilyInPathWithAdminMembership) -> HttpResult {
 | 
				
			||||||
 | 
					    families_service::delete_family(f.family_id()).await?;
 | 
				
			||||||
 | 
					    log::info!("User {:?} deleted family {:?}", f.user_id(), f.family_id());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Accepted().finish())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Get the list of users who belongs to a family
 | 
					/// Get the list of users who belongs to a family
 | 
				
			||||||
pub async fn users(f: FamilyInPath) -> HttpResult {
 | 
					pub async fn users(f: FamilyInPath) -> HttpResult {
 | 
				
			||||||
    Ok(HttpResponse::Ok().json(families_service::get_memberships_of_family(f.family_id()).await?))
 | 
					    Ok(HttpResponse::Ok().json(families_service::get_memberships_of_family(f.family_id()).await?))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,9 @@ use serde::Deserialize;
 | 
				
			|||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub struct FamilyInPath(Membership);
 | 
					pub struct FamilyInPath(Membership);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					pub struct FamilyInPathWithAdminMembership(FamilyInPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl FamilyInPath {
 | 
					impl FamilyInPath {
 | 
				
			||||||
    async fn load_family_from_path(t: &LoginToken, id: FamilyID) -> anyhow::Result<Self> {
 | 
					    async fn load_family_from_path(t: &LoginToken, id: FamilyID) -> anyhow::Result<Self> {
 | 
				
			||||||
        Ok(Self(families_service::get_membership(id, t.user_id).await?))
 | 
					        Ok(Self(families_service::get_membership(id, t.user_id).await?))
 | 
				
			||||||
@@ -26,6 +29,20 @@ impl FamilyInPath {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl FamilyInPathWithAdminMembership {
 | 
				
			||||||
 | 
					    pub fn user_id(&self) -> UserID {
 | 
				
			||||||
 | 
					        self.0.user_id()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn family_id(&self) -> FamilyID {
 | 
				
			||||||
 | 
					        self.0.family_id()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn is_admin(&self) -> bool {
 | 
				
			||||||
 | 
					        self.0.is_admin()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Deserialize)]
 | 
					#[derive(Deserialize)]
 | 
				
			||||||
struct FamilyIdInPath {
 | 
					struct FamilyIdInPath {
 | 
				
			||||||
    id: FamilyID,
 | 
					    id: FamilyID,
 | 
				
			||||||
@@ -54,3 +71,28 @@ impl FromRequest for FamilyInPath {
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl FromRequest for FamilyInPathWithAdminMembership {
 | 
				
			||||||
 | 
					    type Error = actix_web::Error;
 | 
				
			||||||
 | 
					    type Future = futures_util::future::LocalBoxFuture<'static, Result<Self, Self::Error>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
 | 
				
			||||||
 | 
					        let req = req.clone();
 | 
				
			||||||
 | 
					        Box::pin(async move {
 | 
				
			||||||
 | 
					            let family = FamilyInPath::extract(&req).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if !family.is_admin() {
 | 
				
			||||||
 | 
					                log::error!(
 | 
				
			||||||
 | 
					                    "The user {:?} attempted to perform restricted action on family {:?}!",
 | 
				
			||||||
 | 
					                    family.user_id(),
 | 
				
			||||||
 | 
					                    family.family_id()
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                return Err(actix_web::error::ErrorUnauthorized(
 | 
				
			||||||
 | 
					                    "You are not an administrator of this family!",
 | 
				
			||||||
 | 
					                ));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Ok(Self(family))
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -94,13 +94,17 @@ async fn main() -> std::io::Result<()> {
 | 
				
			|||||||
            .route("/family/join", web::post().to(families_controller::join))
 | 
					            .route("/family/join", web::post().to(families_controller::join))
 | 
				
			||||||
            .route("/family/list", web::get().to(families_controller::list))
 | 
					            .route("/family/list", web::get().to(families_controller::list))
 | 
				
			||||||
            .route(
 | 
					            .route(
 | 
				
			||||||
                "/family/{id}/info",
 | 
					                "/family/{id}",
 | 
				
			||||||
                web::get().to(families_controller::single_info),
 | 
					                web::get().to(families_controller::single_info),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            .route(
 | 
					            .route(
 | 
				
			||||||
                "/family/{id}/leave",
 | 
					                "/family/{id}/leave",
 | 
				
			||||||
                web::post().to(families_controller::leave),
 | 
					                web::post().to(families_controller::leave),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					            .route(
 | 
				
			||||||
 | 
					                "/family/{id}",
 | 
				
			||||||
 | 
					                web::delete().to(families_controller::delete),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
            .route(
 | 
					            .route(
 | 
				
			||||||
                "/family/{id}/users",
 | 
					                "/family/{id}/users",
 | 
				
			||||||
                web::get().to(families_controller::users),
 | 
					                web::get().to(families_controller::users),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user