carddav: Require UID in address object

This commit is contained in:
Lennart
2025-08-23 18:09:03 +02:00
parent 4e3c3f3a3b
commit 68a2e7e2a2
2 changed files with 16 additions and 17 deletions

View File

@@ -86,7 +86,8 @@ pub async fn put_object<AS: AddressbookStore>(
true true
}; };
let object = AddressObject::from_vcf(object_id, body)?; let object = AddressObject::from_vcf(body)?;
assert_eq!(object.get_id(), object_id);
addr_store addr_store
.put_object(principal, addressbook_id, object, overwrite) .put_object(principal, addressbook_id, object, overwrite)
.await?; .await?;

View File

@@ -11,7 +11,6 @@ use std::{collections::HashMap, io::BufReader};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct AddressObject { pub struct AddressObject {
id: String,
vcf: String, vcf: String,
vcard: VcardContact, vcard: VcardContact,
} }
@@ -20,19 +19,16 @@ impl TryFrom<VcardContact> for AddressObject {
type Error = Error; type Error = Error;
fn try_from(vcard: VcardContact) -> Result<Self, Self::Error> { fn try_from(vcard: VcardContact) -> Result<Self, Self::Error> {
let id = vcard if vcard.get_uid().is_none() {
.get_property("UID") return Err(Error::InvalidData("missing UID".to_owned()));
.ok_or(Error::InvalidData("Missing UID".to_owned()))? }
.value
.clone()
.ok_or(Error::InvalidData("Missing UID".to_owned()))?;
let vcf = vcard.generate(); let vcf = vcard.generate();
Ok(Self { id, vcf, vcard }) Ok(Self { vcf, vcard })
} }
} }
impl AddressObject { impl AddressObject {
pub fn from_vcf(object_id: String, vcf: String) -> Result<Self, Error> { pub fn from_vcf(vcf: String) -> Result<Self, Error> {
let mut parser = vcard::VcardParser::new(BufReader::new(vcf.as_bytes())); let mut parser = vcard::VcardParser::new(BufReader::new(vcf.as_bytes()));
let vcard = parser.next().ok_or(Error::MissingContact)??; let vcard = parser.next().ok_or(Error::MissingContact)??;
if parser.next().is_some() { if parser.next().is_some() {
@@ -40,20 +36,22 @@ impl AddressObject {
"multiple vcards, only one allowed".to_owned(), "multiple vcards, only one allowed".to_owned(),
)); ));
} }
Ok(Self {
id: object_id, if vcard.get_uid().is_none() {
vcf, return Err(Error::InvalidData("missing UID".to_owned()));
vcard, }
}) Ok(Self { vcf, vcard })
} }
pub fn get_id(&self) -> &str { pub fn get_id(&self) -> &str {
&self.id self.vcard
.get_uid()
.expect("We've validated before that UID exists")
} }
pub fn get_etag(&self) -> String { pub fn get_etag(&self) -> String {
let mut hasher = Sha256::new(); let mut hasher = Sha256::new();
hasher.update(&self.id); hasher.update(self.get_id());
hasher.update(self.get_vcf()); hasher.update(self.get_vcf());
format!("\"{:x}\"", hasher.finalize()) format!("\"{:x}\"", hasher.finalize())
} }