replaced skip_serializing_if with skip_serializing_none (#1932)

* replaced `skip_serializing_if` with `skip_serializing_none`
This commit is contained in:
Sebastiano Tocci 2023-08-03 00:51:30 +02:00 committed by GitHub
parent 6e755543b3
commit 5d96412181
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 30 additions and 84 deletions

2
Cargo.lock generated
View file

@ -2344,6 +2344,7 @@ dependencies = [
"regex", "regex",
"serde", "serde",
"serde_json", "serde_json",
"serde_with",
"sketching", "sketching",
"time 0.3.24", "time 0.3.24",
"tokio", "tokio",
@ -2392,6 +2393,7 @@ dependencies = [
"serde", "serde",
"serde_cbor_2", "serde_cbor_2",
"serde_json", "serde_json",
"serde_with",
"sketching", "sketching",
"smartstring", "smartstring",
"smolset", "smolset",

View file

@ -51,6 +51,7 @@ kanidm_proto = { path = "./proto", version = "1.1.0-rc.14-dev" }
kanidm_unix_int = { path = "./unix_integration" } kanidm_unix_int = { path = "./unix_integration" }
kanidm_utils_users = { path = "./libs/users" } kanidm_utils_users = { path = "./libs/users" }
serde_with = "3.1.0"
argon2 = { version = "0.5.1", features = ["alloc"] } argon2 = { version = "0.5.1", features = ["alloc"] }
async-recursion = "1.0.4" async-recursion = "1.0.4"
async-trait = "^0.1.72" async-trait = "^0.1.72"

View file

@ -22,7 +22,7 @@ num_enum = { workspace = true }
scim_proto = { workspace = true } scim_proto = { workspace = true }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true } serde_json = { workspace = true }
serde_with = "3.1.0" serde_with = { workspace = true }
time = { workspace = true, features = ["serde", "std"] } time = { workspace = true, features = ["serde", "std"] }
tracing = { workspace = true } tracing = { workspace = true }
url = { workspace = true, features = ["serde"] } url = { workspace = true, features = ["serde"] }

View file

@ -20,18 +20,18 @@ pub struct PkceRequest {
pub code_challenge_method: CodeChallengeMethod, pub code_challenge_method: CodeChallengeMethod,
} }
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AuthorisationRequest { pub struct AuthorisationRequest {
// Must be "code". (or token, see 4.2.1) // Must be "code". (or token, see 4.2.1)
pub response_type: String, pub response_type: String,
pub client_id: String, pub client_id: String,
pub state: String, pub state: String,
#[serde(flatten, skip_serializing_if = "Option::is_none")] #[serde(flatten)]
pub pkce_request: Option<PkceRequest>, pub pkce_request: Option<PkceRequest>,
pub redirect_uri: Url, pub redirect_uri: Url,
pub scope: String, pub scope: String,
// OIDC adds a nonce parameter that is optional. // OIDC adds a nonce parameter that is optional.
#[serde(skip_serializing_if = "Option::is_none")]
pub nonce: Option<String>, pub nonce: Option<String>,
// OIDC also allows other optional params // OIDC also allows other optional params
#[serde(flatten)] #[serde(flatten)]
@ -40,23 +40,16 @@ pub struct AuthorisationRequest {
pub unknown_keys: BTreeMap<String, serde_json::value::Value>, pub unknown_keys: BTreeMap<String, serde_json::value::Value>,
} }
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone, Default)] #[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct AuthorisationRequestOidc { pub struct AuthorisationRequestOidc {
#[serde(skip_serializing_if = "Option::is_none")]
pub display: Option<String>, pub display: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt: Option<String>, pub prompt: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_age: Option<i64>, pub max_age: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ui_locales: Option<()>, pub ui_locales: Option<()>,
#[serde(skip_serializing_if = "Option::is_none")]
pub claims_locales: Option<()>, pub claims_locales: Option<()>,
#[serde(skip_serializing_if = "Option::is_none")]
pub id_token_hint: Option<String>, pub id_token_hint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub login_hint: Option<String>, pub login_hint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub acr: Option<String>, pub acr: Option<String>,
} }
@ -99,15 +92,14 @@ pub enum GrantTypeReq {
}, },
} }
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct AccessTokenRequest { pub struct AccessTokenRequest {
#[serde(flatten)] #[serde(flatten)]
pub grant_type: GrantTypeReq, pub grant_type: GrantTypeReq,
// REQUIRED, if the client is not authenticating with the // REQUIRED, if the client is not authenticating with the
// authorization server as described in Section 3.2.1. // authorization server as described in Section 3.2.1.
#[serde(skip_serializing_if = "Option::is_none")]
pub client_id: Option<String>, pub client_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub client_secret: Option<String>, pub client_secret: Option<String>,
} }
@ -121,17 +113,18 @@ impl From<GrantTypeReq> for AccessTokenRequest {
} }
} }
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct TokenRevokeRequest { pub struct TokenRevokeRequest {
pub token: String, pub token: String,
/// Generally not needed. See: /// Generally not needed. See:
/// <https://datatracker.ietf.org/doc/html/rfc7009#section-4.1.2> /// <https://datatracker.ietf.org/doc/html/rfc7009#section-4.1.2>
#[serde(skip_serializing_if = "Option::is_none")]
pub token_type_hint: Option<String>, pub token_type_hint: Option<String>,
} }
// The corresponding Response to a revoke request is empty body with 200. // The corresponding Response to a revoke request is empty body with 200.
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct AccessTokenResponse { pub struct AccessTokenResponse {
// Could be Base64UrlSafeData // Could be Base64UrlSafeData
@ -140,50 +133,37 @@ pub struct AccessTokenResponse {
pub token_type: String, pub token_type: String,
// seconds. // seconds.
pub expires_in: u32, pub expires_in: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub refresh_token: Option<String>, pub refresh_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Space separated list of scopes that were approved, if this differs from the /// Space separated list of scopes that were approved, if this differs from the
/// original request. /// original request.
pub scope: Option<String>, pub scope: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Oidc puts the token here. /// Oidc puts the token here.
pub id_token: Option<String>, pub id_token: Option<String>,
} }
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct AccessTokenIntrospectRequest { pub struct AccessTokenIntrospectRequest {
pub token: String, pub token: String,
/// Generally not needed. See: /// Generally not needed. See:
/// <https://datatracker.ietf.org/doc/html/rfc7009#section-4.1.2> /// <https://datatracker.ietf.org/doc/html/rfc7009#section-4.1.2>
#[serde(skip_serializing_if = "Option::is_none")]
pub token_type_hint: Option<String>, pub token_type_hint: Option<String>,
} }
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct AccessTokenIntrospectResponse { pub struct AccessTokenIntrospectResponse {
pub active: bool, pub active: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub scope: Option<String>, pub scope: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub client_id: Option<String>, pub client_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub username: Option<String>, pub username: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token_type: Option<String>, pub token_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exp: Option<i64>, pub exp: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub iat: Option<i64>, pub iat: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub nbf: Option<i64>, pub nbf: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sub: Option<String>, pub sub: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub aud: Option<String>, pub aud: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub iss: Option<String>, pub iss: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub jti: Option<String>, pub jti: Option<String>,
} }
@ -303,18 +283,16 @@ fn require_request_uri_parameter_supported_default() -> bool {
false false
} }
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata // https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
pub struct OidcDiscoveryResponse { pub struct OidcDiscoveryResponse {
pub issuer: Url, pub issuer: Url,
pub authorization_endpoint: Url, pub authorization_endpoint: Url,
pub token_endpoint: Url, pub token_endpoint: Url,
#[serde(skip_serializing_if = "Option::is_none")]
pub userinfo_endpoint: Option<Url>, pub userinfo_endpoint: Option<Url>,
pub jwks_uri: Url, pub jwks_uri: Url,
#[serde(skip_serializing_if = "Option::is_none")]
pub registration_endpoint: Option<Url>, pub registration_endpoint: Option<Url>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scopes_supported: Option<Vec<String>>, pub scopes_supported: Option<Vec<String>>,
// https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.1 // https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.1
pub response_types_supported: Vec<ResponseType>, pub response_types_supported: Vec<ResponseType>,
@ -324,45 +302,30 @@ pub struct OidcDiscoveryResponse {
// Need to fill in as authorization_code only else a default is assumed. // Need to fill in as authorization_code only else a default is assumed.
#[serde(default = "grant_types_supported_default")] #[serde(default = "grant_types_supported_default")]
pub grant_types_supported: Vec<GrantType>, pub grant_types_supported: Vec<GrantType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub acr_values_supported: Option<Vec<String>>, pub acr_values_supported: Option<Vec<String>>,
// https://openid.net/specs/openid-connect-core-1_0.html#PairwiseAlg // https://openid.net/specs/openid-connect-core-1_0.html#PairwiseAlg
pub subject_types_supported: Vec<SubjectType>, pub subject_types_supported: Vec<SubjectType>,
pub id_token_signing_alg_values_supported: Vec<IdTokenSignAlg>, pub id_token_signing_alg_values_supported: Vec<IdTokenSignAlg>,
#[serde(skip_serializing_if = "Option::is_none")]
pub id_token_encryption_alg_values_supported: Option<Vec<String>>, pub id_token_encryption_alg_values_supported: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub id_token_encryption_enc_values_supported: Option<Vec<String>>, pub id_token_encryption_enc_values_supported: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub userinfo_signing_alg_values_supported: Option<Vec<String>>, pub userinfo_signing_alg_values_supported: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub userinfo_encryption_alg_values_supported: Option<Vec<String>>, pub userinfo_encryption_alg_values_supported: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub userinfo_encryption_enc_values_supported: Option<Vec<String>>, pub userinfo_encryption_enc_values_supported: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub request_object_signing_alg_values_supported: Option<Vec<String>>, pub request_object_signing_alg_values_supported: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub request_object_encryption_alg_values_supported: Option<Vec<String>>, pub request_object_encryption_alg_values_supported: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub request_object_encryption_enc_values_supported: Option<Vec<String>>, pub request_object_encryption_enc_values_supported: Option<Vec<String>>,
// Defaults to client_secret_basic // Defaults to client_secret_basic
#[serde(default = "token_endpoint_auth_methods_supported_default")] #[serde(default = "token_endpoint_auth_methods_supported_default")]
pub token_endpoint_auth_methods_supported: Vec<TokenEndpointAuthMethod>, pub token_endpoint_auth_methods_supported: Vec<TokenEndpointAuthMethod>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token_endpoint_auth_signing_alg_values_supported: Option<Vec<String>>, pub token_endpoint_auth_signing_alg_values_supported: Option<Vec<String>>,
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest // https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
#[serde(skip_serializing_if = "Option::is_none")]
pub display_values_supported: Option<Vec<DisplayValue>>, pub display_values_supported: Option<Vec<DisplayValue>>,
// Default to normal. // Default to normal.
#[serde(default = "claim_types_supported_default")] #[serde(default = "claim_types_supported_default")]
pub claim_types_supported: Vec<ClaimType>, pub claim_types_supported: Vec<ClaimType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub claims_supported: Option<Vec<String>>, pub claims_supported: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service_documentation: Option<Url>, pub service_documentation: Option<Url>,
#[serde(skip_serializing_if = "Option::is_none")]
pub claims_locales_supported: Option<Vec<String>>, pub claims_locales_supported: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ui_locales_supported: Option<Vec<String>>, pub ui_locales_supported: Option<Vec<String>>,
// Default false. // Default false.
#[serde(default = "claims_parameter_supported_default")] #[serde(default = "claims_parameter_supported_default")]
@ -373,18 +336,15 @@ pub struct OidcDiscoveryResponse {
pub request_uri_parameter_supported: bool, pub request_uri_parameter_supported: bool,
#[serde(default = "require_request_uri_parameter_supported_default")] #[serde(default = "require_request_uri_parameter_supported_default")]
pub require_request_uri_registration: bool, pub require_request_uri_registration: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub op_policy_uri: Option<Url>, pub op_policy_uri: Option<Url>,
#[serde(skip_serializing_if = "Option::is_none")]
pub op_tos_uri: Option<Url>, pub op_tos_uri: Option<Url>,
} }
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ErrorResponse { pub struct ErrorResponse {
pub error: String, pub error: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub error_description: Option<String>, pub error_description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error_uri: Option<Url>, pub error_uri: Option<Url>,
} }

View file

@ -1,12 +1,12 @@
use num_enum::TryFromPrimitive;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use url::Url;
use num_enum::TryFromPrimitive;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime; use time::OffsetDateTime;
use url::Url;
use uuid::Uuid; use uuid::Uuid;
use webauthn_rs_proto::{ use webauthn_rs_proto::{
CreationChallengeResponse, PublicKeyCredential, RegisterPublicKeyCredential, CreationChallengeResponse, PublicKeyCredential, RegisterPublicKeyCredential,
@ -574,6 +574,7 @@ pub struct GroupUnixExtend {
pub gidnumber: Option<u32>, pub gidnumber: Option<u32>,
} }
#[skip_serializing_none]
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct UnixUserToken { pub struct UnixUserToken {
pub name: String, pub name: String,
@ -581,7 +582,6 @@ pub struct UnixUserToken {
pub displayname: String, pub displayname: String,
pub gidnumber: u32, pub gidnumber: u32,
pub uuid: Uuid, pub uuid: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub shell: Option<String>, pub shell: Option<String>,
pub groups: Vec<UnixGroupToken>, pub groups: Vec<UnixGroupToken>,
pub sshkeys: Vec<String>, pub sshkeys: Vec<String>,

View file

@ -49,6 +49,7 @@ tracing-subscriber = { workspace = true, features = ["time", "json"] }
urlencoding = { workspace = true } urlencoding = { workspace = true }
kanidm_utils_users = { workspace = true } kanidm_utils_users = { workspace = true }
uuid = { workspace = true, features = ["serde", "v4" ] } uuid = { workspace = true, features = ["serde", "v4" ] }
serde_with = { workspace = true }
[build-dependencies] [build-dependencies]
kanidm_build_profiles = { workspace = true } kanidm_build_profiles = { workspace = true }

View file

@ -5,6 +5,7 @@ use axum::response::{IntoResponse, Response};
use axum::Extension; use axum::Extension;
use http::HeaderValue; use http::HeaderValue;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use super::middleware::KOpId; use super::middleware::KOpId;
// Thanks to the webmanifest crate for a lot of this code // Thanks to the webmanifest crate for a lot of this code
@ -14,6 +15,8 @@ use super::ServerState;
const MIME_TYPE_MANIFEST: &str = "application/manifest+json;charset=utf-8"; const MIME_TYPE_MANIFEST: &str = "application/manifest+json;charset=utf-8";
/// Create a new manifest builder. /// Create a new manifest builder.
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Manifest { pub struct Manifest {
name: String, name: String,
@ -22,28 +25,22 @@ pub struct Manifest {
#[serde(rename = "display")] #[serde(rename = "display")]
display_mode: DisplayMode, display_mode: DisplayMode,
background_color: String, background_color: String,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>, description: Option<String>,
#[serde(rename = "dir")] #[serde(rename = "dir")]
direction: Direction, direction: Direction,
// direction: Option<Direction>, // direction: Option<Direction>,
#[serde(skip_serializing_if = "Option::is_none")]
orientation: Option<String>, orientation: Option<String>,
// orientation: Option<Orientation>, // orientation: Option<Orientation>,
#[serde(skip_serializing_if = "Option::is_none")]
lang: Option<String>, lang: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
scope: Option<String>, scope: Option<String>,
// #[serde(skip_serializing_if = "Option::is_none")] //
theme_color: String, theme_color: String,
#[serde(skip_serializing_if = "Option::is_none")]
prefer_related_applications: Option<bool>, prefer_related_applications: Option<bool>,
// #[serde(borrow)] // #[serde(borrow)]
// #[serde(skip_serializing_if = "Option::is_none")] //
icons: Vec<ManifestIcon>, icons: Vec<ManifestIcon>,
// icons: Vec<Icon<'i>>, // icons: Vec<Icon<'i>>,
// #[serde(borrow)] // #[serde(borrow)]
#[serde(skip_serializing_if = "Option::is_none")]
related_applications: Option<Vec<String>>, related_applications: Option<Vec<String>>,
// related_applications: Vec<Related<'r>>, // related_applications: Vec<Related<'r>>,
} }

View file

@ -65,6 +65,7 @@ uuid = { workspace = true, features = ["serde", "v4" ] }
webauthn-rs = { workspace = true, features = ["resident-key-support", "preview-features", "danger-credential-internals"] } webauthn-rs = { workspace = true, features = ["resident-key-support", "preview-features", "danger-credential-internals"] }
webauthn-rs-core = { workspace = true } webauthn-rs-core = { workspace = true }
zxcvbn = { workspace = true } zxcvbn = { workspace = true }
serde_with = { workspace = true }
# because windows really can't build without the bundled one # because windows really can't build without the bundled one
[target.'cfg(target_family = "windows")'.dependencies] [target.'cfg(target_family = "windows")'.dependencies]

View file

@ -3,6 +3,7 @@ use std::time::Duration;
use hashbrown::HashSet; use hashbrown::HashSet;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use url::Url; use url::Url;
use uuid::Uuid; use uuid::Uuid;
use webauthn_rs::prelude::{ use webauthn_rs::prelude::{
@ -114,54 +115,39 @@ fn is_false(b: &bool) -> bool {
!b !b
} }
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "type_")] #[serde(tag = "type_")]
pub enum DbCred { pub enum DbCred {
// These are the old v1 versions. // These are the old v1 versions.
Pw { Pw {
#[serde(skip_serializing_if = "Option::is_none")]
password: Option<DbPasswordV1>, password: Option<DbPasswordV1>,
#[serde(skip_serializing_if = "Option::is_none")]
webauthn: Option<Vec<DbWebauthnV1>>, webauthn: Option<Vec<DbWebauthnV1>>,
#[serde(skip_serializing_if = "Option::is_none")]
totp: Option<DbTotpV1>, totp: Option<DbTotpV1>,
#[serde(skip_serializing_if = "Option::is_none")]
backup_code: Option<DbBackupCodeV1>, backup_code: Option<DbBackupCodeV1>,
claims: Vec<String>, claims: Vec<String>,
uuid: Uuid, uuid: Uuid,
}, },
GPw { GPw {
#[serde(skip_serializing_if = "Option::is_none")]
password: Option<DbPasswordV1>, password: Option<DbPasswordV1>,
#[serde(skip_serializing_if = "Option::is_none")]
webauthn: Option<Vec<DbWebauthnV1>>, webauthn: Option<Vec<DbWebauthnV1>>,
#[serde(skip_serializing_if = "Option::is_none")]
totp: Option<DbTotpV1>, totp: Option<DbTotpV1>,
#[serde(skip_serializing_if = "Option::is_none")]
backup_code: Option<DbBackupCodeV1>, backup_code: Option<DbBackupCodeV1>,
claims: Vec<String>, claims: Vec<String>,
uuid: Uuid, uuid: Uuid,
}, },
PwMfa { PwMfa {
#[serde(skip_serializing_if = "Option::is_none")]
password: Option<DbPasswordV1>, password: Option<DbPasswordV1>,
#[serde(skip_serializing_if = "Option::is_none")]
webauthn: Option<Vec<DbWebauthnV1>>, webauthn: Option<Vec<DbWebauthnV1>>,
#[serde(skip_serializing_if = "Option::is_none")]
totp: Option<DbTotpV1>, totp: Option<DbTotpV1>,
#[serde(skip_serializing_if = "Option::is_none")]
backup_code: Option<DbBackupCodeV1>, backup_code: Option<DbBackupCodeV1>,
claims: Vec<String>, claims: Vec<String>,
uuid: Uuid, uuid: Uuid,
}, },
Wn { Wn {
#[serde(skip_serializing_if = "Option::is_none")]
password: Option<DbPasswordV1>, password: Option<DbPasswordV1>,
#[serde(skip_serializing_if = "Option::is_none")]
webauthn: Option<Vec<DbWebauthnV1>>, webauthn: Option<Vec<DbWebauthnV1>>,
#[serde(skip_serializing_if = "Option::is_none")]
totp: Option<DbTotpV1>, totp: Option<DbTotpV1>,
#[serde(skip_serializing_if = "Option::is_none")]
backup_code: Option<DbBackupCodeV1>, backup_code: Option<DbBackupCodeV1>,
claims: Vec<String>, claims: Vec<String>,
uuid: Uuid, uuid: Uuid,
@ -680,6 +666,7 @@ impl DbValueSetV2 {
mod tests { mod tests {
use base64::{engine::general_purpose, Engine as _}; use base64::{engine::general_purpose, Engine as _};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use uuid::Uuid; use uuid::Uuid;
use super::{DbBackupCodeV1, DbCred, DbPasswordV1, DbTotpV1, DbWebauthnV1}; use super::{DbBackupCodeV1, DbCred, DbPasswordV1, DbTotpV1, DbWebauthnV1};
@ -699,17 +686,14 @@ mod tests {
// PwWnVer, // PwWnVer,
} }
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DbCredV1 { pub struct DbCredV1 {
#[serde(default = "dbcred_type_default_pw")] #[serde(default = "dbcred_type_default_pw")]
pub type_: DbCredTypeV1, pub type_: DbCredTypeV1,
#[serde(skip_serializing_if = "Option::is_none")]
pub password: Option<DbPasswordV1>, pub password: Option<DbPasswordV1>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webauthn: Option<Vec<DbWebauthnV1>>, pub webauthn: Option<Vec<DbWebauthnV1>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub totp: Option<DbTotpV1>, pub totp: Option<DbTotpV1>,
#[serde(skip_serializing_if = "Option::is_none")]
pub backup_code: Option<DbBackupCodeV1>, pub backup_code: Option<DbBackupCodeV1>,
pub claims: Vec<String>, pub claims: Vec<String>,
pub uuid: Uuid, pub uuid: Uuid,