about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/database/mod.rs9
-rw-r--r--src/database/postgres/mod.rs67
-rw-r--r--src/frontend/mod.rs2
-rw-r--r--src/frontend/onboarding.rs7
-rw-r--r--src/indieauth/mod.rs4
-rw-r--r--src/lib.rs2
-rw-r--r--src/login.rs5
-rw-r--r--src/media/storage/file.rs8
-rw-r--r--src/micropub/mod.rs27
-rw-r--r--src/webmentions/check.rs4
-rw-r--r--src/webmentions/check/rcdom.rs2
-rw-r--r--templates/build.rs8
-rw-r--r--util/src/lib.rs8
-rw-r--r--util/src/micropub.rs3
14 files changed, 38 insertions, 118 deletions
diff --git a/src/database/mod.rs b/src/database/mod.rs
index 7b50196..3b13cb3 100644
--- a/src/database/mod.rs
+++ b/src/database/mod.rs
@@ -55,7 +55,9 @@ pub mod settings {
     /// implementations, as it wouldn't make sense to add new settings
     /// that aren't used by Kittybox itself.
     pub trait Setting<'de>: private::Sealed + std::fmt::Debug + Default + Clone + serde::Serialize + serde::de::DeserializeOwned + /*From<Settings> +*/ Send + Sync {
+        /// The data that the setting carries.
         type Data: std::fmt::Debug + Send + Sync;
+        /// The string ID for the setting, usable as an identifier in the database.
         const ID: &'static str;
 
         /// Unwrap the setting type, returning owned data contained within.
@@ -89,11 +91,6 @@ pub mod settings {
             Self(data)
         }
     }
-    impl SiteName {
-        fn from_str(data: &str) -> Self {
-            Self(data.to_owned())
-        }
-    }
 
     /// Participation status in the IndieWeb Webring: https://πŸ•ΈπŸ’.ws/dashboard
     #[derive(Debug, Default, serde::Deserialize, serde::Serialize, Clone, Copy, PartialEq, Eq)]
@@ -600,7 +597,7 @@ mod tests {
             .await
             .unwrap();
 
-        for (i, post) in posts.iter().rev().enumerate() {
+        for post in posts.iter().rev() {
             backend
                 .put_post(post, &"https://fireburn.ru/".parse().unwrap())
                 .await
diff --git a/src/database/postgres/mod.rs b/src/database/postgres/mod.rs
index 1780672..b2d4339 100644
--- a/src/database/postgres/mod.rs
+++ b/src/database/postgres/mod.rs
@@ -247,11 +247,6 @@ WHERE
 
     #[tracing::instrument(skip(self))]
     async fn get_channels(&self, user: &url::Url) -> Result<Vec<MicropubChannel>> {
-        /*sqlx::query_as::<_, MicropubChannel>("SELECT name, uid FROM kittybox.channels WHERE owner = $1")
-            .bind(user)
-            .fetch_all(&self.db)
-            .await
-            .map_err(|err| err.into())*/
         sqlx::query_as::<_, MicropubChannel>(r#"SELECT mf2 #>> '{properties,name,0}' as name, uid FROM kittybox.mf2_json WHERE '["h-feed"]'::jsonb @> mf2['type'] AND owner = $1"#)
             .bind(user.authority())
             .fetch_all(&self.db)
@@ -263,67 +258,11 @@ WHERE
     async fn read_feed_with_limit(
         &self,
         url: &'_ str,
-        after: Option<&str>,
-        limit: usize,
-        // BUG: this doesn't seem to be used?!
-        user: Option<&url::Url>,
+        _after: Option<&str>,
+        _limit: usize,
+        _user: Option<&url::Url>,
     ) -> Result<Option<serde_json::Value>> {
         unimplemented!("read_feed_with_limit is insecure and deprecated");
-        let mut feed = match sqlx::query_as::<_, (serde_json::Value,)>("
-SELECT jsonb_set(
-    mf2,
-    '{properties,author,0}',
-    (SELECT mf2 FROM kittybox.mf2_json
-     WHERE uid = mf2 #>> '{properties,author,0}')
-) FROM kittybox.mf2_json WHERE uid = $1 OR mf2['properties']['url'] ? $1
-")
-            .bind(url)
-            .fetch_optional(&self.db)
-            .await?
-            .map(|v| v.0)
-        {
-            Some(feed) => feed,
-            None => return Ok(None)
-        };
-
-        let posts: Vec<String> = {
-            let mut posts_iter = feed["children"]
-                .as_array()
-                .cloned()
-                .unwrap_or_default()
-                .into_iter()
-                .map(|s| s.as_str().unwrap().to_string());
-            if let Some(after) = after {
-                for s in posts_iter.by_ref() {
-                    if &s == after {
-                        break;
-                    }
-                }
-            };
-
-            posts_iter.take(limit).collect::<Vec<_>>()
-        };
-        feed["children"] = serde_json::Value::Array(
-            sqlx::query_as::<_, (serde_json::Value,)>("
-SELECT jsonb_set(
-    mf2,
-    '{properties,author,0}',
-    (SELECT mf2 FROM kittybox.mf2_json
-     WHERE uid = mf2 #>> '{properties,author,0}')
-) FROM kittybox.mf2_json
-WHERE uid = ANY($1)
-ORDER BY mf2 #>> '{properties,published,0}' DESC
-")
-                .bind(&posts[..])
-                .fetch_all(&self.db)
-                .await?
-                .into_iter()
-                .map(|v| v.0)
-                .collect::<Vec<_>>()
-        );
-
-        Ok(Some(feed))
-
     }
 
     #[tracing::instrument(skip(self))]
diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs
index 81a03ed..4120b55 100644
--- a/src/frontend/mod.rs
+++ b/src/frontend/mod.rs
@@ -192,7 +192,7 @@ async fn get_post_from_database<S: Storage>(
         .await
     {
         Ok(result) => match result {
-            Some((post, cursor)) => match filter_post(post, user.as_deref()) {
+            Some((post, cursor)) => match filter_post(post, user) {
                 Some(post) => Ok((post, cursor)),
                 None => {
                     // TODO: Authentication
diff --git a/src/frontend/onboarding.rs b/src/frontend/onboarding.rs
index 9f3f36b..be1669f 100644
--- a/src/frontend/onboarding.rs
+++ b/src/frontend/onboarding.rs
@@ -75,13 +75,6 @@ async fn onboard<D: Storage + 'static>(
     }
 
     tracing::debug!("Setting settings...");
-    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.me, data.blog_name.to_owned())
         .await
         .map_err(FrontendError::from)?;
diff --git a/src/indieauth/mod.rs b/src/indieauth/mod.rs
index 036a379..322a0e2 100644
--- a/src/indieauth/mod.rs
+++ b/src/indieauth/mod.rs
@@ -3,7 +3,7 @@ use microformats::types::Class;
 use tracing::error;
 use serde::Deserialize;
 use axum::{
-    extract::{Form, FromRef, Host, Json, Query, State}, http::StatusCode, response::{Html, IntoResponse, Response}, Extension
+    extract::{Form, FromRef, Host, Json, Query, State}, http::StatusCode, response::{Html, IntoResponse, Response}
 };
 #[cfg_attr(not(feature = "webauthn"), allow(unused_imports))]
 use axum_extra::extract::cookie::{CookieJar, Cookie};
@@ -154,7 +154,7 @@ async fn authorization_endpoint_get<A: AuthBackend, D: Storage + 'static>(
                 let text = response.text().await.unwrap();
                 tracing::debug!("Received {} bytes in response", text.len());
                 match microformats::from_html(&text, url) {
-                    Ok(mut mf2) => {
+                    Ok(mf2) => {
                         if let Some(relation) = mf2.rels.items.get(&request.redirect_uri) {
                             if !relation.rels.iter().any(|i| i == "redirect_uri") {
                                 return (StatusCode::BAD_REQUEST,
diff --git a/src/lib.rs b/src/lib.rs
index f1a563e..596ffc0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,7 +3,7 @@
 
 use std::sync::Arc;
 
-use axum::{extract::{FromRef, FromRequestParts}, response::IntoResponse};
+use axum::extract::{FromRef, FromRequestParts};
 use axum_extra::extract::{cookie::Key, SignedCookieJar};
 use database::{FileStorage, PostgresStorage, Storage};
 use indieauth::backend::{AuthBackend, FileBackend as FileAuthBackend};
diff --git a/src/login.rs b/src/login.rs
index f1e2c81..bfa84b3 100644
--- a/src/login.rs
+++ b/src/login.rs
@@ -1,8 +1,8 @@
 use std::borrow::Cow;
 
 use futures_util::FutureExt;
-use axum::{extract::{FromRef, Host, OriginalUri, Query, State}, http::HeaderValue, response::IntoResponse, Form};
-use axum_extra::{extract::{cookie::{self, Cookie}, CookieJar, SignedCookieJar}, headers::Header, TypedHeader};
+use axum::{extract::{FromRef, Host, Query, State}, http::HeaderValue, response::IntoResponse, Form};
+use axum_extra::extract::{cookie::{self, Cookie}, SignedCookieJar};
 use hyper::{header::{CACHE_CONTROL, LOCATION}, StatusCode};
 use kittybox_frontend_renderer::{Template, LoginPage, LogoutPage};
 use kittybox_indieauth::{AuthorizationResponse, Error, GrantType, PKCEVerifier, Scope, Scopes};
@@ -94,6 +94,7 @@ async fn post(
     };
 
     // XXX: Blocked on https://github.com/hyperium/headers/pull/113
+    // use axum_extra::{headers::Header, TypedHeader};
     // let links = response
     //     .headers()
     //     .iter()
diff --git a/src/media/storage/file.rs b/src/media/storage/file.rs
index 7250a6b..b9ab541 100644
--- a/src/media/storage/file.rs
+++ b/src/media/storage/file.rs
@@ -4,7 +4,7 @@ use std::{path::PathBuf, fmt::Debug};
 use tokio::fs::OpenOptions;
 use tokio::io::{BufReader, BufWriter, AsyncWriteExt, AsyncSeekExt};
 use futures::{StreamExt, TryStreamExt};
-use std::ops::{Bound, RangeBounds, Neg};
+use std::ops::{Bound, Neg};
 use std::pin::Pin;
 use sha2::Digest;
 use futures::FutureExt;
@@ -73,7 +73,7 @@ impl MediaStore for FileStore {
                     let chunk = chunk.clone();
                     let tempfile = &mut tempfile;
                     async move {
-                        tempfile.write_all(&*chunk).await
+                        tempfile.write_all(&chunk).await
                     }
                 },
                 {
@@ -102,7 +102,7 @@ impl MediaStore for FileStore {
         tempfile.into_inner().sync_all().await?;
 
         let hash = hasher.finalize();
-        debug!("Pending upload hash: {}", hex::encode(&hash));
+        debug!("Pending upload hash: {}", hex::encode(hash));
         let filename = format!(
             "{}/{}/{}/{}/{}",
             hex::encode([hash[0]]),
@@ -117,7 +117,7 @@ impl MediaStore for FileStore {
         let metapath = self.base.join(domain_str.as_str()).join(&metafilename);
         let metatemppath = self.base.join(domain_str.as_str()).join(metafilename + ".tmp");
         metadata.length = std::num::NonZeroUsize::new(length);
-        metadata.etag = Some(hex::encode(&hash));
+        metadata.etag = Some(hex::encode(hash));
         debug!("File path: {}, metadata: {}", filepath.display(), metapath.display());
         {
             let parent = filepath.parent().unwrap();
diff --git a/src/micropub/mod.rs b/src/micropub/mod.rs
index 65519e4..08150d2 100644
--- a/src/micropub/mod.rs
+++ b/src/micropub/mod.rs
@@ -67,7 +67,7 @@ fn populate_reply_context(
                 if item.is_object() && (i != &item) {
                     if let Some(props) = item["properties"].as_object_mut() {
                         // Fixup the item: if it lacks a URL, add one.
-                        if !props.get("url").and_then(serde_json::Value::as_array).map(|a| a.len() > 0).unwrap_or(false) {
+                        if !props.get("url").and_then(serde_json::Value::as_array).map(|a| !a.is_empty()).unwrap_or(false) {
                             props.insert("url".to_owned(), json!([i.as_str()]));
                         }
                     }
@@ -191,9 +191,9 @@ async fn background_processing<D: 'static + Storage>(
         tokio_stream::iter(
             post_contexts
                 .into_iter()
-                .filter(|(url, ctx)| ctx.webmention.is_some()),
+                .filter(|(_url, ctx)| ctx.webmention.is_some()),
         )
-        .for_each_concurrent(2, |(url, ctx)| async move {
+        .for_each_concurrent(2, |(_url, ctx)| async move {
             let mut map = std::collections::HashMap::new();
             map.insert("source", uid);
             map.insert("target", ctx.url.as_str());
@@ -274,13 +274,6 @@ 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
     tracing::debug!("Saving post to database...");
     db.put_post(&mf2, &user.me).await?;
@@ -303,7 +296,7 @@ pub(crate) async fn _post<D: 'static + Storage>(
         .unwrap()
         .to_string();
     let food_channel = user.me.join(util::FOOD_CHANNEL_PATH).unwrap().to_string();
-    let default_channels = vec![default_channel, vcards_channel, food_channel];
+    let default_channels = [default_channel, vcards_channel, food_channel];
 
     for chan in &mut channels {
         debug!("Adding post {} to channel {}", uid, chan);
@@ -562,13 +555,7 @@ pub(crate) async fn query<D: Storage, A: AuthBackend>(
     }
 
     // TODO: consider replacing by `user.me.authority()`?
-    let user_domain = format!(
-        "{}{}",
-        user.me.host_str().unwrap(),
-        user.me.port()
-            .map(|port| format!(":{}", port))
-            .unwrap_or_default()
-    );
+    let user_domain = user.me.authority();
     match query.q {
         QueryType::Config => {
             let channels: Vec<MicropubChannel> = match db.get_channels(&user.me).await {
@@ -645,7 +632,7 @@ pub(crate) async fn query<D: Storage, A: AuthBackend>(
             axum::response::Json(json!({ "syndicate-to": [] })).into_response()
         },
         QueryType::Category => {
-            let categories = match db.categories(&user_domain).await {
+            let categories = match db.categories(user_domain).await {
                 Ok(categories) => categories,
                 Err(err) => {
                     return MicropubError::new(
@@ -844,7 +831,7 @@ mod tests {
 
     #[tokio::test]
     async fn test_query_foreign_url() {
-        let mut res = super::query(
+        let res = super::query(
             State(crate::database::MemoryStorage::default()),
             Some(axum::extract::Query(super::MicropubQuery::source(
                 "https://aaronparecki.com/feeds/main",
diff --git a/src/webmentions/check.rs b/src/webmentions/check.rs
index 178c008..683cc6b 100644
--- a/src/webmentions/check.rs
+++ b/src/webmentions/check.rs
@@ -38,7 +38,7 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url
                     if let PropertyValue::Url(url) = val {
                         if url == link {
                             tracing::debug!("URL matches! Webmention is valid");
-                            return Ok(Some((interaction_type, serde_json::to_value(&*item).unwrap())))
+                            return Ok(Some((interaction_type, serde_json::to_value(item).unwrap())))
                         }
                     }
                 }
@@ -101,7 +101,7 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url
                             }
                         }
                         if is_mention {
-                            return Ok(Some((MentionType::Mention, serde_json::to_value(&*item).unwrap())));
+                            return Ok(Some((MentionType::Mention, serde_json::to_value(item).unwrap())));
                         }
                     }
                 }
diff --git a/src/webmentions/check/rcdom.rs b/src/webmentions/check/rcdom.rs
index 549610f..08408a2 100644
--- a/src/webmentions/check/rcdom.rs
+++ b/src/webmentions/check/rcdom.rs
@@ -7,7 +7,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(missing_docs)]
+#![allow(missing_docs, dead_code)]
 
 //! A simple reference-counted DOM.
 //!
diff --git a/templates/build.rs b/templates/build.rs
index bdf99fa..ac77059 100644
--- a/templates/build.rs
+++ b/templates/build.rs
@@ -22,7 +22,7 @@ fn main() -> Result<(), std::io::Error> {
 
     println!("cargo:rerun-if-changed=assets/");
     let assets_path = std::path::Path::new("assets");
-    let mut assets = WalkDir::new(&assets_path)
+    let mut assets = WalkDir::new(assets_path)
         .into_iter();
     while let Some(Ok(entry)) = assets.next() {
         if entry.file_type().is_dir() {
@@ -64,19 +64,19 @@ fn main() -> Result<(), std::io::Error> {
                 .write(true)
                 .open(&gzip_path)?;
 
-            let mut in_file = std::fs::File::open(&normal_path)?;
+            let mut in_file = std::fs::File::open(normal_path)?;
 
             let mut encoder = Encoder::new(&mut out_file)?;
             std::io::copy(&mut in_file, &mut encoder)?;
             encoder.finish().into_result()?;
         }
 
-        let normal_len: f64 = std::fs::metadata(&normal_path).unwrap().len() as f64;
+        let normal_len: f64 = std::fs::metadata(normal_path).unwrap().len() as f64;
         let gzipped_len: f64 = std::fs::metadata(&gzip_path).unwrap().len() as f64;
         let ratio = gzipped_len / normal_len;
         eprintln!("Ratio: {}", ratio);
         if ratio <= 0.9 {
-            std::fs::remove_file(&normal_path)?
+            std::fs::remove_file(normal_path)?
         } else {
             println!(
                 "cargo:warning={} compression ratio is {} (> 0.9), leaving as is",
diff --git a/util/src/lib.rs b/util/src/lib.rs
index f92ee1b..cb5f666 100644
--- a/util/src/lib.rs
+++ b/util/src/lib.rs
@@ -22,13 +22,13 @@ pub enum MentionType {
 
 /// Common data-types useful in creating smart authentication systems.
 pub mod auth {
+    /// Various types of credentials Kittybox can use.
     #[derive(PartialEq, Eq, Hash, Clone, Copy)]
     pub enum EnrolledCredential {
-        /// An indicator that a password is enrolled. Passwords can be
-        /// used to recover from a lost token.
+        /// Denotes availability of a password. Passwords can be
+        /// used to recover from a lost passkey.
         Password,
-        /// An indicator that one or more WebAuthn credentials were
-        /// enrolled.
+        /// Denotes availability of one or more passkeys.
         WebAuthn
     }
 }
diff --git a/util/src/micropub.rs b/util/src/micropub.rs
index ce9e2d7..6127079 100644
--- a/util/src/micropub.rs
+++ b/util/src/micropub.rs
@@ -1,3 +1,6 @@
+//! Common protocol types for Micropub.
+//!
+//! Check out the [`kittybox-indieauth`] crate that gives similar treatment to IndieAuth.
 use std::collections::HashMap;
 
 use serde::{Deserialize, Serialize};