about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2023-06-22 21:35:22 +0300
committerVika <vika@fireburn.ru>2023-06-22 21:35:22 +0300
commit858c0ddd9cc36af0acc72efb1ff1bdc1d8e28b0a (patch)
tree5b46bcc88e37fa0e23fea4f49c0242ad21662bca
parentd61e1f6a8e5ad5b7c14b1f9ab3101496f3f9ea00 (diff)
downloadkittybox-858c0ddd9cc36af0acc72efb1ff1bdc1d8e28b0a.tar.zst
database: use domains instead of authorities as owner key
This allows disregarding http/https comparisons and simplifies some
database designs.
-rw-r--r--kittybox-rs/src/database/file/mod.rs53
-rw-r--r--kittybox-rs/src/database/mod.rs12
-rw-r--r--kittybox-rs/src/frontend/mod.rs10
-rw-r--r--kittybox-rs/src/frontend/onboarding.rs11
-rw-r--r--kittybox-rs/src/micropub/mod.rs20
5 files changed, 65 insertions, 41 deletions
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<Vec<super::MicropubChannel>> {
         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<S: settings::Setting<'a>, 'a>(&self, user: &'_ str) -> Result<S> {
         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<S: settings::Setting<'a> + '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<D: Storage>(
             //
             // btw is it more efficient to fetch these in parallel?
             let (blogname, webring, channels) = tokio::join!(
-                db.get_setting::<crate::database::settings::SiteName>(&path)
+                db.get_setting::<crate::database::settings::SiteName>(&host)
                 .map(Result::unwrap_or_default),
 
-                db.get_setting::<crate::database::settings::Webring>(&path)
+                db.get_setting::<crate::database::settings::Webring>(&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<D: Storage>(
                 error!("Error while fetching h-card and/or h-feed: {}", err);
                 // Return the error
                 let (blogname, channels) = tokio::join!(
-                    db.get_setting::<crate::database::settings::SiteName>(&path)
+                    db.get_setting::<crate::database::settings::SiteName>(&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<D: Storage + 'static>(
         ));
     }
 
-    db.set_setting::<settings::SiteName>(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::<settings::SiteName>(&user_domain, data.blog_name.to_owned())
         .await
         .map_err(FrontendError::from)?;
 
-    db.set_setting::<settings::Webring>(user.me.as_str(), false)
+    db.set_setting::<settings::Webring>(&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<D: 'static + Storage>(
             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<D: Storage, A: AuthBackend>(
             .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<MicropubChannel> = match db.get_channels(user.me.as_str()).await {
@@ -580,7 +592,7 @@ pub(crate) async fn query<D: Storage, A: AuthBackend>(
                 }
             }
         }
-        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,