summaryrefslogtreecommitdiffstats
path: root/crates/sellershut/src/server/middleware/sign_request.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/sellershut/src/server/middleware/sign_request.rs')
-rw-r--r--crates/sellershut/src/server/middleware/sign_request.rs124
1 files changed, 100 insertions, 24 deletions
diff --git a/crates/sellershut/src/server/middleware/sign_request.rs b/crates/sellershut/src/server/middleware/sign_request.rs
index 889984f..4eb3bd3 100644
--- a/crates/sellershut/src/server/middleware/sign_request.rs
+++ b/crates/sellershut/src/server/middleware/sign_request.rs
@@ -1,20 +1,21 @@
mod signature;
-use activitypub_federation::config::FederationConfig;
+use activitypub_federation::{config::FederationConfig, traits::Object};
use axum::{
body::Body,
extract::Request,
- http::HeaderValue,
+ http::{HeaderValue, StatusCode},
response::Response,
};
use futures_util::future::BoxFuture;
-use std::{
- task::{Context, Poll},
-};
+use std::task::{Context, Poll};
use tower::{Layer, Service};
+use tracing::trace;
-use crate::{server::middleware::sign_request::signature::Signature, state::AppHandle};
-
+use crate::{
+ server::{middleware::sign_request::signature::Signature, routes::users::get_user::read_user},
+ state::AppHandle,
+};
#[derive(Clone)]
pub struct SignRequestLayer {
@@ -62,30 +63,105 @@ where
fn call(&mut self, request: Request) -> Self::Future {
let mut inner = self.inner.clone();
+ let uri = request.uri().clone();
let (parts, body) = request.into_parts();
+ let state = self.state.to_request_data();
+ let domain = self.state.domain().to_owned();
Box::pin(async move {
- let bytes = axum::body::to_bytes(body, usize::MAX).await.unwrap();
-
- let signature = Signature::create(
- ""
- .as_bytes(),
- bytes,
- )
- .unwrap();
+ let ok_500 = || {
+ let mut response = axum::response::Response::default();
+ *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
+ Ok(response)
+ };
+ let bytes = match axum::body::to_bytes(body, usize::MAX).await {
+ Ok(b) => b,
+ Err(e) => {
+ trace!("could not decode response body: {e:?}");
+ return ok_500();
+ }
+ };
+
+ // Get user
+ let user = match read_user("sellershut", &state).await {
+ Ok(Some(u)) => u,
+ Ok(None) => {
+ trace!("user not found");
+ return ok_500();
+ }
+ Err(e) => {
+ trace!("failed to read user: {e:?}");
+ return ok_500();
+ }
+ };
+
+ let pk = user.private_key.clone().unwrap_or_default();
+
+ let json_user = match user.into_json(&state).await {
+ Ok(j) => j,
+ Err(e) => {
+ trace!("failed to serialise user: {e:?}");
+ return ok_500();
+ }
+ };
+
+ // Sign the body
+ let signature = match Signature::new(pk.as_bytes(), bytes, uri, &domain) {
+ Ok(sig) => sig,
+ Err(e) => {
+ trace!("signature creation failed: {e:?}");
+ return ok_500();
+ }
+ };
let mut new_request = Request::from_parts(parts, Body::from(signature.body));
let head = new_request.headers_mut();
- let header = format!(
- "keyId=\"http://localhost/users/sellershut#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"{}\"",
- signature.signature,
- );
- println!("{header}");
- head.insert("Host", HeaderValue::from_str(&signature.host).unwrap());
- head.insert("Date", HeaderValue::from_str(&signature.date).unwrap());
- head.insert("Digest", HeaderValue::from_str(&signature.digest).unwrap());
- head.insert("Signature", HeaderValue::from_str(&header).unwrap());
+
+ let header = [
+ format!("keyId=\"{}\"", json_user.public_id()),
+ "algorithm=rsa-sha256".to_string(),
+ "headers=\"(request-target) host date digest\"".to_string(),
+ format!("signature=\"{}\"", signature.signature),
+ ]
+ .join(",");
+
+ let host = match HeaderValue::from_str(&signature.host) {
+ Ok(value) => value,
+ Err(e) => {
+ trace!(name = "host",value = ?signature.host, "header creation failed: {e:?}");
+ return ok_500();
+ }
+ };
+
+ let date = match HeaderValue::from_str(&signature.date) {
+ Ok(value) => value,
+ Err(e) => {
+ trace!(name = "date",value = ?signature.date, "header creation failed: {e:?}");
+ return ok_500();
+ }
+ };
+
+ let digest = match HeaderValue::from_str(&signature.digest) {
+ Ok(value) => value,
+ Err(e) => {
+ trace!(name = "digest",value = ?signature.digest, "header creation failed: {e:?}");
+ return ok_500();
+ }
+ };
+
+ let signature = match HeaderValue::from_str(&header) {
+ Ok(value) => value,
+ Err(e) => {
+ trace!(name = "signature", "header creation failed: {e:?}");
+ return ok_500();
+ }
+ };
+
+ head.insert("Host", host);
+ head.insert("Date", date);
+ head.insert("Digest", digest);
+ head.insert("Signature", signature);
inner.call(new_request).await
})