proxmox-backup/src/api2/config/access/tfa.rs
Fabian Grünbichler 9a37bd6c84 tree-wide: fix needless borrows
found and fixed via clippy

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 13:55:33 +01:00

136 lines
3.5 KiB
Rust

//! For now this only has the TFA subdir, which is in this file.
//! If we add more, it should be moved into a sub module.
use anyhow::{format_err, Error};
use hex::FromHex;
use serde::{Deserialize, Serialize};
use proxmox_router::list_subdirs_api_method;
use proxmox_router::{Permission, Router, RpcEnvironment, SubdirMap};
use proxmox_schema::api;
use pbs_api_types::PROXMOX_CONFIG_DIGEST_SCHEMA;
use crate::config::tfa::{self, WebauthnConfig, WebauthnConfigUpdater};
pub const ROUTER: Router = Router::new()
.get(&list_subdirs_api_method!(SUBDIRS))
.subdirs(SUBDIRS);
const SUBDIRS: SubdirMap = &[("webauthn", &WEBAUTHN_ROUTER)];
const WEBAUTHN_ROUTER: Router = Router::new()
.get(&API_METHOD_GET_WEBAUTHN_CONFIG)
.put(&API_METHOD_UPDATE_WEBAUTHN_CONFIG);
#[api(
protected: true,
input: {
properties: {},
},
returns: {
type: WebauthnConfig,
optional: true,
},
access: {
permission: &Permission::Anybody,
},
)]
/// Get the TFA configuration.
pub fn get_webauthn_config(
mut rpcenv: &mut dyn RpcEnvironment,
) -> Result<Option<WebauthnConfig>, Error> {
let (config, digest) = match tfa::webauthn_config()? {
Some(c) => c,
None => return Ok(None),
};
rpcenv["digest"] = hex::encode(&digest).into();
Ok(Some(config))
}
#[api()]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
/// Deletable property name
pub enum DeletableProperty {
/// Delete the origin property.
Origin,
}
#[api(
protected: true,
input: {
properties: {
webauthn: {
flatten: true,
type: WebauthnConfigUpdater,
},
delete: {
description: "List of properties to delete.",
type: Array,
optional: true,
items: {
type: DeletableProperty,
}
},
digest: {
optional: true,
schema: PROXMOX_CONFIG_DIGEST_SCHEMA,
},
},
},
)]
/// Update the TFA configuration.
pub fn update_webauthn_config(
webauthn: WebauthnConfigUpdater,
delete: Option<Vec<DeletableProperty>>,
digest: Option<String>,
) -> Result<(), Error> {
let _lock = tfa::write_lock();
let mut tfa = tfa::read()?;
if let Some(wa) = &mut tfa.webauthn {
if let Some(ref digest) = digest {
let digest = <[u8; 32]>::from_hex(digest)?;
crate::tools::detect_modified_configuration_file(
&digest,
&crate::config::tfa::webauthn_config_digest(wa)?,
)?;
}
if let Some(delete) = delete {
for delete in delete {
match delete {
DeletableProperty::Origin => {
wa.origin = None;
}
}
}
}
if let Some(rp) = webauthn.rp {
wa.rp = rp;
}
if webauthn.origin.is_some() {
wa.origin = webauthn.origin;
}
if let Some(id) = webauthn.id {
wa.id = id;
}
} else {
let rp = webauthn
.rp
.ok_or_else(|| format_err!("missing proeprty: 'rp'"))?;
let origin = webauthn.origin;
let id = webauthn
.id
.ok_or_else(|| format_err!("missing property: 'id'"))?;
tfa.webauthn = Some(WebauthnConfig { rp, origin, id });
}
tfa::write(&tfa)?;
Ok(())
}