diff --git a/src/NoFrixion.MoneyMoov/Claims/IdentityExtensions.cs b/src/NoFrixion.MoneyMoov/Claims/IdentityExtensions.cs index b5fe4a47..0876b779 100755 --- a/src/NoFrixion.MoneyMoov/Claims/IdentityExtensions.cs +++ b/src/NoFrixion.MoneyMoov/Claims/IdentityExtensions.cs @@ -19,6 +19,7 @@ using System.Security.Claims; using System.Security.Principal; using NoFrixion.Common.Permissions; +using NoFrixion.MoneyMoov.Enums; using NoFrixion.MoneyMoov.Extensions; using NoFrixion.MoneyMoov.Models; @@ -339,6 +340,36 @@ public static bool HasMerchantPermission(this IIdentity identity, MerchantPermis return Enum.TryParse(claim.Value, out MerchantPermissions claimPermissions) && claimPermissions.HasFlag(permission); } + + /// + /// Gets the authentication type from the identity token. + /// + /// The token identity + /// The authentication type. + public static AuthenticationTypesEnum GetAuthenticationType(this IIdentity identity) + { + var claimsIdentity = identity as ClaimsIdentity; + + if (claimsIdentity == null) + { + return AuthenticationTypesEnum.None; + } + else + { + var authenticationClaimType = ClaimsConstants.NOFRIXION_CLAIMS_NAMESPACE + NoFrixionClaimsEnum.approveamr; + + var authenticationTypeClaimValue = claimsIdentity.Claims.FirstOrDefault(x => x.Type == authenticationClaimType)?.Value; + + if (Enum.TryParse(authenticationTypeClaimValue, out AuthenticationTypesEnum authenticationType)) + { + return authenticationType; + } + else + { + return AuthenticationTypesEnum.None; + } + } + } } #nullable enable diff --git a/src/NoFrixion.MoneyMoov/Enums/AuthenticationTypesEnum.cs b/src/NoFrixion.MoneyMoov/Enums/AuthenticationTypesEnum.cs index 6b0d7e06..72bbd461 100755 --- a/src/NoFrixion.MoneyMoov/Enums/AuthenticationTypesEnum.cs +++ b/src/NoFrixion.MoneyMoov/Enums/AuthenticationTypesEnum.cs @@ -16,6 +16,7 @@ namespace NoFrixion.MoneyMoov.Enums; +[Flags] public enum AuthenticationTypesEnum { None = 0, diff --git a/src/NoFrixion.MoneyMoov/Extensions/EnumExtensions.cs b/src/NoFrixion.MoneyMoov/Extensions/EnumExtensions.cs index c9d7cdd8..3670927a 100644 --- a/src/NoFrixion.MoneyMoov/Extensions/EnumExtensions.cs +++ b/src/NoFrixion.MoneyMoov/Extensions/EnumExtensions.cs @@ -46,6 +46,40 @@ public static List ToList(this T flags) where T : Enum } } + /// + /// This method converts an Enum with the Flags attribute to a list of Enums. + /// + public static List ToList(this T? flags) where T : struct, Enum + { + if (!typeof(T).IsDefined(typeof(FlagsAttribute), false)) + { + throw new ArgumentException("The type parameter T must have the Flags attribute.", nameof(flags)); + } + + if (flags == null) + { + return []; + } + + // Check if the enum underlying type is ulong + var underlyingType = Enum.GetUnderlyingType(typeof(T)); + + if (underlyingType == typeof(ulong)) + { + return Enum.GetValues(typeof(T)) + .Cast() + .Where(value => flags.Value.HasFlag(value) && Convert.ToUInt64(value) != 0) // Exclude None or 0 + .ToList(); + } + else + { + return Enum.GetValues(typeof(T)) + .Cast() + .Where(value => flags.Value.HasFlag(value) && Convert.ToInt32(value) != 0) // Exclude None or 0 + .ToList(); + } + } + /// /// This method converts list of flag enum values to a single flag enum. /// diff --git a/src/NoFrixion.MoneyMoov/Models/Beneficiary/Beneficiary.cs b/src/NoFrixion.MoneyMoov/Models/Beneficiary/Beneficiary.cs index cc0f7c83..2d55e74b 100755 --- a/src/NoFrixion.MoneyMoov/Models/Beneficiary/Beneficiary.cs +++ b/src/NoFrixion.MoneyMoov/Models/Beneficiary/Beneficiary.cs @@ -18,6 +18,7 @@ using JetBrains.Annotations; using System.Text.Json.Serialization; using Newtonsoft.Json; +using NoFrixion.MoneyMoov.Enums; #nullable disable @@ -86,7 +87,12 @@ public class Beneficiary : IValidatableObject /// The number of distinct authorisers that have authorised the beneficiary. /// public int AuthorisersCompletedCount { get; set; } - + + /// + /// A list of authentication types allowed to authorise the payout. + /// + [CanBeNull] public List AuthenticationMethods { get; set; } + public string CreatedByEmailAddress { get; set; } public string Nonce { get; set; } diff --git a/src/NoFrixion.MoneyMoov/Models/Payouts/Payout.cs b/src/NoFrixion.MoneyMoov/Models/Payouts/Payout.cs index e05cddba..0ce6690e 100755 --- a/src/NoFrixion.MoneyMoov/Models/Payouts/Payout.cs +++ b/src/NoFrixion.MoneyMoov/Models/Payouts/Payout.cs @@ -13,6 +13,7 @@ // MIT. // ----------------------------------------------------------------------------- +using NoFrixion.MoneyMoov.Enums; using System.ComponentModel.DataAnnotations; namespace NoFrixion.MoneyMoov.Models; @@ -345,6 +346,11 @@ public Counterparty? DestinationAccount /// public List? AuthorisedBy { get; set; } + /// + /// A list of authentication types allowed to authorise the payout. + /// + public List? AuthenticationMethods { get; set; } + /// /// If the payout destination is a beneficiary this will be the ID of it's identifier. /// diff --git a/src/NoFrixion.MoneyMoov/Models/Rules/Rule.cs b/src/NoFrixion.MoneyMoov/Models/Rules/Rule.cs index e514f891..1a88e77e 100755 --- a/src/NoFrixion.MoneyMoov/Models/Rules/Rule.cs +++ b/src/NoFrixion.MoneyMoov/Models/Rules/Rule.cs @@ -14,6 +14,7 @@ //----------------------------------------------------------------------------- using System.ComponentModel.DataAnnotations; +using NoFrixion.MoneyMoov.Enums; using Quartz; using static System.String; @@ -119,6 +120,11 @@ public class Rule : IValidatableObject, IWebhookPayload public required string Nonce { get; set; } + /// + /// A list of authentication types allowed to authorise the payout. + /// + public List? AuthenticationMethods { get; set; } + /// /// The approval hash is used when approving the rule and to detect when critical /// fields change.