diff --git a/crates/bitwarden/src/error.rs b/crates/bitwarden/src/error.rs index cd742f810..f33aecdf5 100644 --- a/crates/bitwarden/src/error.rs +++ b/crates/bitwarden/src/error.rs @@ -94,6 +94,16 @@ pub enum EncStringParseError { InvalidLength { expected: usize, got: usize }, } +impl From for Error { + fn from(e: chrono::ParseError) -> Self { + Self::Internal(string_to_static_str(e.to_string())) + } +} + +fn string_to_static_str(s: String) -> &'static str { + Box::leak(s.into_boxed_str()) +} + // Ensure that the error messages implement Send and Sync #[cfg(test)] const _: () = { diff --git a/crates/bitwarden/src/secrets_manager/projects/project_response.rs b/crates/bitwarden/src/secrets_manager/projects/project_response.rs index 52980c45f..8fcace594 100644 --- a/crates/bitwarden/src/secrets_manager/projects/project_response.rs +++ b/crates/bitwarden/src/secrets_manager/projects/project_response.rs @@ -1,4 +1,5 @@ use bitwarden_api_api::models::ProjectResponseModel; +use chrono::{DateTime, Utc}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -7,17 +8,17 @@ use crate::{ client::encryption_settings::EncryptionSettings, crypto::{Decryptable, EncString}, error::{Error, Result}, + util::parse_date, }; #[derive(Serialize, Deserialize, Debug, JsonSchema)] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct ProjectResponse { - pub object: String, pub id: Uuid, pub organization_id: Uuid, pub name: String, - pub creation_date: String, - pub revision_date: String, + pub creation_date: DateTime, + pub revision_date: DateTime, } impl ProjectResponse { @@ -34,14 +35,12 @@ impl ProjectResponse { .decrypt(enc, &Some(organization_id))?; Ok(ProjectResponse { - object: "project".to_owned(), - id: response.id.ok_or(Error::MissingFields)?, organization_id, name, - creation_date: response.creation_date.ok_or(Error::MissingFields)?, - revision_date: response.revision_date.ok_or(Error::MissingFields)?, + creation_date: parse_date(&response.creation_date.ok_or(Error::MissingFields)?)?, + revision_date: parse_date(&response.revision_date.ok_or(Error::MissingFields)?)?, }) } } diff --git a/crates/bitwarden/src/secrets_manager/secrets/secret_response.rs b/crates/bitwarden/src/secrets_manager/secrets/secret_response.rs index 635d1e3c0..ebe1d9cc3 100644 --- a/crates/bitwarden/src/secrets_manager/secrets/secret_response.rs +++ b/crates/bitwarden/src/secrets_manager/secrets/secret_response.rs @@ -1,6 +1,7 @@ use bitwarden_api_api::models::{ BaseSecretResponseModel, BaseSecretResponseModelListResponseModel, SecretResponseModel, }; +use chrono::{DateTime, Utc}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -9,12 +10,12 @@ use crate::{ client::encryption_settings::EncryptionSettings, crypto::{Decryptable, EncString}, error::{Error, Result}, + util::parse_date, }; #[derive(Serialize, Deserialize, Debug, JsonSchema)] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct SecretResponse { - pub object: String, pub id: Uuid, pub organization_id: Uuid, pub project_id: Option, @@ -23,8 +24,8 @@ pub struct SecretResponse { pub value: String, pub note: String, - pub creation_date: String, - pub revision_date: String, + pub creation_date: DateTime, + pub revision_date: DateTime, } impl SecretResponse { @@ -73,7 +74,6 @@ impl SecretResponse { .and_then(|p| p.id); Ok(SecretResponse { - object: "secret".to_owned(), id: response.id.ok_or(Error::MissingFields)?, organization_id: org_id.ok_or(Error::MissingFields)?, project_id: project, @@ -81,8 +81,8 @@ impl SecretResponse { value, note, - creation_date: response.creation_date.ok_or(Error::MissingFields)?, - revision_date: response.revision_date.ok_or(Error::MissingFields)?, + creation_date: parse_date(&response.creation_date.ok_or(Error::MissingFields)?)?, + revision_date: parse_date(&response.revision_date.ok_or(Error::MissingFields)?)?, }) } } diff --git a/crates/bitwarden/src/util.rs b/crates/bitwarden/src/util.rs index fc9f30447..c99c2fafb 100644 --- a/crates/bitwarden/src/util.rs +++ b/crates/bitwarden/src/util.rs @@ -5,6 +5,7 @@ use base64::{ engine::{DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig}, Engine, }; +use chrono::{DateTime, Utc}; use crate::error::Result; @@ -50,6 +51,11 @@ pub fn decode_token(token: &str) -> Result { Ok(serde_json::from_slice(&decoded)?) } +/// Parse a date in RFC3339 format +pub(crate) fn parse_date(date: &str) -> Result> { + Ok(DateTime::parse_from_rfc3339(date)?.with_timezone(&Utc)) +} + #[cfg(test)] mod tests { #[test]