From c639f86068ecc143b21307a2a23114ada7e94d8e Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Sun, 27 Apr 2025 22:29:35 +0200 Subject: [PATCH] Adding permissions during startup --- MainProject/Config/permissions.json | 32 ++++++++++ MainProject/Models/Common/OperationInfo.cs | 9 +++ MainProject/Models/Common/PermissionInfo.cs | 9 +++ MainProject/Models/Common/PermissionsFile.cs | 8 +++ .../Common/RolePermissionModuleOperation.cs | 9 +++ MainProject/Models/Settings/AppSettings.cs | 2 +- .../Models/Settings/PermissionsSettings.cs | 8 +++ MainProject/Program.cs | 1 + MainProject/Services/PermissionService.cs | 62 +++++++++++++------ MainProject/Utils/FileUtils.cs.cs | 52 ++++++++++++++++ MainProject/Utils/ProgramUtils.cs | 22 +++++++ MainProject/appsettings.json | 3 + 12 files changed, 196 insertions(+), 21 deletions(-) create mode 100644 MainProject/Config/permissions.json create mode 100644 MainProject/Models/Common/OperationInfo.cs create mode 100644 MainProject/Models/Common/PermissionInfo.cs create mode 100644 MainProject/Models/Common/PermissionsFile.cs create mode 100644 MainProject/Models/Common/RolePermissionModuleOperation.cs create mode 100644 MainProject/Models/Settings/PermissionsSettings.cs create mode 100644 MainProject/Utils/FileUtils.cs.cs diff --git a/MainProject/Config/permissions.json b/MainProject/Config/permissions.json new file mode 100644 index 0000000..57248b8 --- /dev/null +++ b/MainProject/Config/permissions.json @@ -0,0 +1,32 @@ +{ + "PermissionInfos": [ + { + "System": "base", + "RolePermissionModuleOperations": [ + { + "Module": "role", + "Operations": [ + { "Operation": "create", "Roles": [] }, + { "Operation": "read", "Roles": [] }, + { "Operation": "update", "Roles": [] }, + { "Operation": "delete", "Roles": [] }, + { "Operation": "list", "Roles": [] }, + { "Operation": "use", "Roles": [] } + ] + }, + { + "Module": "user", + "Operations": [ + { "Operation": "create", "Roles": [] }, + { "Operation": "read", "Roles": [] }, + { "Operation": "update", "Roles": [] }, + { "Operation": "delete", "Roles": [] }, + { "Operation": "list", "Roles": [] }, + { "Operation": "use", "Roles": [] } + ] + } + ] + } + + ] +} \ No newline at end of file diff --git a/MainProject/Models/Common/OperationInfo.cs b/MainProject/Models/Common/OperationInfo.cs new file mode 100644 index 0000000..7e9a9a8 --- /dev/null +++ b/MainProject/Models/Common/OperationInfo.cs @@ -0,0 +1,9 @@ +namespace BasicDotnetTemplate.MainProject.Models.Common; + +public class OperationInfo +{ +#nullable enable + public string? Operation { get; set; } + public List? Roles {get; set; } +#nullable disable +} \ No newline at end of file diff --git a/MainProject/Models/Common/PermissionInfo.cs b/MainProject/Models/Common/PermissionInfo.cs new file mode 100644 index 0000000..558fc5d --- /dev/null +++ b/MainProject/Models/Common/PermissionInfo.cs @@ -0,0 +1,9 @@ +namespace BasicDotnetTemplate.MainProject.Models.Common; + +public class PermissionInfo +{ +#nullable enable + public string? System { get; set; } + public List? RolePermissionModuleOperations {get; set; } +#nullable disable +} \ No newline at end of file diff --git a/MainProject/Models/Common/PermissionsFile.cs b/MainProject/Models/Common/PermissionsFile.cs new file mode 100644 index 0000000..f5a4d7b --- /dev/null +++ b/MainProject/Models/Common/PermissionsFile.cs @@ -0,0 +1,8 @@ +namespace BasicDotnetTemplate.MainProject.Models.Common; + +public class PermissionsFile +{ +#nullable enable + public List? PermissionInfos { get; set; } +#nullable disable +} \ No newline at end of file diff --git a/MainProject/Models/Common/RolePermissionModuleOperation.cs b/MainProject/Models/Common/RolePermissionModuleOperation.cs new file mode 100644 index 0000000..6d132e5 --- /dev/null +++ b/MainProject/Models/Common/RolePermissionModuleOperation.cs @@ -0,0 +1,9 @@ +namespace BasicDotnetTemplate.MainProject.Models.Common; + +public class RolePermissionModuleOperation +{ +#nullable enable + public string? Module { get; set; } + public List? Operations { get; set; } +#nullable disable +} \ No newline at end of file diff --git a/MainProject/Models/Settings/AppSettings.cs b/MainProject/Models/Settings/AppSettings.cs index b92311f..3df03e9 100644 --- a/MainProject/Models/Settings/AppSettings.cs +++ b/MainProject/Models/Settings/AppSettings.cs @@ -9,6 +9,6 @@ public class AppSettings public DatabaseSettings? DatabaseSettings { get; set; } public JwtSettings? JwtSettings { get; set; } public EncryptionSettings? EncryptionSettings { get; set; } - + public PermissionsSettings? PermissionsSettings { get; set; } #nullable disable } \ No newline at end of file diff --git a/MainProject/Models/Settings/PermissionsSettings.cs b/MainProject/Models/Settings/PermissionsSettings.cs new file mode 100644 index 0000000..495dc9a --- /dev/null +++ b/MainProject/Models/Settings/PermissionsSettings.cs @@ -0,0 +1,8 @@ +namespace BasicDotnetTemplate.MainProject.Models.Settings; + +public class PermissionsSettings +{ +#nullable enable + public string? FilePath { get; set; } +#nullable disable +} \ No newline at end of file diff --git a/MainProject/Program.cs b/MainProject/Program.cs index 732a39e..e6213b2 100644 --- a/MainProject/Program.cs +++ b/MainProject/Program.cs @@ -45,6 +45,7 @@ internal static class Program WebApplication app = builder.Build(); ProgramUtils.AddMiddlewares(ref app); ProgramUtils.CreateRoles(ref app); + ProgramUtils.CreatePermissions(ref app); Logger.Info("[Program][Initialize] End building"); return app; diff --git a/MainProject/Services/PermissionService.cs b/MainProject/Services/PermissionService.cs index 170e8ad..f56f7bb 100644 --- a/MainProject/Services/PermissionService.cs +++ b/MainProject/Services/PermissionService.cs @@ -4,6 +4,8 @@ using BasicDotnetTemplate.MainProject.Core.Database; using BasicDotnetTemplate.MainProject.Models.Api.Common.Exceptions; using BasicDotnetTemplate.MainProject.Models.Database.SqlServer; using Microsoft.EntityFrameworkCore; +using BasicDotnetTemplate.MainProject.Models.Common; +using BasicDotnetTemplate.MainProject.Utils; namespace BasicDotnetTemplate.MainProject.Services; @@ -32,7 +34,7 @@ public interface IPermissionService Task GetPermissionSystemModuleByGuidAsync(string guid); Task HandleEnabledPermissionSystemModuleAsync(PermissionSystemModule permission, bool enabled); Task CreatePermissionSystemModuleAsync( - PermissionSystem permissionSystem, + PermissionSystem permissionSystem, PermissionModule permissionModule, bool enabled ); @@ -42,7 +44,7 @@ public interface IPermissionService Task GetPermissionSystemModuleOperationByGuidAsync(string guid); Task HandleEnabledPermissionSystemModuleOperationAsync(PermissionSystemModuleOperation permission, bool enabled); Task CreatePermissionSystemModuleOperationAsync( - PermissionSystemModule permissionSystemModule, + PermissionSystemModule permissionSystemModule, PermissionOperation permissionOperation, bool enabled ); @@ -52,11 +54,14 @@ public interface IPermissionService Task GetRolePermissionSystemModuleOperationByGuidAsync(string guid); Task HandleEnabledRolePermissionSystemModuleOperationAsync(RolePermissionSystemModuleOperation permission, bool active); Task CreateRolePermissionSystemModuleOperationAsync( - Role role, + Role role, PermissionSystemModuleOperation permissionSystemModuleOperation, bool enabled ); Task DeleteRolePermissionSystemModuleOperationAsync(RolePermissionSystemModuleOperation permission); + + Task?> CreatePermissionsOnStartupAsync(); + } public class PermissionService : BaseService, IPermissionService @@ -201,8 +206,8 @@ public class PermissionService : BaseService, IPermissionService } private static RolePermissionSystemModuleOperation CreateRolePermissionSystemModuleOperationData( - Role role, - PermissionSystemModuleOperation permissionModuleOperation, + Role role, + PermissionSystemModuleOperation permissionModuleOperation, bool active ) { @@ -221,7 +226,7 @@ public class PermissionService : BaseService, IPermissionService return permission; } -#region "PermissionSystem" + #region "PermissionSystem" public async Task GetPermissionSystemByGuidAsync(string guid) { @@ -290,10 +295,10 @@ public class PermissionService : BaseService, IPermissionService return deleted; } -#endregion + #endregion -#region "PermissionModule" + #region "PermissionModule" public async Task GetPermissionModuleByGuidAsync(string guid) @@ -363,10 +368,10 @@ public class PermissionService : BaseService, IPermissionService return deleted; } -#endregion + #endregion -#region "PermissionOperation" + #region "PermissionOperation" public async Task GetPermissionOperationByGuidAsync(string guid) { @@ -418,10 +423,10 @@ public class PermissionService : BaseService, IPermissionService return deleted; } -#endregion + #endregion -#region "PermissionSystemModule" + #region "PermissionSystemModule" public async Task GetPermissionSystemModuleByGuidAsync(string guid) { @@ -429,7 +434,7 @@ public class PermissionService : BaseService, IPermissionService } public async Task CreatePermissionSystemModuleAsync( - PermissionSystem permissionSystem, + PermissionSystem permissionSystem, PermissionModule permissionModule, bool enabled ) @@ -489,10 +494,10 @@ public class PermissionService : BaseService, IPermissionService return deleted; } -#endregion + #endregion -#region "PermissionSystemModuleOperation" + #region "PermissionSystemModuleOperation" public async Task GetPermissionSystemModuleOperationByGuidAsync(string guid) { @@ -500,7 +505,7 @@ public class PermissionService : BaseService, IPermissionService } public async Task CreatePermissionSystemModuleOperationAsync( - PermissionSystemModule permissionSystemModule, + PermissionSystemModule permissionSystemModule, PermissionOperation permissionOperation, bool enabled ) @@ -560,10 +565,10 @@ public class PermissionService : BaseService, IPermissionService return deleted; } -#endregion + #endregion -#region "RolePermissionSystemModuleOperation" + #region "RolePermissionSystemModuleOperation" public async Task GetRolePermissionSystemModuleOperationByGuidAsync(string guid) { @@ -571,7 +576,7 @@ public class PermissionService : BaseService, IPermissionService } public async Task CreateRolePermissionSystemModuleOperationAsync( - Role role, + Role role, PermissionSystemModuleOperation permissionSystemModuleOperation, bool enabled ) @@ -631,7 +636,24 @@ public class PermissionService : BaseService, IPermissionService return deleted; } -#endregion + #endregion + + + public async Task?> CreatePermissionsOnStartupAsync() + { + try + { + List? newPermissions = null; + PermissionsFile? permissionsFile = FileUtils.ConvertFileToObject(System.AppDomain.CurrentDomain.BaseDirectory + this._appSettings.PermissionsSettings.FilePath); + return newPermissions; + } + catch (Exception exception) + { + Logger.Error(exception, $"[PermissionService][CreatePermissionsOnStartupAsync]"); + throw new CreateException($"An error occurred while adding permissions during startup", exception); + } + + } } diff --git a/MainProject/Utils/FileUtils.cs.cs b/MainProject/Utils/FileUtils.cs.cs new file mode 100644 index 0000000..be3ed4e --- /dev/null +++ b/MainProject/Utils/FileUtils.cs.cs @@ -0,0 +1,52 @@ +using System; +using System.IO; +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Microsoft.OpenApi.Models; +using MongoDB.Driver; +using NLog; +using BasicDotnetTemplate.MainProject.Core.Database; +using BasicDotnetTemplate.MainProject.Core.Middlewares; +using BasicDotnetTemplate.MainProject.Models.Settings; +using BasicDotnetTemplate.MainProject.Services; +using BasicDotnetTemplate.MainProject.Models.Api.Data.Role; +using BasicDotnetTemplate.MainProject.Models.Database.SqlServer; + + + +namespace BasicDotnetTemplate.MainProject.Utils; + +public static class FileUtils +{ + private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + + public static T? ConvertFileToObject(string? filePath = "") + { + Logger.Info("[FileUtils][ReadJson] Reading file"); + + if (string.IsNullOrWhiteSpace(filePath)) + { + throw new ArgumentException("filePath cannot be null or empty", nameof(filePath)); + } + + if (!File.Exists(filePath)) + { + throw new FileNotFoundException("The specified file does not exists", filePath); + } + + try + { + string fileContent = File.ReadAllText(filePath); + + return JsonSerializer.Deserialize(fileContent, new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }); + } + catch (JsonException ex) + { + throw new InvalidOperationException("Error during file deserialization", ex); + } + } + +} \ No newline at end of file diff --git a/MainProject/Utils/ProgramUtils.cs b/MainProject/Utils/ProgramUtils.cs index 7b55858..9e69376 100644 --- a/MainProject/Utils/ProgramUtils.cs +++ b/MainProject/Utils/ProgramUtils.cs @@ -218,6 +218,7 @@ public static class ProgramUtils builder.Services.AddHttpContextAccessor(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); Logger.Info("[ProgramUtils][AddScopes] Done scopes"); @@ -271,4 +272,25 @@ public static class ProgramUtils } + public static void CreatePermissions(ref WebApplication app) + { + Logger.Info("[ProgramUtils][CreatePermissions] Adding permissions..."); + using (var scope = app.Services.CreateScope()) + { + var permissionService = scope.ServiceProvider.GetRequiredService; + if (permissionService != null) + { + var isValidThread = Task.Run(() => permissionService!.Invoke()?.CreatePermissionsOnStartupAsync()); + if (isValidThread.Result != null) + { + Logger.Info("[ProgramUtils][CreatePermissions] Done permissions"); + } + else + { + Logger.Error("[ProgramUtils][CreatePermissions] Something went wrong"); + } + } + } + } + } \ No newline at end of file diff --git a/MainProject/appsettings.json b/MainProject/appsettings.json index 86a85b8..8893bf2 100644 --- a/MainProject/appsettings.json +++ b/MainProject/appsettings.json @@ -37,6 +37,9 @@ "EncryptionSettings": { "Salt": "S7VIidfXQf1tOQYX", "Pepper": "" + }, + "PermissionsSettings": { + "FilePath": "Config/permissions.json" } } } \ No newline at end of file