- 
                Notifications
    You must be signed in to change notification settings 
- Fork 9
Align IssuerMetadata with VCI 1.0 spec #438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v3.0.0
Are you sure you want to change the base?
Changes from 6 commits
25d8566
              1575456
              58770af
              c39bf85
              aff65a5
              4a323b1
              ff1b5cb
              c27a1e9
              f1e6d12
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| using LanguageExt; | ||
| using WalletFramework.Core.ClaimPaths.Errors; | ||
| using WalletFramework.Core.Functional; | ||
| using WalletFramework.Core.Path; | ||
|  | @@ -31,18 +32,60 @@ from components in array.TraverseAll(ClaimPathComponent.Create) | |
| from path in FromComponents(components) | ||
| select path; | ||
| } | ||
|  | ||
| public static JArray ToArray(ClaimPath claimPath) | ||
| { | ||
| var array = new JArray(); | ||
| foreach (var component in claimPath.GetPathComponents()) | ||
| { | ||
| component.Match( | ||
| key => | ||
| { | ||
| array.Add(new JValue(key)); | ||
| return Unit.Default; | ||
| }, | ||
| index => | ||
| { | ||
| array.Add(new JValue(index)); | ||
| return Unit.Default; | ||
| }, | ||
| selectAll => | ||
|          | ||
| { | ||
| array.Add(JValue.CreateNull()); | ||
| return Unit.Default; | ||
| } | ||
| ); | ||
| } | ||
| return array; | ||
| } | ||
| } | ||
|  | ||
| public static class ClaimPathFun | ||
| { | ||
| public static JsonPath ToJsonPath(this ClaimPath claimPath) | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use a StringBuilder | ||
| { | ||
| var jsonPath = "$." + string.Join('.', claimPath.GetPathComponents().Select(x => | ||
| var jsonPath = "$"; | ||
|  | ||
| foreach (var component in claimPath.GetPathComponents()) | ||
| { | ||
| if (x.IsKey) return x.AsKey(); | ||
| if (x.IsIndex) return x.AsIndex()?.ToString(); | ||
| return null; | ||
| }).Where(x => x is not null)); | ||
| component.Match( | ||
| key => | ||
| { | ||
| jsonPath += $".{key}"; | ||
| return Unit.Default; | ||
| }, | ||
| integer => | ||
| { | ||
| jsonPath += $"[{integer}]"; | ||
| return Unit.Default; | ||
| }, | ||
| selectAll => | ||
| { | ||
| jsonPath += "[*]"; | ||
| return Unit.Default; | ||
| }); | ||
| } | ||
|  | ||
| return JsonPath.ValidJsonPath(jsonPath).UnwrapOrThrow(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| using LanguageExt; | ||
| using Newtonsoft.Json.Linq; | ||
| using WalletFramework.Core.Functional; | ||
| using WalletFramework.Core.Json; | ||
| using WalletFramework.Core.Localization; | ||
| using static WalletFramework.Core.Localization.Locale; | ||
| using static WalletFramework.Oid4Vc.Oid4Vci.CredConfiguration.Models.ClaimDisplayJsonExtensions; | ||
|  | ||
| namespace WalletFramework.Oid4Vc.Oid4Vci.CredConfiguration.Models; | ||
|  | ||
| public record ClaimDisplay | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Delete the other legacy ClaimDisplays There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible to have a name without a locale ? Otherwise, a name must be mapped by a locale and this is not reflected here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, according to the specs a name can exist without a locale. https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#appendix-B.2-2.3.1 | ||
| { | ||
| public Option<string> Name { get; set; } | ||
|          | ||
|  | ||
| public Option<Locale> Locale { get; set; } | ||
|          | ||
|  | ||
| private ClaimDisplay(Option<string> name, Option<Locale> locale) | ||
| { | ||
| Name = name; | ||
| Locale = locale; | ||
| } | ||
|  | ||
| private static ClaimDisplay Create(Option<string> name, Option<Locale> locale) => | ||
| new(name, locale); | ||
|  | ||
| public static Validation<ClaimDisplay> ValidClaimDisplay(JToken config) | ||
| { | ||
| var name = | ||
| from jToken in config.GetByKey(NameJsonKey) | ||
| select jToken.ToObject<string>(); | ||
|  | ||
| var locale = | ||
| from jToken in config.GetByKey(LocaleJsonKey) | ||
| from validLocale in ValidLocale(jToken) | ||
| select validLocale; | ||
|  | ||
| return ValidationFun.Valid(Create) | ||
| .Apply(name.ToOption()) | ||
| .Apply(locale.ToOption()); | ||
| } | ||
| } | ||
|  | ||
| public static class ClaimDisplayJsonExtensions | ||
| { | ||
| public const string NameJsonKey = "name"; | ||
| public const string LocaleJsonKey = "locale"; | ||
|  | ||
| public static JObject EncodeToJson(this ClaimDisplay display) | ||
| { | ||
| var result = new JObject(); | ||
|  | ||
| display.Locale.IfSome(locale => result.Add(LocaleJsonKey, locale.ToString())); | ||
| display.Name.IfSome(name => result.Add(NameJsonKey, name)); | ||
|  | ||
| return result; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| using LanguageExt; | ||
| using Newtonsoft.Json.Linq; | ||
| using WalletFramework.Core.ClaimPaths; | ||
| using WalletFramework.Core.Functional; | ||
| using WalletFramework.Core.Json; | ||
| using static WalletFramework.Oid4Vc.Oid4Vci.CredConfiguration.Models.ClaimMetadataJsonExtensions; | ||
|  | ||
| namespace WalletFramework.Oid4Vc.Oid4Vci.CredConfiguration.Models; | ||
|  | ||
| public record ClaimMetadata | ||
| { | ||
| public ClaimPath Path { get; } | ||
|  | ||
| public Option<List<ClaimDisplay>> Display { get; } | ||
|  | ||
| public Option<bool> Mandatory { get; } | ||
|  | ||
| private ClaimMetadata(ClaimPath claimPath, Option<List<ClaimDisplay>> claimDisplays, Option<bool> mandatory) | ||
| { | ||
| Path = claimPath; | ||
| Display = claimDisplays; | ||
| Mandatory = mandatory; | ||
| } | ||
|  | ||
| private static ClaimMetadata Create(ClaimPath claimPath, Option<List<ClaimDisplay>> claimDisplays, Option<bool> mandatory) => | ||
| new(claimPath, claimDisplays, mandatory); | ||
|  | ||
| public static Validation<ClaimMetadata> ValidClaimMetadata(JToken config, Func<JToken, Validation<ClaimPath>> claimPathValidation) | ||
| { | ||
| var claimPath = | ||
| from jToken in config.GetByKey(PathJsonKey) | ||
| from jArray in claimPathValidation(jToken) | ||
| select jArray; | ||
|  | ||
| var claimDisplays = | ||
| from jToken in config.GetByKey(DisplayJsonKey) | ||
| from jArray in jToken.ToJArray() | ||
| from claimDisplay in jArray.TraverseAny(ClaimDisplay.ValidClaimDisplay) | ||
| select claimDisplay.ToList(); | ||
|  | ||
| var mandatory = | ||
| from jToken in config.GetByKey(MandatoryJsonKey) | ||
| select jToken.ToObject<bool>(); | ||
|  | ||
| var result = ValidationFun.Valid(Create) | ||
| .Apply(claimPath) | ||
| .Apply(claimDisplays.ToOption()) | ||
| .Apply(mandatory.ToOption()); | ||
|  | ||
| return result; | ||
| } | ||
| } | ||
|  | ||
| public static class ClaimMetadataJsonExtensions | ||
| { | ||
| public const string PathJsonKey = "path"; | ||
| public const string DisplayJsonKey = "display"; | ||
| public const string MandatoryJsonKey = "mandatory"; | ||
|  | ||
| public static JObject EncodeToJson(this ClaimMetadata display) | ||
| { | ||
| var result = new JObject(); | ||
|  | ||
| result.Add(PathJsonKey, ClaimPath.ToArray(display.Path)); | ||
|  | ||
| display.Display.IfSome(claimDisplays => | ||
| { | ||
| var claimsArray = new JArray(); | ||
| foreach (var claimDisplay in claimDisplays) | ||
| { | ||
| claimsArray.Add(claimDisplay.EncodeToJson()); | ||
| } | ||
| result.Add(DisplayJsonKey, claimsArray); | ||
| }); | ||
|  | ||
| display.Mandatory.IfSome(mandatory => { result.Add(MandatoryJsonKey, mandatory); }); | ||
|  | ||
| return result; | ||
| } | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ToJArray