Skip to content

Commit 5fb9dda

Browse files
committed
Refactor IsVpFormatsSupported and add unit tests
Signed-off-by: Johannes Tuerk <johannes.tuerk@lissi.id>
1 parent 9810c5a commit 5fb9dda

File tree

4 files changed

+371
-79
lines changed

4 files changed

+371
-79
lines changed

src/WalletFramework.Oid4Vc/Oid4Vp/Models/ClientMetadata.cs

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using LanguageExt;
22
using Newtonsoft.Json;
3+
using OneOf;
4+
using WalletFramework.Oid4Vc.Oid4Vp.Dcql.Models;
35
using WalletFramework.Oid4Vc.Oid4Vp.Jwk;
6+
using WalletFramework.Oid4Vc.Oid4Vp.PresentationExchange.Models;
47

58
namespace WalletFramework.Oid4Vc.Oid4Vp.Models;
69

@@ -110,11 +113,87 @@ public ClientMetadata(
110113
/// </summary>
111114
[Obsolete("This property is obsolete.")]
112115
[JsonProperty("vp_formats")]
113-
public Formats VpFormats { get; init; }
116+
public Formats? VpFormats { get; init; }
114117

115118
/// <summary>
116119
/// The URI to a human-readable terms of service document for the client (verifier).
117120
/// </summary>
118121
[JsonProperty("vp_formats_supported")]
119-
public Formats VpFormatsSupported { get; init; }
122+
public Formats? VpFormatsSupported { get; init; }
123+
}
124+
125+
public static class ClientMetadataExtensions
126+
{
127+
public static bool IsVpFormatsSupported(this ClientMetadata clientMetadata, OneOf<DcqlQuery, PresentationDefinition> requirements)
128+
{
129+
return requirements.Match(
130+
dcql =>
131+
{
132+
var walletMetadata = WalletMetadata.CreateDefault();
133+
134+
var (sdJwtRequested, mdocRequested) =
135+
(dcql.CredentialQueries.Any(query => query.Format == Constants.SdJwtDcFormat || query.Format == Constants.SdJwtVcFormat),
136+
dcql.CredentialQueries.Any(query => query.Format == Constants.MdocFormat));
137+
138+
return (sdJwtRequested, mdocRequested) switch
139+
{
140+
(true, false) => IsSdJwtVpFormatSupported(clientMetadata, walletMetadata),
141+
(false, true) => IsMdocVpFormatSupported(clientMetadata, walletMetadata),
142+
(true, true) => IsSdJwtVpFormatSupported(clientMetadata, walletMetadata) &&
143+
IsMdocVpFormatSupported(clientMetadata, walletMetadata),
144+
_ => true
145+
};
146+
},
147+
_ => true);
148+
}
149+
150+
private static bool IsMdocVpFormatSupported(ClientMetadata clientMetadata, WalletMetadata walletMetadata)
151+
{
152+
var rpSupportedVpFormats = clientMetadata.VpFormatsSupported ?? clientMetadata.VpFormats;
153+
var walletMetadataSupportedVpFormats = walletMetadata.VpFormatsSupported;
154+
155+
if (rpSupportedVpFormats?.MDocFormat == null)
156+
return true;
157+
158+
if (rpSupportedVpFormats.MDocFormat.IssuerAuthAlgValues != null &&
159+
!rpSupportedVpFormats.MDocFormat.IssuerAuthAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.MDocFormat!.IssuerAuthAlgValues!.Contains(clientAlg)))
160+
return false;
161+
162+
if (rpSupportedVpFormats.MDocFormat.DeviceAuthAlgValues != null &&
163+
!rpSupportedVpFormats.MDocFormat.DeviceAuthAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.MDocFormat!.DeviceAuthAlgValues!.Contains(clientAlg)))
164+
return false;
165+
166+
return true;
167+
}
168+
169+
private static bool IsSdJwtVpFormatSupported(ClientMetadata clientMetadata, WalletMetadata walletMetadata)
170+
{
171+
var rpSupportedVpFormats = clientMetadata.VpFormatsSupported ?? clientMetadata.VpFormats;
172+
var walletMetadataSupportedVpFormats = walletMetadata.VpFormatsSupported;
173+
174+
if (rpSupportedVpFormats?.SdJwtDcFormat != null)
175+
{
176+
if (rpSupportedVpFormats.SdJwtDcFormat.IssuerSignedJwtAlgValues != null &&
177+
!rpSupportedVpFormats.SdJwtDcFormat.IssuerSignedJwtAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.SdJwtDcFormat!.IssuerSignedJwtAlgValues!.Contains(clientAlg)))
178+
return false;
179+
180+
if (rpSupportedVpFormats.SdJwtDcFormat.KeyBindingJwtAlgValues != null &&
181+
!rpSupportedVpFormats.SdJwtDcFormat.KeyBindingJwtAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.SdJwtDcFormat!.KeyBindingJwtAlgValues!.Contains(clientAlg)))
182+
return false;
183+
}
184+
185+
//TODO: Remove SdJwtVcFormat in the future as it is deprecated (kept for now for backwards compatibility)
186+
if (rpSupportedVpFormats?.SdJwtVcFormat != null)
187+
{
188+
if (rpSupportedVpFormats.SdJwtVcFormat.IssuerSignedJwtAlgValues != null &&
189+
!rpSupportedVpFormats.SdJwtVcFormat.IssuerSignedJwtAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.SdJwtVcFormat!.IssuerSignedJwtAlgValues!.Contains(clientAlg)))
190+
return false;
191+
192+
if (rpSupportedVpFormats.SdJwtVcFormat.KeyBindingJwtAlgValues != null &&
193+
!rpSupportedVpFormats.SdJwtVcFormat.KeyBindingJwtAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.SdJwtVcFormat!.KeyBindingJwtAlgValues!.Contains(clientAlg)))
194+
return false;
195+
}
196+
197+
return true;
198+
}
120199
}

src/WalletFramework.Oid4Vc/Oid4Vp/Services/AuthorizationRequestService.cs

Lines changed: 6 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ private async Task<Validation<AuthorizationRequestCancellation, Option<ClientMet
189189
return await authorizationRequest.ClientMetadata.AsOption().Match(
190190
clientMetadata =>
191191
{
192-
if (!IsVpFormatsSupported(authorizationRequest))
192+
if (clientMetadata.IsVpFormatsSupported(authorizationRequest.Requirements))
193193
{
194194
var error = new VpFormatsNotSupportedError("The provided vp_formats_supported values are not supported");
195195
var authorizationCancellation = new AuthorizationRequestCancellation(authorizationRequest.GetResponseUriMaybe(), [error]);
@@ -210,8 +210,11 @@ private async Task<Validation<AuthorizationRequestCancellation, Option<ClientMet
210210
var response = await httpClient.GetAsync(authorizationRequest.ClientMetadataUri);
211211
var clientMetadataJsonString = await response.Content.ReadAsStringAsync();
212212
var clientMetadata = DeserializeObject<ClientMetadata>(clientMetadataJsonString);
213-
214-
if (!IsVpFormatsSupported(authorizationRequest))
213+
214+
if (clientMetadata == null)
215+
return Option<ClientMetadata>.None;
216+
217+
if (clientMetadata.IsVpFormatsSupported(authorizationRequest.Requirements))
215218
{
216219
var error = new VpFormatsNotSupportedError("The provided vp_formats_supported values are not supported");
217220
var authorizationCancellation = new AuthorizationRequestCancellation(authorizationRequest.GetResponseUriMaybe(), [error]);
@@ -221,78 +224,4 @@ private async Task<Validation<AuthorizationRequestCancellation, Option<ClientMet
221224
return clientMetadata.AsOption();
222225
});
223226
}
224-
225-
226-
private bool IsVpFormatsSupported(AuthorizationRequest authorizationRequest)
227-
{
228-
return authorizationRequest.Requirements.Match(
229-
dcql =>
230-
{
231-
var walletMetadata = WalletMetadata.CreateDefault();
232-
233-
var (sdJwtRequested, mdocRequested) =
234-
(dcql.CredentialQueries.Any(query => query.Format == Constants.SdJwtDcFormat || query.Format == Constants.SdJwtVcFormat),
235-
dcql.CredentialQueries.Any(query => query.Format == Constants.MdocFormat));
236-
237-
return (sdJwtRequested, mdocRequested) switch
238-
{
239-
(true, false) => IsSdJwtVpFormatSupported(authorizationRequest, walletMetadata),
240-
(false, true) => IsMdocVpFormatSupported(authorizationRequest, walletMetadata),
241-
(true, true) => IsSdJwtVpFormatSupported(authorizationRequest, walletMetadata) &&
242-
IsMdocVpFormatSupported(authorizationRequest, walletMetadata),
243-
_ => true
244-
};
245-
},
246-
_ => true);
247-
}
248-
249-
private bool IsMdocVpFormatSupported(AuthorizationRequest authorizationRequest, WalletMetadata walletMetadata)
250-
{
251-
var rpSupportedVpFormats = authorizationRequest.ClientMetadata?.VpFormatsSupported ?? authorizationRequest.ClientMetadata?.VpFormats;
252-
var walletMetadataSupportedVpFormats = walletMetadata.VpFormatsSupported;
253-
254-
if (rpSupportedVpFormats?.MDocFormat == null)
255-
return true;
256-
257-
if (rpSupportedVpFormats.MDocFormat.IssuerAuthAlgValues != null &&
258-
!rpSupportedVpFormats.MDocFormat.IssuerAuthAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.MDocFormat!.IssuerAuthAlgValues!.Contains(clientAlg)))
259-
return false;
260-
261-
if (rpSupportedVpFormats.MDocFormat.DeviceAuthAlgValues != null &&
262-
!rpSupportedVpFormats.MDocFormat.DeviceAuthAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.MDocFormat!.DeviceAuthAlgValues!.Contains(clientAlg)))
263-
return false;
264-
265-
return true;
266-
}
267-
268-
private bool IsSdJwtVpFormatSupported(AuthorizationRequest authorizationRequest, WalletMetadata walletMetadata)
269-
{
270-
var rpSupportedVpFormats = authorizationRequest.ClientMetadata?.VpFormatsSupported ?? authorizationRequest.ClientMetadata?.VpFormats;
271-
var walletMetadataSupportedVpFormats = walletMetadata.VpFormatsSupported;
272-
273-
if (rpSupportedVpFormats?.SdJwtDcFormat != null)
274-
{
275-
if (rpSupportedVpFormats.SdJwtDcFormat.IssuerSignedJwtAlgValues != null &&
276-
!rpSupportedVpFormats.SdJwtDcFormat.IssuerSignedJwtAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.SdJwtDcFormat!.IssuerSignedJwtAlgValues!.Contains(clientAlg)))
277-
return false;
278-
279-
if (rpSupportedVpFormats.SdJwtDcFormat.KeyBindingJwtAlgValues != null &&
280-
!rpSupportedVpFormats.SdJwtDcFormat.KeyBindingJwtAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.SdJwtDcFormat!.KeyBindingJwtAlgValues!.Contains(clientAlg)))
281-
return false;
282-
}
283-
284-
//TODO: Remove SdJwtVcFormat in the future as it is deprecated (kept for now for backwards compatibility)
285-
if (rpSupportedVpFormats?.SdJwtVcFormat != null)
286-
{
287-
if (rpSupportedVpFormats.SdJwtVcFormat.IssuerSignedJwtAlgValues != null &&
288-
!rpSupportedVpFormats.SdJwtVcFormat.IssuerSignedJwtAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.SdJwtVcFormat!.IssuerSignedJwtAlgValues!.Contains(clientAlg)))
289-
return false;
290-
291-
if (rpSupportedVpFormats.SdJwtVcFormat.KeyBindingJwtAlgValues != null &&
292-
!rpSupportedVpFormats.SdJwtVcFormat.KeyBindingJwtAlgValues.Any(clientAlg => walletMetadataSupportedVpFormats.SdJwtVcFormat!.KeyBindingJwtAlgValues!.Contains(clientAlg)))
293-
return false;
294-
}
295-
296-
return true;
297-
}
298227
}

0 commit comments

Comments
 (0)