From 84507c5e1aa5ca9f38b8e85c402cd481901a86ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Thu, 28 Mar 2024 12:36:11 +0100 Subject: [PATCH 1/2] Add require! macro to include field information in MissingFields error --- crates/bitwarden/src/admin_console/policy.rs | 10 +++---- .../bitwarden/src/auth/login/access_token.rs | 6 ++-- crates/bitwarden/src/error.rs | 14 +++++++-- crates/bitwarden/src/platform/domain.rs | 8 ++--- .../src/platform/get_user_api_key.rs | 8 ++--- crates/bitwarden/src/platform/sync.rs | 29 +++++++++---------- .../src/secrets_manager/projects/delete.rs | 4 +-- .../projects/project_response.rs | 20 ++++--------- .../src/secrets_manager/secrets/delete.rs | 4 +-- .../src/secrets_manager/secrets/list.rs | 10 +++---- .../secrets/secret_response.rs | 28 +++++------------- crates/bitwarden/src/tool/exporters/mod.rs | 12 ++++---- crates/bitwarden/src/vault/cipher/cipher.rs | 10 +++---- crates/bitwarden/src/vault/cipher/field.rs | 4 +-- .../bitwarden/src/vault/cipher/linked_id.rs | 2 +- crates/bitwarden/src/vault/cipher/login.rs | 18 ++++++------ .../bitwarden/src/vault/cipher/secure_note.rs | 4 +-- crates/bitwarden/src/vault/collection.rs | 6 ++-- crates/bitwarden/src/vault/folder.rs | 6 ++-- crates/bitwarden/src/vault/send.rs | 16 +++++----- 20 files changed, 100 insertions(+), 119 deletions(-) diff --git a/crates/bitwarden/src/admin_console/policy.rs b/crates/bitwarden/src/admin_console/policy.rs index 7e87b8623..d8ed0b761 100644 --- a/crates/bitwarden/src/admin_console/policy.rs +++ b/crates/bitwarden/src/admin_console/policy.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; use uuid::Uuid; -use crate::error::{Error, Result}; +use crate::error::{require, Error, Result}; #[derive(Serialize, Deserialize, Debug, JsonSchema)] pub struct Policy { @@ -41,11 +41,11 @@ impl TryFrom for Policy { fn try_from(policy: PolicyResponseModel) -> Result { Ok(Self { - id: policy.id.ok_or(Error::MissingFields)?, - organization_id: policy.organization_id.ok_or(Error::MissingFields)?, - r#type: policy.r#type.ok_or(Error::MissingFields)?.into(), + id: require!(policy.id), + organization_id: require!(policy.organization_id), + r#type: require!(policy.r#type).into(), data: policy.data, - enabled: policy.enabled.ok_or(Error::MissingFields)?, + enabled: require!(policy.enabled), }) } } diff --git a/crates/bitwarden/src/auth/login/access_token.rs b/crates/bitwarden/src/auth/login/access_token.rs index 46c3f2b50..4734bc8a7 100644 --- a/crates/bitwarden/src/auth/login/access_token.rs +++ b/crates/bitwarden/src/auth/login/access_token.rs @@ -14,7 +14,7 @@ use crate::{ AccessToken, JWTToken, }, client::{LoginMethod, ServiceAccountLoginMethod}, - error::{Error, Result}, + error::{require, Error, Result}, secrets_manager::state::{self, ClientState}, Client, }; @@ -69,9 +69,7 @@ pub(crate) async fn login_access_token( let access_token_obj: JWTToken = r.access_token.parse()?; // This should always be Some() when logging in with an access token - let organization_id = access_token_obj - .organization - .ok_or(Error::MissingFields)? + let organization_id = require!(access_token_obj.organization) .parse() .map_err(|_| Error::InvalidResponse)?; diff --git a/crates/bitwarden/src/error.rs b/crates/bitwarden/src/error.rs index bd040e51b..6a5f65cba 100644 --- a/crates/bitwarden/src/error.rs +++ b/crates/bitwarden/src/error.rs @@ -24,8 +24,8 @@ pub enum Error { #[error("The response received was invalid and could not be processed")] InvalidResponse, - #[error("The response received was missing some of the required fields")] - MissingFields, + #[error("The response received was missing some of the required fields: {0}")] + MissingFields(&'static str), #[error("Cryptography error, {0}")] Crypto(#[from] bitwarden_crypto::CryptoError), @@ -133,4 +133,14 @@ macro_rules! impl_bitwarden_error { impl_bitwarden_error!(ApiError); impl_bitwarden_error!(IdentityError); +macro_rules! require { + ($val:expr) => { + match $val { + Some(val) => val, + None => return Err($crate::error::Error::MissingFields(stringify!($val))), + } + }; +} +pub(crate) use require; + pub type Result = std::result::Result; diff --git a/crates/bitwarden/src/platform/domain.rs b/crates/bitwarden/src/platform/domain.rs index c903dd5a5..482cb1f59 100644 --- a/crates/bitwarden/src/platform/domain.rs +++ b/crates/bitwarden/src/platform/domain.rs @@ -1,7 +1,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::error::{Error, Result}; +use crate::error::{require, Error, Result}; #[derive(Serialize, Deserialize, Debug, JsonSchema)] pub struct GlobalDomains { @@ -15,9 +15,9 @@ impl TryFrom for GlobalDomains { fn try_from(global_domains: bitwarden_api_api::models::GlobalDomains) -> Result { Ok(Self { - r#type: global_domains.r#type.ok_or(Error::MissingFields)?, - domains: global_domains.domains.ok_or(Error::MissingFields)?, - excluded: global_domains.excluded.ok_or(Error::MissingFields)?, + r#type: require!(global_domains.r#type), + domains: require!(global_domains.domains), + excluded: require!(global_domains.excluded), }) } } diff --git a/crates/bitwarden/src/platform/get_user_api_key.rs b/crates/bitwarden/src/platform/get_user_api_key.rs index 2eaa21894..3e408d926 100644 --- a/crates/bitwarden/src/platform/get_user_api_key.rs +++ b/crates/bitwarden/src/platform/get_user_api_key.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use super::SecretVerificationRequest; use crate::{ client::{LoginMethod, UserLoginMethod}, - error::{Error, Result}, + error::{require, Error, Result}, Client, }; @@ -75,9 +75,7 @@ pub struct UserApiKeyResponse { impl UserApiKeyResponse { pub(crate) fn process_response(response: ApiKeyResponseModel) -> Result { - match response.api_key { - Some(api_key) => Ok(UserApiKeyResponse { api_key }), - None => Err(Error::MissingFields), - } + let api_key = require!(response.api_key); + Ok(UserApiKeyResponse { api_key }) } } diff --git a/crates/bitwarden/src/platform/sync.rs b/crates/bitwarden/src/platform/sync.rs index c1a039137..5a5c6ee82 100644 --- a/crates/bitwarden/src/platform/sync.rs +++ b/crates/bitwarden/src/platform/sync.rs @@ -9,7 +9,7 @@ use super::domain::GlobalDomains; use crate::{ admin_console::Policy, client::{encryption_settings::EncryptionSettings, Client}, - error::{Error, Result}, + error::{require, Error, Result}, vault::{Cipher, Collection, Folder}, }; @@ -25,10 +25,7 @@ pub(crate) async fn sync(client: &mut Client, input: &SyncRequest) -> Result = sync - .profile - .as_ref() - .ok_or(Error::MissingFields)? + let org_keys: Vec<_> = require!(sync.profile.as_ref()) .organizations .as_deref() .unwrap_or_default() @@ -86,8 +83,8 @@ impl SyncResponse { response: SyncResponseModel, enc: &EncryptionSettings, ) -> Result { - let profile = *response.profile.ok_or(Error::MissingFields)?; - let ciphers = response.ciphers.ok_or(Error::MissingFields)?; + let profile = require!(response.profile); + let ciphers = require!(response.ciphers); fn try_into_iter(iter: In) -> Result where @@ -99,13 +96,13 @@ impl SyncResponse { } Ok(SyncResponse { - profile: ProfileResponse::process_response(profile, enc)?, - folders: try_into_iter(response.folders.ok_or(Error::MissingFields)?)?, - collections: try_into_iter(response.collections.ok_or(Error::MissingFields)?)?, + profile: ProfileResponse::process_response(*profile, enc)?, + folders: try_into_iter(require!(response.folders))?, + collections: try_into_iter(require!(response.collections))?, ciphers: try_into_iter(ciphers)?, domains: response.domains.map(|d| (*d).try_into()).transpose()?, - policies: try_into_iter(response.policies.ok_or(Error::MissingFields)?)?, - sends: try_into_iter(response.sends.ok_or(Error::MissingFields)?)?, + policies: try_into_iter(require!(response.policies))?, + sends: try_into_iter(require!(response.sends))?, }) } } @@ -115,7 +112,7 @@ impl ProfileOrganizationResponse { response: ProfileOrganizationResponseModel, ) -> Result { Ok(ProfileOrganizationResponse { - id: response.id.ok_or(Error::MissingFields)?, + id: require!(response.id), }) } } @@ -126,9 +123,9 @@ impl ProfileResponse { _enc: &EncryptionSettings, ) -> Result { Ok(ProfileResponse { - id: response.id.ok_or(Error::MissingFields)?, - name: response.name.ok_or(Error::MissingFields)?, - email: response.email.ok_or(Error::MissingFields)?, + id: require!(response.id), + name: require!(response.name), + email: require!(response.email), //key: response.key, //private_key: response.private_key, organizations: response diff --git a/crates/bitwarden/src/secrets_manager/projects/delete.rs b/crates/bitwarden/src/secrets_manager/projects/delete.rs index 55f792669..05c808c7e 100644 --- a/crates/bitwarden/src/secrets_manager/projects/delete.rs +++ b/crates/bitwarden/src/secrets_manager/projects/delete.rs @@ -7,7 +7,7 @@ use uuid::Uuid; use crate::{ client::Client, - error::{Error, Result}, + error::{require, Result}, }; #[derive(Serialize, Deserialize, Debug, JsonSchema)] @@ -62,7 +62,7 @@ impl ProjectDeleteResponse { response: BulkDeleteResponseModel, ) -> Result { Ok(ProjectDeleteResponse { - id: response.id.ok_or(Error::MissingFields)?, + id: require!(response.id), error: response.error, }) } diff --git a/crates/bitwarden/src/secrets_manager/projects/project_response.rs b/crates/bitwarden/src/secrets_manager/projects/project_response.rs index 1e6f6a158..af67df9ab 100644 --- a/crates/bitwarden/src/secrets_manager/projects/project_response.rs +++ b/crates/bitwarden/src/secrets_manager/projects/project_response.rs @@ -7,7 +7,7 @@ use uuid::Uuid; use crate::{ client::encryption_settings::EncryptionSettings, - error::{Error, Result}, + error::{require, Result}, }; #[derive(Serialize, Deserialize, Debug, JsonSchema)] @@ -25,27 +25,19 @@ impl ProjectResponse { response: ProjectResponseModel, enc: &EncryptionSettings, ) -> Result { - let organization_id = response.organization_id.ok_or(Error::MissingFields)?; + let organization_id = require!(response.organization_id); - let name = response - .name - .ok_or(Error::MissingFields)? + let name = require!(response.name) .parse::()? .decrypt(enc, &Some(organization_id))?; Ok(ProjectResponse { - id: response.id.ok_or(Error::MissingFields)?, + id: require!(response.id), organization_id, name, - creation_date: response - .creation_date - .ok_or(Error::MissingFields)? - .parse()?, - revision_date: response - .revision_date - .ok_or(Error::MissingFields)? - .parse()?, + creation_date: require!(response.creation_date).parse()?, + revision_date: require!(response.revision_date).parse()?, }) } } diff --git a/crates/bitwarden/src/secrets_manager/secrets/delete.rs b/crates/bitwarden/src/secrets_manager/secrets/delete.rs index 19337e7a1..f3fe264e1 100644 --- a/crates/bitwarden/src/secrets_manager/secrets/delete.rs +++ b/crates/bitwarden/src/secrets_manager/secrets/delete.rs @@ -7,7 +7,7 @@ use uuid::Uuid; use crate::{ client::Client, - error::{Error, Result}, + error::{require, Result}, }; #[derive(Serialize, Deserialize, Debug, JsonSchema)] @@ -62,7 +62,7 @@ impl SecretDeleteResponse { response: BulkDeleteResponseModel, ) -> Result { Ok(SecretDeleteResponse { - id: response.id.ok_or(Error::MissingFields)?, + id: require!(response.id), error: response.error, }) } diff --git a/crates/bitwarden/src/secrets_manager/secrets/list.rs b/crates/bitwarden/src/secrets_manager/secrets/list.rs index 7fa46d164..48a507667 100644 --- a/crates/bitwarden/src/secrets_manager/secrets/list.rs +++ b/crates/bitwarden/src/secrets_manager/secrets/list.rs @@ -8,7 +8,7 @@ use uuid::Uuid; use crate::{ client::{encryption_settings::EncryptionSettings, Client}, - error::{Error, Result}, + error::{require, Result}, }; #[derive(Serialize, Deserialize, Debug, JsonSchema)] @@ -93,16 +93,14 @@ impl SecretIdentifierResponse { response: SecretsWithProjectsInnerSecret, enc: &EncryptionSettings, ) -> Result { - let organization_id = response.organization_id.ok_or(Error::MissingFields)?; + let organization_id = require!(response.organization_id); - let key = response - .key - .ok_or(Error::MissingFields)? + let key = require!(response.key) .parse::()? .decrypt(enc, &Some(organization_id))?; Ok(SecretIdentifierResponse { - id: response.id.ok_or(Error::MissingFields)?, + id: require!(response.id), organization_id, key, }) diff --git a/crates/bitwarden/src/secrets_manager/secrets/secret_response.rs b/crates/bitwarden/src/secrets_manager/secrets/secret_response.rs index fe1a4d342..ffaa7f7e0 100644 --- a/crates/bitwarden/src/secrets_manager/secrets/secret_response.rs +++ b/crates/bitwarden/src/secrets_manager/secrets/secret_response.rs @@ -9,7 +9,7 @@ use uuid::Uuid; use crate::{ client::encryption_settings::EncryptionSettings, - error::{Error, Result}, + error::{require, Result}, }; #[derive(Serialize, Deserialize, Debug, JsonSchema)] @@ -51,19 +51,13 @@ impl SecretResponse { ) -> Result { let org_id = response.organization_id; - let key = response - .key - .ok_or(Error::MissingFields)? + let key = require!(response.key) .parse::()? .decrypt(enc, &org_id)?; - let value = response - .value - .ok_or(Error::MissingFields)? + let value = require!(response.value) .parse::()? .decrypt(enc, &org_id)?; - let note = response - .note - .ok_or(Error::MissingFields)? + let note = require!(response.note) .parse::()? .decrypt(enc, &org_id)?; @@ -73,21 +67,15 @@ impl SecretResponse { .and_then(|p| p.id); Ok(SecretResponse { - id: response.id.ok_or(Error::MissingFields)?, - organization_id: org_id.ok_or(Error::MissingFields)?, + id: require!(response.id), + organization_id: require!(org_id), project_id: project, key, value, note, - creation_date: response - .creation_date - .ok_or(Error::MissingFields)? - .parse()?, - revision_date: response - .revision_date - .ok_or(Error::MissingFields)? - .parse()?, + creation_date: require!(response.creation_date).parse()?, + revision_date: require!(response.revision_date).parse()?, }) } } diff --git a/crates/bitwarden/src/tool/exporters/mod.rs b/crates/bitwarden/src/tool/exporters/mod.rs index 45bdfd3fd..2da6ac833 100644 --- a/crates/bitwarden/src/tool/exporters/mod.rs +++ b/crates/bitwarden/src/tool/exporters/mod.rs @@ -4,7 +4,7 @@ use schemars::JsonSchema; use crate::{ client::{LoginMethod, UserLoginMethod}, - error::{Error, Result}, + error::{require, Error, Result}, vault::{ login::LoginUriView, Cipher, CipherType, CipherView, Collection, FieldView, Folder, FolderView, SecureNoteType, @@ -83,7 +83,7 @@ impl TryFrom for bitwarden_exporters::Folder { fn try_from(value: FolderView) -> Result { Ok(Self { - id: value.id.ok_or(Error::MissingFields)?, + id: require!(value.id), name: value.name, }) } @@ -95,7 +95,7 @@ impl TryFrom for bitwarden_exporters::Cipher { fn try_from(value: CipherView) -> Result { let r = match value.r#type { CipherType::Login => { - let l = value.login.ok_or(Error::MissingFields)?; + let l = require!(value.login); bitwarden_exporters::CipherType::Login(Box::new(bitwarden_exporters::Login { username: l.username, password: l.password, @@ -118,7 +118,7 @@ impl TryFrom for bitwarden_exporters::Cipher { }, )), CipherType::Card => { - let c = value.card.ok_or(Error::MissingFields)?; + let c = require!(value.card); bitwarden_exporters::CipherType::Card(Box::new(bitwarden_exporters::Card { cardholder_name: c.cardholder_name, exp_month: c.exp_month, @@ -129,7 +129,7 @@ impl TryFrom for bitwarden_exporters::Cipher { })) } CipherType::Identity => { - let i = value.identity.ok_or(Error::MissingFields)?; + let i = require!(value.identity); bitwarden_exporters::CipherType::Identity(Box::new(bitwarden_exporters::Identity { title: i.title, first_name: i.first_name, @@ -154,7 +154,7 @@ impl TryFrom for bitwarden_exporters::Cipher { }; Ok(Self { - id: value.id.ok_or(Error::MissingFields)?, + id: require!(value.id), folder_id: value.folder_id, name: value.name, notes: value.notes, diff --git a/crates/bitwarden/src/vault/cipher/cipher.rs b/crates/bitwarden/src/vault/cipher/cipher.rs index f0138beb9..8c073fa09 100644 --- a/crates/bitwarden/src/vault/cipher/cipher.rs +++ b/crates/bitwarden/src/vault/cipher/cipher.rs @@ -15,7 +15,7 @@ use super::{ login, secure_note, }; use crate::{ - error::{Error, Result}, + error::{require, Error, Result}, vault::password_history, }; @@ -384,9 +384,9 @@ impl TryFrom for Cipher { organization_id: cipher.organization_id, folder_id: cipher.folder_id, collection_ids: cipher.collection_ids.unwrap_or_default(), - name: EncString::try_from_optional(cipher.name)?.ok_or(Error::MissingFields)?, + name: require!(EncString::try_from_optional(cipher.name)?), notes: EncString::try_from_optional(cipher.notes)?, - r#type: cipher.r#type.ok_or(Error::MissingFields)?.into(), + r#type: require!(cipher.r#type).into(), login: cipher.login.map(|l| (*l).try_into()).transpose()?, identity: cipher.identity.map(|i| (*i).try_into()).transpose()?, card: cipher.card.map(|c| (*c).try_into()).transpose()?, @@ -412,9 +412,9 @@ impl TryFrom for Cipher { .password_history .map(|p| p.into_iter().map(|p| p.try_into()).collect()) .transpose()?, - creation_date: cipher.creation_date.ok_or(Error::MissingFields)?.parse()?, + creation_date: require!(cipher.creation_date).parse()?, deleted_date: cipher.deleted_date.map(|d| d.parse()).transpose()?, - revision_date: cipher.revision_date.ok_or(Error::MissingFields)?.parse()?, + revision_date: require!(cipher.revision_date).parse()?, key: EncString::try_from_optional(cipher.key)?, }) } diff --git a/crates/bitwarden/src/vault/cipher/field.rs b/crates/bitwarden/src/vault/cipher/field.rs index 25a318d6f..1f18a9537 100644 --- a/crates/bitwarden/src/vault/cipher/field.rs +++ b/crates/bitwarden/src/vault/cipher/field.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; use super::linked_id::LinkedIdType; -use crate::error::{Error, Result}; +use crate::error::{require, Error, Result}; #[derive(Clone, Copy, Serialize_repr, Deserialize_repr, Debug, JsonSchema)] #[repr(u8)] @@ -70,7 +70,7 @@ impl TryFrom for Field { Ok(Self { name: EncString::try_from_optional(model.name)?, value: EncString::try_from_optional(model.value)?, - r#type: model.r#type.map(|t| t.into()).ok_or(Error::MissingFields)?, + r#type: require!(model.r#type).into(), linked_id: model .linked_id .map(|id| (id as u32).try_into()) diff --git a/crates/bitwarden/src/vault/cipher/linked_id.rs b/crates/bitwarden/src/vault/cipher/linked_id.rs index 77429438e..b52d756c6 100644 --- a/crates/bitwarden/src/vault/cipher/linked_id.rs +++ b/crates/bitwarden/src/vault/cipher/linked_id.rs @@ -112,7 +112,7 @@ impl TryFrom for LinkedIdType { 416 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::FirstName)), 417 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::LastName)), 418 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::FullName)), - _ => Err(Error::MissingFields), + _ => Err(Error::MissingFields("LinkedIdType")), } } } diff --git a/crates/bitwarden/src/vault/cipher/login.rs b/crates/bitwarden/src/vault/cipher/login.rs index 26fd59001..d29aff220 100644 --- a/crates/bitwarden/src/vault/cipher/login.rs +++ b/crates/bitwarden/src/vault/cipher/login.rs @@ -8,7 +8,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::error::{Error, Result}; +use crate::error::{require, Error, Result}; #[derive(Clone, Copy, Serialize_repr, Deserialize_repr, Debug, JsonSchema)] #[repr(u8)] @@ -222,22 +222,22 @@ impl TryFrom for Fido2Cre fn try_from(value: bitwarden_api_api::models::CipherFido2CredentialModel) -> Result { Ok(Self { - credential_id: value.credential_id.ok_or(Error::MissingFields)?.parse()?, - key_type: value.key_type.ok_or(Error::MissingFields)?.parse()?, - key_algorithm: value.key_algorithm.ok_or(Error::MissingFields)?.parse()?, - key_curve: value.key_curve.ok_or(Error::MissingFields)?.parse()?, - key_value: value.key_value.ok_or(Error::MissingFields)?.parse()?, - rp_id: value.rp_id.ok_or(Error::MissingFields)?.parse()?, + credential_id: require!(value.credential_id).parse()?, + key_type: require!(value.key_type).parse()?, + key_algorithm: require!(value.key_algorithm).parse()?, + key_curve: require!(value.key_curve).parse()?, + key_value: require!(value.key_value).parse()?, + rp_id: require!(value.rp_id).parse()?, user_handle: EncString::try_from_optional(value.user_handle) .ok() .flatten(), user_name: EncString::try_from_optional(value.user_name).ok().flatten(), - counter: value.counter.ok_or(Error::MissingFields)?.parse()?, + counter: require!(value.counter).parse()?, rp_name: EncString::try_from_optional(value.rp_name).ok().flatten(), user_display_name: EncString::try_from_optional(value.user_display_name) .ok() .flatten(), - discoverable: value.discoverable.ok_or(Error::MissingFields)?.parse()?, + discoverable: require!(value.discoverable).parse()?, creation_date: value.creation_date.parse().unwrap(), }) } diff --git a/crates/bitwarden/src/vault/cipher/secure_note.rs b/crates/bitwarden/src/vault/cipher/secure_note.rs index eba4ea2fb..ebcbc3fa4 100644 --- a/crates/bitwarden/src/vault/cipher/secure_note.rs +++ b/crates/bitwarden/src/vault/cipher/secure_note.rs @@ -4,7 +4,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::error::{Error, Result}; +use crate::error::{require, Error, Result}; #[derive(Clone, Copy, Serialize_repr, Deserialize_repr, Debug, JsonSchema)] #[repr(u8)] @@ -48,7 +48,7 @@ impl TryFrom for SecureNote { fn try_from(model: CipherSecureNoteModel) -> Result { Ok(Self { - r#type: model.r#type.map(|t| t.into()).ok_or(Error::MissingFields)?, + r#type: require!(model.r#type).into(), }) } } diff --git a/crates/bitwarden/src/vault/collection.rs b/crates/bitwarden/src/vault/collection.rs index d20e5d729..ce881cb98 100644 --- a/crates/bitwarden/src/vault/collection.rs +++ b/crates/bitwarden/src/vault/collection.rs @@ -6,7 +6,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use uuid::Uuid; -use crate::error::{Error, Result}; +use crate::error::{require, Error, Result}; #[derive(Serialize, Deserialize, Debug, JsonSchema)] #[serde(rename_all = "camelCase", deny_unknown_fields)] @@ -66,8 +66,8 @@ impl TryFrom for Collection { fn try_from(collection: CollectionDetailsResponseModel) -> Result { Ok(Collection { id: collection.id, - organization_id: collection.organization_id.ok_or(Error::MissingFields)?, - name: collection.name.ok_or(Error::MissingFields)?.parse()?, + organization_id: require!(collection.organization_id), + name: require!(collection.name).parse()?, external_id: collection.external_id, hide_passwords: collection.hide_passwords.unwrap_or(false), read_only: collection.read_only.unwrap_or(false), diff --git a/crates/bitwarden/src/vault/folder.rs b/crates/bitwarden/src/vault/folder.rs index edd1cac42..65b18e54b 100644 --- a/crates/bitwarden/src/vault/folder.rs +++ b/crates/bitwarden/src/vault/folder.rs @@ -7,7 +7,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use uuid::Uuid; -use crate::error::{Error, Result}; +use crate::error::{require, Error, Result}; #[derive(Serialize, Deserialize, Debug, JsonSchema)] #[serde(rename_all = "camelCase")] @@ -55,8 +55,8 @@ impl TryFrom for Folder { fn try_from(folder: FolderResponseModel) -> Result { Ok(Folder { id: folder.id, - name: EncString::try_from_optional(folder.name)?.ok_or(Error::MissingFields)?, - revision_date: folder.revision_date.ok_or(Error::MissingFields)?.parse()?, + name: require!(EncString::try_from_optional(folder.name)?), + revision_date: require!(folder.revision_date).parse()?, }) } } diff --git a/crates/bitwarden/src/vault/send.rs b/crates/bitwarden/src/vault/send.rs index 144933899..78c30a5a6 100644 --- a/crates/bitwarden/src/vault/send.rs +++ b/crates/bitwarden/src/vault/send.rs @@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; use uuid::Uuid; -use crate::error::{Error, Result}; +use crate::error::{require, Error, Result}; const SEND_ITERATIONS: u32 = 100_000; @@ -308,19 +308,19 @@ impl TryFrom for Send { Ok(Send { id: send.id, access_id: send.access_id, - name: send.name.ok_or(Error::MissingFields)?.parse()?, + name: require!(send.name).parse()?, notes: EncString::try_from_optional(send.notes)?, - key: send.key.ok_or(Error::MissingFields)?.parse()?, + key: require!(send.key).parse()?, password: send.password, - r#type: send.r#type.ok_or(Error::MissingFields)?.into(), + r#type: require!(send.r#type).into(), file: send.file.map(|f| (*f).try_into()).transpose()?, text: send.text.map(|t| (*t).try_into()).transpose()?, max_access_count: send.max_access_count.map(|s| s as u32), - access_count: send.access_count.ok_or(Error::MissingFields)? as u32, + access_count: require!(send.access_count) as u32, disabled: send.disabled.unwrap_or(false), hide_email: send.hide_email.unwrap_or(false), - revision_date: send.revision_date.ok_or(Error::MissingFields)?.parse()?, - deletion_date: send.deletion_date.ok_or(Error::MissingFields)?.parse()?, + revision_date: require!(send.revision_date).parse()?, + deletion_date: require!(send.deletion_date).parse()?, expiration_date: send.expiration_date.map(|s| s.parse()).transpose()?, }) } @@ -341,7 +341,7 @@ impl TryFrom for SendFile { fn try_from(file: SendFileModel) -> Result { Ok(SendFile { id: file.id, - file_name: file.file_name.ok_or(Error::MissingFields)?.parse()?, + file_name: require!(file.file_name).parse()?, size: file.size.map(|v| v.to_string()), size_name: file.size_name, }) From 432bfc5abdbd7fa872941fc40a197a5d4bb32025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 1 Apr 2024 16:02:58 +0200 Subject: [PATCH 2/2] Add comment --- crates/bitwarden/src/error.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/bitwarden/src/error.rs b/crates/bitwarden/src/error.rs index 6a5f65cba..59fae58d2 100644 --- a/crates/bitwarden/src/error.rs +++ b/crates/bitwarden/src/error.rs @@ -133,6 +133,10 @@ macro_rules! impl_bitwarden_error { impl_bitwarden_error!(ApiError); impl_bitwarden_error!(IdentityError); +/// This macro is used to require that a value is present or return an error otherwise. +/// It is equivalent to using `val.ok_or(Error::MissingFields)?`, but easier to use and +/// with a more descriptive error message. +/// Note that this macro will return early from the function if the value is not present. macro_rules! require { ($val:expr) => { match $val {