Skip to content

Commit

Permalink
feat: add default_subject_syntax_type
Browse files Browse the repository at this point in the history
  • Loading branch information
nanderstabel committed Apr 9, 2024
1 parent 3a9dc39 commit 13f24f5
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 27 deletions.
2 changes: 1 addition & 1 deletion oid4vc-manager/src/managers/presentation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use oid4vp::{
// TODO: make VP/VC fromat agnostic. In current form only jwt_vp_json + jwt_vc_json are supported.
pub fn create_presentation_submission(
presentation_definition: &PresentationDefinition,
credentials: Vec<serde_json::Value>,
credentials: &Vec<serde_json::Value>,
) -> Result<PresentationSubmission> {
let id = "Submission ID".to_string();
let definition_id = presentation_definition.id().clone();
Expand Down
9 changes: 6 additions & 3 deletions oid4vc-manager/src/managers/relying_party.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use oid4vc_core::{
authorization_request::{AuthorizationRequest, Object},
authorization_response::AuthorizationResponse,
openid4vc_extension::{Extension, ResponseHandle},
Subject,
Subject, SubjectSyntaxType,
};
use siopv2::RelyingParty;
use std::sync::Arc;
Expand All @@ -14,9 +14,12 @@ pub struct RelyingPartyManager {
}

impl RelyingPartyManager {
pub fn new(subject: Arc<dyn Subject>, subject_syntax_type: String) -> Result<Self> {
pub fn new(
subject: Arc<dyn Subject>,
default_subject_syntax_type: impl TryInto<SubjectSyntaxType>,
) -> Result<Self> {
Ok(Self {
relying_party: RelyingParty::new(subject, subject_syntax_type)?,
relying_party: RelyingParty::new(subject, default_subject_syntax_type)?,
})
}

Expand Down
3 changes: 1 addition & 2 deletions oid4vc-manager/src/methods/key_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ mod tests {
.unwrap();

// Let the relying party validate the authorization_response.
let relying_party_manager =
RelyingPartyManager::new(Arc::new(KeySubject::new()), "did:key".to_string()).unwrap();
let relying_party_manager = RelyingPartyManager::new(Arc::new(KeySubject::new()), "did:key").unwrap();
assert!(relying_party_manager
.validate_response(&authorization_response)
.await
Expand Down
2 changes: 1 addition & 1 deletion oid4vc-manager/tests/oid4vci/authorization_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ async fn test_authorization_code_flow() {
let subject_did = subject.identifier("did:key").unwrap();

// Create a new wallet.
let wallet = Wallet::new(Arc::new(subject), "did:key".to_string());
let wallet = Wallet::new(Arc::new(subject), "did:key").unwrap();

// Get the credential issuer url.
let credential_issuer_url = credential_issuer
Expand Down
2 changes: 1 addition & 1 deletion oid4vc-manager/tests/oid4vci/pre_authorized_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async fn test_pre_authorized_code_flow(#[case] batch: bool, #[case] by_reference
let subject_did = subject.identifier("did:key").unwrap();

// Create a new wallet.
let wallet: Wallet = Wallet::new(Arc::new(subject), "did:key".to_string());
let wallet: Wallet = Wallet::new(Arc::new(subject), "did:key").unwrap();

// Get the credential offer url.
let credential_offer_query = credential_issuer
Expand Down
4 changes: 2 additions & 2 deletions oid4vc-manager/tests/oid4vp/implicit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ async fn test_implicit_flow() {
// Create a new relying party.
let relying_party = Arc::new(KeySubject::new());
let relying_party_did = relying_party.identifier("did:key").unwrap();
let relying_party_manager = RelyingPartyManager::new(relying_party, "did:key".to_string()).unwrap();
let relying_party_manager = RelyingPartyManager::new(relying_party, "did:key").unwrap();

// Create authorization request with response_type `id_token vp_token`
let authorization_request = AuthorizationRequest::<Object<OID4VP>>::builder()
Expand Down Expand Up @@ -134,7 +134,7 @@ async fn test_implicit_flow() {
// Create presentation submission using the presentation definition and the verifiable credential.
let presentation_submission = create_presentation_submission(
&PRESENTATION_DEFINITION,
vec![serde_json::to_value(&verifiable_credential).unwrap()],
&vec![serde_json::to_value(&verifiable_credential).unwrap()],
)
.unwrap();

Expand Down
2 changes: 1 addition & 1 deletion oid4vc-manager/tests/siopv2/implicit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ async fn test_implicit_flow() {
};

// Create a new relying party manager.
let relying_party_manager = RelyingPartyManager::new(Arc::new(subject), "did:test".to_string()).unwrap();
let relying_party_manager = RelyingPartyManager::new(Arc::new(subject), "did:test").unwrap();

// Create a new RequestUrl with response mode `direct_post` for cross-device communication.
let authorization_request: AuthorizationRequest<Object<SIOPv2>> = AuthorizationRequest::<Object<SIOPv2>>::builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use serde_with::skip_serializing_none;

/// Credentials Supported object as described here: https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0-13.html#section-11.2.3-2.11.1
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
pub struct CredentialConfigurationsSupportedObject<CFC = CredentialFormats<WithParameters>>
where
CFC: CredentialFormatCollection,
Expand Down
26 changes: 16 additions & 10 deletions oid4vci/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::proof::{KeyProofType, ProofType};
use crate::{credential_response::CredentialResponse, token_request::TokenRequest, token_response::TokenResponse};
use anyhow::Result;
use oid4vc_core::authentication::subject::SigningSubject;
use oid4vc_core::SubjectSyntaxType;
use reqwest::Url;
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
use reqwest_retry::policies::ExponentialBackoff;
Expand All @@ -23,23 +24,28 @@ where
CFC: CredentialFormatCollection,
{
pub subject: SigningSubject,
pub default_subject_syntax_type: String,
pub default_subject_syntax_type: SubjectSyntaxType,
pub client: ClientWithMiddleware,
phantom: std::marker::PhantomData<CFC>,
}

impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
pub fn new(subject: SigningSubject, default_subject_syntax_type: String) -> Self {
pub fn new(
subject: SigningSubject,
default_subject_syntax_type: impl TryInto<SubjectSyntaxType>,
) -> anyhow::Result<Self> {
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(5);
let client = ClientBuilder::new(reqwest::Client::new())
.with(RetryTransientMiddleware::new_with_policy(retry_policy))
.build();
Self {
Ok(Self {
subject,
default_subject_syntax_type,
default_subject_syntax_type: default_subject_syntax_type
.try_into()
.map_err(|_| anyhow::anyhow!("Invalid did method"))?,
client,
phantom: std::marker::PhantomData,
}
})
}

pub async fn get_credential_offer(&self, credential_offer_uri: Url) -> Result<CredentialOfferParameters> {
Expand Down Expand Up @@ -107,7 +113,7 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
// TODO: must be `form`, but `AuthorizationRequest needs to be able to serilalize properly.
.json(&AuthorizationRequest {
response_type: "code".to_string(),
client_id: self.subject.identifier(&self.default_subject_syntax_type)?,
client_id: self.subject.identifier(&self.default_subject_syntax_type.to_string())?,
redirect_uri: None,
scope: None,
state: None,
Expand Down Expand Up @@ -143,7 +149,7 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
KeyProofType::builder()
.proof_type(ProofType::Jwt)
.signer(self.subject.clone())
.iss(self.subject.identifier(&self.default_subject_syntax_type)?)
.iss(self.subject.identifier(&self.default_subject_syntax_type.to_string())?)
.aud(credential_issuer_metadata.credential_issuer)
.iat(1571324800)
.exp(9999999999i64)
Expand All @@ -155,7 +161,7 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
.ok_or(anyhow::anyhow!("No c_nonce found."))?
.clone(),
)
.subject_syntax_type(&self.default_subject_syntax_type)
.subject_syntax_type(&self.default_subject_syntax_type.to_string())
.build()?,
),
};
Expand All @@ -181,7 +187,7 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
KeyProofType::builder()
.proof_type(ProofType::Jwt)
.signer(self.subject.clone())
.iss(self.subject.identifier(&self.default_subject_syntax_type)?)
.iss(self.subject.identifier(&self.default_subject_syntax_type.to_string())?)
.aud(credential_issuer_metadata.credential_issuer)
.iat(1571324800)
.exp(9999999999i64)
Expand All @@ -193,7 +199,7 @@ impl<CFC: CredentialFormatCollection + DeserializeOwned> Wallet<CFC> {
.ok_or(anyhow::anyhow!("No c_nonce found."))?
.clone(),
)
.subject_syntax_type(&self.default_subject_syntax_type)
.subject_syntax_type(&self.default_subject_syntax_type.to_string())
.build()?,
);

Expand Down
12 changes: 7 additions & 5 deletions siopv2/src/relying_party.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,26 @@ use oid4vc_core::{
authorization_response::AuthorizationResponse,
jwt,
openid4vc_extension::{Extension, ResponseHandle},
Validator,
SubjectSyntaxType, Validator,
};
use std::collections::HashMap;

pub struct RelyingParty {
// TODO: Strictly speaking a relying party doesn't need to have a [`Subject`]. It just needs methods to
// sign and verify tokens. For simplicity we use a [`Subject`] here for now but we should consider a cleaner solution.
pub subject: SigningSubject,
pub default_subject_syntax_type: String,
pub default_subject_syntax_type: SubjectSyntaxType,
pub sessions: HashMap<(String, String), AuthorizationRequest<Object<SIOPv2>>>,
}

impl RelyingParty {
// TODO: Use RelyingPartyBuilder instead.
pub fn new(subject: SigningSubject, default_subject_syntax_type: String) -> Result<Self> {
pub fn new(subject: SigningSubject, default_subject_syntax_type: impl TryInto<SubjectSyntaxType>) -> Result<Self> {
Ok(RelyingParty {
subject,
default_subject_syntax_type,
default_subject_syntax_type: default_subject_syntax_type
.try_into()
.map_err(|_| anyhow::anyhow!("Invalid did method."))?,
sessions: HashMap::new(),
})
}
Expand All @@ -34,7 +36,7 @@ impl RelyingParty {
self.subject.clone(),
Header::new(Algorithm::EdDSA),
authorization_request,
&self.default_subject_syntax_type,
&self.default_subject_syntax_type.to_string(),
)
}

Expand Down

0 comments on commit 13f24f5

Please sign in to comment.