diff --git a/dependencies.props b/dependencies.props
index 1ac3a3d..fe0615c 100644
--- a/dependencies.props
+++ b/dependencies.props
@@ -11,7 +11,7 @@
6.0.30
6.0.1
1.0.7
- 2.2.0
+ 2.2.1
1.2.0
1.0.1
diff --git a/src/api/NetworkResurrector.Api.Application/NetworkResurrector.Api.Application.csproj b/src/api/NetworkResurrector.Api.Application/NetworkResurrector.Api.Application.csproj
index b687deb..0a0c3a2 100644
--- a/src/api/NetworkResurrector.Api.Application/NetworkResurrector.Api.Application.csproj
+++ b/src/api/NetworkResurrector.Api.Application/NetworkResurrector.Api.Application.csproj
@@ -11,6 +11,7 @@
+
diff --git a/src/api/NetworkResurrector.Api.Application/Queries/GetUserPermissions.cs b/src/api/NetworkResurrector.Api.Application/Queries/GetUserPermissions.cs
new file mode 100644
index 0000000..227967b
--- /dev/null
+++ b/src/api/NetworkResurrector.Api.Application/Queries/GetUserPermissions.cs
@@ -0,0 +1,42 @@
+using MediatR;
+using Netmash.Security.Authentication.Tuitio.Abstractions;
+using NetworkResurrector.Api.Domain.Repositories;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace NetworkResurrector.Api.Application.Queries
+{
+ public class GetUserPermissions
+ {
+ public class Query : IRequest { }
+
+ public class Model
+ {
+ public IEnumerable Permissions { get; set; }
+ }
+
+ public class QueryHandler : IRequestHandler
+ {
+ private readonly IUserContextAccessor _userContext;
+ private readonly ISecurityRepository _securityRepository;
+
+ public QueryHandler(IUserContextAccessor userContext, ISecurityRepository securityRepository)
+ {
+ _userContext=userContext;
+ _securityRepository=securityRepository;
+ }
+
+ public async Task Handle(Query request, CancellationToken cancellationToken)
+ {
+ var roles = _userContext.UserRoles.Select(r => r.id);
+ var permissions = await _securityRepository.GetUserPermissionCodes(roles);
+ return new Model()
+ {
+ Permissions = permissions
+ };
+ }
+ }
+ }
+}
diff --git a/src/api/NetworkResurrector.Api.Domain.Data/DbContexts/NetworkDbContext.cs b/src/api/NetworkResurrector.Api.Domain.Data/DbContexts/NetworkDbContext.cs
index 3aec565..d3c4c54 100644
--- a/src/api/NetworkResurrector.Api.Domain.Data/DbContexts/NetworkDbContext.cs
+++ b/src/api/NetworkResurrector.Api.Domain.Data/DbContexts/NetworkDbContext.cs
@@ -3,6 +3,7 @@ using NetworkResurrector.Api.Domain.Data.EntityTypeConfiguration;
using NetworkResurrector.Api.Domain.Data.EntityTypeConfiguration.Power;
using NetworkResurrector.Api.Domain.Data.EntityTypeConfiguration.Security;
using NetworkResurrector.Api.Domain.Entities;
+using NetworkResurrector.Api.Domain.Entities.Security;
namespace NetworkResurrector.Api.Domain.Data.DbContexts
{
@@ -10,6 +11,8 @@ namespace NetworkResurrector.Api.Domain.Data.DbContexts
{
public DbSet Machines { get; set; }
public DbSet PowerActionConfigurations { get; set; }
+ public DbSet UserRoleAuthorizations { get; set; }
+ public DbSet PermissionHierarchies { get; set; }
public NetworkDbContext(DbContextOptions options)
: base(options)
diff --git a/src/api/NetworkResurrector.Api.Domain.Data/DependencyInjectionExtensions.cs b/src/api/NetworkResurrector.Api.Domain.Data/DependencyInjectionExtensions.cs
index 91c2194..2a653cc 100644
--- a/src/api/NetworkResurrector.Api.Domain.Data/DependencyInjectionExtensions.cs
+++ b/src/api/NetworkResurrector.Api.Domain.Data/DependencyInjectionExtensions.cs
@@ -12,6 +12,7 @@ namespace NetworkResurrector.Api.Domain.Data
public static void AddDataAccess(this IServiceCollection services)
{
services.AddScoped();
+ services.AddScoped();
services
.AddDbContextPool(
diff --git a/src/api/NetworkResurrector.Api.Domain.Data/Repositories/SecurityRepository.cs b/src/api/NetworkResurrector.Api.Domain.Data/Repositories/SecurityRepository.cs
new file mode 100644
index 0000000..a3b65ec
--- /dev/null
+++ b/src/api/NetworkResurrector.Api.Domain.Data/Repositories/SecurityRepository.cs
@@ -0,0 +1,80 @@
+using Microsoft.EntityFrameworkCore;
+using NetworkResurrector.Api.Domain.Data.DbContexts;
+using NetworkResurrector.Api.Domain.Entities.Security;
+using NetworkResurrector.Api.Domain.Repositories;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Threading.Tasks;
+
+namespace NetworkResurrector.Api.Domain.Data.Repositories
+{
+ public class SecurityRepository : ISecurityRepository
+ {
+ private readonly NetworkDbContext _dbContext;
+
+ public SecurityRepository(NetworkDbContext dbContext)
+ {
+ _dbContext=dbContext;
+ }
+
+ private async Task BuildChildrenHierarchy(Permission permission)
+ {
+ var children = await _dbContext.PermissionHierarchies
+ .Include(z => z.Child)
+ .Where(z => z.ParentPermissionId == permission.PermissionId)
+ .AsNoTracking()
+ .ToArrayAsync();
+
+ if (children == null || !children.Any())
+ return;
+
+ permission.Children = children;
+
+ foreach (var element in permission.Children)
+ {
+ await BuildChildrenHierarchy(element.Child);
+ }
+ }
+
+ private IEnumerable GetPermissionCodes(IEnumerable permissions)
+ {
+ var result = new List();
+ foreach (var permission in permissions)
+ {
+ result.Add(permission.PermissionCode);
+ if (permission.Children != null && permission.Children.Count > 0)
+ {
+ var children = permission.Children.Select(ch => ch.Child);
+ var childrenCodes = GetPermissionCodes(children);
+ result.AddRange(childrenCodes);
+ }
+ }
+ return result.Distinct();
+ }
+
+ private async Task> GetUserPermissions(IEnumerable roles)
+ {
+ var authorizations = await _dbContext.UserRoleAuthorizations
+ .Include(z => z.Permission)
+ .AsNoTracking()
+ .Where(z => roles.Contains(z.UserRoleId) && z.Active)
+ .ToArrayAsync();
+
+ var permissions = authorizations.Select(z => z.Permission);
+ foreach (var permission in permissions)
+ {
+ await BuildChildrenHierarchy(permission);
+ }
+
+ return permissions;
+ }
+
+ public async Task> GetUserPermissionCodes(IEnumerable roles)
+ {
+ var permissions = await GetUserPermissions(roles);
+ var codes = GetPermissionCodes(permissions);
+ return codes;
+ }
+ }
+}
diff --git a/src/api/NetworkResurrector.Api.Domain/Abstractions/IUserService.cs b/src/api/NetworkResurrector.Api.Domain/Abstractions/IUserService.cs
deleted file mode 100644
index 76e1518..0000000
--- a/src/api/NetworkResurrector.Api.Domain/Abstractions/IUserService.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace NetworkResurrector.Api.Domain.Abstractions
-{
- public interface IUserService
- {
- bool UserIsLoggedIn { get; }
- string GetUserId();
- string GetUserName();
- bool UserIsGuest();
- }
-}
diff --git a/src/api/NetworkResurrector.Api.Domain/Repositories/ISecurityRepository.cs b/src/api/NetworkResurrector.Api.Domain/Repositories/ISecurityRepository.cs
new file mode 100644
index 0000000..20e73cf
--- /dev/null
+++ b/src/api/NetworkResurrector.Api.Domain/Repositories/ISecurityRepository.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace NetworkResurrector.Api.Domain.Repositories
+{
+ public interface ISecurityRepository
+ {
+ Task> GetUserPermissionCodes(IEnumerable roles);
+ }
+}
diff --git a/src/api/NetworkResurrector.Api/Controllers/SecurityController.cs b/src/api/NetworkResurrector.Api/Controllers/SecurityController.cs
new file mode 100644
index 0000000..d66cc76
--- /dev/null
+++ b/src/api/NetworkResurrector.Api/Controllers/SecurityController.cs
@@ -0,0 +1,28 @@
+using MediatR;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using NetworkResurrector.Api.Application.Queries;
+using System.Threading.Tasks;
+
+namespace NetworkResurrector.Api.Controllers
+{
+ [Authorize]
+ [ApiController]
+ [Route("security")]
+ public class SecurityController : ControllerBase
+ {
+ private readonly IMediator _mediator;
+
+ public SecurityController(IMediator mediator)
+ {
+ _mediator = mediator;
+ }
+
+ [HttpGet("permissions")]
+ public async Task GetUserPermissions([FromRoute] GetUserPermissions.Query query)
+ {
+ var result = await _mediator.Send(query);
+ return Ok(result);
+ }
+ }
+}
diff --git a/src/api/NetworkResurrector.Api/Extensions/StartupExtensions.cs b/src/api/NetworkResurrector.Api/Extensions/StartupExtensions.cs
index 270b672..3ce270f 100644
--- a/src/api/NetworkResurrector.Api/Extensions/StartupExtensions.cs
+++ b/src/api/NetworkResurrector.Api/Extensions/StartupExtensions.cs
@@ -10,9 +10,7 @@ using Netmash.Infrastructure.DatabaseMigration.Constants;
using Netmash.Security.Authentication.Tuitio;
using NetworkResurrector.Agent.Wrapper;
using NetworkResurrector.Api.Application;
-using NetworkResurrector.Api.Domain.Abstractions;
using NetworkResurrector.Api.Domain.Data;
-using NetworkResurrector.Api.Services;
using NetworkResurrector.Server.Wrapper;
using Newtonsoft.Json;
@@ -28,9 +26,6 @@ namespace NetworkResurrector.Api.Extensions
// Add basic authentication
services.AddTuitioAuthentication(configuration.GetSection("Tuitio")["BaseAddress"]);
- services.AddHttpContextAccessor();
- services.AddScoped();
-
// MediatR
services.AddMediatR(typeof(Application.Queries.GetMachines).Assembly);
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
diff --git a/src/api/NetworkResurrector.Api/NetworkResurrector.Api.csproj b/src/api/NetworkResurrector.Api/NetworkResurrector.Api.csproj
index 747ee22..efa7bd8 100644
--- a/src/api/NetworkResurrector.Api/NetworkResurrector.Api.csproj
+++ b/src/api/NetworkResurrector.Api/NetworkResurrector.Api.csproj
@@ -20,7 +20,6 @@
-
diff --git a/src/api/NetworkResurrector.Api/Services/UserService.cs b/src/api/NetworkResurrector.Api/Services/UserService.cs
deleted file mode 100644
index b573afe..0000000
--- a/src/api/NetworkResurrector.Api/Services/UserService.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using NetworkResurrector.Api.Domain.Abstractions;
-using System;
-using System.Linq;
-using System.Security.Claims;
-
-namespace NetworkResurrector.Api.Services
-{
- public class UserService : IUserService
- {
- private readonly IHttpContextAccessor _httpAccessor;
-
- public UserService(IHttpContextAccessor httpAccessor)
- {
- _httpAccessor = httpAccessor;
- }
-
- public bool UserIsLoggedIn => _httpAccessor.HttpContext.User != null;
-
- public string GetUserId()
- {
- var userId = _httpAccessor.HttpContext.User?.Claims.FirstOrDefault(z => z.Type == ClaimTypes.NameIdentifier)?.Value;
-
- if (string.IsNullOrEmpty(userId))
- throw new Exception("User id could not be retrieved from claims.");
-
- return userId;
- }
-
- public string GetUserName()
- {
- var userName = _httpAccessor.HttpContext.User?.Claims.FirstOrDefault(z => z.Type == ClaimTypes.Name)?.Value;
-
- if (string.IsNullOrEmpty(userName))
- throw new Exception("User name could not be retrieved from claims.");
-
- return userName;
- }
-
- public bool UserIsGuest()
- {
- var userIsGuest = _httpAccessor.HttpContext.User?.Claims.FirstOrDefault(z => z.Type == Netmash.Security.Authentication.Tuitio.Constants.ClaimTypes.IsGuestUser)?.Value;
- return !string.IsNullOrEmpty(userIsGuest) && bool.TrueString == userIsGuest;
- }
- }
-}