diff options
Diffstat (limited to 'src/server/falx.rs')
-rw-r--r-- | src/server/falx.rs | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/server/falx.rs b/src/server/falx.rs new file mode 100644 index 0000000..03a8a0b --- /dev/null +++ b/src/server/falx.rs @@ -0,0 +1,61 @@ +use axum::{ + extract::{Path, State}, + http::{HeaderMap, StatusCode, Uri}, + response::{IntoResponse, Response}, + routing::get, + Router, +}; +use axum_extra::extract::CookieJar; + +use crate::server::store::Store; + +use super::{ApiState, Handoffs}; + +pub fn bind(app: Router<ApiState>) -> Router<ApiState> { + app.route("/check/:token/:scope", get(check_)) + .route("/handoff", get(handoff)) +} + +#[axum::debug_handler(state = ApiState)] +async fn check_( + Path((token, scope)): Path<(String, String)>, + State(store): State<Store>, +) -> Response { + let Some(name) = store.check_token(&token).await else { + return StatusCode::UNAUTHORIZED.into_response(); + }; + let Some(account) = store.get_account(&name).await else { + return StatusCode::UNAUTHORIZED.into_response(); + }; + if account.scopes.contains(&scope) { + StatusCode::OK.into_response() + } else { + StatusCode::FORBIDDEN.into_response() + } +} + +#[axum::debug_handler(state = ApiState)] +async fn handoff( + jar: CookieJar, + State(Handoffs(handoffs)): State<Handoffs>, + headers: HeaderMap, +) -> Response { + let Some(origin) = headers.get("Origin") else { + return (StatusCode::BAD_REQUEST, "Missing Origin header").into_response(); + }; + let Some(origin) = origin + .to_str() + .ok() + .and_then(|origin| origin.parse::<Uri>().ok()) + .and_then(|origin| origin.host().map(ToString::to_string)) + else { + return (StatusCode::BAD_REQUEST, "Malformed Origin header").into_response(); + }; + if !handoffs.contains(&origin) { + return (StatusCode::FORBIDDEN, "Origin not registered for handoff").into_response(); + } + let Some(token) = jar.get("dissociate-token") else { + return (StatusCode::UNAUTHORIZED, "Authenticate cookie missing").into_response(); + }; + return (StatusCode::OK, token.value().to_string()).into_response(); +} |