about summary refs log tree commit diff
path: root/kittybox-rs/src/indieauth/webauthn.rs
diff options
context:
space:
mode:
Diffstat (limited to 'kittybox-rs/src/indieauth/webauthn.rs')
-rw-r--r--kittybox-rs/src/indieauth/webauthn.rs140
1 files changed, 0 insertions, 140 deletions
diff --git a/kittybox-rs/src/indieauth/webauthn.rs b/kittybox-rs/src/indieauth/webauthn.rs
deleted file mode 100644
index ea3ad3d..0000000
--- a/kittybox-rs/src/indieauth/webauthn.rs
+++ /dev/null
@@ -1,140 +0,0 @@
-use axum::{
-    extract::{Json, Host},
-    response::{IntoResponse, Response},
-    http::StatusCode, Extension, TypedHeader, headers::{authorization::Bearer, Authorization}
-};
-use axum_extra::extract::cookie::{CookieJar, Cookie};
-
-use super::backend::AuthBackend;
-use crate::database::Storage;
-
-pub(crate) const CHALLENGE_ID_COOKIE: &str = "kittybox_webauthn_challenge_id";
-
-macro_rules! bail {
-    ($msg:literal, $err:expr) => {
-        {
-            ::tracing::error!($msg, $err);
-            return ::axum::http::StatusCode::INTERNAL_SERVER_ERROR.into_response()
-        }
-    }
-}
-
-pub async fn webauthn_pre_register<A: AuthBackend, D: Storage + 'static>(
-    Host(host): Host,
-    Extension(db): Extension<D>,
-    Extension(auth): Extension<A>,
-    cookies: CookieJar
-) -> Response {
-    let uid = format!("https://{}/", host.clone());
-    let uid_url: url::Url = uid.parse().unwrap();
-    // This will not find an h-card in onboarding!
-    let display_name = match db.get_post(&uid).await {
-        Ok(hcard) => match hcard {
-            Some(mut hcard) => {
-                match hcard["properties"]["uid"][0].take() {
-                    serde_json::Value::String(name) => name,
-                    _ => String::default()
-                }
-            },
-            None => String::default()
-        },
-        Err(err) => bail!("Error retrieving h-card: {}", err)
-    };
-
-    let webauthn = webauthn::WebauthnBuilder::new(
-        &host,
-        &uid_url
-    )
-        .unwrap()
-        .rp_name("Kittybox")
-        .build()
-        .unwrap();
-
-    let (challenge, state) = match webauthn.start_passkey_registration(
-        // Note: using a nil uuid here is fine
-        // Because the user corresponds to a website anyway
-        // We do not track multiple users
-        webauthn::prelude::Uuid::nil(),
-        &uid,
-        &display_name,
-        Some(vec![])
-    ) {
-        Ok((challenge, state)) => (challenge, state),
-        Err(err) => bail!("Error generating WebAuthn registration data: {}", err)
-    };
-
-    match auth.persist_registration_challenge(&uid_url, state).await {
-        Ok(challenge_id) => (
-            cookies.add(
-                Cookie::build(CHALLENGE_ID_COOKIE, challenge_id)
-                    .secure(true)
-                    .finish()
-            ),
-            Json(challenge)
-        ).into_response(),
-        Err(err) => bail!("Failed to persist WebAuthn challenge: {}", err)
-    }
-}
-
-pub async fn webauthn_register<A: AuthBackend>(
-    Host(host): Host,
-    Json(credential): Json<webauthn::prelude::RegisterPublicKeyCredential>,
-    // TODO determine if we can use a cookie maybe?
-    user_credential: Option<TypedHeader<Authorization<Bearer>>>,
-    Extension(auth): Extension<A>
-) -> Response {
-    let uid = format!("https://{}/", host.clone());
-    let uid_url: url::Url = uid.parse().unwrap();
-
-    let pubkeys = match auth.list_webauthn_pubkeys(&uid_url).await {
-        Ok(pubkeys) => pubkeys,
-        Err(err) => bail!("Error enumerating existing WebAuthn credentials: {}", err)
-    };
-
-    if !pubkeys.is_empty() {
-        if let Some(TypedHeader(Authorization(token))) = user_credential {
-            // TODO check validity of the credential
-        } else {
-            return StatusCode::UNAUTHORIZED.into_response()
-        }
-    }
-
-    return StatusCode::OK.into_response()
-}
-
-pub(crate) async fn verify<A: AuthBackend>(
-    auth: &A,
-    website: &url::Url,
-    credential: webauthn::prelude::PublicKeyCredential,
-    challenge_id: &str
-) -> std::io::Result<bool> {
-    let host = website.host_str().unwrap();
-
-    let webauthn = webauthn::WebauthnBuilder::new(
-        host,
-        website
-    )
-        .unwrap()
-        .rp_name("Kittybox")
-        .build()
-        .unwrap();
-
-    match webauthn.finish_passkey_authentication(
-        &credential,
-        &auth.retrieve_authentication_challenge(&website, challenge_id).await?
-    ) {
-        Err(err) => {
-            tracing::error!("WebAuthn error: {}", err);
-            Ok(false)
-        },
-        Ok(authentication_result) => {
-            let counter = authentication_result.counter();
-            let cred_id = authentication_result.cred_id();
-
-            if authentication_result.needs_update() {
-                todo!()
-            }
-            Ok(true)
-        }
-    }
-}