diff --git a/Cargo.lock b/Cargo.lock index e8f4c8d..a2babaf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,6 +417,7 @@ dependencies = [ "dotenvy", "hyper", "magnetar_core", + "magnetar_webfinger", "rand", "ring", "rsa", @@ -451,6 +452,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "magnetar_webfinger" +version = "0.1.0" +dependencies = [ + "magnetar_core", + "serde", + "serde_json", +] + [[package]] name = "matchers" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index e3c5621..a240a17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,11 +10,13 @@ members = [ ".", "ext_activity_pub", "ext_nodeinfo", + "ext_webfinger", "core" ] [dependencies] magnetar_core = { path = "./core", version = "0.1" } +magnetar_webfinger = { path = "./ext_webfinger", version = "0.1"} anyhow = "1.0" diff --git a/core/src/web_model/acct.rs b/core/src/web_model/acct.rs new file mode 100644 index 0000000..b2a0ff5 --- /dev/null +++ b/core/src/web_model/acct.rs @@ -0,0 +1,69 @@ +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use std::borrow::Cow; + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct Acct(String); + +impl Acct { + pub fn new(uri_without_acct: Cow<'_, str>) -> Self { + Acct(uri_without_acct.to_string()) + } +} + +impl From<&str> for Acct { + fn from(value: &str) -> Self { + Acct(value.strip_prefix("acct:").unwrap_or(value).to_string()) + } +} + +impl AsRef for Acct { + fn as_ref(&self) -> &str { + &self.0 + } +} + +impl Serialize for Acct { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&format!("acct:{}", self.0)) + } +} + +impl<'de> Deserialize<'de> for Acct { + fn deserialize>(deserializer: D) -> Result { + let acct = String::deserialize(deserializer)?; + + if let Some(rem) = acct.strip_prefix("acct:") { + Ok(Acct(rem.to_owned())) + } else { + Err(de::Error::custom( + "Missing acct protocol for account!".to_owned(), + )) + } + } +} + +#[cfg(test)] +mod test { + use crate::web_model::acct::Acct; + use serde_json::json; + + #[test] + fn should_remove_acct_prefix() { + let json = json!("acct:natty@tech.lgbt"); + + let acct: Acct = serde_json::from_value(json).unwrap(); + + assert_eq!(acct, Acct::from("natty@tech.lgbt")) + } + + #[test] + fn should_add_acct_prefix() { + let acct = Acct::from("natty@tech.lgbt"); + let json = serde_json::to_value(acct).unwrap(); + + assert_eq!(json, json!("acct:natty@tech.lgbt")); + } +} diff --git a/core/src/web_model/mod.rs b/core/src/web_model/mod.rs index 69b3fdb..2fe261b 100644 --- a/core/src/web_model/mod.rs +++ b/core/src/web_model/mod.rs @@ -4,8 +4,8 @@ use serde_json::Value; use std::fmt::Debug; use std::str::FromStr; +pub mod acct; pub mod activity_streams; -pub mod webfinger; trait ContentType: Serialize { fn mime_type(&self) -> &'static str; diff --git a/ext_webfinger/Cargo.toml b/ext_webfinger/Cargo.toml new file mode 100644 index 0000000..c8c3448 --- /dev/null +++ b/ext_webfinger/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "magnetar_webfinger" +version = "0.1.0" +edition = "2021" + +[dependencies] +magnetar_core = { path = "../core", version = "0.1" } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" \ No newline at end of file diff --git a/ext_webfinger/src/lib.rs b/ext_webfinger/src/lib.rs new file mode 100644 index 0000000..a5a4087 --- /dev/null +++ b/ext_webfinger/src/lib.rs @@ -0,0 +1 @@ +pub mod webfinger; diff --git a/core/src/web_model/webfinger/mod.rs b/ext_webfinger/src/webfinger.rs similarity index 58% rename from core/src/web_model/webfinger/mod.rs rename to ext_webfinger/src/webfinger.rs index 158132b..f1486a8 100644 --- a/core/src/web_model/webfinger/mod.rs +++ b/ext_webfinger/src/webfinger.rs @@ -1,8 +1,7 @@ -use crate::web_model::content_type::{ContentActivityStreams, ContentHtml}; -use crate::web_model::rel::{RelOStatusSubscribe, RelSelf, RelWebFingerProfilePage}; -use serde::de::Error; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::borrow::Cow; +use magnetar_core::web_model::acct::Acct; +use magnetar_core::web_model::content_type::{ContentActivityStreams, ContentHtml}; +use magnetar_core::web_model::rel::{RelOStatusSubscribe, RelSelf, RelWebFingerProfilePage}; +use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] pub struct WebFinger { @@ -40,75 +39,15 @@ pub enum WebFingerRel { }, } -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct Acct(String); - -impl Acct { - pub fn new(uri_without_acct: Cow<'_, str>) -> Self { - Acct(uri_without_acct.to_string()) - } -} - -impl From<&str> for Acct { - fn from(value: &str) -> Self { - Acct(value.strip_prefix("acct:").unwrap_or(value).to_string()) - } -} - -impl AsRef for Acct { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl Serialize for Acct { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&format!("acct:{}", self.0)) - } -} - -impl<'de> Deserialize<'de> for Acct { - fn deserialize>(deserializer: D) -> Result { - let acct = String::deserialize(deserializer)?; - - if let Some(rem) = acct.strip_prefix("acct:") { - Ok(Acct(rem.to_owned())) - } else { - Err(Error::custom( - "Missing acct protocol for account!".to_owned(), - )) - } - } -} - #[cfg(test)] mod test { - use crate::web_model::content_type::{ContentActivityStreams, ContentHtml}; - use crate::web_model::rel::{RelOStatusSubscribe, RelSelf, RelWebFingerProfilePage}; - use crate::web_model::webfinger::WebFingerSubject::Url; - use crate::web_model::webfinger::{Acct, WebFinger, WebFingerRel, WebFingerSubject}; + use crate::webfinger::WebFingerSubject::Url; + use crate::webfinger::{WebFinger, WebFingerRel, WebFingerSubject}; + use magnetar_core::web_model::acct::Acct; + use magnetar_core::web_model::content_type::{ContentActivityStreams, ContentHtml}; + use magnetar_core::web_model::rel::{RelOStatusSubscribe, RelSelf, RelWebFingerProfilePage}; use serde_json::json; - #[test] - fn should_remove_acct_prefix() { - let json = json!("acct:natty@tech.lgbt"); - - let acct: Acct = serde_json::from_value(json).unwrap(); - - assert_eq!(acct, Acct("natty@tech.lgbt".to_owned())) - } - - #[test] - fn should_add_acct_prefix() { - let acct = Acct("natty@tech.lgbt".to_owned()); - let json = serde_json::to_value(acct).unwrap(); - - assert_eq!(json, json!("acct:natty@tech.lgbt")); - } - #[test] fn should_parse_webfinger() { let json = json!({ diff --git a/src/main.rs b/src/main.rs index c400e7a..a561d02 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ pub mod config; pub mod webfinger; -use anyhow::{anyhow, Context}; +use anyhow::anyhow; use axum::routing::get; use axum::Router; use dotenvy::dotenv; diff --git a/src/webfinger.rs b/src/webfinger.rs index e38f57b..870e87a 100644 --- a/src/webfinger.rs +++ b/src/webfinger.rs @@ -1,9 +1,10 @@ use axum::extract::Query; use axum::http::StatusCode; use axum::Json; +use magnetar_core::web_model::acct::Acct; use magnetar_core::web_model::content_type::{ContentActivityStreams, ContentHtml}; use magnetar_core::web_model::rel::{RelOStatusSubscribe, RelSelf, RelWebFingerProfilePage}; -use magnetar_core::web_model::webfinger::{Acct, WebFinger, WebFingerRel, WebFingerSubject}; +use magnetar_webfinger::webfinger::{WebFinger, WebFingerRel, WebFingerSubject}; use serde::Deserialize; #[derive(Deserialize)]