From a2c04f605cb8372dc5f7902c2f8dd444b90f1399 Mon Sep 17 00:00:00 2001 From: Frederik Rothenberger Date: Wed, 4 Oct 2023 15:55:22 +0200 Subject: [PATCH] wip --- src/internet_identity/internet_identity.did | 12 +++++++ src/internet_identity/src/main.rs | 34 +++++++++++++++++++ .../src/internet_identity/types/api_v2.rs | 11 ++++++ 3 files changed, 57 insertions(+) diff --git a/src/internet_identity/internet_identity.did b/src/internet_identity/internet_identity.did index 579dec6069..9ae9b9e518 100644 --- a/src/internet_identity/internet_identity.did +++ b/src/internet_identity/internet_identity.did @@ -351,6 +351,11 @@ type AuthnMethodRegistrationInfo = record { expiration: Timestamp; }; +type IdentityAuthnInfo = record { + authn_methods: vec AuthnMethod; + recovery_authn_methods: vec AuthnMethod; +}; + type IdentityInfo = record { authn_methods: vec AuthnMethodData; authn_method_registration: opt AuthnMethodRegistrationInfo; @@ -373,6 +378,10 @@ type IdentityRegisterResponse = variant { invalid_metadata: text; }; +type IdentityAuthnInfoResponse = variant { + ok: IdentityAuthnInfo; +}; + type IdentityInfoResponse = variant { ok: IdentityInfo; }; @@ -500,6 +509,9 @@ service : (opt InternetIdentityInit) -> { // The sender needs to match the supplied authn_method. identity_register: (AuthnMethodData, CaptchaResult, opt principal) -> (opt IdentityRegisterResponse); + // Returns information about the authentication methods of the identity with the given number. + identity_authn_info: (IdentityNumber) -> (opt IdentityAuthnInfoResponse) query; + // Returns information about the identity with the given number. // Requires authentication. identity_info: (IdentityNumber) -> (opt IdentityInfoResponse); diff --git a/src/internet_identity/src/main.rs b/src/internet_identity/src/main.rs index 69a8142d98..9af3f335cf 100644 --- a/src/internet_identity/src/main.rs +++ b/src/internet_identity/src/main.rs @@ -505,6 +505,40 @@ fn check_authentication(anchor_number: AnchorNumber) -> Result<(Anchor, DeviceKe mod v2_api { use super::*; + #[query] + #[candid_method(query)] + fn identity_authn_info(identity_number: IdentityNumber) -> Option { + let anchor = + state::storage_borrow(|storage| storage.read(identity_number).unwrap_or_default()); + + let authn_info = anchor.into_devices().into_iter().fold( + IdentityAuthnInfo { + authn_methods: vec![], + recovery_authn_methods: vec![], + }, + |mut authn_info, device| { + let purpose = device.purpose; + + let authn_method = if let Some(credential_id) = device.credential_id { + AuthnMethod::WebAuthn(WebAuthn { + credential_id, + pubkey: device.pubkey, + }) + } else { + AuthnMethod::PubKey(PublicKeyAuthn { + pubkey: device.pubkey, + }) + }; + match purpose { + Purpose::Authentication => authn_info.authn_methods.push(authn_method), + Purpose::Recovery => authn_info.recovery_authn_methods.push(authn_method), + } + authn_info + }, + ); + Some(IdentityAuthnInfoResponse::Ok(authn_info)) + } + #[update] #[candid_method] async fn captcha_create() -> Option { diff --git a/src/internet_identity_interface/src/internet_identity/types/api_v2.rs b/src/internet_identity_interface/src/internet_identity/types/api_v2.rs index a65090f78c..7a50c29eb8 100644 --- a/src/internet_identity_interface/src/internet_identity/types/api_v2.rs +++ b/src/internet_identity_interface/src/internet_identity/types/api_v2.rs @@ -54,6 +54,12 @@ pub struct AuthnMethodRegistration { pub authn_method: Option, } +#[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] +pub struct IdentityAuthnInfo { + pub authn_methods: Vec, + pub recovery_authn_methods: Vec, +} + #[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] pub struct IdentityInfo { pub authn_methods: Vec, @@ -79,6 +85,11 @@ pub enum IdentityRegisterResponse { InvalidMetadata(String), } +pub enum IdentityAuthnInfoResponse { + #[serde(rename = "ok")] + Ok(IdentityAuthnInfo), +} + #[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)] pub enum IdentityInfoResponse { #[serde(rename = "ok")]