use crate::addressbook::AddressbookResourceService; use crate::addressbook::resource::AddressbookResource; use crate::principal::PrincipalResource; use crate::{CardDavPrincipalUri, Error}; use async_trait::async_trait; use axum::Router; use rustical_dav::resource::{AxumMethods, ResourceService}; use rustical_store::auth::{AuthenticationProvider, Principal}; use rustical_store::{AddressbookStore, SubscriptionStore}; use std::sync::Arc; pub struct PrincipalResourceService< A: AddressbookStore, AP: AuthenticationProvider, S: SubscriptionStore, > { addr_store: Arc, auth_provider: Arc, sub_store: Arc, } impl Clone for PrincipalResourceService { fn clone(&self) -> Self { Self { addr_store: self.addr_store.clone(), auth_provider: self.auth_provider.clone(), sub_store: self.sub_store.clone(), } } } impl PrincipalResourceService { pub const fn new(addr_store: Arc, auth_provider: Arc, sub_store: Arc) -> Self { Self { addr_store, auth_provider, sub_store, } } } #[async_trait] impl ResourceService for PrincipalResourceService { type PathComponents = (String,); type MemberType = AddressbookResource; type Resource = PrincipalResource; type Error = Error; type Principal = Principal; type PrincipalUri = CardDavPrincipalUri; const DAV_HEADER: &str = "1, 3, access-control, addressbook"; async fn get_resource( &self, (principal,): &Self::PathComponents, _show_deleted: bool, ) -> Result { let user = self .auth_provider .get_principal(principal) .await? .ok_or(crate::Error::NotFound)?; Ok(PrincipalResource { members: self.auth_provider.list_members(&user.id).await?, principal: user, }) } async fn get_members( &self, (principal,): &Self::PathComponents, ) -> Result, Self::Error> { let addressbooks = self.addr_store.get_addressbooks(principal).await?; Ok(addressbooks .into_iter() .map(AddressbookResource::from) .collect()) } fn axum_router(self) -> Router { Router::new() .nest( "/{addressbook_id}", AddressbookResourceService::new(self.addr_store.clone(), self.sub_store.clone()) .axum_router(), ) .route_service("/", self.axum_service()) } } impl AxumMethods for PrincipalResourceService { }