From e03ff3151878851af954aa2e9a17e7578873bbae Mon Sep 17 00:00:00 2001 From: Vika Date: Wed, 28 Aug 2024 14:51:13 +0300 Subject: Check validity of Micropub updates In Kittybox, Micropub updates cannot modify UIDs, since UIDs are used as a primary key. Additional constraints may be added later, and perhaps I'll add a Storage method that would check backend-specific constraints. --- src/micropub/mod.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/micropub/mod.rs b/src/micropub/mod.rs index 944506d..9838e5a 100644 --- a/src/micropub/mod.rs +++ b/src/micropub/mod.rs @@ -360,6 +360,47 @@ pub struct MicropubUpdate { pub delete: Option, } impl MicropubUpdate { + pub fn check_validity(&self) -> Result<(), MicropubError> { + if let Some(add) = &self.add { + if add.iter().map(|(k, _)| k.as_str()).any(|k| { + k.to_lowercase().as_str() == "uid" + }) { + return Err(MicropubError { + error: ErrorKind::InvalidRequest, + error_description: "Update cannot modify the post UID".to_owned() + }); + } + } + if let Some(replace) = &self.replace { + if replace.iter().map(|(k, v)| k.as_str()).any(|k| { + k.to_lowercase().as_str() == "uid" + }) { + return Err(MicropubError { + error: ErrorKind::InvalidRequest, + error_description: "Update cannot modify the post UID".to_owned() + }); + } + } + let iter = match &self.delete { + Some(MicropubPropertyDeletion::Properties(keys)) => { + Some(Box::new(keys.iter().map(|k| k.as_str())) as Box>) + }, + Some(MicropubPropertyDeletion::Values(map)) => { + Some(Box::new(map.iter().map(|(k, _)| k.as_str())) as Box>) + }, + None => None, + }; + if let Some(mut iter) = iter { + if iter.any(|k| k.to_lowercase().as_str() == "uid") { + return Err(MicropubError { + error: ErrorKind::InvalidRequest, + error_description: "Update cannot modify the post UID".to_owned() + }); + } + } + Ok(()) + } + /// Update a specified MF2-JSON document with this update. pub fn apply(self, post: &mut serde_json::Value) { if let Some(MicropubPropertyDeletion::Properties(ref delete)) = self.delete { @@ -458,14 +499,17 @@ async fn post_action( }); } - db.update_post( - &action.url, - action.update.ok_or(MicropubError { + let update = if let Some(update) = action.update { + update + } else { + return Err(MicropubError { error: ErrorKind::InvalidRequest, error_description: "Update request is not set.".to_owned(), - })? - ) - .await? + }) + }; + + update.check_validity()?; + db.update_post(&action.url, update).await?; } } -- cgit 1.4.1