proxy support
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
ap_url, instance::*, medias::Media, posts::Post, safe_string::SafeString, schema::blogs,
|
||||
search::Searcher, users::User, Connection, Error, PlumeRocket, Result, ITEMS_PER_PAGE,
|
||||
search::Searcher, users::User, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE,
|
||||
};
|
||||
use activitypub::{
|
||||
actor::Group,
|
||||
@@ -150,7 +150,7 @@ impl Blog {
|
||||
.into_iter()
|
||||
.find(|l| l.mime_type == Some(String::from("application/activity+json")))
|
||||
.ok_or(Error::Webfinger)
|
||||
.and_then(|l| Blog::from_id(c, &l.href?, None).map_err(|(_, e)| e))
|
||||
.and_then(|l| Blog::from_id(c, &l.href?, None, CONFIG.proxy()).map_err(|(_, e)| e))
|
||||
}
|
||||
|
||||
pub fn to_activity(&self, conn: &Connection) -> Result<CustomGroup> {
|
||||
@@ -373,7 +373,7 @@ impl FromId<PlumeRocket> for Blog {
|
||||
Media::save_remote(
|
||||
&c.conn,
|
||||
icon.object_props.url_string().ok()?,
|
||||
&User::from_id(c, &owner, None).ok()?,
|
||||
&User::from_id(c, &owner, None, CONFIG.proxy()).ok()?,
|
||||
)
|
||||
.ok()
|
||||
})
|
||||
@@ -389,7 +389,7 @@ impl FromId<PlumeRocket> for Blog {
|
||||
Media::save_remote(
|
||||
&c.conn,
|
||||
banner.object_props.url_string().ok()?,
|
||||
&User::from_id(c, &owner, None).ok()?,
|
||||
&User::from_id(c, &owner, None, CONFIG.proxy()).ok()?,
|
||||
)
|
||||
.ok()
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
safe_string::SafeString,
|
||||
schema::comments,
|
||||
users::User,
|
||||
Connection, Error, PlumeRocket, Result,
|
||||
Connection, Error, PlumeRocket, Result, CONFIG,
|
||||
};
|
||||
use activitypub::{
|
||||
activity::{Create, Delete},
|
||||
@@ -239,6 +239,7 @@ impl FromId<PlumeRocket> for Comment {
|
||||
c,
|
||||
¬e.object_props.attributed_to_link::<Id>()?,
|
||||
None,
|
||||
CONFIG.proxy(),
|
||||
)
|
||||
.map_err(|(_, e)| e)?
|
||||
.id,
|
||||
@@ -296,7 +297,7 @@ impl FromId<PlumeRocket> for Comment {
|
||||
.collect::<HashSet<_>>() // remove duplicates (don't do a query more than once)
|
||||
.into_iter()
|
||||
.map(|v| {
|
||||
if let Ok(user) = User::from_id(c, &v, None) {
|
||||
if let Ok(user) = User::from_id(c, &v, None, CONFIG.proxy()) {
|
||||
vec![user]
|
||||
} else {
|
||||
vec![] // TODO try to fetch collection
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::search::TokenizerKind as SearchTokenizer;
|
||||
use rocket::config::Limits;
|
||||
use rocket::Config as RocketConfig;
|
||||
use std::collections::HashSet;
|
||||
use std::env::{self, var};
|
||||
|
||||
#[cfg(not(test))]
|
||||
@@ -21,6 +22,12 @@ pub struct Config {
|
||||
pub default_theme: String,
|
||||
pub media_directory: String,
|
||||
pub ldap: Option<LdapConfig>,
|
||||
pub proxy: Option<ProxyConfig>,
|
||||
}
|
||||
impl Config {
|
||||
pub fn proxy(&self) -> Option<&reqwest::Proxy> {
|
||||
self.proxy.as_ref().map(|p| &p.proxy)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -277,6 +284,49 @@ fn get_ldap_config() -> Option<LdapConfig> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ProxyConfig {
|
||||
pub url: reqwest::Url,
|
||||
pub only_domains: Option<HashSet<String>>,
|
||||
pub proxy: reqwest::Proxy,
|
||||
}
|
||||
|
||||
fn get_proxy_config() -> Option<ProxyConfig> {
|
||||
let url: reqwest::Url = var("PROXY_URL").ok()?.parse().expect("Invalid PROXY_URL");
|
||||
let proxy_url = url.clone();
|
||||
let only_domains: Option<HashSet<String>> = var("PROXY_DOMAINS")
|
||||
.ok()
|
||||
.map(|ods| ods.split(",").map(str::to_owned).collect());
|
||||
let proxy = if let Some(ref only_domains) = only_domains {
|
||||
let only_domains = only_domains.clone();
|
||||
reqwest::Proxy::custom(move |url| {
|
||||
if let Some(domain) = url.domain() {
|
||||
if only_domains.contains(domain)
|
||||
|| only_domains
|
||||
.iter()
|
||||
.filter(|target| domain.ends_with(&format!(".{}", target)))
|
||||
.next()
|
||||
.is_some()
|
||||
{
|
||||
Some(proxy_url.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
} else {
|
||||
reqwest::Proxy::all(proxy_url)
|
||||
.ok()
|
||||
.expect("Invalid PROXY_URL")
|
||||
};
|
||||
Some(ProxyConfig {
|
||||
url,
|
||||
only_domains,
|
||||
proxy,
|
||||
})
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref CONFIG: Config = Config {
|
||||
base_url: var("BASE_URL").unwrap_or_else(|_| format!(
|
||||
@@ -305,5 +355,6 @@ lazy_static! {
|
||||
media_directory: var("MEDIA_UPLOAD_DIRECTORY")
|
||||
.unwrap_or_else(|_| "static/media".to_owned()),
|
||||
ldap: get_ldap_config(),
|
||||
proxy: get_proxy_config(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -116,7 +116,12 @@ impl Follow {
|
||||
.accept_props
|
||||
.set_actor_link::<Id>(target.clone().into_id())?;
|
||||
accept.accept_props.set_object_object(follow)?;
|
||||
broadcast(&*target, accept, vec![from.clone()]);
|
||||
broadcast(
|
||||
&*target,
|
||||
accept,
|
||||
vec![from.clone()],
|
||||
CONFIG.proxy().cloned(),
|
||||
);
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
@@ -161,11 +166,21 @@ impl FromId<PlumeRocket> for Follow {
|
||||
}
|
||||
|
||||
fn from_activity(c: &PlumeRocket, follow: FollowAct) -> Result<Self> {
|
||||
let actor =
|
||||
User::from_id(c, &follow.follow_props.actor_link::<Id>()?, None).map_err(|(_, e)| e)?;
|
||||
let actor = User::from_id(
|
||||
c,
|
||||
&follow.follow_props.actor_link::<Id>()?,
|
||||
None,
|
||||
CONFIG.proxy(),
|
||||
)
|
||||
.map_err(|(_, e)| e)?;
|
||||
|
||||
let target = User::from_id(c, &follow.follow_props.object_link::<Id>()?, None)
|
||||
.map_err(|(_, e)| e)?;
|
||||
let target = User::from_id(
|
||||
c,
|
||||
&follow.follow_props.object_link::<Id>()?,
|
||||
None,
|
||||
CONFIG.proxy(),
|
||||
)
|
||||
.map_err(|(_, e)| e)?;
|
||||
Follow::accept_follow(&c.conn, &actor, &target, follow, actor.id, target.id)
|
||||
}
|
||||
}
|
||||
|
||||
+13
-13
@@ -7,7 +7,7 @@ use crate::{
|
||||
posts::{Post, PostUpdate},
|
||||
reshares::Reshare,
|
||||
users::User,
|
||||
Error, PlumeRocket,
|
||||
Error, PlumeRocket, CONFIG,
|
||||
};
|
||||
use plume_common::activity_pub::inbox::Inbox;
|
||||
|
||||
@@ -48,18 +48,18 @@ impl_into_inbox_result! {
|
||||
|
||||
pub fn inbox(ctx: &PlumeRocket, act: serde_json::Value) -> Result<InboxResult, Error> {
|
||||
Inbox::handle(ctx, act)
|
||||
.with::<User, Announce, Post>()
|
||||
.with::<User, Create, Comment>()
|
||||
.with::<User, Create, Post>()
|
||||
.with::<User, Delete, Comment>()
|
||||
.with::<User, Delete, Post>()
|
||||
.with::<User, Delete, User>()
|
||||
.with::<User, Follow, User>()
|
||||
.with::<User, Like, Post>()
|
||||
.with::<User, Undo, Reshare>()
|
||||
.with::<User, Undo, follows::Follow>()
|
||||
.with::<User, Undo, likes::Like>()
|
||||
.with::<User, Update, PostUpdate>()
|
||||
.with::<User, Announce, Post>(CONFIG.proxy())
|
||||
.with::<User, Create, Comment>(CONFIG.proxy())
|
||||
.with::<User, Create, Post>(CONFIG.proxy())
|
||||
.with::<User, Delete, Comment>(CONFIG.proxy())
|
||||
.with::<User, Delete, Post>(CONFIG.proxy())
|
||||
.with::<User, Delete, User>(CONFIG.proxy())
|
||||
.with::<User, Follow, User>(CONFIG.proxy())
|
||||
.with::<User, Like, Post>(CONFIG.proxy())
|
||||
.with::<User, Undo, Reshare>(CONFIG.proxy())
|
||||
.with::<User, Undo, follows::Follow>(CONFIG.proxy())
|
||||
.with::<User, Undo, likes::Like>(CONFIG.proxy())
|
||||
.with::<User, Update, PostUpdate>(CONFIG.proxy())
|
||||
.done()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
notifications::*, posts::Post, schema::likes, timeline::*, users::User, Connection, Error,
|
||||
PlumeRocket, Result,
|
||||
PlumeRocket, Result, CONFIG,
|
||||
};
|
||||
use activitypub::activity;
|
||||
use chrono::NaiveDateTime;
|
||||
@@ -115,12 +115,22 @@ impl FromId<PlumeRocket> for Like {
|
||||
let res = Like::insert(
|
||||
&c.conn,
|
||||
NewLike {
|
||||
post_id: Post::from_id(c, &act.like_props.object_link::<Id>()?, None)
|
||||
.map_err(|(_, e)| e)?
|
||||
.id,
|
||||
user_id: User::from_id(c, &act.like_props.actor_link::<Id>()?, None)
|
||||
.map_err(|(_, e)| e)?
|
||||
.id,
|
||||
post_id: Post::from_id(
|
||||
c,
|
||||
&act.like_props.object_link::<Id>()?,
|
||||
None,
|
||||
CONFIG.proxy(),
|
||||
)
|
||||
.map_err(|(_, e)| e)?
|
||||
.id,
|
||||
user_id: User::from_id(
|
||||
c,
|
||||
&act.like_props.actor_link::<Id>()?,
|
||||
None,
|
||||
CONFIG.proxy(),
|
||||
)
|
||||
.map_err(|(_, e)| e)?
|
||||
.id,
|
||||
ap_url: act.object_props.id_string()?,
|
||||
},
|
||||
)?;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
ap_url, instance::Instance, safe_string::SafeString, schema::medias, users::User, Connection,
|
||||
Error, PlumeRocket, Result,
|
||||
Error, PlumeRocket, Result, CONFIG,
|
||||
};
|
||||
use activitypub::object::Image;
|
||||
use askama_escape::escape;
|
||||
@@ -212,10 +212,16 @@ impl Media {
|
||||
));
|
||||
|
||||
let mut dest = fs::File::create(path.clone()).ok()?;
|
||||
reqwest::get(remote_url.as_str())
|
||||
.ok()?
|
||||
.copy_to(&mut dest)
|
||||
.ok()?;
|
||||
if let Some(proxy) = CONFIG.proxy() {
|
||||
reqwest::ClientBuilder::new().proxy(proxy.clone()).build()?
|
||||
} else {
|
||||
reqwest::Client::new()
|
||||
}
|
||||
.get(remote_url.as_str())
|
||||
.send()
|
||||
.ok()?
|
||||
.copy_to(&mut dest)
|
||||
.ok()?;
|
||||
|
||||
Media::insert(
|
||||
conn,
|
||||
@@ -236,6 +242,7 @@ impl Media {
|
||||
.next()?
|
||||
.as_ref(),
|
||||
None,
|
||||
CONFIG.proxy(),
|
||||
)
|
||||
.map_err(|(_, e)| e)?
|
||||
.id,
|
||||
|
||||
@@ -570,12 +570,15 @@ impl FromId<PlumeRocket> for Post {
|
||||
.into_iter()
|
||||
.fold((None, vec![]), |(blog, mut authors), link| {
|
||||
let url = link;
|
||||
match User::from_id(&c, &url, None) {
|
||||
match User::from_id(&c, &url, None, CONFIG.proxy()) {
|
||||
Ok(u) => {
|
||||
authors.push(u);
|
||||
(blog, authors)
|
||||
}
|
||||
Err(_) => (blog.or_else(|| Blog::from_id(&c, &url, None).ok()), authors),
|
||||
Err(_) => (
|
||||
blog.or_else(|| Blog::from_id(&c, &url, None, CONFIG.proxy()).ok()),
|
||||
authors,
|
||||
),
|
||||
}
|
||||
});
|
||||
|
||||
@@ -728,7 +731,7 @@ impl AsObject<User, Update, &PlumeRocket> for PostUpdate {
|
||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
||||
let conn = &*c.conn;
|
||||
let searcher = &c.searcher;
|
||||
let mut post = Post::from_id(c, &self.ap_url, None).map_err(|(_, e)| e)?;
|
||||
let mut post = Post::from_id(c, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?;
|
||||
|
||||
if !post.is_author(conn, actor.id)? {
|
||||
// TODO: maybe the author was added in the meantime
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
notifications::*, posts::Post, schema::reshares, timeline::*, users::User, Connection, Error,
|
||||
PlumeRocket, Result,
|
||||
PlumeRocket, Result, CONFIG,
|
||||
};
|
||||
use activitypub::activity::{Announce, Undo};
|
||||
use chrono::NaiveDateTime;
|
||||
@@ -140,12 +140,22 @@ impl FromId<PlumeRocket> for Reshare {
|
||||
let res = Reshare::insert(
|
||||
&c.conn,
|
||||
NewReshare {
|
||||
post_id: Post::from_id(c, &act.announce_props.object_link::<Id>()?, None)
|
||||
.map_err(|(_, e)| e)?
|
||||
.id,
|
||||
user_id: User::from_id(c, &act.announce_props.actor_link::<Id>()?, None)
|
||||
.map_err(|(_, e)| e)?
|
||||
.id,
|
||||
post_id: Post::from_id(
|
||||
c,
|
||||
&act.announce_props.object_link::<Id>()?,
|
||||
None,
|
||||
CONFIG.proxy(),
|
||||
)
|
||||
.map_err(|(_, e)| e)?
|
||||
.id,
|
||||
user_id: User::from_id(
|
||||
c,
|
||||
&act.announce_props.actor_link::<Id>()?,
|
||||
None,
|
||||
CONFIG.proxy(),
|
||||
)
|
||||
.map_err(|(_, e)| e)?
|
||||
.id,
|
||||
ap_url: act.object_props.id_string()?,
|
||||
},
|
||||
)?;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::{
|
||||
ap_url, blocklisted_emails::BlocklistedEmail, blogs::Blog, config::CONFIG, db_conn::DbConn,
|
||||
follows::Follow, instance::*, medias::Media, notifications::Notification,
|
||||
post_authors::PostAuthor, posts::Post, safe_string::SafeString, schema::users,
|
||||
search::Searcher, timeline::Timeline, Connection, Error, PlumeRocket, Result, ITEMS_PER_PAGE,
|
||||
ap_url, blocklisted_emails::BlocklistedEmail, blogs::Blog, db_conn::DbConn, follows::Follow,
|
||||
instance::*, medias::Media, notifications::Notification, post_authors::PostAuthor, posts::Post,
|
||||
safe_string::SafeString, schema::users, search::Searcher, timeline::Timeline, Connection,
|
||||
Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE,
|
||||
};
|
||||
use activitypub::{
|
||||
activity::Delete,
|
||||
@@ -210,7 +210,7 @@ impl User {
|
||||
.into_iter()
|
||||
.find(|l| l.mime_type == Some(String::from("application/activity+json")))
|
||||
.ok_or(Error::Webfinger)?;
|
||||
User::from_id(c, link.href.as_ref()?, None).map_err(|(_, e)| e)
|
||||
User::from_id(c, link.href.as_ref()?, None, CONFIG.proxy()).map_err(|(_, e)| e)
|
||||
}
|
||||
|
||||
pub fn fetch_remote_interact_uri(acct: &str) -> Result<String> {
|
||||
|
||||
Reference in New Issue
Block a user