diff --git a/proxmox-tfa/src/api/methods.rs b/proxmox-tfa/src/api/methods.rs index e7461290..f0ee2a61 100644 --- a/proxmox-tfa/src/api/methods.rs +++ b/proxmox-tfa/src/api/methods.rs @@ -12,7 +12,7 @@ use proxmox_schema::api; use super::{OpenUserChallengeData, TfaConfig, TfaInfo, TfaUserData}; use crate::totp::Totp; -pub use crate::types::{TfaType, TfaUpdateInfo, TypedTfaInfo}; +pub use crate::types::{TfaType, TfaUpdateInfo, TfaUser, TypedTfaInfo}; fn to_data(data: &TfaUserData) -> Vec { let mut out = Vec::with_capacity( @@ -216,33 +216,6 @@ pub fn unlock_and_reset_tfa( config.unlock_and_reset_tfa(access, userid) } -#[cfg_attr(feature = "api-types", api( - properties: { - "entries": { - type: Array, - items: { type: TypedTfaInfo }, - }, - }, -))] -#[derive(Deserialize, Serialize)] -#[serde(deny_unknown_fields, rename_all = "kebab-case")] -/// Over the API we only provide the descriptions for TFA data. -pub struct TfaUser { - /// The user this entry belongs to. - pub userid: String, - - /// TFA entries. - pub entries: Vec, - - /// The user is locked out of TOTP authentication. - #[serde(default, skip_serializing_if = "super::bool_is_false")] - pub totp_locked: bool, - - /// If a user's second factor is blocked, this contains the block's expiration time. - #[serde(skip_serializing_if = "Option::is_none")] - pub tfa_locked_until: Option, -} - /// API call implementation for `GET /access/tfa`. /// /// Caller needs to have performed the required privilege checks already. diff --git a/proxmox-tfa/src/api/mod.rs b/proxmox-tfa/src/api/mod.rs index 7f4bbb31..d7f37771 100644 --- a/proxmox-tfa/src/api/mod.rs +++ b/proxmox-tfa/src/api/mod.rs @@ -15,6 +15,7 @@ use url::Url; use webauthn_rs::{proto::UserVerificationPolicy, Webauthn}; use crate::totp::Totp; +use crate::types::bool_is_false; use proxmox_uuid::Uuid; mod serde_tools; @@ -1265,10 +1266,6 @@ impl TfaChallenge { } } -fn bool_is_false(v: &bool) -> bool { - !v -} - /// A user's response to a TFA challenge. pub enum TfaResponse { Totp(String), diff --git a/proxmox-tfa/src/lib.rs b/proxmox-tfa/src/lib.rs index 1f65508b..33f1d457 100644 --- a/proxmox-tfa/src/lib.rs +++ b/proxmox-tfa/src/lib.rs @@ -12,4 +12,4 @@ pub mod api; #[cfg(feature = "types")] mod types; #[cfg(feature = "types")] -pub use types::{TfaInfo, TfaType, TfaUpdateInfo, TypedTfaInfo}; +pub use types::{TfaInfo, TfaType, TfaUpdateInfo, TfaUser, TypedTfaInfo}; diff --git a/proxmox-tfa/src/types.rs b/proxmox-tfa/src/types.rs index c6e45921..ace9fd19 100644 --- a/proxmox-tfa/src/types.rs +++ b/proxmox-tfa/src/types.rs @@ -73,7 +73,7 @@ impl TfaInfo { ) )] /// A TFA entry for a user. -#[derive(Deserialize, Serialize)] +#[derive(Clone, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct TypedTfaInfo { #[serde(rename = "type")] @@ -121,3 +121,34 @@ impl TfaUpdateInfo { } } } + +#[cfg_attr(feature = "api-types", api( + properties: { + "entries": { + type: Array, + items: { type: TypedTfaInfo }, + }, + }, +))] +#[derive(Deserialize, Serialize)] +#[serde(deny_unknown_fields, rename_all = "kebab-case")] +/// Over the API we only provide the descriptions for TFA data. +pub struct TfaUser { + /// The user this entry belongs to. + pub userid: String, + + /// TFA entries. + pub entries: Vec, + + /// The user is locked out of TOTP authentication. + #[serde(default, skip_serializing_if = "bool_is_false")] + pub totp_locked: bool, + + /// If a user's second factor is blocked, this contains the block's expiration time. + #[serde(skip_serializing_if = "Option::is_none")] + pub tfa_locked_until: Option, +} + +pub(crate) fn bool_is_false(v: &bool) -> bool { + !v +}