about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVika Shleina <vika@fireburn.ru>2021-07-19 10:32:42 +0300
committerVika Shleina <vika@fireburn.ru>2021-07-19 10:55:32 +0300
commit47c3b54d1d0b276fb87d1b4b71a584e0e0c7b43d (patch)
tree9b9b9d2512a91da502187d17cb9c1e5dce398009 /src
parent8399371adc5c48e1847061deee1936c0d64f2a85 (diff)
downloadkittybox-47c3b54d1d0b276fb87d1b4b71a584e0e0c7b43d.tar.zst
Relaxed anti-takeover URL check to simply not place redirects at foreign URLs
Diffstat (limited to 'src')
-rw-r--r--src/database/mod.rs6
-rw-r--r--src/database/redis/mod.rs4
-rw-r--r--src/frontend/mod.rs4
-rw-r--r--src/lib.rs5
-rw-r--r--src/micropub/post.rs11
5 files changed, 14 insertions, 16 deletions
diff --git a/src/database/mod.rs b/src/database/mod.rs
index 8579125..e0e4e7b 100644
--- a/src/database/mod.rs
+++ b/src/database/mod.rs
@@ -123,7 +123,7 @@ pub trait Storage: Clone + Send + Sync {
     /// Save a post to the database as an MF2-JSON structure.
     ///
     /// Note that the `post` object MUST have `post["properties"]["uid"][0]` defined.
-    async fn put_post<'a>(&self, post: &'a serde_json::Value) -> Result<()>;
+    async fn put_post<'a>(&self, post: &'a serde_json::Value, user: &'a str) -> Result<()>;
 
     /*/// Save a post and add it to the relevant feeds listed in `post["properties"]["channel"]`.
     ///
@@ -198,7 +198,7 @@ mod tests {
         let alt_url = post["properties"]["url"][1].as_str().unwrap().to_string();
 
         // Reading and writing
-        backend.put_post(&post).await.unwrap();
+        backend.put_post(&post, "https://fireburn.ru/").await.unwrap();
         if let Ok(Some(returned_post)) = backend.get_post(&key).await {
             assert!(returned_post.is_object());
             assert_eq!(
@@ -254,7 +254,7 @@ mod tests {
             },
             "children": []
         });
-        backend.put_post(&feed).await.unwrap();
+        backend.put_post(&feed, "https://fireburn.ru/").await.unwrap();
         let chans = backend
             .get_channels(&crate::indieauth::User::new(
                 "https://fireburn.ru/",
diff --git a/src/database/redis/mod.rs b/src/database/redis/mod.rs
index e64120f..c331e47 100644
--- a/src/database/redis/mod.rs
+++ b/src/database/redis/mod.rs
@@ -180,7 +180,7 @@ impl Storage for RedisStorage {
         .collect::<Vec<_>>())
     }
 
-    async fn put_post<'a>(&self, post: &'a serde_json::Value) -> Result<()> {
+    async fn put_post<'a>(&self, post: &'a serde_json::Value, user: &'a str) -> Result<()> {
         let mut conn = self.redis.get().await?;
         let key: &str;
         match post["properties"]["uid"][0].as_str() {
@@ -201,7 +201,7 @@ impl Storage for RedisStorage {
                 .iter()
                 .map(|i| i.as_str().unwrap().to_string())
             {
-                if url != key {
+                if url != key && url.starts_with(user) {
                     conn.hset::<&str, &str, String, ()>(
                         &"posts",
                         &url,
diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs
index a92d769..c698370 100644
--- a/src/frontend/mod.rs
+++ b/src/frontend/mod.rs
@@ -751,7 +751,7 @@ pub async fn onboarding_receiver<S: Storage>(mut req: Request<ApplicationState<S
     // post function is just to ensure that the posts will be syndicated
     // and inserted into proper feeds. Here, we don't have a need for this,
     // since the h-card is DIRECTLY accessible via its own URL.
-    backend.put_post(&hcard).await?;
+    backend.put_post(&hcard, me.as_str()).await?;
 
     for feed in body.feeds {
         let (_, feed) = crate::micropub::normalize_mf2(
@@ -762,7 +762,7 @@ pub async fn onboarding_receiver<S: Storage>(mut req: Request<ApplicationState<S
             &user,
         );
 
-        backend.put_post(&feed).await?;
+        backend.put_post(&feed, me.as_str()).await?;
     }
 
     // This basically puts the h-entry post through the normal creation process.
diff --git a/src/lib.rs b/src/lib.rs
index 91dd340..0ea7860 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -164,7 +164,10 @@ mod tests {
             }),
         )
         .await;
-        assert_eq!(response.status(), 403);
+        // Should be posted successfully, but...
+        assert!(response.status() == 201 || response.status() == 202);
+        // ...won't be available on a foreign URL
+        assert!(db.get_post("https://aaronparecki.com/posts/more-fake-news").await.unwrap().is_none());
 
         let response = post_json(&app, json!({
             "type": ["h-entry"],
diff --git a/src/micropub/post.rs b/src/micropub/post.rs
index 639346b..eaa603a 100644
--- a/src/micropub/post.rs
+++ b/src/micropub/post.rs
@@ -171,12 +171,7 @@ pub async fn new_post<S: Storage>(
     // This software might also be used in a multi-user setting
     // where several users or identities share one Micropub server
     // (maybe a family website or a shitpost sideblog?)
-    if post["properties"]["url"]
-        .as_array()
-        .unwrap()
-        .iter()
-        .any(|url| !url.as_str().unwrap().starts_with(user.me.as_str()))
-        || !post["properties"]["uid"][0]
+    if !post["properties"]["uid"][0]
             .as_str()
             .unwrap()
             .starts_with(user.me.as_str())
@@ -209,7 +204,7 @@ pub async fn new_post<S: Storage>(
         Err(err) => return Ok(err.into()),
     }
 
-    if let Err(err) = storage.put_post(&post).await {
+    if let Err(err) = storage.put_post(&post, user.me.as_str()).await {
         return error_json!(500, "database_error", format!("{}", err));
     }
 
@@ -303,7 +298,7 @@ async fn create_feed(
         }),
         &user,
     );
-    storage.put_post(&feed).await
+    storage.put_post(&feed, user.me.as_str()).await
 }
 
 async fn post_process_new_post<S: Storage>(