diff --git a/crates/caldav/src/lib.rs b/crates/caldav/src/lib.rs index d4503f6..72af678 100644 --- a/crates/caldav/src/lib.rs +++ b/crates/caldav/src/lib.rs @@ -1,3 +1,5 @@ +use axum::response::Redirect; +use axum::routing::any; use axum::{Extension, Router}; use derive_more::Constructor; use principal::PrincipalResourceService; @@ -46,8 +48,16 @@ pub fn caldav_router< cal_store: store.clone(), }; - RootResourceService::<_, User, CalDavPrincipalUri>::new(principal_service.clone()) - .axum_router() - .layer(AuthenticationLayer::new(auth_provider)) - .layer(Extension(CalDavPrincipalUri(prefix))) + Router::new() + .nest( + prefix, + RootResourceService::<_, User, CalDavPrincipalUri>::new(principal_service.clone()) + .axum_router() + .layer(AuthenticationLayer::new(auth_provider)) + .layer(Extension(CalDavPrincipalUri(prefix))), + ) + .route( + "/.well-known/caldav", + any(async || Redirect::permanent(prefix)), + ) } diff --git a/crates/carddav/src/lib.rs b/crates/carddav/src/lib.rs index 56b0b30..7e3ad3b 100644 --- a/crates/carddav/src/lib.rs +++ b/crates/carddav/src/lib.rs @@ -1,3 +1,5 @@ +use axum::response::Redirect; +use axum::routing::any; use axum::{Extension, Router}; use derive_more::Constructor; pub use error::Error; @@ -36,8 +38,16 @@ pub fn carddav_router::new(principal_service.clone()) - .axum_router() - .layer(AuthenticationLayer::new(auth_provider)) - .layer(Extension(CardDavPrincipalUri(prefix))) + Router::new() + .nest( + prefix, + RootResourceService::<_, User, CardDavPrincipalUri>::new(principal_service.clone()) + .axum_router() + .layer(AuthenticationLayer::new(auth_provider)) + .layer(Extension(CardDavPrincipalUri(prefix))), + ) + .route( + "/.well-known/carddav", + any(async || Redirect::permanent(prefix)), + ) } diff --git a/crates/dav_push/src/lib.rs b/crates/dav_push/src/lib.rs index 45049d9..4571581 100644 --- a/crates/dav_push/src/lib.rs +++ b/crates/dav_push/src/lib.rs @@ -2,6 +2,30 @@ mod extension; pub mod notifier; mod prop; pub mod register; - +use derive_more::Constructor; pub use extension::*; pub use prop::*; +use rustical_store::{CollectionOperation, SubscriptionStore}; +use std::sync::Arc; +use tokio::sync::mpsc::Receiver; +use tracing::error; + +#[derive(Debug, Constructor)] +pub struct DavPushController { + allowed_push_servers: Option>, + sub_store: Arc, +} + +impl DavPushController { + pub async fn notifier(&self, mut recv: Receiver) { + while let Some(message) = recv.recv().await { + let subscribers = match self.sub_store.get_subscriptions(&message.topic).await { + Ok(subs) => subs, + Err(err) => { + error!("{err}"); + continue; + } + }; + } + } +} diff --git a/crates/frontend/src/lib.rs b/crates/frontend/src/lib.rs index 2aece05..d533245 100644 --- a/crates/frontend/src/lib.rs +++ b/crates/frontend/src/lib.rs @@ -3,7 +3,7 @@ use axum::{ body::Body, extract::{OriginalUri, Request}, middleware::{self, Next}, - response::Response, + response::{Redirect, Response}, routing::{get, post}, }; use headers::{ContentType, HeaderMapExt}; @@ -51,6 +51,7 @@ pub fn frontend_router< AS: AddressbookStore, S: SessionStore + Clone, >( + prefix: &'static str, auth_provider: Arc, cal_store: Arc, addr_store: Arc, @@ -120,7 +121,7 @@ pub fn frontend_router< .layer(Extension(oidc_config)); } - router + router = router .layer(AuthenticationLayer::new(auth_provider.clone())) .layer( SessionManagerLayer::new(session_store) @@ -133,7 +134,11 @@ pub fn frontend_router< .layer(Extension(addr_store.clone())) .layer(Extension(frontend_config.clone())) .layer(Extension(oidc_config.clone())) - .layer(middleware::from_fn(unauthorized_handler)) + .layer(middleware::from_fn(unauthorized_handler)); + + Router::new() + .nest(prefix, router) + .route("/", get(async || Redirect::to(prefix))) } async fn unauthorized_handler(mut request: Request, next: Next) -> Response { diff --git a/src/app.rs b/src/app.rs index d5aa9ac..c01ca5a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,7 +1,6 @@ use axum::Router; use axum::extract::Request; -use axum::response::{Redirect, Response}; -use axum::routing::{any, get}; +use axum::response::Response; use rustical_caldav::caldav_router; use rustical_carddav::carddav_router; use rustical_frontend::nextcloud_login::{NextcloudFlows, nextcloud_login_router}; @@ -30,49 +29,31 @@ pub fn make_app( nextcloud_flows_state: Arc, ) -> Router { let mut router = Router::new() - .nest( + .merge(caldav_router( "/caldav", - caldav_router( - "/caldav", - auth_provider.clone(), - cal_store.clone(), - addr_store.clone(), - subscription_store.clone(), - ), - ) - .nest( + auth_provider.clone(), + cal_store.clone(), + addr_store.clone(), + subscription_store.clone(), + )) + .merge(carddav_router( "/carddav", - carddav_router( - "/carddav", - auth_provider.clone(), - addr_store.clone(), - subscription_store.clone(), - ), - ) - .route( - "/.well-known/caldav", - any(async || Redirect::permanent("/caldav")), - ) - .route( - "/.well-known/carddav", - any(async || Redirect::permanent("/carddav")), - ); + auth_provider.clone(), + addr_store.clone(), + subscription_store.clone(), + )); let session_store = MemoryStore::default(); if frontend_config.enabled { - router = router - .nest( - "/frontend", - frontend_router( - auth_provider.clone(), - cal_store.clone(), - addr_store.clone(), - frontend_config, - oidc_config, - session_store.clone(), - ), - ) - .route("/", get(async || Redirect::to("/frontend"))); + router = router.merge(frontend_router( + "/frontend", + auth_provider.clone(), + cal_store.clone(), + addr_store.clone(), + frontend_config, + oidc_config, + session_store.clone(), + )); } if nextcloud_login_config.enabled { diff --git a/src/main.rs b/src/main.rs index 08c26ae..c475e62 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ use commands::{cmd_gen_config, cmd_pwhash}; use config::{DataStoreConfig, SqliteDataStoreConfig}; use figment::Figment; use figment::providers::{Env, Format, Toml}; +use rustical_dav_push::DavPushController; use rustical_dav_push::notifier::push_notifier; use rustical_frontend::nextcloud_login::NextcloudFlows; use rustical_store::auth::AuthenticationProvider; @@ -97,12 +98,16 @@ async fn main() -> Result<()> { let (addr_store, cal_store, subscription_store, principal_store, update_recv) = get_data_stores(!args.no_migrations, &config.data_store).await?; + let mut tasks = vec![]; + if config.dav_push.enabled { - tokio::spawn(push_notifier( + let dav_push_controller = DavPushController::new( config.dav_push.allowed_push_servers, - update_recv, subscription_store.clone(), - )); + ); + tasks.push(tokio::spawn(async move { + dav_push_controller.notifier(update_recv).await; + })); } let nextcloud_flows = Arc::new(NextcloudFlows::default()); @@ -126,7 +131,13 @@ async fn main() -> Result<()> { config.http.host, config.http.port )) .await?; - axum::serve(listener, app).await?; + tasks.push(tokio::spawn(async { + axum::serve(listener, app).await.unwrap() + })); + + for task in tasks { + task.await?; + } } } Ok(())