Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ public interface IOid4VciClientService
/// <param name="uri">The issuers uri</param>
/// <param name="clientOptions">The client options</param>
/// <param name="language">Optional language tag</param>
/// <param name="credentialType">Specifies whether Sd-Jwt or MDoc should be issued</param>
/// <param name="specVersion">Optional language tag</param>
/// <returns></returns>
Task<Uri> InitiateAuthFlow(Uri uri, ClientOptions clientOptions, Option<Locale> language);
Task<Uri> InitiateAuthFlow(Uri uri, ClientOptions clientOptions, Option<Locale> language, Option<OneOf<Vct, DocType>> credentialType, Option<int> specVersion);

/// <summary>
/// Requests a verifiable credential using the authorization code flow.
Expand All @@ -40,18 +42,17 @@ public interface IOid4VciClientService
/// <returns>
/// A list of credentials.
/// </returns>
Task<Validation<CredentialSetRecord>> RequestCredentialSet(IssuanceSession issuanceSession);
Task<Validation<IEnumerable<CredentialSetRecord>>> RequestCredentialSet(IssuanceSession issuanceSession);

/// <summary>
/// Requests a verifiable credential using the authorization code flow and C''.
/// </summary>
/// <param name="issuanceSession">Holds authorization session relevant information.</param>
/// <param name="authorizationRequest">The AuthorizationRequest that is associated witht the ad-hoc crednetial issuance</param>
/// <param name="credentialType">Specifies whether Sd-Jwt or MDoc should be issued</param>
/// <returns>
/// A list of credentials.
/// </returns>
Task<Validation<OnDemandCredentialSet>> RequestOnDemandCredentialSet(IssuanceSession issuanceSession, AuthorizationRequest authorizationRequest, OneOf<Vct, DocType> credentialType);
Task<Validation<IEnumerable<OnDemandCredentialSet>>> RequestOnDemandCredentialSet(IssuanceSession issuanceSession, AuthorizationRequest authorizationRequest);

/// <summary>
/// Processes a credential offer
Expand All @@ -66,7 +67,7 @@ public interface IOid4VciClientService
/// ///
/// <param name="credentialOfferMetadata">Credential offer and Issuer Metadata</param>
/// <param name="transactionCode">The Transaction Code.</param>
Task<Validation<CredentialSetRecord>> AcceptOffer(
Task<Validation<IEnumerable<CredentialSetRecord>>> AcceptOffer(
CredentialOfferMetadata credentialOfferMetadata,
string? transactionCode);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Hyperledger.Aries.Agents;
using LanguageExt;
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Models;
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Records;

Expand Down Expand Up @@ -44,10 +45,12 @@ public interface IAuthFlowSessionStorage
/// flow.
/// </param>
/// <param name="authFlowSessionState">Session State Identifier of a Authorization Code Flow session</param>
/// <param name="specVersion">Session State Identifier of a Authorization Code Flow session</param>
/// <returns></returns>
Task<string> StoreAsync(
IAgentContext agentContext,
AuthorizationData authorizationData,
AuthorizationCodeParameters authorizationCodeParameters,
AuthFlowSessionState authFlowSessionState);
AuthFlowSessionState authFlowSessionState,
Option<int> specVersion);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Hyperledger.Aries.Agents;
using Hyperledger.Aries.Storage;
using LanguageExt;
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Abstractions;
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Models;
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Records;
Expand All @@ -22,16 +23,17 @@ public AuthFlowSessionStorage(IWalletRecordService recordService)
private readonly IWalletRecordService _recordService;

/// <inheritdoc />
public async Task<string> StoreAsync(
IAgentContext agentContext,
public async Task<string> StoreAsync(IAgentContext agentContext,
AuthorizationData authorizationData,
AuthorizationCodeParameters authorizationCodeParameters,
AuthFlowSessionState authFlowSessionState)
AuthFlowSessionState authFlowSessionState,
Option<int> specVersion)
{
var record = new AuthFlowSessionRecord(
authorizationData,
authorizationCodeParameters,
authFlowSessionState);
authFlowSessionState,
specVersion.ToNullable());

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public record AuthorizationDetails

[JsonProperty("locations", NullValueHandling = NullValueHandling.Ignore)]
public string[]? Locations { get; }

[JsonProperty("credential_identifiers", NullValueHandling = NullValueHandling.Ignore)]
public string[]? CredentialIdentifiers { get; }

internal AuthorizationDetails(
string credentialConfigurationId,
Expand All @@ -44,4 +47,21 @@ internal AuthorizationDetails(
CredentialConfigurationId = credentialConfigurationId;
Locations = locations;
}

[JsonConstructor]
private AuthorizationDetails(
string format,
string? vct,
string? docType,
string? credentialConfigurationId,
string[]? locations,
string[]? credentialIdentifiers)
{
Format = format;
Vct = vct;
DocType = docType;
CredentialConfigurationId = credentialConfigurationId;
Locations = locations;
CredentialIdentifiers = credentialIdentifiers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Models;

public struct CredentialIdentifier
{
private string Value { get; }

public override string ToString() => Value;

public CredentialIdentifier(string id) => Value = id;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public AuthFlowSessionState AuthFlowSessionState
/// The parameters for the 'authorization_code' grant type.
/// </summary>
public AuthorizationCodeParameters AuthorizationCodeParameters { get; }

/// <summary>
/// Used to track the VCI Specification verison
/// </summary>
public int? SpecVersion { get; }

/// <summary>
/// Initializes a new instance of the <see cref="AuthFlowSessionRecord" /> class.
Expand All @@ -58,15 +63,18 @@ public AuthFlowSessionRecord()
/// <param name="authorizationData"></param>
/// <param name="authorizationCodeParameters"></param>
/// <param name="authFlowSessionState"></param>
/// <param name="specVersion"></param>
public AuthFlowSessionRecord(
AuthorizationData authorizationData,
AuthorizationCodeParameters authorizationCodeParameters,
AuthFlowSessionState authFlowSessionState)
AuthFlowSessionState authFlowSessionState,
int? specVersion)
{
AuthFlowSessionState = authFlowSessionState;
RecordVersion = 1;
AuthorizationCodeParameters = authorizationCodeParameters;
AuthorizationData = authorizationData;
SpecVersion = specVersion;
}
}

Expand Down Expand Up @@ -94,6 +102,7 @@ public static class AuthFlowSessionRecordFun
{
private const string AuthorizationDataJsonKey = "authorization_data";
private const string AuthorizationCodeParametersJsonKey = "authorization_code_parameters";
private const string SpecVersionJsonKey = "spec_version";

public static JObject EncodeToJson(this AuthFlowSessionRecord record)
{
Expand All @@ -104,7 +113,8 @@ public static JObject EncodeToJson(this AuthFlowSessionRecord record)
{
{ nameof(RecordBase.Id), record.Id },
{ AuthorizationDataJsonKey, authorizationData },
{ AuthorizationCodeParametersJsonKey, authorizationCodeParameters }
{ AuthorizationCodeParametersJsonKey, authorizationCodeParameters },
{ SpecVersionJsonKey, record.SpecVersion }
};
}

Expand All @@ -119,8 +129,10 @@ public static AuthFlowSessionRecord DecodeFromJson(JObject json)

var authorizationData = AuthorizationDataFun
.DecodeFromJson(json[AuthorizationDataJsonKey]!.ToObject<JObject>()!);

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

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

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

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@ public record OAuthToken
/// <summary>
/// Gets or sets the credential identifier.
/// </summary>
[JsonProperty("credential_identifiers")]
public AuthorizationDetails? CredentialIdentifier { get; set; }
[JsonProperty("authorization_details", NullValueHandling = NullValueHandling.Ignore)]
public AuthorizationDetails[]? AuthorizationDetails { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using WalletFramework.Core.Functional;

namespace WalletFramework.Oid4Vc.Oid4Vci.CredOffer.Errors;

public record ScopeIsNullOrWhitespaceError()
: Error("The scope is null or whitespace");
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using LanguageExt;
using Newtonsoft.Json.Linq;
using WalletFramework.Core.Functional;
using WalletFramework.Oid4Vc.Oid4Vci.CredConfiguration.Models;

namespace WalletFramework.Oid4Vc.Oid4Vci.CredOffer.Models;

public record ScopedCredentialConfiguration(CredentialConfigurationId CredentialConfigurationId, Option<Scope> Scope);

public static class ScopedCredentialConfigurationExtensions
{
private const string ScopeJsonKey = "scope";
private const string CredentialConfigurationIdJsonKey = "credential_configuration_id";

public static JObject EncodeToJson(this ScopedCredentialConfiguration scopedCredentialConfiguration)
{
return new JObject
{
{ ScopeJsonKey, scopedCredentialConfiguration.Scope.MatchUnsafe(scope => scope.ToString(), () => null) },
{ CredentialConfigurationIdJsonKey, scopedCredentialConfiguration.CredentialConfigurationId.ToString() }
};
}

public static ScopedCredentialConfiguration DecodeFromJson(JObject json)
{
var scope = Scope.OptionalScope(json[ScopeJsonKey]!);
var credentialConfigurationId = CredentialConfigurationId.ValidCredentialConfigurationId(json[CredentialConfigurationIdJsonKey]!.ToString()).UnwrapOrThrow();

return new ScopedCredentialConfiguration(credentialConfigurationId, scope);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
using WalletFramework.Oid4Vc.Oid4Vci.AuthFlow.Models;
using WalletFramework.Oid4Vc.Oid4Vci.Authorization.DPop.Models;
using WalletFramework.Oid4Vc.Oid4Vci.Authorization.Models;
using WalletFramework.Oid4Vc.Oid4Vci.CredConfiguration.Models.Mdoc;
using WalletFramework.Oid4Vc.Oid4Vci.CredConfiguration.Models.SdJwt;
using WalletFramework.Oid4Vc.Oid4Vci.CredConfiguration.Models;
using WalletFramework.Oid4Vc.Oid4Vci.CredOffer.Models;
using WalletFramework.Oid4Vc.Oid4Vci.CredResponse;
using WalletFramework.Oid4Vc.Oid4Vci.Issuer.Models;
using WalletFramework.Oid4Vc.Oid4Vp.Models;
Expand All @@ -14,10 +14,11 @@ namespace WalletFramework.Oid4Vc.Oid4Vci.CredRequest.Abstractions;

public interface ICredentialRequestService
{
public Task<Validation<CredentialResponse>> RequestCredentials(
OneOf<SdJwtConfiguration, MdocConfiguration> configuration,
public Task<Validation<IEnumerable<CredentialResponse>>> RequestCredentials(
KeyValuePair<CredentialConfigurationId, SupportedCredentialConfiguration> configurationPair,
IssuerMetadata issuerMetadata,
OneOf<OAuthToken, DPopToken> token,
Option<ClientOptions> clientOptions,
Option<AuthorizationRequest> authorizationRequest);
Option<AuthorizationRequest> authorizationRequest,
Option<int> specVersion);
}
Loading
Loading