use actix_web::http::Method; use actix_web::web::{self, Data}; use actix_web::{guard, HttpResponse, Responder}; use error::Error; use resources::calendar::CalendarResource; use resources::event::EventResource; use resources::principal::PrincipalCalendarsResource; use resources::root::RootResource; use routes::propfind::route_propfind; use routes::{calendar, event}; use rustical_auth::CheckAuthentication; use rustical_store::calendar::CalendarStore; use std::str::FromStr; use std::sync::Arc; use tokio::sync::RwLock; pub mod depth_extractor; pub mod error; pub mod namespace; pub mod proptypes; pub mod resource; pub mod resources; pub mod routes; mod xml_snippets; pub struct CalDavContext { pub prefix: String, pub store: Arc>, } pub fn configure_well_known(cfg: &mut web::ServiceConfig, caldav_root: String) { cfg.service(web::redirect("/caldav", caldav_root).permanent()); } pub fn configure_dav( cfg: &mut web::ServiceConfig, prefix: String, auth: Arc, store: Arc>, ) { let propfind_method = || Method::from_str("PROPFIND").unwrap(); let report_method = || Method::from_str("REPORT").unwrap(); let mkcol_method = || Method::from_str("MKCOL").unwrap(); cfg.app_data(Data::new(CalDavContext { prefix, store: store.clone(), })) .app_data(Data::from(store.clone())) .app_data(Data::from(auth)) .service( web::resource("{path:.*}") // Without the guard this service would handle all requests .guard(guard::Method(Method::OPTIONS)) .to(options_handler), ) .service( web::resource("").route(web::method(propfind_method()).to(route_propfind::< A, RootResource, C, >)), ) .service(web::resource("/{principal}").route( web::method(propfind_method()).to(route_propfind::, C>), )) .service( web::resource("/{principal}/{calendar}") .route(web::method(report_method()).to(calendar::route_report_calendar::)) .route(web::method(propfind_method()).to(route_propfind::, C>)) .route(web::method(mkcol_method()).to(calendar::route_mkcol_calendar::)), ) .service( web::resource("/{principal}/{calendar}/{event}") .route(web::method(propfind_method()).to(route_propfind::, C>)) .route(web::method(Method::DELETE).to(event::delete_event::)) .route(web::method(Method::GET).to(event::get_event::)) .route(web::method(Method::PUT).to(event::put_event::)), ); } async fn options_handler() -> impl Responder { HttpResponse::Ok() .insert_header(( "Allow", "OPTIONS, GET, HEAD, POST, PUT, REPORT, PROPFIND, PROPPATCH, MKCOL", )) .insert_header(( "DAV", "1, 2, 3, calendar-access, extended-mkcol", // "1, 2, 3, calendar-access, addressbook, extended-mkcol", )) .body("options") }