This commit is contained in:
Tangel 2024-01-18 08:39:41 +00:00 committed by GitHub
parent 3fe565b14d
commit 5afb1d50db
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 36 additions and 28 deletions

View file

@ -26,7 +26,7 @@ tracing = "0.1.40"
base64 = "0.21.5"
openssl = "0.10.62"
once_cell = "1.19.0"
http = "0.2.11"
http = "1.0.0"
sha2 = "0.10.8"
thiserror = "1.0.56"
derive_builder = "0.12.0"
@ -60,12 +60,11 @@ moka = { version = "0.12.2", features = ["future"] }
actix-web = { version = "4.4.1", default-features = false, optional = true }
# Axum
axum = { version = "0.6.20", features = [
axum = { git = "https://github.com/tokio-rs/axum.git", features = [
"json",
"headers",
], default-features = false, optional = true }
tower = { version = "0.4.13", optional = true }
hyper = { version = "0.14", optional = true }
hyper = { version = "1.1.0", optional = true }
http-body-util = {version = "0.1.0", optional = true }
[dev-dependencies]
@ -73,12 +72,12 @@ anyhow = "1.0.79"
rand = "0.8.5"
env_logger = "0.10.1"
tower-http = { version = "0.5.0", features = ["map-request-body", "util"] }
axum = { version = "0.6.20", features = [
axum = { git = "https://github.com/tokio-rs/axum.git", features = [
"http1",
"tokio",
"query",
], default-features = false }
axum-macros = "0.3.8"
axum-macros = { git = "https://github.com/tokio-rs/axum.git" }
tokio = { version = "1.35.1", features = ["full"] }
[profile.dev]

View file

@ -38,7 +38,7 @@ pub fn listen(config: &FederationConfig<DatabaseHandle>) -> Result<(), Error> {
let addr = tokio::net::TcpListener::from_std(TcpListener::bind(hostname)?)?;
let server = axum::serve(addr, app.into_make_service());
tokio::spawn(server);
tokio::spawn(async move { server.await.unwrap() });
Ok(())
}

View file

@ -205,7 +205,7 @@ mod tests {
// This will periodically send back internal errors to test the retry
async fn dodgy_handler(
State(state): State<Arc<AtomicUsize>>,
headers: HeaderMap,
headers: http::HeaderMap,
body: Bytes,
) -> Result<(), StatusCode> {
debug!("Headers:{:?}", headers);

View file

@ -9,6 +9,7 @@ use crate::{
};
use actix_web::{web::Bytes, HttpRequest, HttpResponse};
use serde::de::DeserializeOwned;
use std::str::FromStr;
use tracing::debug;
/// Handles incoming activities, verifying HTTP signatures and other checks
@ -34,7 +35,7 @@ where
verify_signature(
request.headers(),
request.method(),
request.uri(),
&http::Uri::from_str(&request.uri().to_string()).unwrap(),
actor.public_key_pem(),
)?;

View file

@ -12,6 +12,7 @@ use crate::{
};
use actix_web::{web::Bytes, HttpRequest};
use serde::Deserialize;
use std::str::FromStr;
/// Checks whether the request is signed by an actor of type A, and returns
/// the actor in question if a valid signature is found.
@ -27,5 +28,11 @@ where
{
verify_body_hash(request.headers().get("Digest"), &body.unwrap_or_default())?;
http_signatures::signing_actor(request.headers(), request.method(), request.uri(), data).await
http_signatures::signing_actor(
request.headers(),
request.method(),
&http::Uri::from_str(&request.uri().to_string()).unwrap(),
data,
)
.await
}

View file

@ -11,9 +11,8 @@ use crate::{
};
use axum::{
async_trait,
body::Body,
extract::FromRequest,
http::{Request, StatusCode},
extract::{FromRequest, Request},
http::StatusCode,
response::{IntoResponse, Response},
};
use http::{HeaderMap, Method, Uri};
@ -65,18 +64,20 @@ where
{
type Rejection = Response;
async fn from_request(req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
let (parts, body) = req.into_parts();
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let headers = req.headers().clone();
let method = req.method().clone();
let uri = req.uri().clone();
// this wont work if the body is an long running stream
let bytes = hyper::body::to_bytes(body)
let bytes = hyper::body::Bytes::from_request(req, state)
.await
.map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response())?;
Ok(Self {
headers: parts.headers,
method: parts.method,
uri: parts.uri,
headers,
method,
uri,
body: bytes.to_vec(),
})
}

View file

@ -88,7 +88,7 @@ async fn fetch_object_http_with_accept<T: Clone, Kind: DeserializeOwned>(
req.send().await?
};
if res.status() == StatusCode::GONE {
if res.status().as_u16() == StatusCode::GONE.as_u16() {
return Err(Error::ObjectDeleted(url.clone()));
}

View file

@ -14,7 +14,7 @@ use crate::{
};
use base64::{engine::general_purpose::STANDARD as Base64, Engine};
use bytes::Bytes;
use http::{header::HeaderName, uri::PathAndQuery, HeaderValue, Method, Uri};
use http::{uri::PathAndQuery, Uri};
use http_signature_normalization_reqwest::{
prelude::{Config, SignExt},
DefaultSpawner,
@ -26,7 +26,11 @@ use openssl::{
rsa::Rsa,
sign::{Signer, Verifier},
};
use reqwest::Request;
use reqwest::{
header::{HeaderName, HeaderValue},
Method,
Request,
};
use reqwest_middleware::RequestBuilder;
use serde::Deserialize;
use sha2::{Digest, Sha256};
@ -292,7 +296,7 @@ pub mod test {
// use hardcoded date in order to test against hardcoded signature
headers.insert(
"date",
HeaderValue::from_str("Tue, 28 Mar 2023 21:03:44 GMT").unwrap(),
reqwest::header::HeaderValue::from_str("Tue, 28 Mar 2023 21:03:44 GMT").unwrap(),
);
let request_builder = ClientWithMiddleware::from(Client::new())

View file

@ -26,7 +26,6 @@ use url::Url;
/// Default context used in Activitypub
const DEFAULT_CONTEXT: &str = "https://www.w3.org/ns/activitystreams";
const DEFAULT_SECURITY_CONTEXT: &str = "https://w3id.org/security/v1";
/// Wrapper for federated structs which handles `@context` field.
#[derive(Serialize, Deserialize, Debug)]
@ -40,10 +39,7 @@ pub struct WithContext<T> {
impl<T> WithContext<T> {
/// Create a new wrapper with the default Activitypub context.
pub fn new_default(inner: T) -> WithContext<T> {
let context = vec![
Value::String(DEFAULT_CONTEXT.to_string()),
Value::String(DEFAULT_SECURITY_CONTEXT.to_string()),
];
let context = Value::String(DEFAULT_CONTEXT.to_string());
WithContext::new(inner, context)
}