stuff
This commit is contained in:
parent
d0f37c699f
commit
bff0567c27
13 changed files with 56 additions and 35 deletions
|
|
@ -12,9 +12,9 @@ use activitypub_federation::{
|
|||
kinds::activity::CreateType,
|
||||
protocol::{context::WithContext, helpers::deserialize_one_or_many},
|
||||
traits::{ActivityHandler, Object},
|
||||
url::Url,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ use activitypub_federation::{
|
|||
kinds::actor::PersonType,
|
||||
protocol::{public_key::PublicKey, verification::verify_domains_match},
|
||||
traits::{ActivityHandler, Actor, Object},
|
||||
url::Url,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use url::Url;
|
||||
use std::{fmt::Debug, str::FromStr};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DbUser {
|
||||
|
|
@ -36,8 +36,8 @@ pub enum PersonAcceptedActivities {
|
|||
|
||||
impl DbUser {
|
||||
pub fn new(hostname: &str, name: &str) -> Result<DbUser, Error> {
|
||||
let ap_id = Url::parse(&format!("https://{}/{}", hostname, &name))?.into();
|
||||
let inbox = Url::parse(&format!("https://{}/{}/inbox", hostname, &name))?;
|
||||
let ap_id = Url::from_str(&format!("https://{}/{}", hostname, &name))?.into();
|
||||
let inbox = Url::from_str(&format!("https://{}/{}/inbox", hostname, &name))?;
|
||||
let keypair = generate_actor_keypair()?;
|
||||
Ok(DbUser {
|
||||
name: name.to_string(),
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ use activitypub_federation::{
|
|||
kinds::{object::NoteType, public},
|
||||
protocol::{helpers::deserialize_one_or_many, verification::verify_domains_match},
|
||||
traits::{Actor, Object},
|
||||
url::Url,
|
||||
};
|
||||
use activitystreams_kinds::link::MentionType;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DbPost {
|
||||
|
|
@ -63,7 +63,7 @@ impl Object for DbPost {
|
|||
id: self.ap_id,
|
||||
content: self.text,
|
||||
attributed_to: self.creator,
|
||||
to: vec![public()],
|
||||
to: vec![public().try_into()?],
|
||||
tag: vec![],
|
||||
in_reply_to: None,
|
||||
})
|
||||
|
|
@ -98,7 +98,7 @@ impl Object for DbPost {
|
|||
kind: Default::default(),
|
||||
id: generate_object_id(data.domain())?.into(),
|
||||
attributed_to: data.local_user().ap_id,
|
||||
to: vec![public()],
|
||||
to: vec![public().try_into()?],
|
||||
content: format!("Hello {}", creator.name),
|
||||
in_reply_to: Some(json.id.clone()),
|
||||
tag: vec![mention],
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use activitypub_federation::url::Url;
|
||||
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
||||
use url::{ParseError, Url};
|
||||
use url::ParseError;
|
||||
|
||||
/// Just generate random url as object id. In a real project, you probably want to use
|
||||
/// an url which contains the database id for easy retrieval (or store the random id in db).
|
||||
|
|
@ -9,5 +12,5 @@ pub fn generate_object_id(domain: &str) -> Result<Url, ParseError> {
|
|||
.take(7)
|
||||
.map(char::from)
|
||||
.collect();
|
||||
Url::parse(&format!("https://{}/objects/{}", domain, id))
|
||||
Url::from_str(&format!("https://{}/objects/{}", domain, id))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ use activitypub_federation::{
|
|||
fetch::object_id::ObjectId,
|
||||
kinds::activity::AcceptType,
|
||||
traits::ActivityHandler,
|
||||
url::Url,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ use activitypub_federation::{
|
|||
kinds::activity::CreateType,
|
||||
protocol::helpers::deserialize_one_or_many,
|
||||
traits::{ActivityHandler, Object},
|
||||
url::Url,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ use activitypub_federation::{
|
|||
fetch::object_id::ObjectId,
|
||||
kinds::activity::FollowType,
|
||||
traits::{ActivityHandler, Actor},
|
||||
url::Url,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
|
|||
|
|
@ -2,21 +2,23 @@ use crate::{
|
|||
objects::{person::DbUser, post::DbPost},
|
||||
Error,
|
||||
};
|
||||
use activitypub_federation::config::{FederationConfig, UrlVerifier};
|
||||
use activitypub_federation::{
|
||||
config::{FederationConfig, UrlVerifier},
|
||||
url::Url,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use async_trait::async_trait;
|
||||
use std::{
|
||||
str::FromStr,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
pub async fn new_instance(
|
||||
hostname: &str,
|
||||
name: String,
|
||||
) -> Result<FederationConfig<DatabaseHandle>, Error> {
|
||||
let mut system_user = DbUser::new(hostname, "system".into())?;
|
||||
system_user.ap_id = Url::parse(&format!("http://{}/", hostname))?.into();
|
||||
system_user.ap_id = Url::from_str(&format!("http://{}/", hostname))?.into();
|
||||
|
||||
let local_user = DbUser::new(hostname, name)?;
|
||||
let database = Arc::new(Database {
|
||||
|
|
@ -51,7 +53,7 @@ struct MyUrlVerifier();
|
|||
#[async_trait]
|
||||
impl UrlVerifier for MyUrlVerifier {
|
||||
async fn verify(&self, url: &Url) -> Result<(), activitypub_federation::error::Error> {
|
||||
if url.domain() == Some("malicious.com") {
|
||||
if url.domain() == "malicious.com" {
|
||||
Err(activitypub_federation::error::Error::Other(
|
||||
"malicious domain".into(),
|
||||
))
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ use activitypub_federation::{
|
|||
kinds::actor::PersonType,
|
||||
protocol::{context::WithContext, public_key::PublicKey, verification::verify_domains_match},
|
||||
traits::{ActivityHandler, Actor, Object},
|
||||
url::Url,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use url::Url;
|
||||
use std::{fmt::Debug, str::FromStr};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DbUser {
|
||||
|
|
@ -46,8 +46,8 @@ pub enum PersonAcceptedActivities {
|
|||
|
||||
impl DbUser {
|
||||
pub fn new(hostname: &str, name: String) -> Result<DbUser, Error> {
|
||||
let ap_id = Url::parse(&format!("http://{}/{}", hostname, &name))?.into();
|
||||
let inbox = Url::parse(&format!("http://{}/{}/inbox", hostname, &name))?;
|
||||
let ap_id = Url::from_str(&format!("http://{}/{}", hostname, &name))?.into();
|
||||
let inbox = Url::from_str(&format!("http://{}/{}/inbox", hostname, &name))?;
|
||||
let keypair = generate_actor_keypair()?;
|
||||
Ok(DbUser {
|
||||
name,
|
||||
|
|
@ -79,7 +79,7 @@ impl DbUser {
|
|||
}
|
||||
|
||||
pub fn followers_url(&self) -> Result<Url, Error> {
|
||||
Ok(Url::parse(&format!("{}/followers", self.ap_id.inner()))?)
|
||||
Ok(Url::from_str(&format!("{}/followers", self.ap_id.inner()))?)
|
||||
}
|
||||
|
||||
pub async fn follow(&self, other: &str, data: &Data<DatabaseHandle>) -> Result<(), Error> {
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ use activitypub_federation::{
|
|||
kinds::{object::NoteType, public},
|
||||
protocol::{helpers::deserialize_one_or_many, verification::verify_domains_match},
|
||||
traits::Object,
|
||||
url::Url,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DbPost {
|
||||
|
|
@ -19,7 +19,7 @@ pub struct DbPost {
|
|||
|
||||
impl DbPost {
|
||||
pub fn new(text: String, creator: ObjectId<DbUser>) -> Result<DbPost, Error> {
|
||||
let ap_id = generate_object_id(creator.inner().domain().unwrap())?.into();
|
||||
let ap_id = generate_object_id(creator.inner().domain())?.try_into()?;
|
||||
Ok(DbPost {
|
||||
text,
|
||||
ap_id,
|
||||
|
|
@ -65,7 +65,7 @@ impl Object for DbPost {
|
|||
kind: Default::default(),
|
||||
id: self.ap_id,
|
||||
attributed_to: self.creator,
|
||||
to: vec![public(), creator.followers_url()?],
|
||||
to: vec![public().try_into()?, creator.followers_url()?],
|
||||
content: self.text,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ where
|
|||
#[cfg(test)]
|
||||
#[allow(clippy::unwrap_used)]
|
||||
mod test {
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
activity_sending::generate_request_headers,
|
||||
|
|
@ -165,7 +167,7 @@ mod test {
|
|||
actor: ObjectId::parse("http://localhost:123").unwrap(),
|
||||
object: ObjectId::parse("http://localhost:124").unwrap(),
|
||||
kind: Default::default(),
|
||||
id: "http://localhost:123/1".try_into().unwrap(),
|
||||
id: "http://localhost:123/1".parse().unwrap(),
|
||||
};
|
||||
let body: Bytes = serde_json::to_vec(&activity).unwrap().into();
|
||||
let incoming_request = construct_request(&body, activity.actor.inner()).await;
|
||||
|
|
|
|||
|
|
@ -135,13 +135,13 @@ async fn fetch_object_http_with_accept<T: Clone, Kind: DeserializeOwned>(
|
|||
match serde_json::from_slice(&text) {
|
||||
Ok(object) => Ok(FetchObjectResponse {
|
||||
object,
|
||||
url: url.into(),
|
||||
url: url.try_into()?,
|
||||
content_type,
|
||||
object_id,
|
||||
}),
|
||||
Err(e) => Err(ParseFetchedObject(
|
||||
e,
|
||||
url.into(),
|
||||
url.try_into()?,
|
||||
String::from_utf8(Vec::from(text))?,
|
||||
)),
|
||||
}
|
||||
|
|
|
|||
28
src/url.rs
28
src/url.rs
|
|
@ -1,13 +1,12 @@
|
|||
//! Wrapper for `url::Url` type.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fmt::{Display, Formatter},
|
||||
ops::Deref,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Wrapper for `url::Url` type. Has `domain` as mandatory field, and prints plain
|
||||
/// string for debugging.
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Debug)]
|
||||
|
|
@ -22,6 +21,7 @@ impl Deref for Url {
|
|||
}
|
||||
|
||||
impl Display for Url {
|
||||
#[allow(clippy::to_string_in_format_args)]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0.to_string())
|
||||
}
|
||||
|
|
@ -30,14 +30,24 @@ impl Display for Url {
|
|||
impl Url {
|
||||
/// Returns domain of the url
|
||||
pub fn domain(&self) -> &str {
|
||||
// TODO: must have error handling, or ensure at creation that it has domain
|
||||
self.0.domain().expect("has domain")
|
||||
}
|
||||
}
|
||||
|
||||
impl From<url::Url> for Url {
|
||||
fn from(value: url::Url) -> Self {
|
||||
Url(value)
|
||||
impl TryFrom<url::Url> for Url {
|
||||
type Error = url::ParseError;
|
||||
fn try_from(value: url::Url) -> Result<Self, Self::Error> {
|
||||
if value.domain().is_none() {
|
||||
return Err(url::ParseError::EmptyHost);
|
||||
}
|
||||
Ok(Url(value))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::from_over_into)]
|
||||
impl Into<url::Url> for Url {
|
||||
fn into(self) -> url::Url {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,6 +55,10 @@ impl FromStr for Url {
|
|||
type Err = url::ParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(url::Url::from_str(s).map(Url).unwrap())
|
||||
let url = url::Url::from_str(s)?;
|
||||
if url.domain().is_none() {
|
||||
return Err(url::ParseError::EmptyHost);
|
||||
}
|
||||
Ok(Url(url))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue