Skip to content

Commit

Permalink
feat: allow querying all offers and all credentials of issuer (#121)
Browse files Browse the repository at this point in the history
* feat: add queries to agent_issuance

* chore: renaming

* feat: add queries to in_memory

* feat: add endpoints

* feat: add new tables to postgres

* feat: add requests to postman collection

* chore: cargo fmt

* refactor: re-order view repositories

* fix: fix Postman collection

* fix: fix Postman collection

* fix: remove GET request body

---------

Co-authored-by: Nander Stabel <nander.stabel@impierce.com>
  • Loading branch information
Oran-Dan and nanderstabel authored Oct 3, 2024
1 parent 1a1045d commit d284e8a
Show file tree
Hide file tree
Showing 20 changed files with 284 additions and 87 deletions.
80 changes: 80 additions & 0 deletions agent_api_rest/postman/ssi-agent.postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,46 @@
},
"response": []
},
{
"name": "all_credentials",
"event": [
{
"listen": "test",
"script": {
"exec": [
""
],
"type": "text/javascript",
"packages": {}
}
},
{
"listen": "prerequest",
"script": {
"exec": [
""
],
"type": "text/javascript",
"packages": {}
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{HOST}}/v0/credentials",
"host": [
"{{HOST}}"
],
"path": [
"v0",
"credentials"
]
}
},
"response": []
},
{
"name": "offers",
"event": [
Expand Down Expand Up @@ -177,6 +217,46 @@
},
"response": []
},
{
"name": "all_offers",
"event": [
{
"listen": "test",
"script": {
"exec": [
""
],
"type": "text/javascript",
"packages": {}
}
},
{
"listen": "prerequest",
"script": {
"exec": [
""
],
"type": "text/javascript",
"packages": {}
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{HOST}}/v0/offers",
"host": [
"{{HOST}}"
],
"path": [
"v0",
"offers"
]
}
},
"response": []
},
{
"name": "offers_send",
"request": {
Expand Down
2 changes: 1 addition & 1 deletion agent_api_rest/src/holder/holder/credentials/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use serde_json::json;

#[axum_macros::debug_handler]
pub(crate) async fn credentials(State(state): State<HolderState>) -> Response {
match query_handler("all_credentials", &state.query.all_credentials).await {
match query_handler("all_holder_credentials", &state.query.all_holder_credentials).await {
Ok(Some(all_credentials_view)) => (StatusCode::OK, Json(all_credentials_view)).into_response(),
Ok(None) => (StatusCode::OK, Json(json!({}))).into_response(),
_ => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
Expand Down
10 changes: 5 additions & 5 deletions agent_api_rest/src/holder/holder/offers/accept.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use agent_holder::{
credential::command::CredentialCommand,
offer::{command::OfferCommand, queries::OfferView},
offer::{command::OfferCommand, queries::ReceivedOfferView},
state::HolderState,
};
use agent_shared::handlers::{command_handler, query_handler};
Expand All @@ -18,8 +18,8 @@ pub(crate) async fn accept(State(state): State<HolderState>, Path(offer_id): Pat
// Furthermore, the Application Layer (not implemented yet) should be kept very thin as well. See: https://github.com/impierce/ssi-agent/issues/114

// Accept the Credential Offer if it exists
match query_handler(&offer_id, &state.query.offer).await {
Ok(Some(OfferView { .. })) => {
match query_handler(&offer_id, &state.query.received_offer).await {
Ok(Some(ReceivedOfferView { .. })) => {
let command = OfferCommand::AcceptCredentialOffer {
offer_id: offer_id.clone(),
};
Expand All @@ -45,8 +45,8 @@ pub(crate) async fn accept(State(state): State<HolderState>, Path(offer_id): Pat
return StatusCode::INTERNAL_SERVER_ERROR.into_response();
}

let credentials = match query_handler(&offer_id, &state.query.offer).await {
Ok(Some(OfferView { credentials, .. })) => credentials,
let credentials = match query_handler(&offer_id, &state.query.received_offer).await {
Ok(Some(ReceivedOfferView { credentials, .. })) => credentials,
_ => return StatusCode::INTERNAL_SERVER_ERROR.into_response(),
};

Expand Down
2 changes: 1 addition & 1 deletion agent_api_rest/src/holder/holder/offers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use serde_json::json;

#[axum_macros::debug_handler]
pub(crate) async fn offers(State(state): State<HolderState>) -> Response {
match query_handler("all_offers", &state.query.all_offers).await {
match query_handler("all_received_offers", &state.query.all_received_offers).await {
Ok(Some(all_offers_view)) => (StatusCode::OK, Json(all_offers_view)).into_response(),
Ok(None) => (StatusCode::OK, Json(json!({}))).into_response(),
_ => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
Expand Down
11 changes: 11 additions & 0 deletions agent_api_rest/src/issuance/credentials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use serde::{Deserialize, Serialize};
use serde_json::Value;
use tracing::info;

use serde_json::json;

#[axum_macros::debug_handler]
pub(crate) async fn get_credentials(State(state): State<IssuanceState>, Path(credential_id): Path<String>) -> Response {
// Get the credential if it exists.
Expand Down Expand Up @@ -160,6 +162,15 @@ pub(crate) async fn credentials(
}
}

#[axum_macros::debug_handler]
pub(crate) async fn all_credentials(State(state): State<IssuanceState>) -> Response {
match query_handler("all_credentials", &state.query.all_credentials).await {
Ok(Some(all_credentials_view)) => (StatusCode::OK, Json(all_credentials_view)).into_response(),
Ok(None) => (StatusCode::OK, Json(json!({}))).into_response(),
_ => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
}

#[cfg(test)]
pub mod tests {
use super::*;
Expand Down
6 changes: 4 additions & 2 deletions agent_api_rest/src/issuance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pub mod offers;
use agent_issuance::state::IssuanceState;
use axum::routing::get;
use axum::{routing::post, Router};
use credentials::all_credentials;
use offers::all_offers;

use crate::issuance::{
credential_issuer::{
Expand All @@ -21,9 +23,9 @@ pub fn router(issuance_state: IssuanceState) -> Router {
.nest(
API_VERSION,
Router::new()
.route("/credentials", post(credentials))
.route("/credentials", post(credentials).get(all_credentials))
.route("/credentials/:credential_id", get(get_credentials))
.route("/offers", post(offers))
.route("/offers", post(offers).get(all_offers))
.route("/offers/send", post(send)),
)
.route(
Expand Down
10 changes: 10 additions & 0 deletions agent_api_rest/src/issuance/offers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use axum::{
};
use hyper::header;
use serde::{Deserialize, Serialize};
use serde_json::json;
use serde_json::Value;
use tracing::info;

Expand Down Expand Up @@ -81,6 +82,15 @@ pub(crate) async fn offers(State(state): State<IssuanceState>, Json(payload): Js
}
}

#[axum_macros::debug_handler]
pub(crate) async fn all_offers(State(state): State<IssuanceState>) -> Response {
match query_handler("all_offers", &state.query.all_offers).await {
Ok(Some(all_offers_view)) => (StatusCode::OK, Json(all_offers_view)).into_response(),
Ok(None) => (StatusCode::OK, Json(json!({}))).into_response(),
_ => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
}

#[cfg(test)]
pub mod tests {
use super::*;
Expand Down
20 changes: 18 additions & 2 deletions agent_application/docker/db/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ CREATE TABLE offer
PRIMARY KEY (view_id)
);

CREATE TABLE all_offers
(
view_id text NOT NULL,
version bigint CHECK (version >= 0) NOT NULL,
payload json NOT NULL,
PRIMARY KEY (view_id)
);

CREATE TABLE pre_authorized_code
(
view_id text NOT NULL,
Expand All @@ -42,6 +50,14 @@ CREATE TABLE credential
PRIMARY KEY (view_id)
);

CREATE TABLE all_credentials
(
view_id text NOT NULL,
version bigint CHECK (version >= 0) NOT NULL,
payload json NOT NULL,
PRIMARY KEY (view_id)
);

CREATE TABLE server_config
(
view_id text NOT NULL,
Expand All @@ -58,7 +74,7 @@ CREATE TABLE received_offer
PRIMARY KEY (view_id)
);

CREATE TABLE all_offers
CREATE TABLE all_received_offers
(
view_id text NOT NULL,
version bigint CHECK (version >= 0) NOT NULL,
Expand All @@ -75,7 +91,7 @@ CREATE TABLE holder_credential
);


CREATE TABLE all_credentials
CREATE TABLE all_holder_credentials
(
view_id text NOT NULL,
version bigint CHECK (version >= 0) NOT NULL,
Expand Down
8 changes: 4 additions & 4 deletions agent_holder/src/credential/queries/all_credentials.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use super::CredentialView;
use super::HolderCredentialView;
use crate::credential::queries::Credential;
use cqrs_es::{EventEnvelope, View};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct AllCredentialsView {
pub struct AllHolderCredentialsView {
#[serde(flatten)]
pub credentials: HashMap<String, CredentialView>,
pub credentials: HashMap<String, HolderCredentialView>,
}

impl View<Credential> for AllCredentialsView {
impl View<Credential> for AllHolderCredentialsView {
fn update(&mut self, event: &EventEnvelope<Credential>) {
self.credentials
// Get the entry for the aggregate_id
Expand Down
4 changes: 2 additions & 2 deletions agent_holder/src/credential/queries/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ use cqrs_es::{EventEnvelope, View};
use serde::{Deserialize, Serialize};

#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct CredentialView {
pub struct HolderCredentialView {
pub credential_id: Option<String>,
pub offer_id: Option<String>,
pub credential: Option<serde_json::Value>,
}

impl View<Credential> for CredentialView {
impl View<Credential> for HolderCredentialView {
fn update(&mut self, event: &EventEnvelope<Credential>) {
use CredentialEvent::*;

Expand Down
8 changes: 4 additions & 4 deletions agent_holder/src/offer/queries/all_offers.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use super::OfferView;
use super::ReceivedOfferView;
use crate::offer::queries::Offer;
use cqrs_es::{EventEnvelope, View};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct AllOffersView {
pub struct AllReceivedOffersView {
#[serde(flatten)]
pub offers: HashMap<String, OfferView>,
pub offers: HashMap<String, ReceivedOfferView>,
}

impl View<Offer> for AllOffersView {
impl View<Offer> for AllReceivedOffersView {
fn update(&mut self, event: &EventEnvelope<Offer>) {
self.offers
// Get the entry for the aggregate_id
Expand Down
4 changes: 2 additions & 2 deletions agent_holder/src/offer/queries/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct OfferView {
pub struct ReceivedOfferView {
pub credential_offer: Option<CredentialOfferParameters>,
pub status: Status,
pub credential_configurations: Option<HashMap<String, CredentialConfigurationsSupportedObject>>,
pub token_response: Option<TokenResponse>,
pub credentials: Vec<serde_json::Value>,
}

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

Expand Down
Loading

0 comments on commit d284e8a

Please sign in to comment.