* Use anyhow::Error for UrlVerifier return type (fixes #61) * fmt * uncomment
This commit is contained in:
parent
32e3cd5574
commit
426871f5af
4 changed files with 26 additions and 22 deletions
|
@ -49,9 +49,9 @@ struct MyUrlVerifier();
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl UrlVerifier for MyUrlVerifier {
|
impl UrlVerifier for MyUrlVerifier {
|
||||||
async fn verify(&self, url: &Url) -> Result<(), &'static str> {
|
async fn verify(&self, url: &Url) -> Result<(), anyhow::Error> {
|
||||||
if url.domain() == Some("malicious.com") {
|
if url.domain() == Some("malicious.com") {
|
||||||
Err("malicious domain")
|
Err(anyhow!("malicious domain"))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ use crate::{
|
||||||
protocol::verification::verify_domains_match,
|
protocol::verification::verify_domains_match,
|
||||||
traits::{ActivityHandler, Actor},
|
traits::{ActivityHandler, Actor},
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::{anyhow, Context};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use derive_builder::Builder;
|
use derive_builder::Builder;
|
||||||
use dyn_clone::{clone_trait_object, DynClone};
|
use dyn_clone::{clone_trait_object, DynClone};
|
||||||
|
@ -114,9 +114,9 @@ impl<T: Clone> FederationConfig<T> {
|
||||||
verify_domains_match(activity.id(), activity.actor())?;
|
verify_domains_match(activity.id(), activity.actor())?;
|
||||||
self.verify_url_valid(activity.id()).await?;
|
self.verify_url_valid(activity.id()).await?;
|
||||||
if self.is_local_url(activity.id()) {
|
if self.is_local_url(activity.id()) {
|
||||||
return Err(Error::UrlVerificationError(
|
return Err(Error::UrlVerificationError(anyhow!(
|
||||||
"Activity was sent from local instance",
|
"Activity was sent from local instance"
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -139,12 +139,12 @@ impl<T: Clone> FederationConfig<T> {
|
||||||
"https" => {}
|
"https" => {}
|
||||||
"http" => {
|
"http" => {
|
||||||
if !self.allow_http_urls {
|
if !self.allow_http_urls {
|
||||||
return Err(Error::UrlVerificationError(
|
return Err(Error::UrlVerificationError(anyhow!(
|
||||||
"Http urls are only allowed in debug mode",
|
"Http urls are only allowed in debug mode"
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Err(Error::UrlVerificationError("Invalid url scheme")),
|
_ => return Err(Error::UrlVerificationError(anyhow!("Invalid url scheme"))),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Urls which use our local domain are not a security risk, no further verification needed
|
// Urls which use our local domain are not a security risk, no further verification needed
|
||||||
|
@ -153,13 +153,15 @@ impl<T: Clone> FederationConfig<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if url.domain().is_none() {
|
if url.domain().is_none() {
|
||||||
return Err(Error::UrlVerificationError("Url must have a domain"));
|
return Err(Error::UrlVerificationError(anyhow!(
|
||||||
|
"Url must have a domain"
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if url.domain() == Some("localhost") && !self.debug {
|
if url.domain() == Some("localhost") && !self.debug {
|
||||||
return Err(Error::UrlVerificationError(
|
return Err(Error::UrlVerificationError(anyhow!(
|
||||||
"Localhost is only allowed in debug mode",
|
"Localhost is only allowed in debug mode"
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.url_verifier
|
self.url_verifier
|
||||||
|
@ -258,6 +260,7 @@ impl<T: Clone> Deref for FederationConfig<T> {
|
||||||
/// # use async_trait::async_trait;
|
/// # use async_trait::async_trait;
|
||||||
/// # use url::Url;
|
/// # use url::Url;
|
||||||
/// # use activitypub_federation::config::UrlVerifier;
|
/// # use activitypub_federation::config::UrlVerifier;
|
||||||
|
/// # use anyhow::anyhow;
|
||||||
/// # #[derive(Clone)]
|
/// # #[derive(Clone)]
|
||||||
/// # struct DatabaseConnection();
|
/// # struct DatabaseConnection();
|
||||||
/// # async fn get_blocklist(_: &DatabaseConnection) -> Vec<String> {
|
/// # async fn get_blocklist(_: &DatabaseConnection) -> Vec<String> {
|
||||||
|
@ -270,11 +273,11 @@ impl<T: Clone> Deref for FederationConfig<T> {
|
||||||
///
|
///
|
||||||
/// #[async_trait]
|
/// #[async_trait]
|
||||||
/// impl UrlVerifier for Verifier {
|
/// impl UrlVerifier for Verifier {
|
||||||
/// async fn verify(&self, url: &Url) -> Result<(), &'static str> {
|
/// async fn verify(&self, url: &Url) -> Result<(), anyhow::Error> {
|
||||||
/// let blocklist = get_blocklist(&self.db_connection).await;
|
/// let blocklist = get_blocklist(&self.db_connection).await;
|
||||||
/// let domain = url.domain().unwrap().to_string();
|
/// let domain = url.domain().unwrap().to_string();
|
||||||
/// if blocklist.contains(&domain) {
|
/// if blocklist.contains(&domain) {
|
||||||
/// Err("Domain is blocked")
|
/// Err(anyhow!("Domain is blocked"))
|
||||||
/// } else {
|
/// } else {
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
|
@ -284,7 +287,7 @@ impl<T: Clone> Deref for FederationConfig<T> {
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait UrlVerifier: DynClone + Send {
|
pub trait UrlVerifier: DynClone + Send {
|
||||||
/// Should return Ok iff the given url is valid for processing.
|
/// Should return Ok iff the given url is valid for processing.
|
||||||
async fn verify(&self, url: &Url) -> Result<(), &'static str>;
|
async fn verify(&self, url: &Url) -> Result<(), anyhow::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default URL verifier which does nothing.
|
/// Default URL verifier which does nothing.
|
||||||
|
@ -293,7 +296,7 @@ struct DefaultUrlVerifier();
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl UrlVerifier for DefaultUrlVerifier {
|
impl UrlVerifier for DefaultUrlVerifier {
|
||||||
async fn verify(&self, _url: &Url) -> Result<(), &'static str> {
|
async fn verify(&self, _url: &Url) -> Result<(), anyhow::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@ pub enum Error {
|
||||||
#[error("Object to be fetched was deleted")]
|
#[error("Object to be fetched was deleted")]
|
||||||
ObjectDeleted,
|
ObjectDeleted,
|
||||||
/// url verification error
|
/// url verification error
|
||||||
#[error("{0}")]
|
#[error("URL failed verification: {0}")]
|
||||||
UrlVerificationError(&'static str),
|
UrlVerificationError(anyhow::Error),
|
||||||
/// Incoming activity has invalid digest for body
|
/// Incoming activity has invalid digest for body
|
||||||
#[error("Incoming activity has invalid digest for body")]
|
#[error("Incoming activity has invalid digest for body")]
|
||||||
ActivityBodyDigestInvalid,
|
ActivityBodyDigestInvalid,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Verify that received data is valid
|
//! Verify that received data is valid
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
use anyhow::anyhow;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
/// Check that both urls have the same domain. If not, return UrlVerificationError.
|
/// Check that both urls have the same domain. If not, return UrlVerificationError.
|
||||||
|
@ -15,7 +16,7 @@ use url::Url;
|
||||||
/// ```
|
/// ```
|
||||||
pub fn verify_domains_match(a: &Url, b: &Url) -> Result<(), Error> {
|
pub fn verify_domains_match(a: &Url, b: &Url) -> Result<(), Error> {
|
||||||
if a.domain() != b.domain() {
|
if a.domain() != b.domain() {
|
||||||
return Err(Error::UrlVerificationError("Domains do not match"));
|
return Err(Error::UrlVerificationError(anyhow!("Domains do not match")));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -32,7 +33,7 @@ pub fn verify_domains_match(a: &Url, b: &Url) -> Result<(), Error> {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn verify_urls_match(a: &Url, b: &Url) -> Result<(), Error> {
|
pub fn verify_urls_match(a: &Url, b: &Url) -> Result<(), Error> {
|
||||||
if a != b {
|
if a != b {
|
||||||
return Err(Error::UrlVerificationError("Urls do not match"));
|
return Err(Error::UrlVerificationError(anyhow!("Urls do not match")));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue