diff --git a/crates/caldav/src/principal/mod.rs b/crates/caldav/src/principal/mod.rs index 7f8a998..4a8f860 100644 --- a/crates/caldav/src/principal/mod.rs +++ b/crates/caldav/src/principal/mod.rs @@ -77,16 +77,23 @@ impl Resource for PrincipalResource { prop: &PrincipalPropWrapperName, ) -> Result { let principal_url = Self::get_url(rmap, vec![&self.principal]).unwrap(); + let home_set = CalendarHomeSet( - self.home_set - .iter() - .map(|&(home_name, _read_only)| format!("{}/{}", principal_url, home_name).into()) + user.memberships() + .into_iter() + .map(|principal| Self::get_url(rmap, vec![principal]).unwrap()) + .flat_map(|principal_url| { + self.home_set.iter().map(move |&(home_name, _read_only)| { + HrefElement::new(format!("{}/{}", &principal_url, home_name)) + }) + }) .collect(), ); Ok(match prop { PrincipalPropWrapperName::Principal(prop) => { PrincipalPropWrapper::Principal(match prop { + // TODO: principal types PrincipalPropName::CalendarUserType => { PrincipalProp::CalendarUserType("INDIVIDUAL") } diff --git a/crates/store/src/auth/user.rs b/crates/store/src/auth/user.rs index ec85916..9569c3d 100644 --- a/crates/store/src/auth/user.rs +++ b/crates/store/src/auth/user.rs @@ -15,6 +15,8 @@ pub struct User { pub password: Option, #[serde(default)] pub app_tokens: Vec, + #[serde(default)] + pub memberships: Vec, } impl User { @@ -25,7 +27,16 @@ impl User { if self.id == principal { return true; } - false + self.memberships + .iter() + .any(|membership| membership == principal) + } + + /// Returns all principals the user implements + pub fn memberships(&self) -> Vec<&str> { + let mut memberships: Vec<_> = self.memberships.iter().map(String::as_ref).collect(); + memberships.push(self.id.as_str()); + memberships } } diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 797d947..2dcc442 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -35,6 +35,10 @@ pub fn cmd_gen_config(_args: GenConfigArgs) -> anyhow::Result<()> { app_tokens: vec![ "generate an app token hash with rustical pwhash --algorithm pbkdf2".to_owned(), ], + memberships: vec![ + "Here you can specify other principals this principal should be a member of" + .to_owned(), + ], }], }), data_store: DataStoreConfig::Sqlite(SqliteDataStoreConfig {