Skip to content

Commit 4fb7ef5

Browse files
committed
improve vci draft version handling
Signed-off-by: kenkosmowski <ken.kosmowski@gmx.de>
1 parent 4b2cded commit 4fb7ef5

File tree

10 files changed

+86
-46
lines changed

10 files changed

+86
-46
lines changed

src/WalletFramework.Oid4Vc/Oid4Vci/Abstractions/IOid4VciClientService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public interface IOid4VciClientService
3333
/// <param name="credentialType">Specifies whether Sd-Jwt or MDoc should be issued</param>
3434
/// <param name="specVersion">Optional language tag</param>
3535
/// <returns></returns>
36-
Task<Uri> InitiateAuthFlow(Uri uri, ClientOptions clientOptions, Option<Locale> language, Option<OneOf<Vct, DocType>> credentialType, int specVersion);
36+
Task<Uri> InitiateAuthFlow(Uri uri, ClientOptions clientOptions, Option<Locale> language, Option<OneOf<Vct, DocType>> credentialType, Option<int> specVersion);
3737

3838
/// <summary>
3939
/// Requests a verifiable credential using the authorization code flow.

src/WalletFramework.Oid4Vc/Oid4Vci/AuthFlow/Abstractions/IAuthFlowSessionStorage.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Hyperledger.Aries.Agents;
2+
using LanguageExt;
23
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Models;
34
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Records;
45

@@ -51,5 +52,5 @@ Task<string> StoreAsync(
5152
AuthorizationData authorizationData,
5253
AuthorizationCodeParameters authorizationCodeParameters,
5354
AuthFlowSessionState authFlowSessionState,
54-
int specVersion = 15);
55+
Option<int> specVersion);
5556
}

src/WalletFramework.Oid4Vc/Oid4Vci/AuthFlow/Implementations/AuthFlowSessionStorage.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Hyperledger.Aries.Agents;
22
using Hyperledger.Aries.Storage;
3+
using LanguageExt;
34
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Abstractions;
45
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Models;
56
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Records;
@@ -22,18 +23,17 @@ public AuthFlowSessionStorage(IWalletRecordService recordService)
2223
private readonly IWalletRecordService _recordService;
2324

2425
/// <inheritdoc />
25-
public async Task<string> StoreAsync(
26-
IAgentContext agentContext,
26+
public async Task<string> StoreAsync(IAgentContext agentContext,
2727
AuthorizationData authorizationData,
2828
AuthorizationCodeParameters authorizationCodeParameters,
2929
AuthFlowSessionState authFlowSessionState,
30-
int specVersion)
30+
Option<int> specVersion)
3131
{
3232
var record = new AuthFlowSessionRecord(
3333
authorizationData,
3434
authorizationCodeParameters,
3535
authFlowSessionState,
36-
specVersion);
36+
specVersion.ToNullable());
3737

3838
await _recordService.AddAsync(agentContext.Wallet, record);
3939

src/WalletFramework.Oid4Vc/Oid4Vci/AuthFlow/Records/AuthFlowSessionRecord.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public AuthFlowSessionState AuthFlowSessionState
4141
/// <summary>
4242
/// Used to track the VCI Specification verison
4343
/// </summary>
44-
public int SpecVersion { get; }
44+
public int? SpecVersion { get; }
4545

4646
/// <summary>
4747
/// Initializes a new instance of the <see cref="AuthFlowSessionRecord" /> class.
@@ -68,7 +68,7 @@ public AuthFlowSessionRecord(
6868
AuthorizationData authorizationData,
6969
AuthorizationCodeParameters authorizationCodeParameters,
7070
AuthFlowSessionState authFlowSessionState,
71-
int specVersion)
71+
int? specVersion)
7272
{
7373
AuthFlowSessionState = authFlowSessionState;
7474
RecordVersion = 1;
@@ -130,7 +130,7 @@ public static AuthFlowSessionRecord DecodeFromJson(JObject json)
130130
var authorizationData = AuthorizationDataFun
131131
.DecodeFromJson(json[AuthorizationDataJsonKey]!.ToObject<JObject>()!);
132132

133-
var specVersion = json[SpecVersionJsonKey]!.ToObject<int>();
133+
var specVersion = json[SpecVersionJsonKey]!.ToObject<int?>();
134134

135135
var result = new AuthFlowSessionRecord(authorizationData, authCodeParameters!, id, specVersion);
136136

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
using WalletFramework.Core.Functional;
2+
3+
namespace WalletFramework.Oid4Vc.Oid4Vci.CredOffer.Errors;
4+
5+
public record ScopeIsNullOrWhitespaceError()
6+
: Error("The scope is null or whitespace");
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using LanguageExt;
2+
using Newtonsoft.Json.Linq;
3+
using WalletFramework.Core.Functional;
4+
using WalletFramework.Oid4Vc.Oid4Vci.CredConfiguration.Models;
5+
6+
namespace WalletFramework.Oid4Vc.Oid4Vci.CredOffer.Models;
7+
8+
public record ScopedCredentialConfiguration(CredentialConfigurationId CredentialConfigurationId, Option<Scope> Scope);
9+
10+
public static class ScopedCredentialConfigurationExtensions
11+
{
12+
private const string ScopeJsonKey = "scope";
13+
private const string CredentialConfigurationIdJsonKey = "credential_configuration_id";
14+
15+
public static JObject EncodeToJson(this ScopedCredentialConfiguration scopedCredentialConfiguration)
16+
{
17+
return new JObject
18+
{
19+
{ ScopeJsonKey, scopedCredentialConfiguration.Scope.MatchUnsafe(scope => scope.ToString(), () => null) },
20+
{ CredentialConfigurationIdJsonKey, scopedCredentialConfiguration.CredentialConfigurationId.ToString() }
21+
};
22+
}
23+
24+
public static ScopedCredentialConfiguration DecodeFromJson(JObject json)
25+
{
26+
var scope = Scope.OptionalScope(json[ScopeJsonKey]!);
27+
var credentialConfigurationId = CredentialConfigurationId.ValidCredentialConfigurationId(json[CredentialConfigurationIdJsonKey]!.ToString()).UnwrapOrThrow();
28+
29+
return new ScopedCredentialConfiguration(credentialConfigurationId, scope);
30+
}
31+
}

src/WalletFramework.Oid4Vc/Oid4Vci/CredRequest/Abstractions/ICredentialRequestService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ public Task<Validation<IEnumerable<CredentialResponse>>> RequestCredentials(
2020
OneOf<OAuthToken, DPopToken> token,
2121
Option<ClientOptions> clientOptions,
2222
Option<AuthorizationRequest> authorizationRequest,
23-
int specVersion = 15);
23+
Option<int> specVersion);
2424
}

src/WalletFramework.Oid4Vc/Oid4Vci/CredRequest/Implementations/CredentialRequestService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private async Task<CredentialRequest> CreateCredentialRequest(
5151
Format format,
5252
OneOf<CredentialIdentifier, CredentialConfigurationId> credentialIdentification,
5353
OneOf<OAuthToken, DPopToken> token,
54-
int specVersion,
54+
Option<int> specVersion,
5555
IssuerMetadata issuerMetadata,
5656
Option<ClientOptions> clientOptions,
5757
Option<AuthorizationRequest> authorizationRequest)
@@ -139,7 +139,7 @@ async Task<Validation<IEnumerable<CredentialResponse>>> ICredentialRequestServic
139139
OneOf<OAuthToken, DPopToken> token,
140140
Option<ClientOptions> clientOptions,
141141
Option<AuthorizationRequest> authorizationRequest,
142-
int specVersion)
142+
Option<int> specVersion)
143143
{
144144
var credentialIdentifications =
145145
token.Match(

src/WalletFramework.Oid4Vc/Oid4Vci/CredRequest/Models/CredentialRequest.cs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,13 @@ namespace WalletFramework.Oid4Vc.Oid4Vci.CredRequest.Models;
1414
/// This request contains the format of the credential, the type of credential,
1515
/// and a proof of possession of the key material the issued credential shall be bound to.
1616
/// </summary>
17-
public record CredentialRequest(OneOf<CredentialIdentifier, CredentialConfigurationId> CredentialIdentification, Format Format, int specVersion, Option<ProofOfPossession> Proof, Option<ProofsOfPossession> Proofs, Option<SessionTranscript> SessionTranscript)
18-
{
19-
/// <summary>
20-
/// Gets the proof of possession of the key material the issued credential shall be bound to.
21-
/// </summary>
22-
public Option<ProofOfPossession> Proof { get; } = Proof;
23-
24-
/// <summary>
25-
/// Gets one or more proof of possessions of the key material the issued credential shall be bound to.
26-
/// </summary>
27-
public Option<ProofsOfPossession> Proofs { get; } = Proofs;
28-
29-
//TODO: Remove when backward compatibility is not needed anymore
30-
/// <summary>
31-
/// Gets the format of the credential to be issued.
32-
/// </summary>
33-
public Format Format { get; } = Format;
34-
35-
public Option<SessionTranscript> SessionTranscript { get; } = SessionTranscript;
36-
37-
public OneOf<CredentialIdentifier, CredentialConfigurationId> CredentialIdentification { get; } = CredentialIdentification;
38-
39-
public int SpecVersion { get; } = specVersion;
40-
}
17+
public record CredentialRequest(
18+
OneOf<CredentialIdentifier, CredentialConfigurationId> CredentialIdentification,
19+
Format Format,
20+
Option<int> SpecVersion,
21+
Option<ProofOfPossession> Proof,
22+
Option<ProofsOfPossession> Proofs,
23+
Option<SessionTranscript> SessionTranscript);
4124

4225
public static class CredentialRequestFun
4326
{
@@ -75,10 +58,28 @@ public static JObject EncodeToJson(this CredentialRequest request)
7558
},
7659
configurationId =>
7760
{
78-
if (request.SpecVersion == 15)
79-
result.Add(CredentialConfigurationIdKey, configurationId.ToString());
80-
else
81-
result.Add(FormatJsonKey, request.Format.ToString());
61+
request.SpecVersion.Match(specVersion =>
62+
{
63+
switch (specVersion)
64+
{
65+
case 14:
66+
result.Add(FormatJsonKey, request.Format.ToString());
67+
break;
68+
case 15:
69+
result.Add(CredentialConfigurationIdKey, configurationId.ToString());
70+
break;
71+
default:
72+
result.Add(FormatJsonKey, request.Format.ToString());
73+
result.Add(CredentialConfigurationIdKey, configurationId.ToString());
74+
break;
75+
}
76+
},
77+
() =>
78+
{
79+
result.Add(FormatJsonKey, request.Format.ToString());
80+
result.Add(CredentialConfigurationIdKey, configurationId.ToString());
81+
}
82+
);
8283

8384
return Unit.Default;
8485
});

src/WalletFramework.Oid4Vc/Oid4Vci/Implementations/Oid4VciClientService.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,13 @@ await _authFlowSessionStorage.StoreAsync(
164164
context,
165165
authorizationData,
166166
authorizationCodeParameters,
167-
sessionId);
167+
sessionId,
168+
Option<int>.None);
168169

169170
return authorizationRequestUri;
170171
}
171172

172-
public async Task<Uri> InitiateAuthFlow(Uri uri, ClientOptions clientOptions, Option<Locale> language, Option<OneOf<Vct, DocType>> credentialType, int specVersion)
173+
public async Task<Uri> InitiateAuthFlow(Uri uri, ClientOptions clientOptions, Option<Locale> language, Option<OneOf<Vct, DocType>> credentialType, Option<int> specVersion)
173174
{
174175
var locale = language.Match(
175176
some => some,
@@ -297,7 +298,8 @@ from preAuthCode in grants.PreAuthorizedCode
297298
issuerMetadata,
298299
token,
299300
Option<ClientOptions>.None,
300-
Option<AuthorizationRequest>.None);
301+
Option<AuthorizationRequest>.None,
302+
Option<int>.None);
301303

302304
var credentialSets = new List<CredentialSetRecord>();
303305
var result =
@@ -414,7 +416,7 @@ public async Task<Validation<IEnumerable<CredentialSetRecord>>> RequestCredentia
414416
token,
415417
session.AuthorizationData.ClientOptions,
416418
Option<AuthorizationRequest>.None,
417-
session.SpecVersion);
419+
session.SpecVersion.ToOption());
418420

419421
var result =
420422
from responses in validResponses
@@ -543,8 +545,7 @@ public async Task<Validation<IEnumerable<OnDemandCredentialSet>>> RequestOnDeman
543545
token,
544546
session.AuthorizationData.ClientOptions,
545547
authorizationRequest,
546-
session.SpecVersion
547-
);
548+
session.SpecVersion.ToOption());
548549

549550
var result =
550551
from responses in validResponses

0 commit comments

Comments
 (0)