Skip to content

Commit

Permalink
use typed parameters for accessing client metadata fields
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Tate <[email protected]>
  • Loading branch information
Ryanmtate committed Dec 1, 2024
1 parent 7f0833a commit 6e881de
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 48 deletions.
69 changes: 21 additions & 48 deletions src/core/authorization_request/parameters.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
use std::{fmt, ops::Deref};

use crate::core::{
metadata::parameters::verifier::VpFormats,
metadata::parameters::{
verifier::{JWKs, VpFormats},
wallet::{
AuthorizationEncryptedResponseAlg, AuthorizationEncryptedResponseEnc,
AuthorizationSignedResponseAlg,
},
},
object::{ParsingErrorContext, TypedParameter, UntypedObject},
presentation_definition::PresentationDefinition as PresentationDefinitionParsed,
util::{base_request, AsyncHttpClient},
Expand Down Expand Up @@ -207,13 +213,8 @@ impl ClientMetadata {
///
/// See: https://openid.net/specs/oauth-v2-jarm-final.html#section-3-4
///
pub fn jwks(&self) -> Option<Vec<JWK>> {
self.0 .0.get("jwks").and_then(|j| j.as_array()).map(|j| {
j.iter()
// NOTE: we're ignoring the errors here, but may wish to handle the errors in the future.
.filter_map(|jwk| serde_json::from_value(jwk.clone()).ok())
.collect()
})
pub fn jwks(&self) -> Option<Result<JWKs, Error>> {
self.0.get()
}

/// Return the `VpFormats` from the `client_metadata` field.
Expand Down Expand Up @@ -249,22 +250,12 @@ impl ClientMetadata {
/// See: https://openid.net/specs/oauth-v2-jarm-final.html#section-3-3.2.1
/// See: https://datatracker.ietf.org/doc/html/rfc7518#section-3.1
///
pub fn authorization_signed_response_alg(&self) -> Result<ssi::crypto::Algorithm, Error> {
let alg = self
.0
.0
.get("authorization_signed_response_alg")
.map(ToOwned::to_owned)
.map(serde_json::from_value)
.transpose()
.map_err(|e| {
anyhow!("Failed to parse `authorization_signed_response_alg` algorithm: {e:?}")
})?
// NOTE: If this `authorization_signed_response_alg` is undefined, the default value
// is RS256.
.unwrap_or(ssi::crypto::Algorithm::RS256);

Ok(alg)
pub fn authorization_signed_response_alg(
&self,
) -> Result<AuthorizationSignedResponseAlg, Error> {
self.0.get().unwrap_or(Ok(AuthorizationSignedResponseAlg(
ssi::crypto::Algorithm::RS256,
)))
}

/// OPTIONAL. As defined in [JARM](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#JARM).
Expand All @@ -286,17 +277,8 @@ impl ClientMetadata {
///
pub fn authorization_encrypted_response_alg(
&self,
) -> Option<Result<ssi::crypto::Algorithm, Error>> {
self.0
.0
.get("authorization_encrypted_response_alg")
.map(|value| {
serde_json::from_value(value.clone()).map_err(|e| {
anyhow!(
"Failed to parse `authorization_encrypted_response_alg` algorithm: {e:?}"
)
})
})
) -> Option<Result<AuthorizationEncryptedResponseAlg, Error>> {
self.0.get()
}

/// OPTIONAL. As defined in [JARM](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#JARM).
Expand All @@ -315,21 +297,12 @@ impl ClientMetadata {
///
pub fn authorization_encrypted_response_enc(
&self,
// TODO: ssi::crypto lacks an encryption algorithm enum type,
// which we may want to create for use cases like this one.
//
// Using a string type here in the interim.
) -> Option<String> {
match self.0 .0.get("authorization_encrypted_response_enc") {
// NOTE: ignoring the error of casting the value to a string,
// if it fails, then this will return a None value.
//
// We may wish to handle this error explicitly, instead of
// ignoring.
Some(value) => serde_json::to_string(value).ok(),
) -> Option<Result<AuthorizationEncryptedResponseEnc, Error>> {
match self.0.get() {
Some(enc) => Some(enc),
None => self
.authorization_encrypted_response_alg()
.map(|_| "A128CBC-HS256".into()),
.map(|_| Ok(AuthorizationEncryptedResponseEnc("A128CBC-HS256".into()))),
}
}
}
Expand Down
67 changes: 67 additions & 0 deletions src/core/metadata/parameters/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,73 @@ impl From<AuthorizationEncryptionEncValuesSupported> for Json {
}
}

#[derive(Debug, Clone)]
pub struct AuthorizationSignedResponseAlg(pub ssi::crypto::Algorithm);

impl TypedParameter for AuthorizationSignedResponseAlg {
const KEY: &'static str = "authorization_signed_response_alg";
}

impl TryFrom<Json> for AuthorizationSignedResponseAlg {
type Error = Error;

fn try_from(value: Json) -> Result<Self, Self::Error> {
Ok(Self(serde_json::from_value(value)?))
}
}

impl From<AuthorizationSignedResponseAlg> for Json {
fn from(value: AuthorizationSignedResponseAlg) -> Json {
Json::String(value.0.to_string())
}
}

#[derive(Debug, Clone)]
pub struct AuthorizationEncryptedResponseAlg(pub ssi::crypto::Algorithm);

impl TypedParameter for AuthorizationEncryptedResponseAlg {
const KEY: &'static str = "authorization_encrypted_response_alg";
}

impl TryFrom<Json> for AuthorizationEncryptedResponseAlg {
type Error = Error;

fn try_from(value: Json) -> Result<Self, Self::Error> {
Ok(Self(serde_json::from_value(value)?))
}
}

impl From<AuthorizationEncryptedResponseAlg> for Json {
fn from(value: AuthorizationEncryptedResponseAlg) -> Json {
Json::String(value.0.to_string())
}
}

// TODO: ssi::crypto lacks an encryption algorithm enum type,
// which we may want to create for use cases like this one.
//
// Using a string type here in the interim.
#[derive(Debug, Clone)]
pub struct AuthorizationEncryptedResponseEnc(pub String);

impl TypedParameter for AuthorizationEncryptedResponseEnc {
const KEY: &'static str = "authorization_encrypted_response_enc";
}

impl TryFrom<Json> for AuthorizationEncryptedResponseEnc {
type Error = Error;

fn try_from(value: Json) -> Result<Self, Self::Error> {
Ok(Self(serde_json::from_value(value)?))
}
}

impl From<AuthorizationEncryptedResponseEnc> for Json {
fn from(value: AuthorizationEncryptedResponseEnc) -> Json {
Json::String(value.0)
}
}

#[cfg(test)]
mod test {
use serde_json::json;
Expand Down

0 comments on commit 6e881de

Please sign in to comment.