Skip to content

Commit

Permalink
fix: fix compilation and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nanderstabel committed Dec 12, 2024
1 parent 32b6250 commit f1f0bc5
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 161 deletions.
3 changes: 2 additions & 1 deletion agent_api_rest/src/issuance/credential_issuer/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,10 @@ mod tests {
tests::{BASE_URL, CREDENTIAL_CONFIGURATION_ID, OFFER_ID},
};
use agent_event_publisher_http::EventPublisherHttp;
use agent_issuance::credential::aggregate::CredentialExpiry;
use agent_issuance::{offer::event::OfferEvent, startup_commands::startup_commands, state::initialize};
use agent_secret_manager::service::Service;
use agent_shared::config::{set_config, CredentialExpiry, Events};
use agent_shared::config::{set_config, Events};
use agent_store::{in_memory, EventPublisher};
use axum::{
body::Body,
Expand Down
12 changes: 5 additions & 7 deletions agent_api_rest/src/issuance/credentials.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use crate::API_VERSION;
use agent_issuance::{
credential::{command::CredentialCommand, entity::Data, views::CredentialView},
credential::{aggregate::CredentialExpiry, command::CredentialCommand, entity::Data, views::CredentialView},
offer::command::OfferCommand,
server_config::queries::ServerConfigView,
state::{IssuanceState, SERVER_CONFIG_ID},
};
use agent_shared::{
config::CredentialExpiry,
handlers::{command_handler, query_handler},
};
use agent_shared::handlers::{command_handler, query_handler};
use axum::{
extract::{Json, Path, State},
http::StatusCode,
Expand Down Expand Up @@ -102,7 +99,7 @@ pub(crate) async fn credentials(
credential_id: credential_id.clone(),
data: Data { raw: data },
credential_configuration,
expires: Some(expires),
expires,
}
};

Expand Down Expand Up @@ -229,7 +226,8 @@ pub mod tests {
"credential": {
"credentialSubject": CREDENTIAL_SUBJECT.clone()
},
"credentialConfigurationId": CREDENTIAL_CONFIGURATION_ID
"credentialConfigurationId": CREDENTIAL_CONFIGURATION_ID,
"expires": "never"
}))
.unwrap(),
))
Expand Down
3 changes: 2 additions & 1 deletion agent_holder/src/offer/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,8 @@ pub mod tests {
"name": "Master of Oceanography"
}
}},
"credentialConfigurationId": "badge"
"credentialConfigurationId": "badge",
"expires": "never"
}))
.unwrap(),
))
Expand Down
165 changes: 18 additions & 147 deletions agent_issuance/src/credential/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::credential::command::CredentialCommand;
use crate::credential::error::CredentialError::{self};
use crate::credential::event::CredentialEvent;
use crate::services::IssuanceServices;
use agent_shared::config::{config, get_preferred_did_method, get_preferred_signing_algorithm, CredentialExpiry};
use agent_shared::config::{config, get_preferred_did_method, get_preferred_signing_algorithm};
use async_trait::async_trait;
use cqrs_es::Aggregate;
use derivative::Derivative;
Expand All @@ -22,7 +22,7 @@ use oid4vci::VerifiableCredentialJwt;
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::sync::Arc;
use tracing::{info, warn};
use tracing::info;
use types_ob_v3::prelude::{
AchievementCredential, AchievementCredentialBuilder, AchievementCredentialType, AchievementSubject, Profile,
ProfileBuilder,
Expand Down Expand Up @@ -133,7 +133,12 @@ impl Aggregate for Credential {
identity_core::common::Timestamp::parse(&issuance_date).expect("Could not parse issuance_date");

let expiration_date = match expires {
CredentialExpiry::Fixed(fixed) => Some(fixed),
CredentialExpiry::Fixed(fixed) => {
let fixed = identity_core::common::Timestamp::from_unix(fixed.timestamp())
.map_err(|_| InvalidExpirationDateError)?;

Some(fixed)
}
CredentialExpiry::Never => None,
};

Expand Down Expand Up @@ -403,81 +408,12 @@ impl Aggregate for Credential {
}
}

// fn calculate_expiration_timestamp(
// overwrite: Option<CredentialExpiry>,
// ) -> Result<Option<identity_core::common::Timestamp>, CredentialError> {
// #[cfg(feature = "test_utils")]
// let now = "2010-01-02T00:00:00Z".parse::<chrono::DateTime<chrono::Utc>>().unwrap();
// #[cfg(not(feature = "test_utils"))]
// let now = chrono::Utc::now();

// let config = config().credential_expiry.clone();

// match overwrite.unwrap_or(config) {
// // CredentialExpiry::Relative(duration) => {
// // println!("Duration: {:?}", duration);
// // // === convert iso8601::Duration to `chrono::TimeDelta`
// // let d = chrono::TimeDelta::try_from(duration); // .to_string().parse::<i64>();
// // println!("Duration (parse result): {:?}", d);
// // if d.is_err() {
// // warn!("Could not parse duration: {}", duration);
// // return None;
// // }
// // let n = match duration {
// // iso8601::Duration::YMDHMS {
// // year,
// // month,
// // day,
// // hour,
// // minute,
// // second,
// // millisecond,
// // } => {
// // now.checked_add_days(Days::new(day.into()));
// // // .and_then(|d| d.checked_add_months(month));
// // now
// // }
// // iso8601::Duration::Weeks(weeks) => now,
// // };
// // // let time_delta = chrono::TimeDelta::new(d.unwrap(), 0).unwrap();
// // let time_delta = d.unwrap();
// // // === end
// // let expires_at = now.checked_add_signed(time_delta);
// // match expires_at {
// // Some(expires_at) => Some(identity_core::common::Timestamp::from_unix(expires_at.timestamp()).unwrap()),
// // None => {
// // warn!("{duration} is too large to be added to the current time. Skipping expiration date.");
// // None
// // }
// // }
// // }
// CredentialExpiry::Fixed(fixed) => {
// let x = identity_core::common::Timestamp::from_unix(fixed.timestamp()).map_err(|e| {
// warn!("Invalid timestamp: {:?}", e);
// CredentialError::InvalidVerifiableCredentialError(format!("invalid timestamp: {e}"))
// })?;
// Ok(Some(x))
// // match x {
// // Ok(t) => Some(t),
// // Err(e) => e,
// // }
// // if fixed.timestamp() > 253402300799 {
// // None
// // } else {
// // Some(identity_core::common::Timestamp::from_unix(fixed.timestamp()).unwrap())
// // }
// }
// CredentialExpiry::Never => Ok(None),
// }
// }

#[cfg(test)]
pub mod credential_tests {
use super::test_utils::*;
use super::*;

use agent_secret_manager::service::Service;
use agent_shared::config::{set_config, CredentialExpiry};
use jsonwebtoken::Algorithm;

use rstest::rstest;
Expand Down Expand Up @@ -517,7 +453,7 @@ pub mod credential_tests {
raw: credential_subject,
},
credential_configuration: Box::new(credential_configuration.clone()),
expires: None,
expires: CredentialExpiry::Never,
})
.then_expect_events(vec![CredentialEvent::UnsignedCredentialCreated {
credential_id,
Expand Down Expand Up @@ -566,84 +502,19 @@ pub mod credential_tests {
}])
}

#[rstest]
#[case(None, CredentialExpiry::Never, None)]
#[case(None, CredentialExpiry::Fixed("2025-04-03T02:01:00Z".parse::<chrono::DateTime<chrono::Utc>>().unwrap()), Some("2025-04-03T02:01:00Z"))]
#[serial_test::serial]
async fn test_calculate_expiration_timestamp(
#[case] provided: Option<CredentialExpiry>,
#[case] configured: CredentialExpiry,
#[case] expected: Option<&str>,
) {
set_config().credential_expiry = configured;

let expires = calculate_expiration_timestamp(provided);

// Test teardown: reset the configuration to the default value
set_config().credential_expiry = CredentialExpiry::Never;

// match expires {
// Ok(Some(e)) => {
// assert_eq!(e.to_rfc3339(), expected.unwrap().unwrap());
// }
// Ok(None) => {
// assert_eq!(None, expected.unwrap());
// }
// Err(e) => {
// assert_eq!(e.to_string(), expected.unwrap_err().to_string());
// }
// }

assert_eq!(expires.unwrap().map(|t| t.to_rfc3339()).as_deref(), expected);
}
}

pub mod expiry_tests {
use super::*;

use std::str::FromStr;

#[test]
fn custom_serializer_for_credential_expiry() {
let deserialized: CredentialExpiry = serde_json::from_value(serde_json::json!("never")).unwrap();
assert_eq!(deserialized, CredentialExpiry::Never);

let serialized = serde_json::to_value(&CredentialExpiry::Never).unwrap();
assert_eq!(serialized, serde_json::json!("never"));
}

// #[test]
// fn large_relative_expiry_panics_due_to_overflow() {
// let overwrite = Some(CredentialExpiry::Relative(
// iso8601::Duration::from_str("P100000000Y").unwrap(), // <-- eight 0's
// ));
pub mod expiry_tests {
use super::*;

// calculate_expiration_timestamp(overwrite);
// // thread 'credential::aggregate::test' panicked at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chrono-0.4.38/src/datetime/mod.rs:1482:38:
// // `DateTime + TimeDelta` overflowed
// }
#[test]
fn custom_serializer_for_credential_expiry() {
let deserialized: CredentialExpiry = serde_json::from_value(serde_json::json!("never")).unwrap();
assert_eq!(deserialized, CredentialExpiry::Never);

#[test]
fn large_fixed_expiry_panics_due_to_invalid_timestamp() {
let overwrite = Some(CredentialExpiry::Fixed(chrono::DateTime::<chrono::Utc>::MAX_UTC));

calculate_expiration_timestamp(overwrite);
// thread 'credential::aggregate::large_fixed_expiry_panics_due_to_invalid_timestamp' panicked at agent_issuance/src/credential/aggregate.rs:387:111:
// called `Result::unwrap()` on an `Err` value: InvalidTimestamp(ComponentRange(ComponentRange { name: "timestamp", minimum: -377705116800, maximum: 253402300799, value: 8210266876799, conditional_range: false }))
let serialized = serde_json::to_value(&CredentialExpiry::Never).unwrap();
assert_eq!(serialized, serde_json::json!("never"));
}
}

// #[test]
// fn large_relative_expiry_panics_due_to_invalid_timestamp() {
// let overwrite = Some(CredentialExpiry::Relative(
// iso8601::Duration::from_str("P10000000Y").unwrap(), // <-- seven 0's
// ));

// calculate_expiration_timestamp(overwrite);
// // thread 'credential::aggregate::test' panicked at agent_issuance/src/credential/aggregate.rs:385:86:
// // called `Result::unwrap()` on an `Err` value: InvalidTimestamp(ComponentRange(ComponentRange { name: "timestamp", minimum: -377705116800, maximum: 253402300799, value: 316622289664, conditional_range: false }))
// }
}

#[cfg(feature = "test_utils")]
pub mod test_utils {
use super::*;
Expand Down
7 changes: 2 additions & 5 deletions agent_issuance/src/credential/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ use thiserror::Error;
pub enum CredentialError {
#[error("Credential must be an object")]
InvalidCredentialError,

#[error("This Credential format it not supported")]
UnsupportedCredentialFormat,

#[error("The `credentialSubject` parameter is missing")]
MissingCredentialSubjectError,

#[error("The supplied `credentialSubject` is invalid: {0}")]
InvalidCredentialSubjectError(String),

#[error("The verifiable credential is invalid: {0}")]
InvalidVerifiableCredentialError(String),

#[error("Could not find any data to be signed")]
MissingCredentialDataError,
#[error("Invalid expiration data: The expiration date must not exceed `9999-12-31T23:59:59`. Please provide a valid date within the supported range.")]
InvalidExpirationDateError,
}

0 comments on commit f1f0bc5

Please sign in to comment.