Move DELETE method to Resource framework

This commit is contained in:
Lennart
2024-06-30 19:44:13 +02:00
parent 8afcbccd6a
commit 6f4bc4ba7b
10 changed files with 62 additions and 79 deletions

View File

@@ -12,7 +12,7 @@ a calendar server
- [ ] ICS parsing
- [x] Datetime parsing
- [x] Implement PROPPATCH
- [ ] Auth
- [ ] Auth (There currently is no authentication at all in place for some routes)
- [ ] Access control
- [ ] preparation for different principal types (groups)
- [ ] authentication rewrite? (argon2 is very slow for each request)

View File

@@ -1,36 +0,0 @@
use crate::CalDavContext;
use crate::Error;
use actix_web::HttpRequest;
use actix_web::{
web::{Data, Path},
HttpResponse,
};
use rustical_auth::{AuthInfoExtractor, CheckAuthentication};
use rustical_store::CalendarStore;
pub async fn route_delete_calendar<A: CheckAuthentication, C: CalendarStore + ?Sized>(
context: Data<CalDavContext<C>>,
path: Path<(String, String)>,
auth: AuthInfoExtractor<A>,
req: HttpRequest,
) -> Result<HttpResponse, Error> {
let (principal, cid) = path.into_inner();
if principal != auth.inner.user_id {
return Err(Error::Unauthorized);
}
let no_trash = req
.headers()
.get("X-No-Trashbin")
.map(|val| matches!(val.to_str(), Ok("1")))
.unwrap_or(false);
context
.store
.write()
.await
.delete_calendar(&principal, &cid, !no_trash)
.await?;
Ok(HttpResponse::Ok().body(""))
}

View File

@@ -1,3 +1,2 @@
pub mod delete;
pub mod mkcalendar;
pub mod report;

View File

@@ -289,4 +289,13 @@ impl<C: CalendarStore + ?Sized> ResourceService for CalendarResource<C> {
.await?;
Ok(())
}
async fn delete_file(&self, use_trashbin: bool) -> Result<(), Self::Error> {
self.cal_store
.write()
.await
.delete_calendar(&self.principal, &self.calendar_id, use_trashbin)
.await?;
Ok(())
}
}

View File

@@ -8,37 +8,6 @@ use actix_web::HttpResponse;
use rustical_auth::{AuthInfoExtractor, CheckAuthentication};
use rustical_store::CalendarStore;
pub async fn delete_event<A: CheckAuthentication, C: CalendarStore + ?Sized>(
context: Data<CalDavContext<C>>,
path: Path<(String, String, String)>,
auth: AuthInfoExtractor<A>,
req: HttpRequest,
) -> Result<HttpResponse, Error> {
let (principal, mut cid, uid) = path.into_inner();
if auth.inner.user_id != principal {
return Ok(HttpResponse::Unauthorized().body(""));
}
if cid.ends_with(".ics") {
cid.truncate(cid.len() - 4);
}
let no_trash = req
.headers()
.get("X-No-Trashbin")
.map(|val| matches!(val.to_str(), Ok("1")))
.unwrap_or(false);
context
.store
.write()
.await
.delete_event(&principal, &cid, &uid, !no_trash)
.await?;
Ok(HttpResponse::Ok().body(""))
}
pub async fn get_event<A: CheckAuthentication, C: CalendarStore + ?Sized>(
context: Data<CalDavContext<C>>,
path: Path<(String, String, String)>,

View File

@@ -79,7 +79,11 @@ impl<C: CalendarStore + ?Sized> ResourceService for EventResource<C> {
_auth_info: &AuthInfo,
path_components: Self::PathComponents,
) -> Result<Self, Self::Error> {
let (principal, cid, uid) = path_components;
let (principal, cid, mut uid) = path_components;
if uid.ends_with(".ics") {
uid.truncate(uid.len() - 4);
}
let cal_store = req
.app_data::<Data<RwLock<C>>>()
@@ -109,4 +113,13 @@ impl<C: CalendarStore + ?Sized> ResourceService for EventResource<C> {
async fn save_file(&self, _file: Self::File) -> Result<(), Self::Error> {
Err(Error::NotImplemented)
}
async fn delete_file(&self, use_trashbin: bool) -> Result<(), Self::Error> {
self.cal_store
.write()
.await
.delete_event(&self.principal, &self.cid, &self.uid, use_trashbin)
.await?;
Ok(())
}
}

View File

@@ -6,6 +6,7 @@ use event::resource::EventResource;
use principal::PrincipalResource;
use root::RootResource;
use rustical_auth::CheckAuthentication;
use rustical_dav::delete::route_delete;
use rustical_dav::propfind::{route_propfind, ServicePrefix};
use rustical_dav::proppatch::route_proppatch;
use rustical_store::CalendarStore;
@@ -81,14 +82,13 @@ pub fn configure_dav<A: CheckAuthentication, C: CalendarStore + ?Sized>(
proppatch_method()
.to(route_proppatch::<A, CalendarResource<C>>),
)
.route(
web::method(Method::DELETE)
.to(route_delete::<A, CalendarResource<C>>),
)
.route(mkcalendar_method().to(
calendar::methods::mkcalendar::route_mkcol_calendar::<A, C>,
))
.route(
web::method(Method::DELETE).to(
calendar::methods::delete::route_delete_calendar::<A, C>,
),
),
)),
)
.service(
web::resource("/{event}")
@@ -98,7 +98,7 @@ pub fn configure_dav<A: CheckAuthentication, C: CalendarStore + ?Sized>(
)
.route(
web::method(Method::DELETE)
.to(event::methods::delete_event::<A, C>),
.to(route_delete::<A, EventResource<C>>),
)
.route(
web::method(Method::GET).to(event::methods::get_event::<A, C>),

26
crates/dav/src/delete.rs Normal file
View File

@@ -0,0 +1,26 @@
use crate::resource::ResourceService;
use actix_web::web::Path;
use actix_web::HttpRequest;
use actix_web::HttpResponse;
use actix_web::Responder;
use rustical_auth::{AuthInfoExtractor, CheckAuthentication};
pub async fn route_delete<A: CheckAuthentication, R: ResourceService + ?Sized>(
path_components: Path<R::PathComponents>,
req: HttpRequest,
auth: AuthInfoExtractor<A>,
) -> Result<impl Responder, R::Error> {
let auth_info = auth.inner;
let path_components = path_components.into_inner();
let no_trash = req
.headers()
.get("X-No-Trashbin")
.map(|val| matches!(val.to_str(), Ok("1")))
.unwrap_or(false);
let resource_service = R::new(&req, &auth_info, path_components.clone()).await?;
resource_service.delete_file(!no_trash).await?;
Ok(HttpResponse::Ok().body(""))
}

View File

@@ -1,3 +1,4 @@
pub mod delete;
pub mod depth_extractor;
pub mod error;
pub mod namespace;

View File

@@ -51,8 +51,6 @@ pub trait ResourceService: Sized {
path_components: Self::PathComponents,
) -> Result<Self, Self::Error>;
async fn get_file(&self) -> Result<Self::File, Self::Error>;
async fn get_members(
&self,
_auth_info: AuthInfo,
@@ -60,7 +58,11 @@ pub trait ResourceService: Sized {
Ok(vec![])
}
async fn get_file(&self) -> Result<Self::File, Self::Error>;
async fn save_file(&self, file: Self::File) -> Result<(), Self::Error>;
async fn delete_file(&self, _use_trashbin: bool) -> Result<(), Self::Error> {
Err(crate::Error::Unauthorized.into())
}
}
#[derive(Serialize)]