Skip to content

Commit

Permalink
feat: add Status field to Issuance Offer and Credential
Browse files Browse the repository at this point in the history
  • Loading branch information
nanderstabel committed Oct 9, 2024
1 parent 129b6b2 commit f62388e
Show file tree
Hide file tree
Showing 19 changed files with 124 additions and 102 deletions.
7 changes: 2 additions & 5 deletions agent_api_rest/src/issuance/credential_issuer/credential.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use std::time::{Duration, Instant};

use agent_issuance::{
credential::{command::CredentialCommand, queries::CredentialView},
offer::{
command::OfferCommand,
queries::{access_token::AccessTokenView, OfferView},
},
credential::{command::CredentialCommand, views::CredentialView},
offer::{command::OfferCommand, queries::access_token::AccessTokenView, views::OfferView},
server_config::queries::ServerConfigView,
state::{IssuanceState, SERVER_CONFIG_ID},
};
Expand Down
5 changes: 1 addition & 4 deletions agent_api_rest/src/issuance/credential_issuer/token.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use agent_issuance::{
offer::{
command::OfferCommand,
queries::{pre_authorized_code::PreAuthorizedCodeView, OfferView},
},
offer::{command::OfferCommand, queries::pre_authorized_code::PreAuthorizedCodeView, views::OfferView},
state::IssuanceState,
};
use agent_shared::handlers::{command_handler, query_handler};
Expand Down
2 changes: 1 addition & 1 deletion agent_api_rest/src/issuance/credentials.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::API_VERSION;
use agent_issuance::{
credential::{command::CredentialCommand, entity::Data, queries::CredentialView},
credential::{command::CredentialCommand, entity::Data, views::CredentialView},
offer::command::OfferCommand,
server_config::queries::ServerConfigView,
state::{IssuanceState, SERVER_CONFIG_ID},
Expand Down
2 changes: 1 addition & 1 deletion agent_api_rest/src/issuance/offers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub mod send;

use agent_issuance::{
offer::{command::OfferCommand, queries::OfferView},
offer::{command::OfferCommand, views::OfferView},
server_config::queries::ServerConfigView,
state::{IssuanceState, SERVER_CONFIG_ID},
};
Expand Down
2 changes: 2 additions & 0 deletions agent_event_publisher_http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ where
mod tests {
use super::*;

use agent_issuance::offer::aggregate::Status;
use agent_issuance::offer::event::OfferEvent;
use agent_shared::config::{set_config, Events};
use wiremock::matchers::{method, path};
Expand Down Expand Up @@ -284,6 +285,7 @@ mod tests {
let offer_event = OfferEvent::FormUrlEncodedCredentialOfferCreated {
offer_id: Default::default(),
form_url_encoded_credential_offer: "form_url_encoded_credential_offer".to_string(),
status: Status::Pending,
};

let events = [EventEnvelope::<Offer> {
Expand Down
26 changes: 21 additions & 5 deletions agent_issuance/src/credential/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,20 @@ use types_ob_v3::prelude::{
ProfileBuilder,
};

#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
pub enum Status {
#[default]
Pending,
Issued,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default, Derivative)]
#[derivative(PartialEq)]
pub struct Credential {
data: Option<Data>,
credential_configuration: CredentialConfigurationsSupportedObject,
signed: Option<serde_json::Value>,
pub data: Option<Data>,
pub credential_configuration: CredentialConfigurationsSupportedObject,
pub signed: Option<serde_json::Value>,
pub status: Status,
}

#[async_trait]
Expand Down Expand Up @@ -237,7 +245,10 @@ impl Aggregate for Credential {
.ok())
};

Ok(vec![CredentialSigned { signed_credential }])
Ok(vec![CredentialSigned {
signed_credential,
status: Status::Issued,
}])
}
}
}
Expand All @@ -258,8 +269,12 @@ impl Aggregate for Credential {
SignedCredentialCreated { signed_credential } => {
self.signed.replace(signed_credential);
}
CredentialSigned { signed_credential } => {
CredentialSigned {
signed_credential,
status,
} => {
self.signed.replace(signed_credential);
self.status = status;
}
}
}
Expand Down Expand Up @@ -347,6 +362,7 @@ pub mod credential_tests {
})
.then_expect_events(vec![CredentialEvent::CredentialSigned {
signed_credential: json!(verifiable_credential_jwt),
status: Status::Issued,
}])
}
}
Expand Down
3 changes: 2 additions & 1 deletion agent_issuance/src/credential/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use cqrs_es::DomainEvent;
use oid4vci::credential_issuer::credential_configurations_supported::CredentialConfigurationsSupportedObject;
use serde::{Deserialize, Serialize};

use super::entity::Data;
use super::{aggregate::Status, entity::Data};

#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub enum CredentialEvent {
Expand All @@ -16,6 +16,7 @@ pub enum CredentialEvent {
},
CredentialSigned {
signed_credential: serde_json::Value,
status: Status,
},
}

Expand Down
2 changes: 1 addition & 1 deletion agent_issuance/src/credential/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ pub mod command;
pub mod entity;
pub mod error;
pub mod event;
pub mod queries;
pub mod views;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::CredentialView;
use crate::credential::queries::Credential;
use crate::credential::views::Credential;
use cqrs_es::{EventEnvelope, View};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
pub mod all_credentials;

use super::{entity::Data, event::CredentialEvent};
use super::event::CredentialEvent;
use crate::credential::aggregate::Credential;
use cqrs_es::{EventEnvelope, View};
use oid4vci::credential_issuer::credential_configurations_supported::CredentialConfigurationsSupportedObject;
use serde::{Deserialize, Serialize};

#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct CredentialView {
pub data: Option<Data>,
pub credential_configuration: CredentialConfigurationsSupportedObject,
pub signed: Option<serde_json::Value>,
}
pub type CredentialView = Credential;

impl View<Credential> for CredentialView {
impl View<Credential> for Credential {
fn update(&mut self, event: &EventEnvelope<Credential>) {
match &event.payload {
CredentialEvent::UnsignedCredentialCreated {
Expand All @@ -26,8 +19,12 @@ impl View<Credential> for CredentialView {
CredentialEvent::SignedCredentialCreated { signed_credential } => {
self.signed.replace(signed_credential.clone());
}
CredentialEvent::CredentialSigned { signed_credential } => {
CredentialEvent::CredentialSigned {
signed_credential,
status,
} => {
self.signed.replace(signed_credential.clone());
self.status.clone_from(status);
}
}
}
Expand Down
22 changes: 21 additions & 1 deletion agent_issuance/src/offer/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ use crate::offer::error::OfferError::{self, *};
use crate::offer::event::OfferEvent;
use crate::services::IssuanceServices;

#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
pub enum Status {
#[default]
Created,
Pending,
Issued,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Offer {
pub credential_offer: Option<CredentialOffer>,
Expand All @@ -25,6 +33,7 @@ pub struct Offer {
pub token_response: Option<TokenResponse>,
pub access_token: String,
pub credential_response: Option<CredentialResponse>,
pub status: Status,
}

#[async_trait]
Expand Down Expand Up @@ -98,6 +107,7 @@ impl Aggregate for Offer {
.as_ref()
.ok_or(MissingCredentialOfferError)?
.to_string(),
status: Status::Pending,
}]),
SendCredentialOffer { offer_id, target_url } => {
// TODO: add to `service`?
Expand All @@ -110,7 +120,11 @@ impl Aggregate for Offer {
.await
.map_err(|e| SendCredentialOfferError(e.to_string()))?;

Ok(vec![CredentialOfferSent { offer_id, target_url }])
Ok(vec![CredentialOfferSent {
offer_id,
target_url,
status: Status::Pending,
}])
}
CreateTokenResponse {
offer_id,
Expand Down Expand Up @@ -188,6 +202,7 @@ impl Aggregate for Offer {
Ok(vec![CredentialResponseCreated {
offer_id,
credential_response,
status: Status::Issued,
}])
}
}
Expand Down Expand Up @@ -329,6 +344,7 @@ pub mod tests {
.then_expect_events(vec![OfferEvent::FormUrlEncodedCredentialOfferCreated {
offer_id: Default::default(),
form_url_encoded_credential_offer,
status: Status::Pending,
}]);
}

Expand Down Expand Up @@ -357,6 +373,7 @@ pub mod tests {
OfferEvent::FormUrlEncodedCredentialOfferCreated {
offer_id: Default::default(),
form_url_encoded_credential_offer,
status: Status::Pending,
},
])
.when(OfferCommand::CreateTokenResponse {
Expand Down Expand Up @@ -398,6 +415,7 @@ pub mod tests {
OfferEvent::FormUrlEncodedCredentialOfferCreated {
offer_id: Default::default(),
form_url_encoded_credential_offer,
status: Status::Pending,
},
OfferEvent::TokenResponseCreated {
offer_id: Default::default(),
Expand Down Expand Up @@ -442,6 +460,7 @@ pub mod tests {
OfferEvent::FormUrlEncodedCredentialOfferCreated {
offer_id: Default::default(),
form_url_encoded_credential_offer,
status: Status::Pending,
},
OfferEvent::TokenResponseCreated {
offer_id: Default::default(),
Expand All @@ -459,6 +478,7 @@ pub mod tests {
.then_expect_events(vec![OfferEvent::CredentialResponseCreated {
offer_id: Default::default(),
credential_response,
status: Status::Issued,
}]);
}
}
Expand Down
4 changes: 4 additions & 0 deletions agent_issuance/src/offer/event.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::aggregate::Status;
use cqrs_es::DomainEvent;
use oid4vci::{
credential_offer::CredentialOffer, credential_response::CredentialResponse, token_response::TokenResponse,
Expand All @@ -20,10 +21,12 @@ pub enum OfferEvent {
FormUrlEncodedCredentialOfferCreated {
offer_id: String,
form_url_encoded_credential_offer: String,
status: Status,
},
CredentialOfferSent {
offer_id: String,
target_url: Url,
status: Status,
},
TokenResponseCreated {
offer_id: String,
Expand All @@ -36,6 +39,7 @@ pub enum OfferEvent {
CredentialResponseCreated {
offer_id: String,
credential_response: CredentialResponse,
status: Status,
},
}

Expand Down
1 change: 1 addition & 0 deletions agent_issuance/src/offer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod command;
pub mod error;
pub mod event;
pub mod queries;
pub mod views;
5 changes: 3 additions & 2 deletions agent_issuance/src/offer/queries/access_token.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use crate::offer::queries::{Offer, OfferEvent, ViewRepository};
use agent_shared::custom_queries::CustomQuery;
use async_trait::async_trait;
use cqrs_es::{
persist::{PersistenceError, ViewContext},
persist::{PersistenceError, ViewContext, ViewRepository},
EventEnvelope, Query, View,
};
use serde::{Deserialize, Serialize};
use std::marker::PhantomData;
use std::sync::Arc;

use crate::offer::{aggregate::Offer, event::OfferEvent};

/// A custom query trait for the Offer aggregate. This query is used to update the `AccessTokenView`.
pub struct AccessTokenQuery<R, V>
where
Expand Down
62 changes: 0 additions & 62 deletions agent_issuance/src/offer/queries/mod.rs
Original file line number Diff line number Diff line change
@@ -1,64 +1,2 @@
pub mod access_token;
pub mod all_offers;
pub mod pre_authorized_code;

use super::event::OfferEvent;
use crate::offer::aggregate::Offer;
use cqrs_es::{persist::ViewRepository, EventEnvelope, View};
use oid4vci::{
credential_offer::CredentialOffer, credential_response::CredentialResponse, token_response::TokenResponse,
};
use serde::{Deserialize, Serialize};

#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct OfferView {
pub credential_offer: Option<CredentialOffer>,
pub subject_id: Option<String>,
pub credential_ids: Vec<String>,
pub pre_authorized_code: String,
pub access_token: String,
pub form_url_encoded_credential_offer: String,
pub token_response: Option<TokenResponse>,
pub credential_response: Option<CredentialResponse>,
}

impl View<Offer> for OfferView {
fn update(&mut self, event: &EventEnvelope<Offer>) {
use crate::offer::event::OfferEvent::*;

match &event.payload {
CredentialOfferCreated {
pre_authorized_code,
access_token,
..
} => {
self.pre_authorized_code.clone_from(pre_authorized_code);
self.access_token.clone_from(access_token)
}
CredentialsAdded {
credential_ids: credential_id,
..
} => {
self.credential_ids.clone_from(credential_id);
}
FormUrlEncodedCredentialOfferCreated {
form_url_encoded_credential_offer,
..
} => self
.form_url_encoded_credential_offer
.clone_from(form_url_encoded_credential_offer),
CredentialOfferSent { .. } => {}
CredentialRequestVerified { subject_id, .. } => {
self.subject_id.replace(subject_id.clone());
}
TokenResponseCreated { token_response, .. } => {
self.token_response.replace(token_response.clone());
}
CredentialResponseCreated {
credential_response, ..
} => {
self.credential_response.replace(credential_response.clone());
}
}
}
}
Loading

0 comments on commit f62388e

Please sign in to comment.