credential_exchange_format/
login.rs

1//! # Login Credentials
2
3use serde::{Deserialize, Serialize};
4
5use super::{EditableFieldBoolean, EditableFieldWifiNetworkSecurityType};
6use crate::{
7    b64url::B32, B64Url, EditableField, EditableFieldConcealedString, EditableFieldDate,
8    EditableFieldString,
9};
10
11/// A [ApiKeyCredential] contains information to interact with an Application's Programming
12/// Interface (API).
13#[derive(Clone, Debug, Default, Serialize, Deserialize)]
14#[serde(rename_all = "camelCase", bound(deserialize = "E: Deserialize<'de>"))]
15pub struct ApiKeyCredential<E = ()> {
16    /// This member denotes the key to communicate with the API.
17    #[serde(default, skip_serializing_if = "Option::is_none")]
18    pub key: Option<EditableField<EditableFieldConcealedString, E>>,
19    /// This member denotes the username associated with the key.
20    #[serde(default, skip_serializing_if = "Option::is_none")]
21    pub username: Option<EditableField<EditableFieldString, E>>,
22    /// This member denotes the type of the API key, such as bearer token or JSON Web Token. It is
23    /// flexible to allow any type and not restrict it to a set list of types.
24    #[serde(default, skip_serializing_if = "Option::is_none")]
25    pub key_type: Option<EditableField<EditableFieldString, E>>,
26    /// This member denotes the url the API key is used with and SHOULD conform to the
27    /// [URL Standard](https://url.spec.whatwg.org/).
28    #[serde(default, skip_serializing_if = "Option::is_none")]
29    pub url: Option<EditableField<EditableFieldString, E>>,
30    /// This member denotes the date the API key is valid from.
31    #[serde(default, skip_serializing_if = "Option::is_none")]
32    pub valid_from: Option<EditableField<EditableFieldDate, E>>,
33    /// This member denotes the date on which the API key expires.
34    #[serde(default, skip_serializing_if = "Option::is_none")]
35    pub expiry_date: Option<EditableField<EditableFieldDate, E>>,
36}
37
38/// A [BasicAuthCredential] contains a username/password login credential.
39/// Can either represent a [Basic access authentication](https://www.rfc-editor.org/rfc/rfc7617)
40/// or a form on a web page.
41///
42/// A [BasicAuthCredential] SHOULD have an accompanying [super::CredentialScope] in the credentials
43/// array. This indicates in which websites or applications these fields SHOULD be presented.
44#[derive(Clone, Debug, Default, Serialize, Deserialize)]
45#[serde(rename_all = "camelCase", bound(deserialize = "E: Deserialize<'de>"))]
46pub struct BasicAuthCredential<E = ()> {
47    /// The username associated with the credential.
48    #[serde(default, skip_serializing_if = "Option::is_none")]
49    pub username: Option<EditableField<EditableFieldString, E>>,
50    /// The password associated with the credential.
51    #[serde(default, skip_serializing_if = "Option::is_none")]
52    pub password: Option<EditableField<EditableFieldConcealedString, E>>,
53}
54
55/// A [GeneratedPasswordCredential] type represents a credential consisting of a machine-generated
56/// password.
57///
58/// Note: A [GeneratedPasswordCredential] is used when a password is generated independently of
59/// creating a new [BasicAuthCredential]. Some providers may offer a dedicated password generator
60/// feature. In such cases, the provider may create [GeneratedPasswordCredential] instances as
61/// deemed appropriate for the use of this feature.
62#[derive(Clone, Debug, Serialize, Deserialize)]
63#[serde(rename_all = "camelCase")]
64pub struct GeneratedPasswordCredential {
65    /// The machine-generated password.
66    pub password: String,
67}
68
69/// An [SshKeyCredential] represents an SSH (Secure Shell) key pair.
70#[derive(Clone, Debug, Serialize, Deserialize)]
71#[serde(rename_all = "camelCase", bound(deserialize = "E: Deserialize<'de>"))]
72pub struct SshKeyCredential<E = ()> {
73    /// The type of SSH key algorithm used. Common values include "ssh-rsa", "ssh-ed25519", or
74    /// "ecdsa-sha2-nistp256". This MUST be a string value representing a valid SSH public key
75    /// algorithm as defined in IANA SSH Protocol Parameters.
76    pub key_type: String,
77    /// The private part of the SSH key pair. This MUST be a PKCS#8 ASN.1 DER formatted byte string
78    /// which is then Base64url encoded.
79    pub private_key: B64Url,
80    /// This member contains a user-defined string to identify or describe the key.
81    #[serde(default, skip_serializing_if = "Option::is_none")]
82    pub key_comment: Option<String>,
83    /// This member indicates when the key was created.
84    #[serde(default, skip_serializing_if = "Option::is_none")]
85    pub creation_date: Option<EditableField<EditableFieldDate, E>>,
86    /// This member indicates when the key will expire, if applicable.
87    #[serde(default, skip_serializing_if = "Option::is_none")]
88    pub expiry_date: Option<EditableField<EditableFieldDate, E>>,
89    /// This member indicates where the key was originally generated. E.g.,
90    /// `https://github.com/settings/ssh/new` for GitHub.
91    #[serde(default, skip_serializing_if = "Option::is_none")]
92    pub key_generation_source: Option<EditableField<EditableFieldString, E>>,
93}
94
95/// Note: Enrollment in TOTP credentials historically has been quite non-standardized but typically
96/// authenticator and RP implementations have more or less aligned with the early Google
97/// Authenticator implementation spelled out at <https://github.com/google/google-authenticator/wiki/Key-Uri-Format>.
98/// This specification was designed with that in mind.
99#[derive(Clone, Debug, Serialize, Deserialize)]
100#[serde(rename_all = "camelCase")]
101pub struct TotpCredential {
102    /// The [shared secret](https://www.rfc-editor.org/rfc/rfc4226#section-5) used to generate the
103    /// OTPs. This MUST be a [Base32 string](https://www.rfc-editor.org/rfc/rfc4648#section-6)
104    pub secret: B32,
105    /// The time step used to refresh the OTP in seconds. The default SHOULD be 30 seconds,
106    /// although the [relying party](https://www.w3.org/TR/webauthn-3/#relying-party) MAY customize
107    /// this to a different value.
108    pub period: u8,
109    /// The number of digits to generate and display to the user each period. The default SHOULD be
110    /// 6, although the [relying party](https://www.w3.org/TR/webauthn-3/#relying-party) MAY
111    /// customize this to a different value.
112    pub digits: u8,
113    /// This member contains the username of the account this [TotpCredential] is used for.
114    ///
115    /// Note: While this member is optional, it is strongly recommended to be included if
116    /// available.
117    #[serde(default, skip_serializing_if = "Option::is_none")]
118    pub username: Option<String>,
119    /// The algorithm used to generate the OTP hashes. This value SHOULD be a member of
120    /// [OTPHashAlgorithm] but importers MUST ignore [TotpCredential] entries with unknown
121    /// algorithm values.
122    pub algorithm: OTPHashAlgorithm,
123    /// This member contains the relying party that issued the credential and should be user
124    /// consumable.
125    ///
126    /// Note: While this member is optional, it is strongly recommended to be included if
127    /// available.
128    #[serde(default, skip_serializing_if = "Option::is_none")]
129    pub issuer: Option<String>,
130}
131
132#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
133#[serde(rename_all = "lowercase")]
134#[non_exhaustive]
135pub enum OTPHashAlgorithm {
136    /// This algorithm denotes that [SHA1](https://www.rfc-editor.org/rfc/rfc3174) MUST be used to
137    /// generate the OTP hash.
138    Sha1,
139    /// This algorithm denotes that [SHA256](https://www.rfc-editor.org/rfc/rfc6234) MUST be used
140    /// to generate the OTP hash.
141    Sha256,
142    /// This algorithm denotes that [SHA512](https://www.rfc-editor.org/rfc/rfc6234) MUST be used
143    /// to generate the OTP hash.
144    Sha512,
145    #[serde(untagged)]
146    Unknown(String),
147}
148
149/// Wi-Fi Passphrase
150#[derive(Clone, Debug, Default, Serialize, Deserialize)]
151#[serde(rename_all = "camelCase", bound(deserialize = "E: Deserialize<'de>"))]
152pub struct WifiCredential<E = ()> {
153    #[serde(default, skip_serializing_if = "Option::is_none")]
154    pub ssid: Option<EditableField<EditableFieldString, E>>,
155    #[serde(default, skip_serializing_if = "Option::is_none")]
156    pub network_security_type: Option<EditableField<EditableFieldWifiNetworkSecurityType, E>>,
157    #[serde(default, skip_serializing_if = "Option::is_none")]
158    pub passphrase: Option<EditableField<EditableFieldConcealedString, E>>,
159    #[serde(default, skip_serializing_if = "Option::is_none")]
160    pub hidden: Option<EditableField<EditableFieldBoolean, E>>,
161}