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 AGENT_ISSUANCE_CREDENTIAL_LOGO_URL and test feature flag #11

Merged
merged 11 commits into from
Dec 21, 2023
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
AGENT_CONFIG_LOG_FORMAT=json
AGENT_CONFIG_EVENT_STORE=postgres
AGENT_APPLICATION_HOST=my-domain.example.org
AGENT_ISSUANCE_CREDENTIAL_NAME="Demo Credential"
AGENT_ISSUANCE_CREDENTIAL_LOGO_URL=https://my-domain.example.org/credential_logo.png
AGENT_STORE_DB_CONNECTION_STRING=postgresql://demo_user:demo_pass@localhost:5432/demo
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions agent_api_rest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ serde_json.workspace = true
tracing.workspace = true

[dev-dependencies]
agent_shared = { path = "../agent_shared", features = ["test"] }
agent_store = { path = "../agent_store" }

lazy_static.workspace = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,23 @@ mod tests {
startup_commands::{create_credentials_supported, load_credential_issuer_metadata},
state::{initialize, CQRS},
};
use agent_shared::config;
use agent_store::in_memory;
use axum::{
body::Body,
http::{self, Request},
};
use serde_json::{json, Value};
use oid4vci::{
credential_format_profiles::{
w3c_verifiable_credentials::jwt_vc_json::{CredentialDefinition, JwtVcJson},
CredentialFormats, Parameters,
},
credential_issuer::{
credential_issuer_metadata::CredentialIssuerMetadata, credentials_supported::CredentialsSupportedObject,
},
ProofType,
};
use serde_json::json;
use tower::ServiceExt;

#[tokio::test]
Expand Down Expand Up @@ -73,31 +84,41 @@ mod tests {
assert_eq!(response.status(), StatusCode::OK);

let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
let body: Value = serde_json::from_slice(&body).unwrap();
let cfredential_issuer_metadata: CredentialIssuerMetadata = serde_json::from_slice(&body).unwrap();
nanderstabel marked this conversation as resolved.
Show resolved Hide resolved
assert_eq!(
body,
json!({
"credential_issuer": "https://example.com/",
"credential_endpoint": "https://example.com/openid4vci/credential",
"credentials_supported": [{
"format": "jwt_vc_json",
"cryptographic_binding_methods_supported": [
"did:key"
],
"cryptographic_suites_supported": [
"EdDSA"
],
"credential_definition":{
"type": [
"VerifiableCredential",
"OpenBadgeCredential"
]
},
"proof_types_supported": [
"jwt"
]
}]
})
cfredential_issuer_metadata,
CredentialIssuerMetadata {
credential_issuer: BASE_URL.clone(),
authorization_server: None,
credential_endpoint: BASE_URL.join("openid4vci/credential").unwrap(),
batch_credential_endpoint: None,
deferred_credential_endpoint: None,
credentials_supported: vec![CredentialsSupportedObject {
id: None,
credential_format: CredentialFormats::JwtVcJson(Parameters {
format: JwtVcJson,
parameters: (
CredentialDefinition {
type_: vec!["VerifiableCredential".to_string(), "OpenBadgeCredential".to_string()],
credential_subject: None,
},
None,
)
.into(),
}),
scope: None,
cryptographic_binding_methods_supported: Some(vec!["did:key".to_string()]),
cryptographic_suites_supported: Some(vec!["EdDSA".to_string()]),
proof_types_supported: Some(vec![ProofType::Jwt]),
display: Some(vec![json!({
"name": config!("credential_name").unwrap(),
"logo": {
"url": config!("credential_logo_url").unwrap()
}
})]),
}],
display: None,
}
);
}
}
6 changes: 3 additions & 3 deletions agent_issuance/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ impl View<IssuanceData> for IssuanceDataView {
.replace(credential_offer.clone());
}
UnsignedCredentialCreated { subject_id, credential } => {
if let Some(subject) = self.subjects
.iter_mut()
.find(|subject| subject.id == *subject_id) { subject.credentials.replace(credential.clone()); }
if let Some(subject) = self.subjects.iter_mut().find(|subject| subject.id == *subject_id) {
subject.credentials.replace(credential.clone());
}
}
PreAuthorizedCodeUpdated {
subject_id,
Expand Down
9 changes: 8 additions & 1 deletion agent_issuance/src/startup_commands.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use agent_shared::config;
use oid4vci::{
credential_format_profiles::{
w3c_verifiable_credentials::jwt_vc_json::{CredentialDefinition, JwtVcJson},
Expand All @@ -9,6 +10,7 @@ use oid4vci::{
},
ProofType,
};
use serde_json::json;

use crate::command::IssuanceCommand;

Expand Down Expand Up @@ -74,7 +76,12 @@ pub fn create_credentials_supported() -> IssuanceCommand {
cryptographic_binding_methods_supported: Some(vec!["did:key".to_string()]),
cryptographic_suites_supported: Some(vec!["EdDSA".to_string()]),
proof_types_supported: Some(vec![ProofType::Jwt]),
display: None,
display: Some(vec![json!({
"name": config!("credential_name").unwrap(),
"logo": {
"url": config!("credential_logo_url").unwrap()
}
})]),
}],
}
}
3 changes: 3 additions & 0 deletions agent_shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ edition = "2021"
config = { version = "0.13" }
dotenvy = { version = "0.15" }
tracing.workspace = true

[features]
test = []
33 changes: 25 additions & 8 deletions agent_shared/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
use tracing::info;

/// Read environment variables
#[allow(unused)]
pub fn config(package_name: &str) -> config::Config {
// Load global .env file
dotenvy::dotenv().ok();
#[cfg(feature = "test")]
let config = test_config();

// Build configuration
let config = config::Config::builder()
.add_source(config::Environment::with_prefix(package_name))
.add_source(config::Environment::with_prefix("AGENT_CONFIG"))
.build()
.unwrap();
#[cfg(not(feature = "test"))]
let config = {
dotenvy::dotenv().ok();

config::Config::builder()
.add_source(config::Environment::with_prefix(package_name))
.add_source(config::Environment::with_prefix("AGENT_CONFIG"))
.build()
.unwrap()
};

info!("{:?}", config);

config
}

/// Read environment variables for tests that can be used across packages
#[cfg(feature = "test")]
fn test_config() -> config::Config {
dotenvy::from_filename("agent_shared/tests/.env.test").ok();

config::Config::builder()
.add_source(config::Environment::with_prefix("TEST"))
.add_source(config::Environment::with_prefix("AGENT_CONFIG"))
.build()
.unwrap()
}
4 changes: 3 additions & 1 deletion agent_shared/tests/.env.test
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
AGENT_SHARED_VARIABLE=env_value
TEST_VARIABLE=env_value
AGENT_CONFIG_GLOBAL_VARIABLE=global_env_value
AGENT_OTHER_OTHER_VARIABLE=other_env_value
TEST_CREDENTIAL_NAME="Demo Credential"
TEST_CREDENTIAL_LOGO_URL=https://my-domain.example.org/credential_logo.png
3 changes: 1 addition & 2 deletions agent_shared/tests/config.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use agent_shared::config;

#[cfg(feature = "test")]
#[test]
fn test_config() {
dotenvy::from_filename("tests/.env.test").ok();

assert_eq!(config!("variable").unwrap(), "env_value");
assert_eq!(config!("global_variable").unwrap(), "global_env_value");
// Reading from an environment variable that belongs to another package should fail.
Expand Down