implement principal types

This commit is contained in:
Lennart
2025-02-02 12:27:03 +01:00
parent 207cb5cd27
commit bb8f2bb370
3 changed files with 35 additions and 3 deletions

View File

@@ -6,6 +6,7 @@ use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
use rustical_dav::privileges::UserPrivilegeSet;
use rustical_dav::resource::{NamedRoute, Resource, ResourceService};
use rustical_dav::xml::{HrefElement, Resourcetype, ResourcetypeInner};
use rustical_store::auth::user::PrincipalType;
use rustical_store::auth::User;
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
@@ -26,7 +27,7 @@ pub enum PrincipalProp {
// Scheduling Extensions to CalDAV (RFC 6638)
#[xml(ns = "rustical_dav::namespace::NS_CALDAV", skip_deserializing)]
CalendarUserType(&'static str),
CalendarUserType(PrincipalType),
#[xml(ns = "rustical_dav::namespace::NS_CALDAV")]
CalendarUserAddressSet(HrefElement),
@@ -78,6 +79,7 @@ impl Resource for PrincipalResource {
) -> Result<Self::Prop, Self::Error> {
let principal_url = Self::get_url(rmap, vec![&self.principal]).unwrap();
// BUG: We need to read the properties of the principal, not the requesting user
let home_set = CalendarHomeSet(
user.memberships()
.into_iter()
@@ -93,9 +95,8 @@ impl Resource for PrincipalResource {
Ok(match prop {
PrincipalPropWrapperName::Principal(prop) => {
PrincipalPropWrapper::Principal(match prop {
// TODO: principal types
PrincipalPropName::CalendarUserType => {
PrincipalProp::CalendarUserType("INDIVIDUAL")
PrincipalProp::CalendarUserType(user.user_type.to_owned())
}
PrincipalPropName::Displayname => {
PrincipalProp::Displayname(self.principal.to_owned())

View File

@@ -4,14 +4,44 @@ use actix_web::{
FromRequest, HttpMessage, HttpResponse, ResponseError,
};
use derive_more::Display;
use rustical_xml::ValueSerialize;
use serde::{Deserialize, Serialize};
use std::future::{ready, Ready};
/// https://datatracker.ietf.org/doc/html/rfc5545#section-3.2.3
#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum PrincipalType {
#[default]
Individual,
Group,
Resource,
Room,
Unknown,
// TODO: X-Name, IANA-token
}
impl ValueSerialize for PrincipalType {
fn serialize(&self) -> String {
match self {
PrincipalType::Individual => "INDIVIDUAL",
PrincipalType::Group => "GROUP",
PrincipalType::Resource => "RESOURCE",
PrincipalType::Room => "ROOM",
PrincipalType::Unknown => "UNKNOWN",
}
.to_owned()
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
// TODO: Rename this to Principal
pub struct User {
pub id: String,
pub displayname: Option<String>,
#[serde(default)]
pub user_type: PrincipalType,
pub password: Option<String>,
#[serde(default)]
pub app_tokens: Vec<String>,

View File

@@ -29,6 +29,7 @@ pub fn cmd_gen_config(_args: GenConfigArgs) -> anyhow::Result<()> {
users: vec![User {
id: "default".to_owned(),
displayname: Some("Default user".to_owned()),
user_type: Default::default(),
password: Some(
"generate a password hash with rustical pwhash --algorithm argon2".to_owned(),
),