mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 19:22:26 +00:00
Improve routing
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
use super::prop::{SupportedCalendarComponentSet, SupportedCalendarData, SupportedReportSet};
|
use super::prop::{SupportedCalendarComponentSet, SupportedCalendarData, SupportedReportSet};
|
||||||
use crate::calendar::methods::mkcalendar::route_mkcalendar;
|
use crate::calendar::methods::mkcalendar::route_mkcalendar;
|
||||||
use crate::calendar::methods::report::route_report_calendar;
|
use crate::calendar::methods::report::route_report_calendar;
|
||||||
use crate::calendar_object::resource::CalendarObjectResource;
|
use crate::calendar_object::resource::{CalendarObjectResource, CalendarObjectResourceService};
|
||||||
use crate::{CalDavPrincipalUri, Error};
|
use crate::{CalDavPrincipalUri, Error};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use axum::Router;
|
||||||
use axum::extract::Request;
|
use axum::extract::Request;
|
||||||
use axum::handler::Handler;
|
use axum::handler::Handler;
|
||||||
use axum::response::Response;
|
use axum::response::Response;
|
||||||
@@ -398,6 +399,15 @@ impl<C: CalendarStore, S: SubscriptionStore> ResourceService for CalendarResourc
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn axum_router<State: Send + Sync + Clone + 'static>(self) -> axum::Router<State> {
|
||||||
|
Router::new()
|
||||||
|
.nest(
|
||||||
|
"/{object_id}",
|
||||||
|
CalendarObjectResourceService::new(self.cal_store.clone()).axum_router(),
|
||||||
|
)
|
||||||
|
.route_service("/", self.axum_service())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CalendarStore, S: SubscriptionStore> AxumMethods for CalendarResourceService<C, S> {
|
impl<C: CalendarStore, S: SubscriptionStore> AxumMethods for CalendarResourceService<C, S> {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::calendar::resource::CalendarResource;
|
use crate::calendar::resource::{CalendarResource, CalendarResourceService};
|
||||||
use crate::{CalDavPrincipalUri, Error};
|
use crate::{CalDavPrincipalUri, Error};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use axum::Router;
|
||||||
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
||||||
use rustical_dav::privileges::UserPrivilegeSet;
|
use rustical_dav::privileges::UserPrivilegeSet;
|
||||||
use rustical_dav::resource::{AxumMethods, PrincipalUri, Resource, ResourceService};
|
use rustical_dav::resource::{AxumMethods, PrincipalUri, Resource, ResourceService};
|
||||||
@@ -125,5 +126,15 @@ impl<C: CalendarStore, S: SubscriptionStore> ResourceService for CalendarSetReso
|
|||||||
})
|
})
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn axum_router<State: Send + Sync + Clone + 'static>(self) -> axum::Router<State> {
|
||||||
|
Router::new()
|
||||||
|
.nest(
|
||||||
|
"/{calendar_id}",
|
||||||
|
CalendarResourceService::new(self.cal_store.clone(), self.sub_store.clone())
|
||||||
|
.axum_router(),
|
||||||
|
)
|
||||||
|
.route_service("/", self.axum_service())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl<C: CalendarStore, S: SubscriptionStore> AxumMethods for CalendarSetResourceService<C, S> {}
|
impl<C: CalendarStore, S: SubscriptionStore> AxumMethods for CalendarSetResourceService<C, S> {}
|
||||||
|
|||||||
@@ -17,10 +17,6 @@ pub mod principal;
|
|||||||
|
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
|
|
||||||
use crate::calendar::resource::CalendarResourceService;
|
|
||||||
use crate::calendar_object::resource::CalendarObjectResourceService;
|
|
||||||
use crate::calendar_set::CalendarSetResourceService;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Constructor)]
|
#[derive(Debug, Clone, Constructor)]
|
||||||
pub struct CalDavPrincipalUri(&'static str);
|
pub struct CalDavPrincipalUri(&'static str);
|
||||||
|
|
||||||
@@ -50,44 +46,8 @@ pub fn caldav_router<
|
|||||||
cal_store: store.clone(),
|
cal_store: store.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Router::new()
|
|
||||||
.route_service(
|
|
||||||
"/",
|
|
||||||
RootResourceService::<_, User, CalDavPrincipalUri>::new(principal_service.clone())
|
RootResourceService::<_, User, CalDavPrincipalUri>::new(principal_service.clone())
|
||||||
.axum_service(),
|
.axum_router()
|
||||||
)
|
|
||||||
.route_service("/principal/{principal}", principal_service.axum_service())
|
|
||||||
.route_service(
|
|
||||||
"/principal/{principal}/calendar",
|
|
||||||
CalendarSetResourceService::new("calendar", store.clone(), subscription_store.clone())
|
|
||||||
.axum_service(),
|
|
||||||
)
|
|
||||||
.route_service(
|
|
||||||
"/principal/{principal}/calendar/{calendar_id}",
|
|
||||||
CalendarResourceService::new(store.clone(), subscription_store.clone()).axum_service(),
|
|
||||||
)
|
|
||||||
.route_service(
|
|
||||||
"/principal/{principal}/calendar/{calendar_id}/{object_id}",
|
|
||||||
CalendarObjectResourceService::new(store.clone()).axum_service(),
|
|
||||||
)
|
|
||||||
.route_service(
|
|
||||||
"/principal/{principal}/birthdays",
|
|
||||||
CalendarSetResourceService::new(
|
|
||||||
"birthdays",
|
|
||||||
birthday_store.clone(),
|
|
||||||
subscription_store.clone(),
|
|
||||||
)
|
|
||||||
.axum_service(),
|
|
||||||
)
|
|
||||||
.route_service(
|
|
||||||
"/principal/{principal}/birthdays/{calendar_id}",
|
|
||||||
CalendarResourceService::new(birthday_store.clone(), subscription_store.clone())
|
|
||||||
.axum_service(),
|
|
||||||
)
|
|
||||||
.route_service(
|
|
||||||
"/principal/{principal}/birthdays/{calendar_id}/{object_id}",
|
|
||||||
CalendarObjectResourceService::new(birthday_store.clone()).axum_service(),
|
|
||||||
)
|
|
||||||
.layer(AuthenticationLayer::new(auth_provider))
|
.layer(AuthenticationLayer::new(auth_provider))
|
||||||
.layer(Extension(CalDavPrincipalUri(prefix)))
|
.layer(Extension(CalDavPrincipalUri(prefix)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::calendar_set::CalendarSetResource;
|
use crate::calendar_set::{CalendarSetResource, CalendarSetResourceService};
|
||||||
use crate::{CalDavPrincipalUri, Error};
|
use crate::{CalDavPrincipalUri, Error};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use axum::Router;
|
||||||
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
||||||
use rustical_dav::privileges::UserPrivilegeSet;
|
use rustical_dav::privileges::UserPrivilegeSet;
|
||||||
use rustical_dav::resource::{AxumMethods, PrincipalUri, Resource, ResourceService};
|
use rustical_dav::resource::{AxumMethods, PrincipalUri, Resource, ResourceService};
|
||||||
@@ -193,6 +194,29 @@ impl<AP: AuthenticationProvider, S: SubscriptionStore, CS: CalendarStore, BS: Ca
|
|||||||
),
|
),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn axum_router<State: Send + Sync + Clone + 'static>(self) -> axum::Router<State> {
|
||||||
|
Router::new()
|
||||||
|
.nest(
|
||||||
|
"/calendar",
|
||||||
|
CalendarSetResourceService::new(
|
||||||
|
"calendar",
|
||||||
|
self.cal_store.clone(),
|
||||||
|
self.sub_store.clone(),
|
||||||
|
)
|
||||||
|
.axum_router(),
|
||||||
|
)
|
||||||
|
.nest(
|
||||||
|
"/birthdays",
|
||||||
|
CalendarSetResourceService::new(
|
||||||
|
"birthdays",
|
||||||
|
self.birthday_store.clone(),
|
||||||
|
self.sub_store.clone(),
|
||||||
|
)
|
||||||
|
.axum_router(),
|
||||||
|
)
|
||||||
|
.route_service("/", self.axum_service())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<AP: AuthenticationProvider, S: SubscriptionStore, CS: CalendarStore, BS: CalendarStore>
|
impl<AP: AuthenticationProvider, S: SubscriptionStore, CS: CalendarStore, BS: CalendarStore>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use super::methods::mkcol::route_mkcol;
|
use super::methods::mkcol::route_mkcol;
|
||||||
use super::methods::report::route_report_addressbook;
|
use super::methods::report::route_report_addressbook;
|
||||||
use super::prop::{SupportedAddressData, SupportedReportSet};
|
use super::prop::{SupportedAddressData, SupportedReportSet};
|
||||||
use crate::address_object::resource::AddressObjectResource;
|
use crate::address_object::resource::{AddressObjectResource, AddressObjectResourceService};
|
||||||
use crate::{CardDavPrincipalUri, Error};
|
use crate::{CardDavPrincipalUri, Error};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use axum::Router;
|
||||||
use axum::extract::Request;
|
use axum::extract::Request;
|
||||||
use axum::handler::Handler;
|
use axum::handler::Handler;
|
||||||
use axum::response::Response;
|
use axum::response::Response;
|
||||||
@@ -266,6 +267,15 @@ impl<AS: AddressbookStore, S: SubscriptionStore> ResourceService
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn axum_router<State: Send + Sync + Clone + 'static>(self) -> Router<State> {
|
||||||
|
Router::new()
|
||||||
|
.nest(
|
||||||
|
"/{object_id}",
|
||||||
|
AddressObjectResourceService::new(self.addr_store.clone()).axum_router(),
|
||||||
|
)
|
||||||
|
.route_service("/", self.axum_service())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<AS: AddressbookStore, S: SubscriptionStore> AxumMethods for AddressbookResourceService<AS, S> {
|
impl<AS: AddressbookStore, S: SubscriptionStore> AxumMethods for AddressbookResourceService<AS, S> {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
use crate::address_object::resource::AddressObjectResourceService;
|
|
||||||
use crate::addressbook::resource::AddressbookResourceService;
|
|
||||||
use axum::{Extension, Router};
|
use axum::{Extension, Router};
|
||||||
use derive_more::Constructor;
|
use derive_more::Constructor;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
@@ -38,22 +36,8 @@ pub fn carddav_router<AP: AuthenticationProvider, A: AddressbookStore, S: Subscr
|
|||||||
auth_provider.clone(),
|
auth_provider.clone(),
|
||||||
subscription_store.clone(),
|
subscription_store.clone(),
|
||||||
);
|
);
|
||||||
Router::new()
|
|
||||||
.route_service(
|
|
||||||
"/",
|
|
||||||
RootResourceService::<_, User, CardDavPrincipalUri>::new(principal_service.clone())
|
RootResourceService::<_, User, CardDavPrincipalUri>::new(principal_service.clone())
|
||||||
.axum_service(),
|
.axum_router()
|
||||||
)
|
|
||||||
.route_service("/principal/{principal}", principal_service.axum_service())
|
|
||||||
.route_service(
|
|
||||||
"/principal/{principal}/{addressbook_id}",
|
|
||||||
AddressbookResourceService::new(store.clone(), subscription_store.clone())
|
|
||||||
.axum_service(),
|
|
||||||
)
|
|
||||||
.route_service(
|
|
||||||
"/principal/{principal}/{addressbook_id}/{object_id}",
|
|
||||||
AddressObjectResourceService::new(store.clone()).axum_service(),
|
|
||||||
)
|
|
||||||
.layer(AuthenticationLayer::new(auth_provider))
|
.layer(AuthenticationLayer::new(auth_provider))
|
||||||
.layer(Extension(CardDavPrincipalUri(prefix)))
|
.layer(Extension(CardDavPrincipalUri(prefix)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::addressbook::resource::AddressbookResource;
|
use crate::addressbook::resource::{AddressbookResource, AddressbookResourceService};
|
||||||
use crate::{CardDavPrincipalUri, Error};
|
use crate::{CardDavPrincipalUri, Error};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use axum::Router;
|
||||||
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
||||||
use rustical_dav::privileges::UserPrivilegeSet;
|
use rustical_dav::privileges::UserPrivilegeSet;
|
||||||
use rustical_dav::resource::{AxumMethods, PrincipalUri, Resource, ResourceService};
|
use rustical_dav::resource::{AxumMethods, PrincipalUri, Resource, ResourceService};
|
||||||
@@ -174,6 +175,16 @@ impl<A: AddressbookStore, AP: AuthenticationProvider, S: SubscriptionStore> Reso
|
|||||||
.map(|addressbook| (addressbook.id.to_owned(), addressbook.into()))
|
.map(|addressbook| (addressbook.id.to_owned(), addressbook.into()))
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn axum_router<State: Send + Sync + Clone + 'static>(self) -> Router<State> {
|
||||||
|
Router::new()
|
||||||
|
.nest(
|
||||||
|
"/{addressbook_id}",
|
||||||
|
AddressbookResourceService::new(self.addr_store.clone(), self.sub_store.clone())
|
||||||
|
.axum_router(),
|
||||||
|
)
|
||||||
|
.route_service("/", self.axum_service())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: AddressbookStore, AP: AuthenticationProvider, S: SubscriptionStore> AxumMethods
|
impl<A: AddressbookStore, AP: AuthenticationProvider, S: SubscriptionStore> AxumMethods
|
||||||
|
|||||||
@@ -2,15 +2,18 @@ use super::{PrincipalUri, Resource};
|
|||||||
use crate::Principal;
|
use crate::Principal;
|
||||||
use crate::resource::{AxumMethods, AxumService};
|
use crate::resource::{AxumMethods, AxumService};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use axum::Router;
|
||||||
|
use axum::extract::FromRequestParts;
|
||||||
|
use axum::response::IntoResponse;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait ResourceService: Sized + Send + Sync + 'static {
|
pub trait ResourceService: Clone + Sized + Send + Sync + AxumMethods + 'static {
|
||||||
type PathComponents: for<'de> Deserialize<'de> + Sized + Send + Sync + Clone + 'static; // defines how the resource URI maps to parameters, i.e. /{principal}/{calendar} -> (String, String)
|
type PathComponents: for<'de> Deserialize<'de> + Sized + Send + Sync + Clone + 'static; // defines how the resource URI maps to parameters, i.e. /{principal}/{calendar} -> (String, String)
|
||||||
type MemberType: Resource<Error = Self::Error, Principal = Self::Principal>;
|
type MemberType: Resource<Error = Self::Error, Principal = Self::Principal>;
|
||||||
type Resource: Resource<Error = Self::Error, Principal = Self::Principal>;
|
type Resource: Resource<Error = Self::Error, Principal = Self::Principal>;
|
||||||
type Error: From<crate::Error> + Send;
|
type Error: From<crate::Error> + Send + Sync + IntoResponse + 'static;
|
||||||
type Principal: Principal;
|
type Principal: Principal + FromRequestParts<Self>;
|
||||||
type PrincipalUri: PrincipalUri;
|
type PrincipalUri: PrincipalUri;
|
||||||
|
|
||||||
const DAV_HEADER: &'static str;
|
const DAV_HEADER: &'static str;
|
||||||
@@ -45,8 +48,12 @@ pub trait ResourceService: Sized + Send + Sync + 'static {
|
|||||||
|
|
||||||
fn axum_service(self) -> AxumService<Self>
|
fn axum_service(self) -> AxumService<Self>
|
||||||
where
|
where
|
||||||
Self: Clone + Send + Sync + AxumMethods,
|
Self: AxumMethods,
|
||||||
{
|
{
|
||||||
AxumService::new(self)
|
AxumService::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn axum_router<S: Send + Sync + Clone + 'static>(self) -> Router<S> {
|
||||||
|
Router::new().route_service("/", self.axum_service())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ use crate::privileges::UserPrivilegeSet;
|
|||||||
use crate::resource::{AxumMethods, PrincipalUri, Resource, ResourceService};
|
use crate::resource::{AxumMethods, PrincipalUri, Resource, ResourceService};
|
||||||
use crate::xml::{Resourcetype, ResourcetypeInner};
|
use crate::xml::{Resourcetype, ResourcetypeInner};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use axum::Router;
|
||||||
|
use axum::extract::FromRequestParts;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -59,8 +61,11 @@ impl<PRS: ResourceService + Clone, P: Principal, PURI: PrincipalUri>
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<PRS: ResourceService<Principal = P> + Clone, P: Principal, PURI: PrincipalUri> ResourceService
|
impl<
|
||||||
for RootResourceService<PRS, P, PURI>
|
PRS: ResourceService<Principal = P> + Clone,
|
||||||
|
P: Principal + FromRequestParts<Self>,
|
||||||
|
PURI: PrincipalUri,
|
||||||
|
> ResourceService for RootResourceService<PRS, P, PURI>
|
||||||
{
|
{
|
||||||
type PathComponents = ();
|
type PathComponents = ();
|
||||||
type MemberType = PRS::Resource;
|
type MemberType = PRS::Resource;
|
||||||
@@ -74,6 +79,12 @@ impl<PRS: ResourceService<Principal = P> + Clone, P: Principal, PURI: PrincipalU
|
|||||||
async fn get_resource(&self, _: &()) -> Result<Self::Resource, Self::Error> {
|
async fn get_resource(&self, _: &()) -> Result<Self::Resource, Self::Error> {
|
||||||
Ok(RootResource::<PRS::Resource, P>::default())
|
Ok(RootResource::<PRS::Resource, P>::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn axum_router<S: Send + Sync + Clone + 'static>(self) -> Router<S> {
|
||||||
|
Router::new()
|
||||||
|
.nest("/principal/{principal}", self.0.clone().axum_router())
|
||||||
|
.route_service("/", self.axum_service())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<PRS: ResourceService<Principal = P> + Clone, P: Principal, PURI: PrincipalUri> AxumMethods
|
impl<PRS: ResourceService<Principal = P> + Clone, P: Principal, PURI: PrincipalUri> AxumMethods
|
||||||
|
|||||||
Reference in New Issue
Block a user