From 858c0ddd9cc36af0acc72efb1ff1bdc1d8e28b0a Mon Sep 17 00:00:00 2001 From: Vika Date: Thu, 22 Jun 2023 21:35:22 +0300 Subject: database: use domains instead of authorities as owner key This allows disregarding http/https comparisons and simplifies some database designs. --- kittybox-rs/src/database/file/mod.rs | 53 +++++++++++++++++++--------------- kittybox-rs/src/database/mod.rs | 12 ++++---- kittybox-rs/src/frontend/mod.rs | 10 +++---- kittybox-rs/src/frontend/onboarding.rs | 11 +++++-- kittybox-rs/src/micropub/mod.rs | 20 ++++++++++--- 5 files changed, 65 insertions(+), 41 deletions(-) (limited to 'kittybox-rs') diff --git a/kittybox-rs/src/database/file/mod.rs b/kittybox-rs/src/database/file/mod.rs index a9de63e..3b373d8 100644 --- a/kittybox-rs/src/database/file/mod.rs +++ b/kittybox-rs/src/database/file/mod.rs @@ -108,9 +108,16 @@ fn url_to_path(root: &Path, url: &str) -> PathBuf { } fn url_to_relative_path(url: &str) -> relative_path::RelativePathBuf { - let url = axum::http::Uri::try_from(url).expect("Couldn't parse a URL"); + let url = url::Url::try_from(url).expect("Couldn't parse a URL"); let mut path = relative_path::RelativePathBuf::new(); - path.push(url.authority().unwrap().to_string() + url.path() + ".json"); + let user_domain = format!( + "{}{}", + url.host_str().unwrap(), + url.port() + .map(|port| format!(":{}", port)) + .unwrap_or_default() + ); + path.push(user_domain + url.path() + ".json"); path } @@ -353,7 +360,17 @@ impl Storage for FileStorage { if let Some(urls) = post["properties"]["url"].as_array() { for url in urls.iter().map(|i| i.as_str().unwrap()) { - if url != key && url.starts_with(user) { + let url_domain = { + let url = url::Url::parse(url).unwrap(); + format!( + "{}{}", + url.host_str().unwrap(), + url.port() + .map(|port| format!(":{}", port)) + .unwrap_or_default() + ) + }; + if url != key && url_domain == user { let link = url_to_path(&self.root_dir, url); debug!("Creating a symlink at {:?}", link); let orig = path.clone(); @@ -377,20 +394,14 @@ impl Storage for FileStorage { .iter() .any(|s| s.as_str() == Some("h-feed")) { - println!("Adding to channel list..."); + tracing::debug!("Adding to channel list..."); // Add the h-feed to the channel list let mut path = relative_path::RelativePathBuf::new(); - path.push( - axum::http::Uri::try_from(user.to_string()) - .unwrap() - .authority() - .unwrap() - .to_string(), - ); + path.push(user); path.push("channels"); - let path = path.to_path(&self.root_dir); - let tempfilename = (&path).with_extension("tmp"); + tracing::debug!("Channels file path: {}", path.display()); + let tempfilename = path.with_extension("tmp"); let channel_name = post["properties"]["name"][0] .as_str() .map(|s| s.to_string()) @@ -468,16 +479,12 @@ impl Storage for FileStorage { #[tracing::instrument(skip(self))] async fn get_channels(&self, user: &'_ str) -> Result> { let mut path = relative_path::RelativePathBuf::new(); - path.push( - axum::http::Uri::try_from(user.to_string()) - .unwrap() - .authority() - .unwrap() - .to_string(), - ); + path.push(user); path.push("channels"); let path = path.to_path(&self.root_dir); + tracing::debug!("Channels file path: {}", path.display()); + match File::open(&path).await { Ok(mut f) => { let mut content = String::new(); @@ -595,9 +602,8 @@ impl Storage for FileStorage { #[tracing::instrument(skip(self))] async fn get_setting, 'a>(&self, user: &'_ str) -> Result { debug!("User for getting settings: {}", user); - let url = axum::http::Uri::try_from(user).expect("Couldn't parse a URL"); let mut path = relative_path::RelativePathBuf::new(); - path.push(url.authority().unwrap().to_string()); + path.push(user); path.push("settings"); let path = path.to_path(&self.root_dir); @@ -616,9 +622,8 @@ impl Storage for FileStorage { #[tracing::instrument(skip(self))] async fn set_setting + 'a, 'a>(&self, user: &'a str, value: S::Data) -> Result<()> { - let url = axum::http::Uri::try_from(user).expect("Couldn't parse a URL"); let mut path = relative_path::RelativePathBuf::new(); - path.push(url.authority().unwrap().to_string()); + path.push(user); path.push("settings"); let path = path.to_path(&self.root_dir); diff --git a/kittybox-rs/src/database/mod.rs b/kittybox-rs/src/database/mod.rs index 4b1b348..aa675d3 100644 --- a/kittybox-rs/src/database/mod.rs +++ b/kittybox-rs/src/database/mod.rs @@ -370,7 +370,7 @@ mod tests { // Reading and writing backend - .put_post(&post, "https://fireburn.ru/") + .put_post(&post, "fireburn.ru") .await .unwrap(); if let Some(returned_post) = backend.get_post(&key).await.unwrap() { @@ -434,7 +434,7 @@ mod tests { // Reading and writing backend - .put_post(&post, "https://fireburn.ru/") + .put_post(&post, "fireburn.ru") .await .unwrap(); @@ -493,10 +493,10 @@ mod tests { "children": [] }); backend - .put_post(&feed, "https://fireburn.ru/") + .put_post(&feed, "fireburn.ru") .await .unwrap(); - let chans = backend.get_channels("https://fireburn.ru/").await.unwrap(); + let chans = backend.get_channels("fireburn.ru").await.unwrap(); assert_eq!(chans.len(), 1); assert_eq!( chans[0], @@ -566,13 +566,13 @@ mod tests { let key = feed["properties"]["uid"][0].as_str().unwrap(); backend - .put_post(&feed, "https://fireburn.ru/") + .put_post(&feed, "fireburn.ru") .await .unwrap(); println!("---"); for (i, post) in posts.iter().enumerate() { backend - .put_post(post, "https://fireburn.ru/") + .put_post(post, "fireburn.ru") .await .unwrap(); println!("posts[{}] = {}", i, post["properties"]["uid"][0]); diff --git a/kittybox-rs/src/frontend/mod.rs b/kittybox-rs/src/frontend/mod.rs index d677005..ed3932b 100644 --- a/kittybox-rs/src/frontend/mod.rs +++ b/kittybox-rs/src/frontend/mod.rs @@ -132,13 +132,13 @@ pub async fn homepage( // // btw is it more efficient to fetch these in parallel? let (blogname, webring, channels) = tokio::join!( - db.get_setting::(&path) + db.get_setting::(&host) .map(Result::unwrap_or_default), - db.get_setting::(&path) + db.get_setting::(&host) .map(Result::unwrap_or_default), - db.get_channels(&path).map(|i| i.unwrap_or_default()) + db.get_channels(&host).map(|i| i.unwrap_or_default()) ); // Render the homepage ( @@ -176,10 +176,10 @@ pub async fn homepage( error!("Error while fetching h-card and/or h-feed: {}", err); // Return the error let (blogname, channels) = tokio::join!( - db.get_setting::(&path) + db.get_setting::(&host) .map(Result::unwrap_or_default), - db.get_channels(&path).map(|i| i.unwrap_or_default()) + db.get_channels(&host).map(|i| i.unwrap_or_default()) ); ( diff --git a/kittybox-rs/src/frontend/onboarding.rs b/kittybox-rs/src/frontend/onboarding.rs index f797abd..3f73e62 100644 --- a/kittybox-rs/src/frontend/onboarding.rs +++ b/kittybox-rs/src/frontend/onboarding.rs @@ -68,11 +68,18 @@ async fn onboard( )); } - db.set_setting::(user.me.as_str(), data.blog_name.to_owned()) + let user_domain = format!( + "{}{}", + user.me.host_str().unwrap(), + user.me.port() + .map(|port| format!(":{}", port)) + .unwrap_or_default() + ); + db.set_setting::(&user_domain, data.blog_name.to_owned()) .await .map_err(FrontendError::from)?; - db.set_setting::(user.me.as_str(), false) + db.set_setting::(&user_domain, false) .await .map_err(FrontendError::from)?; diff --git a/kittybox-rs/src/micropub/mod.rs b/kittybox-rs/src/micropub/mod.rs index ee4d334..5c297f9 100644 --- a/kittybox-rs/src/micropub/mod.rs +++ b/kittybox-rs/src/micropub/mod.rs @@ -262,9 +262,15 @@ pub(crate) async fn _post( error_description: "UID clash was detected, operation aborted.".to_owned(), }); } - + let user_domain = format!( + "{}{}", + user.me.host_str().unwrap(), + user.me.port() + .map(|port| format!(":{}", port)) + .unwrap_or_default() + ); // Save the post - db.put_post(&mf2, user.me.as_str()).await?; + db.put_post(&mf2, &user_domain).await?; let mut channels = mf2["properties"]["channel"] .as_array() @@ -521,7 +527,13 @@ pub(crate) async fn query( .into_response(); } - + let user_domain = format!( + "{}{}", + user.me.host_str().unwrap(), + user.me.port() + .map(|port| format!(":{}", port)) + .unwrap_or_default() + ); match query.q { QueryType::Config => { let channels: Vec = match db.get_channels(user.me.as_str()).await { @@ -580,7 +592,7 @@ pub(crate) async fn query( } } } - QueryType::Channel => match db.get_channels(user.me.as_str()).await { + QueryType::Channel => match db.get_channels(&user_domain).await { Ok(chans) => axum::response::Json(json!({ "channels": chans })).into_response(), Err(err) => MicropubError::new( ErrorType::InternalServerError, -- cgit 1.4.1