tfa: provide TfaUser via the 'types' feature and module

So we can access it from UI code.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2024-10-01 11:51:16 +02:00
parent ee113bf244
commit 8698f3afc7
4 changed files with 35 additions and 34 deletions

View File

@ -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<TypedTfaInfo> {
let mut out = Vec::with_capacity(
@ -216,33 +216,6 @@ pub fn unlock_and_reset_tfa<A: ?Sized + OpenUserChallengeData>(
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<TypedTfaInfo>,
/// 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<i64>,
}
/// API call implementation for `GET /access/tfa`.
///
/// Caller needs to have performed the required privilege checks already.

View File

@ -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),

View File

@ -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};

View File

@ -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<TypedTfaInfo>,
/// 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<i64>,
}
pub(crate) fn bool_is_false(v: &bool) -> bool {
!v
}