Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Status field to Issuance's Offer and Credential aggregates #133

Open
wants to merge 1 commit into
base: nanderstabel/issue125
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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