Use Url instead of String
This commit is contained in:
parent
45d13145b5
commit
3320c2d651
6 changed files with 42 additions and 37 deletions
1
server/Cargo.lock
generated
vendored
1
server/Cargo.lock
generated
vendored
|
@ -2743,6 +2743,7 @@ dependencies = [
|
|||
"idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
2
server/Cargo.toml
vendored
2
server/Cargo.toml
vendored
|
@ -34,7 +34,7 @@ rss = "1.9.0"
|
|||
htmlescape = "0.3.1"
|
||||
config = "0.10.1"
|
||||
hjson = "0.8.2"
|
||||
url = "2.1.1"
|
||||
url = { version = "2.1.1", features = ["serde"] }
|
||||
percent-encoding = "2.1.0"
|
||||
isahc = "0.9"
|
||||
comrak = "0.7"
|
||||
|
|
|
@ -22,6 +22,7 @@ use diesel::r2d2::{ConnectionManager, Pool};
|
|||
use diesel::PgConnection;
|
||||
use failure::Error;
|
||||
use serde::Deserialize;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CommunityQuery {
|
||||
|
@ -87,16 +88,14 @@ impl Community {
|
|||
|
||||
impl CommunityForm {
|
||||
pub fn from_group(group: &GroupExt, conn: &PgConnection) -> Result<Self, Error> {
|
||||
let followers_uri = &group.extension.get_followers().unwrap().to_string();
|
||||
let outbox_uri = &group.extension.get_outbox().to_string();
|
||||
let _outbox = fetch_remote_object::<OrderedCollection>(outbox_uri)?;
|
||||
let _followers = fetch_remote_object::<UnorderedCollection>(followers_uri)?;
|
||||
let followers_uri = Url::parse(&group.extension.get_followers().unwrap().to_string())?;
|
||||
let outbox_uri = Url::parse(&group.extension.get_outbox().to_string())?;
|
||||
let _outbox = fetch_remote_object::<OrderedCollection>(&outbox_uri)?;
|
||||
let _followers = fetch_remote_object::<UnorderedCollection>(&followers_uri)?;
|
||||
let oprops = &group.base.object_props;
|
||||
let aprops = &group.extension;
|
||||
let creator = fetch_remote_user(
|
||||
&oprops.get_attributed_to_xsd_any_uri().unwrap().to_string(),
|
||||
conn,
|
||||
)?;
|
||||
let apub_id = Url::parse(&oprops.get_attributed_to_xsd_any_uri().unwrap().to_string())?;
|
||||
let creator = fetch_remote_user(&apub_id, conn)?;
|
||||
Ok(CommunityForm {
|
||||
name: oprops.get_name_xsd_string().unwrap().to_string(),
|
||||
title: aprops.get_preferred_username().unwrap().to_string(),
|
||||
|
|
|
@ -12,6 +12,7 @@ use diesel::r2d2::{ConnectionManager, Pool};
|
|||
use diesel::PgConnection;
|
||||
use failure::Error;
|
||||
use serde::Deserialize;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct PostQuery {
|
||||
|
@ -64,10 +65,8 @@ impl Post {
|
|||
impl PostForm {
|
||||
pub fn from_page(page: &Page, conn: &PgConnection) -> Result<PostForm, Error> {
|
||||
let oprops = &page.object_props;
|
||||
let creator = fetch_remote_user(
|
||||
&oprops.get_attributed_to_xsd_any_uri().unwrap().to_string(),
|
||||
conn,
|
||||
)?;
|
||||
let apub_id = Url::parse(&oprops.get_attributed_to_xsd_any_uri().unwrap().to_string())?;
|
||||
let creator = fetch_remote_user(&apub_id, conn)?;
|
||||
Ok(PostForm {
|
||||
name: oprops.get_name_xsd_string().unwrap().to_string(),
|
||||
url: oprops.get_url_xsd_any_uri().map(|u| u.to_string()),
|
||||
|
|
|
@ -15,22 +15,23 @@ use isahc::prelude::*;
|
|||
use log::warn;
|
||||
use serde::Deserialize;
|
||||
use std::time::Duration;
|
||||
use url::Url;
|
||||
|
||||
fn fetch_node_info(domain: &str) -> Result<NodeInfo, Error> {
|
||||
let well_known_uri = format!(
|
||||
let well_known_uri = Url::parse(&format!(
|
||||
"{}://{}/.well-known/nodeinfo",
|
||||
get_apub_protocol_string(),
|
||||
domain
|
||||
);
|
||||
))?;
|
||||
let well_known = fetch_remote_object::<NodeInfoWellKnown>(&well_known_uri)?;
|
||||
Ok(fetch_remote_object::<NodeInfo>(&well_known.links.href)?)
|
||||
}
|
||||
|
||||
fn fetch_communities_from_instance(
|
||||
community_list_url: &str,
|
||||
community_list: &Url,
|
||||
conn: &PgConnection,
|
||||
) -> Result<Vec<Community>, Error> {
|
||||
fetch_remote_object::<UnorderedCollection>(community_list_url)?
|
||||
fetch_remote_object::<UnorderedCollection>(community_list)?
|
||||
.collection_props
|
||||
.get_many_items_base_boxes()
|
||||
.unwrap()
|
||||
|
@ -53,16 +54,16 @@ fn fetch_communities_from_instance(
|
|||
}
|
||||
|
||||
// TODO: add an optional param last_updated and only fetch if its too old
|
||||
pub fn fetch_remote_object<Response>(uri: &str) -> Result<Response, Error>
|
||||
pub fn fetch_remote_object<Response>(url: &Url) -> Result<Response, Error>
|
||||
where
|
||||
Response: for<'de> Deserialize<'de>,
|
||||
{
|
||||
if Settings::get().federation.tls_enabled && !uri.starts_with("https://") {
|
||||
return Err(format_err!("Activitypub uri is insecure: {}", uri));
|
||||
if Settings::get().federation.tls_enabled && url.scheme() != "https" {
|
||||
return Err(format_err!("Activitypub uri is insecure: {}", url));
|
||||
}
|
||||
// TODO: this function should return a future
|
||||
let timeout = Duration::from_secs(60);
|
||||
let text = Request::get(uri)
|
||||
let text = Request::get(url.as_str())
|
||||
.header("Accept", APUB_JSON_CONTENT_TYPE)
|
||||
.connect_timeout(timeout)
|
||||
.timeout(timeout)
|
||||
|
@ -78,11 +79,14 @@ fn fetch_remote_community_posts(
|
|||
community: &Community,
|
||||
conn: &PgConnection,
|
||||
) -> Result<Vec<Post>, Error> {
|
||||
let endpoint = format!("http://{}/federation/c/{}", instance, community.name);
|
||||
let endpoint = Url::parse(&format!(
|
||||
"http://{}/federation/c/{}",
|
||||
instance, community.name
|
||||
))?;
|
||||
let group = fetch_remote_object::<GroupExt>(&endpoint)?;
|
||||
let outbox_uri = &group.extension.get_outbox().to_string();
|
||||
let outbox_uri = Url::parse(&group.extension.get_outbox().to_string())?;
|
||||
// TODO: outbox url etc should be stored in local db
|
||||
let outbox = fetch_remote_object::<OrderedCollection>(outbox_uri)?;
|
||||
let outbox = fetch_remote_object::<OrderedCollection>(&outbox_uri)?;
|
||||
let items = outbox.collection_props.get_many_items_base_boxes();
|
||||
|
||||
Ok(
|
||||
|
@ -106,7 +110,7 @@ fn fetch_remote_community_posts(
|
|||
)
|
||||
}
|
||||
|
||||
pub fn fetch_remote_user(apub_id: &str, conn: &PgConnection) -> Result<User_, Error> {
|
||||
pub fn fetch_remote_user(apub_id: &Url, conn: &PgConnection) -> Result<User_, Error> {
|
||||
let person = fetch_remote_object::<PersonExt>(apub_id)?;
|
||||
let uf = UserForm::from_person(&person)?;
|
||||
let existing = User_::read_from_apub_id(conn, &uf.actor_id);
|
||||
|
@ -122,8 +126,8 @@ pub fn fetch_remote_user(apub_id: &str, conn: &PgConnection) -> Result<User_, Er
|
|||
pub fn fetch_all(conn: &PgConnection) -> Result<(), Error> {
|
||||
for instance in &get_following_instances() {
|
||||
let node_info = fetch_node_info(instance)?;
|
||||
if let Some(community_list_url) = node_info.metadata.community_list_url {
|
||||
let communities = fetch_communities_from_instance(&community_list_url, conn)?;
|
||||
if let Some(community_list) = node_info.metadata.community_list_url {
|
||||
let communities = fetch_communities_from_instance(&community_list, conn)?;
|
||||
for c in communities {
|
||||
fetch_remote_community_posts(instance, &c, conn)?;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,10 @@ use actix_web::web;
|
|||
use actix_web::HttpResponse;
|
||||
use diesel::r2d2::{ConnectionManager, Pool};
|
||||
use diesel::PgConnection;
|
||||
use failure::Error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use url::Url;
|
||||
|
||||
pub fn config(cfg: &mut web::ServiceConfig) {
|
||||
cfg
|
||||
|
@ -16,18 +18,18 @@ pub fn config(cfg: &mut web::ServiceConfig) {
|
|||
.route("/.well-known/nodeinfo", web::get().to(node_info_well_known));
|
||||
}
|
||||
|
||||
async fn node_info_well_known() -> HttpResponse<Body> {
|
||||
async fn node_info_well_known() -> Result<HttpResponse<Body>, Error> {
|
||||
let node_info = NodeInfoWellKnown {
|
||||
links: NodeInfoWellKnownLinks {
|
||||
rel: "http://nodeinfo.diaspora.software/ns/schema/2.0".to_string(),
|
||||
href: format!(
|
||||
rel: Url::parse("http://nodeinfo.diaspora.software/ns/schema/2.0")?,
|
||||
href: Url::parse(&format!(
|
||||
"{}://{}/nodeinfo/2.0.json",
|
||||
get_apub_protocol_string(),
|
||||
Settings::get().hostname
|
||||
),
|
||||
))?,
|
||||
},
|
||||
};
|
||||
HttpResponse::Ok().json(node_info)
|
||||
Ok(HttpResponse::Ok().json(node_info))
|
||||
}
|
||||
|
||||
async fn node_info(
|
||||
|
@ -60,11 +62,11 @@ async fn node_info(
|
|||
open_registrations: site_view.open_registration,
|
||||
},
|
||||
metadata: NodeInfoMetadata {
|
||||
community_list_url: Some(format!(
|
||||
community_list_url: Some(Url::parse(&format!(
|
||||
"{}://{}/federation/communities",
|
||||
get_apub_protocol_string(),
|
||||
Settings::get().hostname
|
||||
)),
|
||||
))?),
|
||||
},
|
||||
})
|
||||
})
|
||||
|
@ -81,8 +83,8 @@ pub struct NodeInfoWellKnown {
|
|||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct NodeInfoWellKnownLinks {
|
||||
pub rel: String,
|
||||
pub href: String,
|
||||
pub rel: Url,
|
||||
pub href: Url,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
@ -116,5 +118,5 @@ pub struct NodeInfoUsers {
|
|||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct NodeInfoMetadata {
|
||||
pub community_list_url: Option<String>,
|
||||
pub community_list_url: Option<Url>,
|
||||
}
|
||||
|
|
Reference in a new issue