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}