| | | 1 | | using System.Security.Claims; |
| | | 2 | | using Elsa.ExternalAuthentication.Contracts; |
| | | 3 | | using Elsa.ExternalAuthentication.Models; |
| | | 4 | | using Elsa.ExternalAuthentication.Options; |
| | | 5 | | using Elsa.ExternalAuthentication.Permissions; |
| | | 6 | | using Microsoft.Extensions.Options; |
| | | 7 | | |
| | | 8 | | namespace Elsa.ExternalAuthentication.Services; |
| | | 9 | | |
| | | 10 | | /// <summary>Prevents a management edit from removing the final ordinary sign-in path by accident.</summary> |
| | 10 | 11 | | public sealed class FinalLoginPathGuard(IIdentityProviderConnectionRegistry registry, IOptions<ExternalAuthenticationOpt |
| | | 12 | | { |
| | | 13 | | public async ValueTask<FinalLoginPathGuardResult> AuthorizeAsync(IdentityProviderConnection existing, IdentityProvid |
| | | 14 | | { |
| | 18 | 15 | | var guard = options.Value.FinalLoginPathGuard; |
| | 18 | 16 | | if (!guard.IsEnabled || !guard.RequireRecoveryMethod || !IsNormal(existing) || IsNormal(candidate) || guard.HasB |
| | 15 | 17 | | return FinalLoginPathGuardResult.Allowed; |
| | 3 | 18 | | var effective = await registry.GetAsync(targetTenantId, cancellationToken); |
| | 5 | 19 | | if (effective.Connections.Any(x => !string.Equals(x.Connection.Id, existing.Id, StringComparison.Ordinal) && IsN |
| | 0 | 20 | | return FinalLoginPathGuardResult.Allowed; |
| | 4 | 21 | | var canOverride = confirmedOverride && actor.FindAll(PermissionNames.ClaimType).Any(x => x.Value == PermissionNa |
| | 3 | 22 | | return canOverride ? FinalLoginPathGuardResult.Allowed : FinalLoginPathGuardResult.Denied; |
| | 18 | 23 | | } |
| | | 24 | | |
| | 9 | 25 | | private static bool IsNormal(IdentityProviderConnection connection) => connection.IsEnabled && connection.ArchivedAt |
| | | 26 | | } |
| | | 27 | | |
| | | 28 | | public enum FinalLoginPathGuardResult { Allowed, Denied } |