mirror of
https://github.com/LemmyNet/activitypub-federation-rust.git
synced 2024-06-02 13:29:36 +00:00
Use actix rt for axum example
This commit is contained in:
parent
aa43308749
commit
4777d114c7
62
Cargo.lock
generated
62
Cargo.lock
generated
|
@ -12,7 +12,6 @@ dependencies = [
|
|||
"anyhow",
|
||||
"async-trait",
|
||||
"axum",
|
||||
"axum-macros",
|
||||
"background-jobs",
|
||||
"base64",
|
||||
"chrono",
|
||||
|
@ -40,6 +39,7 @@ dependencies = [
|
|||
"tower",
|
||||
"tower-http",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -1138,6 +1138,15 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||
dependencies = [
|
||||
"regex-automata",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.6.0"
|
||||
|
@ -1196,6 +1205,16 @@ dependencies = [
|
|||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||
dependencies = [
|
||||
"overload",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
|
@ -1276,6 +1295,12 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
|
@ -1423,6 +1448,15 @@ dependencies = [
|
|||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.28"
|
||||
|
@ -1895,6 +1929,7 @@ dependencies = [
|
|||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1940,6 +1975,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1962,15 +1998,33 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2043,6 +2097,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
|
|
@ -31,26 +31,27 @@ enum_delegate = "0.2.0"
|
|||
httpdate = "1.0.2"
|
||||
http-signature-normalization-reqwest = { version = "0.7.1", default-features = false, features = ["sha-2", "middleware"] }
|
||||
http-signature-normalization = "0.6.0"
|
||||
actix-rt = { version = "2.7.0" }
|
||||
|
||||
actix-web = { version = "4.2.1", default-features = false, optional = true }
|
||||
http-signature-normalization-actix = { version = "0.6.1", default-features = false, features = ["server", "sha-2"], optional = true }
|
||||
axum = { version = "0.6.0-rc.5", features = ["json", "headers", "macros", "original-uri"], optional = true }
|
||||
|
||||
# Axum
|
||||
tower-http = { version = "0.3", features = ["map-request-body", "util"], optional = true }
|
||||
tower-http = { version = "0.3", features = ["map-request-body", "util", "trace"], optional = true }
|
||||
tower = { version = "0.4.13", optional = true }
|
||||
hyper = { version = "0.14", optional = true }
|
||||
|
||||
## FIXME: this is for debugging purpose
|
||||
axum-macros = "0.3.0"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"], optional = true }
|
||||
|
||||
[features]
|
||||
default = ["actix"]
|
||||
actix = ["dep:actix-web", "dep:http-signature-normalization-actix"]
|
||||
axum = [
|
||||
"dep:axum",
|
||||
"dep:tower-http",
|
||||
"dep:tower",
|
||||
"dep:hyper",
|
||||
"dep:tracing-subscriber",
|
||||
]
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -24,7 +24,6 @@ use activitypub_federation::{
|
|||
|
||||
use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer};
|
||||
use async_trait::async_trait;
|
||||
/// FIXME: actix
|
||||
use http_signature_normalization_actix::prelude::VerifyDigest;
|
||||
use reqwest::Client;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
|
|
@ -30,11 +30,10 @@ use axum::{
|
|||
Extension,
|
||||
Router,
|
||||
};
|
||||
use http::{header::CONTENT_TYPE, HeaderMap, Request, Response};
|
||||
use http::{header::CONTENT_TYPE, HeaderMap, Method, Request, Response};
|
||||
use reqwest::Client;
|
||||
use std::{
|
||||
net::SocketAddr,
|
||||
str::FromStr,
|
||||
net::ToSocketAddrs,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use tokio::task;
|
||||
|
@ -104,10 +103,14 @@ impl Instance {
|
|||
.layer(middleware::from_fn(verify_request_payload)),
|
||||
)
|
||||
.route("/objects/:user_name", get(http_get_user))
|
||||
.with_state(instance);
|
||||
.with_state(instance)
|
||||
.layer(TraceLayer::new_for_http());
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from_str(hostname)?;
|
||||
let addr = hostname
|
||||
.to_socket_addrs()?
|
||||
.next()
|
||||
.expect("Failed to lookup domain name");
|
||||
let server = axum::Server::bind(&addr).serve(app.into_make_service());
|
||||
|
||||
task::spawn(server);
|
||||
|
@ -116,11 +119,8 @@ impl Instance {
|
|||
}
|
||||
|
||||
use activitypub_federation::core::axum::inbox::receive_activity;
|
||||
/// FIXME
|
||||
use axum_macros::debug_handler;
|
||||
use tower_http::trace::TraceLayer;
|
||||
|
||||
#[debug_handler(body = Body)]
|
||||
/// Handles requests to fetch user json over HTTP
|
||||
async fn http_get_user(
|
||||
State(data): State<InstanceHandle>,
|
||||
request: Request<Body>,
|
||||
|
@ -149,10 +149,9 @@ async fn http_get_user(
|
|||
.expect("failed to build response")
|
||||
}
|
||||
|
||||
/// Handles messages received in user inbox
|
||||
#[debug_handler(body = BoxBody)]
|
||||
async fn http_post_user_inbox(
|
||||
headers: HeaderMap,
|
||||
method: Method,
|
||||
OriginalUri(uri): OriginalUri,
|
||||
State(data): State<InstanceHandle>,
|
||||
Extension(digest_verified): Extension<DigestVerified>,
|
||||
|
@ -164,6 +163,7 @@ async fn http_post_user_inbox(
|
|||
&data.clone().local_instance,
|
||||
&Data::new(data),
|
||||
headers,
|
||||
method,
|
||||
uri,
|
||||
)
|
||||
.await
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{error::Error, instance::Instance, objects::note::MyPost, utils::generate_object_id};
|
||||
use tracing::log::LevelFilter;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
mod activities;
|
||||
mod error;
|
||||
|
@ -7,10 +7,15 @@ mod instance;
|
|||
mod objects;
|
||||
mod utils;
|
||||
|
||||
#[tokio::main]
|
||||
#[actix_rt::main]
|
||||
async fn main() -> Result<(), Error> {
|
||||
env_logger::builder()
|
||||
.filter_level(LevelFilter::Debug)
|
||||
tracing_subscriber::registry()
|
||||
.with(tracing_subscriber::EnvFilter::new(
|
||||
std::env::var("RUST_LOG").unwrap_or_else(|_| {
|
||||
"activitypub_federation=debug,federation-axum=debug,tower_http=debug".into()
|
||||
}),
|
||||
))
|
||||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
|
||||
let alpha = Instance::new("localhost:8001".to_string())?;
|
||||
|
@ -23,6 +28,7 @@ async fn main() -> Result<(), Error> {
|
|||
.local_user()
|
||||
.follow(&beta.local_user(), &alpha)
|
||||
.await?;
|
||||
|
||||
// assert that follow worked correctly
|
||||
assert_eq!(
|
||||
beta.local_user().followers(),
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::{
|
|||
Error,
|
||||
LocalInstance,
|
||||
};
|
||||
use http::{HeaderMap, Uri};
|
||||
use http::{HeaderMap, Method, Uri};
|
||||
use serde::de::DeserializeOwned;
|
||||
use tracing::debug;
|
||||
|
||||
|
@ -19,6 +19,7 @@ pub async fn receive_activity<Activity, ActorT, Datatype>(
|
|||
local_instance: &LocalInstance,
|
||||
data: &Data<Datatype>,
|
||||
headers: HeaderMap,
|
||||
method: Method,
|
||||
uri: Uri,
|
||||
) -> Result<(), <Activity as ActivityHandler>::Error>
|
||||
where
|
||||
|
@ -29,7 +30,6 @@ where
|
|||
+ From<Error>
|
||||
+ From<<ActorT as ApubObject>::Error>
|
||||
+ From<serde_json::Error>,
|
||||
// + From<http_signature_normalization_actix::digest::middleware::VerifyError>,
|
||||
<ActorT as ApubObject>::Error: From<Error> + From<anyhow::Error>,
|
||||
{
|
||||
local_instance.verify_url_and_domain(&activity).await?;
|
||||
|
@ -39,7 +39,7 @@ where
|
|||
.dereference(data, local_instance, request_counter)
|
||||
.await?;
|
||||
|
||||
verify_signature(&headers, uri, actor.public_key())?;
|
||||
verify_signature(&headers, method, uri, actor.public_key())?;
|
||||
|
||||
debug!("Verifying activity {}", activity.id().to_string());
|
||||
activity.verify(data, request_counter).await?;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use anyhow::anyhow;
|
||||
use http::{HeaderMap, Uri};
|
||||
use http::{HeaderMap, Method, Uri};
|
||||
use http_signature_normalization::Config;
|
||||
use openssl::{hash::MessageDigest, pkey::PKey, sign::Verifier};
|
||||
use std::collections::BTreeMap;
|
||||
|
@ -8,6 +8,7 @@ use tracing::debug;
|
|||
/// Verifies the HTTP signature on an incoming inbox request.
|
||||
pub fn verify_signature(
|
||||
headers: &HeaderMap,
|
||||
method: Method,
|
||||
uri: Uri,
|
||||
public_key: &str,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
|
@ -19,8 +20,13 @@ pub fn verify_signature(
|
|||
}
|
||||
}
|
||||
|
||||
let path_and_query = uri
|
||||
.path_and_query()
|
||||
.ok_or(anyhow!("empty uri while veryfying signature "))?
|
||||
.as_str();
|
||||
|
||||
let verified = config
|
||||
.begin_verify("GET", "/foo?bar=baz", header_map)?
|
||||
.begin_verify(method.as_str(), path_and_query, header_map)?
|
||||
.verify(|signature, signing_string| -> anyhow::Result<bool> {
|
||||
debug!(
|
||||
"Verifying with key {}, message {}",
|
||||
|
|
Loading…
Reference in a new issue