Skip to content

Commit

Permalink
(#2) add request and hadnlers
Browse files Browse the repository at this point in the history
  • Loading branch information
SaintAngeLs committed Sep 26, 2024
1 parent 5435591 commit e76dfca
Show file tree
Hide file tree
Showing 56 changed files with 3,789 additions and 28 deletions.
29 changes: 29 additions & 0 deletions src/Nuar/Nuar/Auth/AuthenticationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Nuar.Options;

namespace Nuar.Auth
{
internal sealed class AuthenticationManager : IAuthenticationManager
{
private readonly NuarOptions _options;

public AuthenticationManager(NuarOptions options)
{
_options = options;
}

public async Task<bool> TryAuthenticateAsync(HttpRequest request, RouteConfig routeConfig)
{
if (_options.Auth == null || !_options.Auth.Enabled ||
(_options.Auth?.Global != true && routeConfig.Route?.Auth != true))
{
return true;
}

var result = await request.HttpContext.AuthenticateAsync();
return result.Succeeded;
}
}
}
40 changes: 40 additions & 0 deletions src/Nuar/Nuar/Auth/AuthorizationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;

namespace Nuar.Auth
{
internal sealed class AuthorizationManager : IAuthorizationManager
{
private readonly IPolicyManager _policyManager;

public AuthorizationManager(IPolicyManager policyManager)
{
_policyManager = policyManager;
}

public bool IsAuthorized(ClaimsPrincipal user, RouteConfig routeConfig)
{
if (user == null)
{
return false;
}

if (routeConfig.Route == null)
{
return true;
}

return HasPolicies(user, routeConfig.Route.Policies) && HasClaims(user, routeConfig.Route.Claims);
}

private bool HasPolicies(ClaimsPrincipal user, IEnumerable<string> policies)
=> policies == null || policies.All(p => HasPolicy(user, p));

private bool HasPolicy(ClaimsPrincipal user, string policy)
=> HasClaims(user, _policyManager.GetClaims(policy));

private static bool HasClaims(ClaimsPrincipal user, IDictionary<string, string> claims)
=> claims == null || claims.All(claim => user.HasClaim(claim.Key, claim.Value));
}
}
48 changes: 48 additions & 0 deletions src/Nuar/Nuar/Auth/PolicyManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Nuar.Configuration;
using Nuar.Options;

namespace Nuar.Auth
{
internal sealed class PolicyManager : IPolicyManager
{
private readonly IDictionary<string, Dictionary<string, string>> _policies;
private readonly NuarOptions _options;

public PolicyManager(NuarOptions options)
{
_options = options;
_policies = LoadPolicies();
}

public IDictionary<string, string> GetClaims(string policy)
=> _policies.TryGetValue(policy, out var claims) ? claims : null;

private IDictionary<string, Dictionary<string, string>> LoadPolicies()
{
var policies = (_options.Auth?.Policies ?? new Dictionary<string, Policy>())
.ToDictionary(p => p.Key, p => p.Value.Claims.ToDictionary(c => c.Key, c => c.Value));
VerifyPolicies(policies);

return policies;
}

private void VerifyPolicies(IDictionary<string, Dictionary<string, string>> policies)
{
var definedPolicies = (_options.Modules ?? new Dictionary<string, Module>())
.Select(m => m.Value)
.SelectMany(m => m.Routes ?? Enumerable.Empty<Route>())
.SelectMany(r => r.Policies ?? Enumerable.Empty<string>())
.Distinct();

var missingPolicies = definedPolicies.Except(policies.Select(p => p.Key)).ToArray();

if (missingPolicies.Any())
{
throw new InvalidOperationException($"Missing policies: '{string.Join(", ", missingPolicies)}'");
}
}
}
}
1 change: 1 addition & 0 deletions src/Nuar/Nuar/Configuration/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public class Module
public string Name { get; set; }
public string Description { get; set; }
public string Version { get; set; }
public string Path { get; set; }
public bool? Enabled { get; set; }
public IEnumerable<Route> Routes { get; set; }
public IDictionary<string, Service> Services { get; set; }
Expand Down
14 changes: 14 additions & 0 deletions src/Nuar/Nuar/Extensions/EnabledExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Nuar.Extensions
{
public sealed class EnabledExtension : IEnabledExtension
{
public IExtension Extension { get; }
public IExtensionOptions Options { get; }

public EnabledExtension(IExtension extension, IExtensionOptions options)
{
Extension = extension;
Options = options;
}
}
}
8 changes: 8 additions & 0 deletions src/Nuar/Nuar/Extensions/ExtensionOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Nuar.Extensions
{
public sealed class ExtensionOptions : IExtensionOptions
{
public int? Order { get; set; }
public bool? Enabled { get; set; }
}
}
51 changes: 51 additions & 0 deletions src/Nuar/Nuar/Extensions/ExtensionProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Nuar.Options;

namespace Nuar.Extensions
{
public sealed class ExtensionProvider : IExtensionProvider
{
private ISet<IEnabledExtension> _extensions = new HashSet<IEnabledExtension>();
private readonly NuarOptions _options;

public ExtensionProvider(NuarOptions options)
{
_options = options;
}

public IEnumerable<IEnabledExtension> GetAll()
{
if (_extensions.Any())
{
return _extensions;
}

var type = typeof(IExtension);
var extensionTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p) && !p.IsInterface);

var extensions = new HashSet<IEnabledExtension>();

foreach (var extensionType in extensionTypes)
{
var extension = (IExtension) Activator.CreateInstance(extensionType);
var options = _options.Extensions?.SingleOrDefault(o =>
o.Key.Equals(extension.Name, StringComparison.InvariantCultureIgnoreCase)).Value;

if (options is null)
{
continue;
}

extensions.Add(new EnabledExtension(extension, options));
}

_extensions = new HashSet<IEnabledExtension>(extensions.OrderBy(e => e.Options.Order));

return _extensions;
}
}
}
Loading

0 comments on commit e76dfca

Please sign in to comment.