vault_client_rs/types/
totp.rs1use std::fmt;
2
3use secrecy::{ExposeSecret, SecretString};
4use serde::{Deserialize, Serialize};
5use zeroize::{Zeroize, ZeroizeOnDrop};
6
7use super::redaction::redact;
8
9#[derive(Debug, Serialize, Default, Zeroize, ZeroizeOnDrop)]
10pub struct TotpKeyRequest {
11 pub generate: bool,
12 #[serde(skip_serializing_if = "Option::is_none")]
13 pub exported: Option<bool>,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub key_size: Option<u32>,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 pub url: Option<String>,
18 #[serde(
19 serialize_with = "super::serde_secret::serialize_option",
20 skip_serializing_if = "Option::is_none"
21 )]
22 pub key: Option<SecretString>,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub issuer: Option<String>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub account_name: Option<String>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub period: Option<u32>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub algorithm: Option<String>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub digits: Option<u32>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub skew: Option<u32>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 pub qr_size: Option<u32>,
37}
38
39impl Clone for TotpKeyRequest {
40 fn clone(&self) -> Self {
41 Self {
42 generate: self.generate,
43 exported: self.exported,
44 key_size: self.key_size,
45 url: self.url.clone(),
46 key: self.key.clone(),
47 issuer: self.issuer.clone(),
48 account_name: self.account_name.clone(),
49 period: self.period,
50 algorithm: self.algorithm.clone(),
51 digits: self.digits,
52 skew: self.skew,
53 qr_size: self.qr_size,
54 }
55 }
56}
57
58#[derive(Debug, Deserialize, Clone)]
59#[non_exhaustive]
60pub struct TotpKeyInfo {
61 #[serde(default)]
62 pub account_name: String,
63 #[serde(default)]
64 pub algorithm: String,
65 #[serde(default)]
66 pub digits: u32,
67 #[serde(default)]
68 pub issuer: String,
69 #[serde(default)]
70 pub period: u32,
71}
72
73#[derive(Deserialize, Zeroize, ZeroizeOnDrop)]
74#[non_exhaustive]
75pub struct TotpGenerateResponse {
76 pub barcode: Option<SecretString>,
77 pub url: Option<SecretString>,
78}
79
80impl Clone for TotpGenerateResponse {
81 fn clone(&self) -> Self {
82 Self {
83 barcode: self.barcode.clone(),
84 url: self.url.clone(),
85 }
86 }
87}
88
89impl fmt::Debug for TotpGenerateResponse {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 f.debug_struct("TotpGenerateResponse")
92 .field(
93 "barcode",
94 &self.barcode.as_ref().map(|s| redact(s.expose_secret())),
95 )
96 .field("url", &self.url.as_ref().map(|s| redact(s.expose_secret())))
97 .finish()
98 }
99}
100
101#[derive(Deserialize, Zeroize, ZeroizeOnDrop)]
102#[non_exhaustive]
103pub struct TotpCode {
104 pub code: SecretString,
105}
106
107impl Clone for TotpCode {
108 fn clone(&self) -> Self {
109 Self {
110 code: self.code.clone(),
111 }
112 }
113}
114
115impl From<SecretString> for TotpCode {
116 fn from(code: SecretString) -> Self {
117 Self { code }
118 }
119}
120
121impl From<&str> for TotpCode {
122 fn from(code: &str) -> Self {
123 Self {
124 code: SecretString::from(code.to_owned()),
125 }
126 }
127}
128
129impl fmt::Debug for TotpCode {
130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131 f.debug_struct("TotpCode")
132 .field("code", &redact(self.code.expose_secret()))
133 .finish()
134 }
135}
136
137#[derive(Debug, Deserialize, Clone)]
138#[non_exhaustive]
139pub struct TotpValidation {
140 pub valid: bool,
141}