Compare commits

..

2 Commits

Author SHA1 Message Date
Shadowfacts da7566b2d0 Add WebFinger response for OIDC 2023-06-24 21:55:54 -07:00
Shadowfacts 19f7cba75a Listen on all interfaces in dev 2023-05-29 12:49:38 -07:00
2 changed files with 34 additions and 14 deletions

View File

@ -10,10 +10,15 @@ use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
static ACCT: Lazy<String> = Lazy::new(|| format!("blog@{}", *DOMAIN)); static ACCT: Lazy<String> = Lazy::new(|| format!("blog@{}", *DOMAIN));
const OIDC_SUBJECT: &'static str = "me@shadowfacts.net";
pub async fn handle(req: Request<Body>) -> Response { pub async fn handle(req: Request<Body>) -> Response {
if is_resource_blog(req).await { let resource = resource(req).await;
Json(WebfingerResponse::new()).into_response() if resource.as_deref() == Some(&*ACCT) {
Json(WebfingerResponse::blog()).into_response()
} else if resource.as_deref() == Some(&OIDC_SUBJECT) {
// used for tailscale OIDC
Json(WebfingerResponse::oidc()).into_response()
} else { } else {
// mastodon responds with 400 and an empty body, so we do too // mastodon responds with 400 and an empty body, so we do too
StatusCode::BAD_REQUEST.into_response() StatusCode::BAD_REQUEST.into_response()
@ -43,18 +48,16 @@ pub async fn handle_interact(
.into_response() .into_response()
} }
async fn is_resource_blog(req: Request<Body>) -> bool { async fn resource(req: Request<Body>) -> Option<String> {
let mut parts = RequestParts::new(req); let mut parts = RequestParts::new(req);
if let Ok(Query(params)) = parts.extract::<Query<Params>>().await { let params = parts.extract::<Query<Params>>().await;
let resource = if params.resource.starts_with("acct:") { params.ok().map(|Query(params)| {
&params.resource[5..] if params.resource.starts_with("acct:") {
params.resource[5..].into()
} else { } else {
&params.resource params.resource
}; }
resource == ACCT.as_str() })
} else {
false
}
} }
async fn query(acct: &str) -> anyhow::Result<WebfingerResponse> { async fn query(acct: &str) -> anyhow::Result<WebfingerResponse> {
@ -89,7 +92,7 @@ pub struct WebfingerResponse {
} }
impl WebfingerResponse { impl WebfingerResponse {
fn new() -> Self { fn blog() -> Self {
Self { Self {
subject: ACCT.to_owned(), subject: ACCT.to_owned(),
links: vec![Link { links: vec![Link {
@ -101,6 +104,18 @@ impl WebfingerResponse {
}], }],
} }
} }
fn oidc() -> Self {
Self {
subject: OIDC_SUBJECT.to_owned(),
links: vec![Link {
rel: "http://openid.net/specs/connect/1.0/issuer".to_owned(),
payload: LinkPayload::Href {
href: "https://auth.shadowfacts.net/application/o/tailscale/".to_owned(),
},
}],
}
}
} }
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
@ -115,6 +130,7 @@ pub struct Link {
pub enum LinkPayload { pub enum LinkPayload {
Webfinger { r#type: String, href: String }, Webfinger { r#type: String, href: String },
OStatusSubscribe { template: String }, OStatusSubscribe { template: String },
Href { href: String },
} }
#[cfg(test)] #[cfg(test)]

View File

@ -166,7 +166,11 @@ async fn serve(posts: &[Post<HtmlContent>], pool: SqlitePool) {
.fallback(get_service(articles_or_fallback)) .fallback(get_service(articles_or_fallback))
.layer(Extension(pool)); .layer(Extension(pool));
let addr = SocketAddr::from(([127, 0, 0, 1], 8084)); let addr = if cfg!(debug_assertions) {
SocketAddr::from(([0, 0, 0, 0], 8084))
} else {
SocketAddr::from(([127, 0, 0, 1], 8084))
};
info!("Listening on {}", addr); info!("Listening on {}", addr);
axum::Server::bind(&addr) axum::Server::bind(&addr)
.serve(app.into_make_service()) .serve(app.into_make_service())