Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d284e8a

Browse files
Oran-Dannanderstabel
andauthoredOct 3, 2024··
feat: allow querying all offers and all credentials of issuer (#121)
* 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>
1 parent 1a1045d commit d284e8a

File tree

20 files changed

+284
-87
lines changed

20 files changed

+284
-87
lines changed
 

‎agent_api_rest/postman/ssi-agent.postman_collection.json

+80
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,46 @@
118118
},
119119
"response": []
120120
},
121+
{
122+
"name": "all_credentials",
123+
"event": [
124+
{
125+
"listen": "test",
126+
"script": {
127+
"exec": [
128+
""
129+
],
130+
"type": "text/javascript",
131+
"packages": {}
132+
}
133+
},
134+
{
135+
"listen": "prerequest",
136+
"script": {
137+
"exec": [
138+
""
139+
],
140+
"type": "text/javascript",
141+
"packages": {}
142+
}
143+
}
144+
],
145+
"request": {
146+
"method": "GET",
147+
"header": [],
148+
"url": {
149+
"raw": "{{HOST}}/v0/credentials",
150+
"host": [
151+
"{{HOST}}"
152+
],
153+
"path": [
154+
"v0",
155+
"credentials"
156+
]
157+
}
158+
},
159+
"response": []
160+
},
121161
{
122162
"name": "offers",
123163
"event": [
@@ -177,6 +217,46 @@
177217
},
178218
"response": []
179219
},
220+
{
221+
"name": "all_offers",
222+
"event": [
223+
{
224+
"listen": "test",
225+
"script": {
226+
"exec": [
227+
""
228+
],
229+
"type": "text/javascript",
230+
"packages": {}
231+
}
232+
},
233+
{
234+
"listen": "prerequest",
235+
"script": {
236+
"exec": [
237+
""
238+
],
239+
"type": "text/javascript",
240+
"packages": {}
241+
}
242+
}
243+
],
244+
"request": {
245+
"method": "GET",
246+
"header": [],
247+
"url": {
248+
"raw": "{{HOST}}/v0/offers",
249+
"host": [
250+
"{{HOST}}"
251+
],
252+
"path": [
253+
"v0",
254+
"offers"
255+
]
256+
}
257+
},
258+
"response": []
259+
},
180260
{
181261
"name": "offers_send",
182262
"request": {

‎agent_api_rest/src/holder/holder/credentials/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use serde_json::json;
1010

1111
#[axum_macros::debug_handler]
1212
pub(crate) async fn credentials(State(state): State<HolderState>) -> Response {
13-
match query_handler("all_credentials", &state.query.all_credentials).await {
13+
match query_handler("all_holder_credentials", &state.query.all_holder_credentials).await {
1414
Ok(Some(all_credentials_view)) => (StatusCode::OK, Json(all_credentials_view)).into_response(),
1515
Ok(None) => (StatusCode::OK, Json(json!({}))).into_response(),
1616
_ => StatusCode::INTERNAL_SERVER_ERROR.into_response(),

‎agent_api_rest/src/holder/holder/offers/accept.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use agent_holder::{
22
credential::command::CredentialCommand,
3-
offer::{command::OfferCommand, queries::OfferView},
3+
offer::{command::OfferCommand, queries::ReceivedOfferView},
44
state::HolderState,
55
};
66
use agent_shared::handlers::{command_handler, query_handler};
@@ -18,8 +18,8 @@ pub(crate) async fn accept(State(state): State<HolderState>, Path(offer_id): Pat
1818
// Furthermore, the Application Layer (not implemented yet) should be kept very thin as well. See: https://github.com/impierce/ssi-agent/issues/114
1919

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

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

‎agent_api_rest/src/holder/holder/offers/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use serde_json::json;
1313

1414
#[axum_macros::debug_handler]
1515
pub(crate) async fn offers(State(state): State<HolderState>) -> Response {
16-
match query_handler("all_offers", &state.query.all_offers).await {
16+
match query_handler("all_received_offers", &state.query.all_received_offers).await {
1717
Ok(Some(all_offers_view)) => (StatusCode::OK, Json(all_offers_view)).into_response(),
1818
Ok(None) => (StatusCode::OK, Json(json!({}))).into_response(),
1919
_ => StatusCode::INTERNAL_SERVER_ERROR.into_response(),

‎agent_api_rest/src/issuance/credentials.rs

+11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use serde::{Deserialize, Serialize};
1717
use serde_json::Value;
1818
use tracing::info;
1919

20+
use serde_json::json;
21+
2022
#[axum_macros::debug_handler]
2123
pub(crate) async fn get_credentials(State(state): State<IssuanceState>, Path(credential_id): Path<String>) -> Response {
2224
// Get the credential if it exists.
@@ -160,6 +162,15 @@ pub(crate) async fn credentials(
160162
}
161163
}
162164

165+
#[axum_macros::debug_handler]
166+
pub(crate) async fn all_credentials(State(state): State<IssuanceState>) -> Response {
167+
match query_handler("all_credentials", &state.query.all_credentials).await {
168+
Ok(Some(all_credentials_view)) => (StatusCode::OK, Json(all_credentials_view)).into_response(),
169+
Ok(None) => (StatusCode::OK, Json(json!({}))).into_response(),
170+
_ => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
171+
}
172+
}
173+
163174
#[cfg(test)]
164175
pub mod tests {
165176
use super::*;

‎agent_api_rest/src/issuance/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ pub mod offers;
55
use agent_issuance::state::IssuanceState;
66
use axum::routing::get;
77
use axum::{routing::post, Router};
8+
use credentials::all_credentials;
9+
use offers::all_offers;
810

911
use crate::issuance::{
1012
credential_issuer::{
@@ -21,9 +23,9 @@ pub fn router(issuance_state: IssuanceState) -> Router {
2123
.nest(
2224
API_VERSION,
2325
Router::new()
24-
.route("/credentials", post(credentials))
26+
.route("/credentials", post(credentials).get(all_credentials))
2527
.route("/credentials/:credential_id", get(get_credentials))
26-
.route("/offers", post(offers))
28+
.route("/offers", post(offers).get(all_offers))
2729
.route("/offers/send", post(send)),
2830
)
2931
.route(

‎agent_api_rest/src/issuance/offers/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use axum::{
1313
};
1414
use hyper::header;
1515
use serde::{Deserialize, Serialize};
16+
use serde_json::json;
1617
use serde_json::Value;
1718
use tracing::info;
1819

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

85+
#[axum_macros::debug_handler]
86+
pub(crate) async fn all_offers(State(state): State<IssuanceState>) -> Response {
87+
match query_handler("all_offers", &state.query.all_offers).await {
88+
Ok(Some(all_offers_view)) => (StatusCode::OK, Json(all_offers_view)).into_response(),
89+
Ok(None) => (StatusCode::OK, Json(json!({}))).into_response(),
90+
_ => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
91+
}
92+
}
93+
8494
#[cfg(test)]
8595
pub mod tests {
8696
use super::*;

‎agent_application/docker/db/init.sql

+18-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ CREATE TABLE offer
1818
PRIMARY KEY (view_id)
1919
);
2020

21+
CREATE TABLE all_offers
22+
(
23+
view_id text NOT NULL,
24+
version bigint CHECK (version >= 0) NOT NULL,
25+
payload json NOT NULL,
26+
PRIMARY KEY (view_id)
27+
);
28+
2129
CREATE TABLE pre_authorized_code
2230
(
2331
view_id text NOT NULL,
@@ -42,6 +50,14 @@ CREATE TABLE credential
4250
PRIMARY KEY (view_id)
4351
);
4452

53+
CREATE TABLE all_credentials
54+
(
55+
view_id text NOT NULL,
56+
version bigint CHECK (version >= 0) NOT NULL,
57+
payload json NOT NULL,
58+
PRIMARY KEY (view_id)
59+
);
60+
4561
CREATE TABLE server_config
4662
(
4763
view_id text NOT NULL,
@@ -58,7 +74,7 @@ CREATE TABLE received_offer
5874
PRIMARY KEY (view_id)
5975
);
6076

61-
CREATE TABLE all_offers
77+
CREATE TABLE all_received_offers
6278
(
6379
view_id text NOT NULL,
6480
version bigint CHECK (version >= 0) NOT NULL,
@@ -75,7 +91,7 @@ CREATE TABLE holder_credential
7591
);
7692

7793

78-
CREATE TABLE all_credentials
94+
CREATE TABLE all_holder_credentials
7995
(
8096
view_id text NOT NULL,
8197
version bigint CHECK (version >= 0) NOT NULL,

‎agent_holder/src/credential/queries/all_credentials.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
use super::CredentialView;
1+
use super::HolderCredentialView;
22
use crate::credential::queries::Credential;
33
use cqrs_es::{EventEnvelope, View};
44
use serde::{Deserialize, Serialize};
55
use std::collections::HashMap;
66

77
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
8-
pub struct AllCredentialsView {
8+
pub struct AllHolderCredentialsView {
99
#[serde(flatten)]
10-
pub credentials: HashMap<String, CredentialView>,
10+
pub credentials: HashMap<String, HolderCredentialView>,
1111
}
1212

13-
impl View<Credential> for AllCredentialsView {
13+
impl View<Credential> for AllHolderCredentialsView {
1414
fn update(&mut self, event: &EventEnvelope<Credential>) {
1515
self.credentials
1616
// Get the entry for the aggregate_id

‎agent_holder/src/credential/queries/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ use cqrs_es::{EventEnvelope, View};
66
use serde::{Deserialize, Serialize};
77

88
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
9-
pub struct CredentialView {
9+
pub struct HolderCredentialView {
1010
pub credential_id: Option<String>,
1111
pub offer_id: Option<String>,
1212
pub credential: Option<serde_json::Value>,
1313
}
1414

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

‎agent_holder/src/offer/queries/all_offers.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
use super::OfferView;
1+
use super::ReceivedOfferView;
22
use crate::offer::queries::Offer;
33
use cqrs_es::{EventEnvelope, View};
44
use serde::{Deserialize, Serialize};
55
use std::collections::HashMap;
66

77
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
8-
pub struct AllOffersView {
8+
pub struct AllReceivedOffersView {
99
#[serde(flatten)]
10-
pub offers: HashMap<String, OfferView>,
10+
pub offers: HashMap<String, ReceivedOfferView>,
1111
}
1212

13-
impl View<Offer> for AllOffersView {
13+
impl View<Offer> for AllReceivedOffersView {
1414
fn update(&mut self, event: &EventEnvelope<Offer>) {
1515
self.offers
1616
// Get the entry for the aggregate_id

‎agent_holder/src/offer/queries/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ use serde::{Deserialize, Serialize};
1111
use std::collections::HashMap;
1212

1313
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
14-
pub struct OfferView {
14+
pub struct ReceivedOfferView {
1515
pub credential_offer: Option<CredentialOfferParameters>,
1616
pub status: Status,
1717
pub credential_configurations: Option<HashMap<String, CredentialConfigurationsSupportedObject>>,
1818
pub token_response: Option<TokenResponse>,
1919
pub credentials: Vec<serde_json::Value>,
2020
}
2121

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

There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Please sign in to comment.