Compare commits

..

3 Commits

Author SHA1 Message Date
Avery f153a8b9c7
Print panic messages to the log
10 months ago
Avery 1bafa23e81
Logging for HitLock, implement IntoResponce for UserResponse, Use
10 months ago
Avery 0fc16e7870
Create workspace and move NotePoster and HitLock into workspace
10 months ago

3
.gitmodules vendored

@ -1,3 +0,0 @@
[submodule "NotePoster"]
path = NotePoster
url = https://gitea.itycodes.org/itycodes/NotePoster

865
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -1,13 +1,16 @@
[package] [workspace]
name = "rust_fedi" members = ["HitLock", "NotePoster"]
version = "0.1.0" resolver = "2"
edition = "2024"
[dependencies] [workspace.dependencies]
axum = "0.8.3"
env_logger = "0.11.8" env_logger = "0.11.8"
rsa = "0.9.8" log = "0.4.27"
rand = "0.8"
base64 = "0.22.1"
openssl = "0.10.72"
pkcs8 = { version = "0.10.2", features = ["pem"] }
sha2 = "0.10.9"
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140" serde_json = "1.0.140"
sha2 = "0.10.8"
tokio = { version = "1.44.2", features = ["full"] }

@ -0,0 +1,17 @@
[package]
name = "rust_fedi"
version = "0.1.0"
edition = "2024"
[dependencies]
tokio = { version = "1.44.2", features = ["full"] }
axum = "0.8.3"
tower-layer = "0.3.3"
tower-service = "0.3.3"
webfinger-rs = { version = "0.0.13", features = ["axum"] }
serde = { workspace = true }
serde_json = { workspace = true }
env_logger = { workspace = true }
log = { workspace = true }

@ -0,0 +1,28 @@
use axum::body::Bytes;
use axum::extract::Path;
use axum::http::HeaderMap;
use log::{debug, info};
use std::fs::File;
use std::io::Write;
use crate::sanitize_printable;
pub async fn inbox_post(Path(user): Path<String>, headers: HeaderMap, bytes: Bytes) {
info!("Got post to inbox of user: {:?}", user);
debug!("With headers: {:#?}", headers);
File::create("./last.json")
.map(|mut res| {
res.write_all(&bytes).expect("Failed writing");
println!("Writing file");
})
.expect("Failed to create file");
let json = String::from_utf8(Vec::from(bytes)).expect("Invalid UTF-8");
let json: serde_json::Value = serde_json::from_str(&json).expect("Invalid JSON");
match serde_json::to_string_pretty(&json) {
Ok(pretty_json) => info!("Received JSON:\n{}\n\n", sanitize_printable(&pretty_json)),
Err(err) => info!("Failed to format JSON: {}\n\n", err),
}
}

@ -0,0 +1,133 @@
mod inbox;
mod users;
mod webfinger;
use std::{
fmt::{self, Debug},
iter::once,
panic,
task::{Context, Poll},
};
use axum::{
Router,
http::{StatusCode, Uri},
routing::{get, post},
};
use inbox::inbox_post;
use log::{error, info, trace};
use tower_layer::Layer;
use tower_service::Service;
use users::users_get;
use webfinger::webfinger_get;
const HOST: &'static str = "testing4host.com";
const USER: &'static str = "test71";
fn init_logger() {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.parse_default_env()
.init()
}
#[tokio::main]
async fn main() {
init_logger();
panic::set_hook(Box::new(|i| {
if let Some(loc) = i.location() {
if let Some(s) = i.payload().downcast_ref::<&str>() {
error!(
"Panicked at {}:{}:{}\n{}",
loc.file(),
loc.line(),
loc.column(),
sanitize_printable(s)
);
} else if let Some(s) = i.payload().downcast_ref::<String>() {
error!(
"Panicked at {}:{}:{}\n{}",
loc.file(),
loc.line(),
loc.column(),
sanitize_printable(s)
);
}
} else {
if let Some(s) = i.payload().downcast_ref::<&str>() {
error!("Panicked\n{s:?}",);
} else if let Some(s) = i.payload().downcast_ref::<String>() {
error!("Panicked\n{s:?}",);
}
}
}));
let app = Router::new()
.route("/", get(root))
.route("/.well-known/webfinger", get(webfinger_get))
.route("/users/{users}/", get(users_get))
.route("/users/{users}", get(users_get))
.route("/inbox/{users}/", post(inbox_post))
.fallback(fallback)
.layer(TraceLayer);
let listener = tokio::net::TcpListener::bind("0.0.0.0:8000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
async fn root() -> &'static str {
"Hello World!"
}
#[derive(Clone)]
pub struct TraceLayer;
async fn fallback(uri: Uri) -> (StatusCode, String) {
info!("Unknown url! {}", uri);
(StatusCode::NOT_FOUND, format!("No route for {uri}"))
}
impl<S> Layer<S> for TraceLayer {
type Service = TraceService<S>;
fn layer(&self, service: S) -> Self::Service {
TraceService { service }
}
}
#[derive(Clone)]
pub struct TraceService<S> {
service: S,
}
impl<S, Request> Service<Request> for TraceService<S>
where
S: Service<Request>,
Request: fmt::Debug,
{
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.service.poll_ready(cx)
}
fn call(&mut self, request: Request) -> Self::Future {
trace!("request = {:?}", request);
self.service.call(request)
}
}
fn sanitize_printable(src: &str) -> String {
src.chars()
.flat_map(|c| -> Box<dyn Iterator<Item = char>> {
if c.is_control() && !c.is_whitespace() {
Box::new(c.escape_unicode())
} else {
Box::new(once(c))
}
})
.collect()
}

@ -0,0 +1,76 @@
use axum::{
extract::Path,
response::{IntoResponse, Response},
};
use log::info;
use serde::Serialize;
use crate::USER;
#[derive(Serialize)]
pub struct UsersPublicKey {
id: String,
owner: String,
#[serde(rename = "publicKeyPem")]
public_key_pem: String,
}
#[derive(Serialize)]
pub struct UsersResponse {
#[serde(rename = "@context")]
context: Vec<String>,
r#type: String,
name: String,
id: String,
inbox: String,
outbox: String,
following: String,
followers: String,
summary: String,
url: String,
published: String,
tag: Vec<String>,
attachment: Vec<String>,
icon: String,
#[serde(rename = "preferredUsername")]
preferred_username: String,
#[serde(rename = "publicKey")]
public_key: UsersPublicKey,
}
pub async fn users_get(Path(user): Path<String>) -> UsersResponse {
info!("Got request for user: {:?}", user);
assert_eq!(user, USER);
UsersResponse {
context: vec!["https://www.w3.org/ns/activitystreams".to_string(), "https://w3id.org/security/v1".to_string()],
r#type: "Person".to_string(),
name: "Testing Slasher".to_string(),
id: "https://testing4host.com/users/test71/".to_string(),
inbox: "https://testing4host.com/inbox/test71/".to_string(),
outbox: "https://testing4host.com/outbox/test71/".to_string(),
followers: "https://testing4host.com/followers/test71/".to_string(),
following: "https://testing4host.com/following/test71/".to_string(),
summary: "Hi!".to_string(),
url: "https://testing4host.com/@test71/".to_string(),
published: "2024-07-13T00:00:00Z".to_string(),
tag: vec![],
attachment: vec![],
icon: "https://testing4host.com/avatar/test71".to_string(),
preferred_username: "test71".to_string(),
public_key: UsersPublicKey {
id: "https://testing4host.com/users/test71/#main-key".to_string(),
owner: "https://testing4host.com/users/test71/".to_string(),
public_key_pem: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuqubzHLVItM9522mUYSd\nFkpPs0GQalcXVKBFgBCz611fpRzKS5xSGQ8BUVSn/uGkYnOxnh1j41Nk59VUQqCe\nj6d2PUnASbQHc7hcUAPwsgXxZ2LR0z5YTflNIpymd5q3hMqv7NVf05LQnm1t+bbv\nIhiH382J70Ob5FYcae4Shtp5xeBA8IzD9Wo2DwNjH3oP83fybHIEOSofccXB+DI+\np6DZPg2E2/DPpXqVMTmwurlIYX/9jYKYALE9LwX0jY/60lRYkzag9Gr57nlEZH2g\nOOZiy2JmTSvwSWc2LfQyU789w/+b5x9E+lJl1uA4g5HN9F+nEadLRjeMIKyWFdq7\nywIDAQAB\n-----END PUBLIC KEY-----\n".to_string()
}
}
}
impl IntoResponse for UsersResponse {
fn into_response(self) -> Response {
Response::builder()
.header("content-type", "application/activity+json; charset=utf-8")
.body(serde_json::to_string(&self).unwrap().into())
.unwrap()
}
}

@ -0,0 +1,27 @@
use log::debug;
use webfinger_rs::{Link, Rel, WebFingerRequest, WebFingerResponse};
use crate::{HOST, USER};
pub async fn webfinger_get(request: WebFingerRequest) -> WebFingerResponse {
let resource = request.resource.to_string();
debug!("Got webfinger request for resource: {resource}");
let Some((typ, val)) = resource.split_once(':') else {
panic!()
};
assert_eq!(typ, "acct");
let Some((usr, dom)) = val.split_once('@') else {
panic!()
};
assert_eq!(usr, USER);
assert_eq!(dom, HOST);
WebFingerResponse::builder(format!("acct:{USER}@{HOST}"))
.alias(format!("https://{HOST}/users/{USER}"))
.link(
Link::builder(Rel::new("self"))
.r#type("application/activity+json")
.href(format!("https://{HOST}/users/{USER}")),
)
.build()
}

@ -1 +0,0 @@
Subproject commit d594dbc68635e746361a8ef0a0d0583d800c0506

814
NotePoster/Cargo.lock generated

@ -0,0 +1,814 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "adler2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3"
[[package]]
name = "bitflags"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cc"
version = "1.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "const-oid"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "der"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
dependencies = [
"const-oid",
"pem-rfc7468",
"zeroize",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"const-oid",
"crypto-common",
]
[[package]]
name = "flate2"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "http"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "httparse"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "httpdate"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
dependencies = [
"spin",
]
[[package]]
name = "libc"
version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "libm"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72"
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "miniz_oxide"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
dependencies = [
"adler2",
]
[[package]]
name = "noteposter"
version = "0.1.0"
dependencies = [
"base64",
"httpdate",
"openssl",
"pkcs8",
"rand",
"rsa",
"serde",
"serde_json",
"sha2",
"ureq",
]
[[package]]
name = "num-bigint-dig"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
dependencies = [
"byteorder",
"lazy_static",
"libm",
"num-integer",
"num-iter",
"num-traits",
"rand",
"smallvec",
"zeroize",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "openssl"
version = "0.10.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da"
dependencies = [
"bitflags",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "openssl-sys"
version = "0.9.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
dependencies = [
"base64ct",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pkcs1"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [
"der",
"pkcs8",
"spki",
]
[[package]]
name = "pkcs8"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der",
"spki",
]
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "ring"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"untrusted",
"windows-sys",
]
[[package]]
name = "rsa"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b"
dependencies = [
"const-oid",
"digest",
"num-bigint-dig",
"num-integer",
"num-traits",
"pkcs1",
"pkcs8",
"rand_core",
"sha2",
"signature",
"spki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls"
version = "0.23.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0"
dependencies = [
"log",
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pemfile"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
[[package]]
name = "rustls-webpki"
version = "0.103.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signature"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest",
"rand_core",
]
[[package]]
name = "smallvec"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "spki"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
"base64ct",
"der",
]
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "typenum"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "ureq"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7a3e9af6113ecd57b8c63d3cd76a385b2e3881365f1f489e54f49801d0c83ea"
dependencies = [
"base64",
"flate2",
"log",
"percent-encoding",
"rustls",
"rustls-pemfile",
"rustls-pki-types",
"ureq-proto",
"utf-8",
"webpki-roots",
]
[[package]]
name = "ureq-proto"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fadf18427d33828c311234884b7ba2afb57143e6e7e69fda7ee883b624661e36"
dependencies = [
"base64",
"http",
"httparse",
"log",
]
[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "webpki-roots"
version = "0.26.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37493cadf42a2a939ed404698ded7fb378bf301b5011f973361779a3a74f8c93"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "zerocopy"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"

@ -0,0 +1,20 @@
[package]
name = "noteposter"
version = "0.1.0"
edition = "2024"
[dependencies]
ureq = "3.0.11"
httpdate = "1.0.3"
rand = { workspace = true }
base64 = { workspace = true }
openssl = { workspace = true }
pkcs8 = { workspace = true }
sha2 = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
env_logger = { workspace = true }
log = { workspace = true }

@ -0,0 +1,86 @@
use base64::prelude::*;
use httpdate::fmt_http_date;
use openssl::hash::MessageDigest;
use openssl::pkey::PKey;
use openssl::sign::Signer;
use serde::{Deserialize, Serialize};
use sha2::Digest;
use std::time::SystemTime;
#[derive(Serialize, Deserialize)]
struct CreateActivity {
street: String,
city: String,
}
fn sha256sum(bytes: &[u8]) -> String {
let mut hasher = sha2::Sha256::new();
hasher.update(bytes);
return BASE64_STANDARD.encode(hasher.finalize());
}
fn main() {
let host = "estradiol.city";
let path = "/users/ity/inbox";
let url = format!("https://{}{}", host, path);
let key_id = "https://testing4host.com/users/test71/#main-key";
let json = include_bytes!("note.json");
let digest = format!("SHA-256={}", sha256sum(json));
println!("digest: {}", digest);
let date = fmt_http_date(SystemTime::now());
let mut headers = String::new();
headers.push_str(format!("(request-target): post {}\n", path).as_str());
headers.push_str(format!("host: {}\n", host).as_str());
headers.push_str(format!("date: {}\n", date).as_str());
headers.push_str(format!("digest: {}", digest).as_str());
println!("signed_string: {:?}", headers);
let privkey_file = include_str!("private.pem");
let pubkey_file = include_str!("public.pem");
let privkey =
PKey::private_key_from_pem(privkey_file.as_bytes()).expect("Failed decoding private.pem");
let _pubkey =
PKey::public_key_from_pem(pubkey_file.as_bytes()).expect("Failed decoding public.pem");
let mut signer = Signer::new(MessageDigest::sha256(), &privkey).unwrap();
signer.update(headers.as_bytes()).unwrap();
let signature = BASE64_STANDARD.encode(signer.sign_to_vec().unwrap());
let header = format!(
"keyId=\"{}\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"{}\"",
key_id, signature
);
println!("header: {}", header);
let response = ureq::post(url)
.header("Content-Type", "application/activity+json")
.header("Signature", header)
.header("host", host)
.header("date", date)
.header("digest", digest)
.send(json);
match response {
Err(v) => println!("{:#?}", v),
Ok(v) => {
println!("Status: {}", v.status());
println!(
"Response: {}",
v.into_body()
.read_to_string()
.expect("Invalid response: decode error")
);
}
}
}

@ -0,0 +1,31 @@
{
"actor":"https://testing4host.com/users/test71/",
"object":{
"id": "https://testing4host.com/hello-world-4aaaaaaaaaaa3",
"type": "Note",
"published": "2025-04-23T17:17:11Z",
"attributedTo": "https://testing4host.com/users/test71/",
"inReplyTo": null,
"content": "<p>Sexy Omega Giga Lesbian.</p>",
"to": "https://estradiol.city/users/ity",
"directMessage": true
},
"id":"https://testing4host.com/posts/a78hbr30ngfqz7aaaaaamaaaaaafaff",
"type":"Create",
"to": [
"https://estradiol.city/users/ity"
],
"cc": [
"https://estradiol.city/users/ity"
],
"@context":[
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"toot":"http://joinmastodon.org/ns#",
"misskey":"https://misskey-hub.net/ns#",
"litepub": "http://litepub.social/ns#",
"directMessage": "litepub:directMessage"
}
]
}

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6q5vMctUi0z3n
baZRhJ0WSk+zQZBqVxdUoEWAELPrXV+lHMpLnFIZDwFRVKf+4aRic7GeHWPjU2Tn
1VRCoJ6Pp3Y9ScBJtAdzuFxQA/CyBfFnYtHTPlhN+U0inKZ3mreEyq/s1V/TktCe
bW35tu8iGIffzYnvQ5vkVhxp7hKG2nnF4EDwjMP1ajYPA2Mfeg/zd/JscgQ5Kh9x
xcH4Mj6noNk+DYTb8M+lepUxObC6uUhhf/2NgpgAsT0vBfSNj/rSVFiTNqD0avnu
eURkfaA45mLLYmZNK/BJZzYt9DJTvz3D/5vnH0T6UmXW4DiDkc30X6cRp0tGN4wg
rJYV2rvLAgMBAAECggEAKu7HMXmDvbO5/B1C8GLAwlyrAf5lWZ/YNNV7xp2Q0+Qw
2EfL2yID29GQqwT+cmexKBeV1VjLHYCTp6Jv87b/YOjSD/yDZjAqupm/WYPeewNU
50NaIOyo4J4i+H/w5XdHGBqJ5b2ZgY61vopKjfFeBIiBz551R/tTwmtvs4lW5365
Zxi27MEBbnjc+pb3QiRAvDo3Mb0y4eXXnSdjb7N9zZrHGhJR2ZC6i+zbmTQc3l+2
xkgtGWcWD7l3qauM5EDkTib48tqN36oSHNddBlZ7MpYYFxKxbmo3M3rcgg9LUy8u
PRDYtr3+gG4m+T5kQqjcEG3jFgrbFz5sqDvoVNNMEQKBgQDnF5EtHjG67cmcn/1+
/bwjWEiOSyLnKmIzU0xWNP/CxY/IKajaGqz6cGZnw3f3E6+5pOJNjlFU38kwCLRn
DqhyuSpb1lSklobtKlyZ4Ha8NMW8A+9EX0MlBg5IMdoopRanhBd7L6nHUStGwZ1u
J33KrsQiEHHT0ihKE4PBLim+cwKBgQDOylSdJX5XhZNlJjJOkZtdJqz2uEpL5eNc
HJbLE0LUuYzIgnFFPlNNqfBdw6H/ctGPCuVnjNpY3wzqxY6Zx0tAk+/MXsy+Uglz
05fjKZhvP/loLFakS/kJiBj8KvJssN/273gSL3Bf4W091Zk/XJXtnMUwhwbgkNJf
PFk1oi6fSQKBgDP8Wj1TGI7bpUolt6oUvHkbCB9yiaSFJVg0eey+uXaAaQr3TDPc
YmNoW7EmCNu9Qv+5NuuJg4RbX2/91U+FvaEpRH0qZxorfqjlqbU4CJ3oJT9Zhz7T
S1CN3zKgfFo+YS1ICtw8aa4b9WdScO7x1Vt+G0MqfeDP2x5m63HOx7c/AoGBAMJY
g+dhKnllD57bpCIVVJfaVmpVz3W/a8vRDqNyybeVX0u+1GfIaJAwK7hjuWeT6IFw
MyP7y+YEU2Z+H0RFemMJ5jAD1Jb2EO4rqa8UE7BSxrryGMe2oyojH6A3WLlwDj1M
2GL29L0X5wxbJ/jVsg6r7ONrs7nwQdbBp/HxJ7IJAoGBAK/iwgmf/Bqo4MRO/LLs
HOJM0X8d9aaTJaqCBEudNVAx8+0UsXyHt2bZUTX3LcCbjuPVGykPgkeORITB1Adz
ymAwPIrYP6C90YtWf3IEmLmQs2sOuZzCpKZqeWfUjW4FqbVDI9r+OqiB62Z3NmYb
D+TVXY37h9J21RUxmNIh5o2+
-----END PRIVATE KEY-----

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuqubzHLVItM9522mUYSd
FkpPs0GQalcXVKBFgBCz611fpRzKS5xSGQ8BUVSn/uGkYnOxnh1j41Nk59VUQqCe
j6d2PUnASbQHc7hcUAPwsgXxZ2LR0z5YTflNIpymd5q3hMqv7NVf05LQnm1t+bbv
IhiH382J70Ob5FYcae4Shtp5xeBA8IzD9Wo2DwNjH3oP83fybHIEOSofccXB+DI+
p6DZPg2E2/DPpXqVMTmwurlIYX/9jYKYALE9LwX0jY/60lRYkzag9Gr57nlEZH2g
OOZiy2JmTSvwSWc2LfQyU789w/+b5x9E+lJl1uA4g5HN9F+nEadLRjeMIKyWFdq7
ywIDAQAB
-----END PUBLIC KEY-----

@ -0,0 +1,61 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1745930157,
"narHash": "sha256-y3h3NLnzRSiUkYpnfvnS669zWZLoqqI6NprtLQ+5dck=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "46e634be05ce9dc6d4db8e664515ba10b78151ae",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

@ -0,0 +1,26 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = {
self,
nixpkgs,
flake-utils,
...
} @ inputs:
flake-utils.lib.eachDefaultSystem (system: let
name = "HitLock";
src = ./.;
pkgs = import nixpkgs {
inherit system;
};
in {
devShells.default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [pkg-config];
buildInputs = with pkgs; [openssl];
};
});
}

@ -1,20 +0,0 @@
use axum::http::HeaderMap;
use axum::body::Bytes;
use core::slice::SlicePattern;
use std::fs::File;
use std::io::Write;
pub async fn inbox_post(headers: HeaderMap, bytes: Bytes) {
println!("Headers: {:#?}", headers);
let _ = File::create("./last.json").map(|mut res| {
res.write_all(&bytes).expect("Failed writing");
println!("Writing file");
});
let json = String::from_utf8(Vec::from(bytes.as_slice())).expect("Invalid UTF-8");
let json: serde_json::Value = serde_json::from_str(&json).expect("Invalid JSON");
match serde_json::to_string_pretty(&json) {
Ok(pretty_json) => println!("Received JSON:\n{}\n\n", pretty_json),
Err(err) => println!("Failed to format JSON: {}\n\n", err),
}
}

@ -1,42 +0,0 @@
#![feature(slice_pattern)]
mod inbox;
mod users;
mod webfinger;
use axum::{
Router,
http::{StatusCode, Uri},
routing::{get, post},
};
use inbox::inbox_post;
use users::users_get;
use webfinger::webfinger_get;
const HOST: &'static str = "testing4host.com";
const USER: &'static str = "test71";
async fn fallback(uri: Uri) -> (StatusCode, String) {
println!("Unknown url! {}", uri);
(StatusCode::NOT_FOUND, format!("No route for {uri}"))
}
#[tokio::main]
async fn main() {
env_logger::init();
let app = Router::new()
.route("/", get(root))
.route("/.well-known/webfinger", get(webfinger_get))
.route("/users/{users}/", get(users_get))
.route("/users/{users}", get(users_get))
.route("/inbox/{users}/", post(inbox_post))
.fallback(fallback);
let listener = tokio::net::TcpListener::bind("0.0.0.0:8000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
async fn root() -> &'static str {
"Hello World!"
}

@ -1,69 +0,0 @@
use axum::{extract::Path, response::Response};
use serde::Serialize;
use crate::USER;
#[derive(Serialize)]
pub struct UsersPublicKey {
id: String,
owner: String,
#[serde(rename = "publicKeyPem")]
public_key_pem: String,
}
#[derive(Serialize)]
pub struct UsersResponse {
#[serde(rename = "@context")]
context: Vec<String>,
r#type: String,
name: String,
id: String,
inbox: String,
outbox: String,
following: String,
followers: String,
summary: String,
url: String,
published: String,
tag: Vec<String>,
attachment: Vec<String>,
icon: String,
#[serde(rename = "preferredUsername")]
preferred_username: String,
#[serde(rename = "publicKey")]
public_key: UsersPublicKey,
}
pub async fn users_get(Path(user): Path<String>) -> Response {
println!("users: {}", user);
assert_eq!(user, USER);
Response::builder()
.header("content-type", "application/activity+json; charset=utf-8")
.body(
serde_json::to_string(&UsersResponse {
context: vec!["https://www.w3.org/ns/activitystreams".to_string(), "https://w3id.org/security/v1".to_string()],
r#type: "Person".to_string(),
name: "Testing Slasher".to_string(),
id: "https://testing4host.com/users/test71/".to_string(),
inbox: "https://testing4host.com/inbox/test71/".to_string(),
outbox: "https://testing4host.com/outbox/test71/".to_string(),
followers: "https://testing4host.com/followers/test71/".to_string(),
following: "https://testing4host.com/following/test71/".to_string(),
summary: "Hi!".to_string(),
url: "https://testing4host.com/@test71/".to_string(),
published: "2024-07-13T00:00:00Z".to_string(),
tag: vec![],
attachment: vec![],
icon: "https://testing4host.com/avatar/test71".to_string(),
preferred_username: "test71".to_string(),
public_key: UsersPublicKey {
id: "https://testing4host.com/users/test71/#main-key".to_string(),
owner: "https://testing4host.com/users/test71/".to_string(),
public_key_pem: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuqubzHLVItM9522mUYSd\nFkpPs0GQalcXVKBFgBCz611fpRzKS5xSGQ8BUVSn/uGkYnOxnh1j41Nk59VUQqCe\nj6d2PUnASbQHc7hcUAPwsgXxZ2LR0z5YTflNIpymd5q3hMqv7NVf05LQnm1t+bbv\nIhiH382J70Ob5FYcae4Shtp5xeBA8IzD9Wo2DwNjH3oP83fybHIEOSofccXB+DI+\np6DZPg2E2/DPpXqVMTmwurlIYX/9jYKYALE9LwX0jY/60lRYkzag9Gr57nlEZH2g\nOOZiy2JmTSvwSWc2LfQyU789w/+b5x9E+lJl1uA4g5HN9F+nEadLRjeMIKyWFdq7\nywIDAQAB\n-----END PUBLIC KEY-----\n".to_string() }
})
.unwrap()
.into(),
)
.unwrap()
}

@ -1,53 +0,0 @@
use axum::extract::Query;
use axum::response::Response;
use serde::{Deserialize, Serialize};
use crate::{HOST, USER};
#[derive(Deserialize)]
pub struct WebfingerQuery {
resource: String,
}
#[derive(Serialize)]
pub struct WebfingerResponse {
subject: String,
alias: Vec<String>,
links: Vec<WebfigerLink>,
}
#[derive(Serialize)]
pub struct WebfigerLink {
rel: String,
r#type: String,
href: String,
}
pub async fn webfinger_get(Query(WebfingerQuery { resource }): Query<WebfingerQuery>) -> Response {
println!("webfinger: {}", resource);
let Some((typ, val)) = resource.split_once(':') else {
panic!()
};
assert_eq!(typ, "acct");
let Some((usr, dom)) = val.split_once('@') else {
panic!()
};
assert_eq!(usr, USER);
assert_eq!(dom, HOST);
Response::builder()
.header("content-type", "application/jrd+json; charset=utf-8")
.body(
serde_json::to_string(&WebfingerResponse {
subject: format!("acct:{USER}@{HOST}"),
alias: vec![format!("https://{HOST}/users/{USER}/")],
links: vec![WebfigerLink {
rel: "self".to_string(),
r#type: "application/activity+json".to_string(),
href: format!("https://{HOST}/users/{USER}/"),
}],
})
.unwrap()
.into(),
)
.unwrap()
}
Loading…
Cancel
Save