diff --git a/.gitignore b/.gitignore index d751038..89ec5c5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ **/bin **/obj **/obj/** -**/Debug \ No newline at end of file +**/Debug + +.idea/ \ No newline at end of file diff --git a/Client/Modules/SZUAbsolventenverein.Module.ReportSystem/Index.razor b/Client/Modules/SZUAbsolventenverein.Module.ReportSystem/Index.razor new file mode 100644 index 0000000..1b3ca78 --- /dev/null +++ b/Client/Modules/SZUAbsolventenverein.Module.ReportSystem/Index.razor @@ -0,0 +1,79 @@ +@namespace SZUAbsolventenverein.Module.ReportSystem +@using Microsoft.VisualBasic.FileIO +@using SZUAbsolventenverein.Module.ReportSystem.Models +@using SZUAbsolventenverein.Module.ReportSystem.Services + +@inherits ModuleBase +@inject NavigationManager NavigationManager +@inject IReportSystemReportingService ReportingService +@inject IStringLocalizer Localizer + +@if (reportings == null) +{ +

Loading...

+} +else +{ +
+
+ @if (reportings.Count != 0) + { + +
+   +   +   + @Localizer["Name"] +
+ + + + + @context.Reason + +
+ } + else + { +

@Localizer["Message.DisplayNone"]

+ } +} + + +@code { + public override string RenderMode => RenderModes.Interactive; + + public override List Resources => new List() + { + new Stylesheet("_content/SZUAbsolventenverein.Module.ReportSystem/Module.css"), + new Script("_content/SZUAbsolventenverein.Module.ReportSystem/Module.js") + }; + + private List reportings = new List(); + + protected override async Task OnInitializedAsync() + { + try + { + reportings = await ReportingService.GetReportsAsync(ModuleState.ModuleId); + } + catch (Exception ex) + { + logger.LogError("Error fetching reportings: {Message}", ex.Message); + }; + } + + private async Task Delete(Reporting reporting) + { + try + { + await ReportingService.DeleteReportingAsync(reporting.ReportingID, ModuleState.ModuleId); + reportings.Remove(reporting); + StateHasChanged(); + } + catch (Exception ex) + { + logger.LogError("Error deleting reporting: {Message}", ex.Message); + } + } +} \ No newline at end of file diff --git a/Client/Modules/SZUAbsolventenverein.Module.ReportSystem/ModuleInfo.cs b/Client/Modules/SZUAbsolventenverein.Module.ReportSystem/ModuleInfo.cs new file mode 100644 index 0000000..6a49366 --- /dev/null +++ b/Client/Modules/SZUAbsolventenverein.Module.ReportSystem/ModuleInfo.cs @@ -0,0 +1,21 @@ +using System; +using Oqtane.Models; +using Oqtane.Modules; + +namespace SZUAbsolventenverein.Module.ReportSystem +{ + public class ModuleInfo : IModule + { + public ModuleDefinition ModuleDefinition => new ModuleDefinition + { + Name = "ReportSystem", + Description = "Handle Systemwide Reporting", + Version = "1.0.0", + ServerManagerType = + "SZUAbsolventenverein.Module.ReportSystem.Manager.ReportSystemManager, SZUAbsolventenverein.Module.AdminModules.Server.Oqtane", + ReleaseVersions = "1.0.0", + Dependencies = "SZUAbsolventenverein.Module.ReportSystem.Shared.Oqtane", + PackageName = "SZUAbsolventenverein.Module.ReportSystem", + }; + } +} \ No newline at end of file diff --git a/Client/Modules/SZUAbsolventenverein.Module.ReportSystem/Settings.razor b/Client/Modules/SZUAbsolventenverein.Module.ReportSystem/Settings.razor new file mode 100644 index 0000000..d0f3e97 --- /dev/null +++ b/Client/Modules/SZUAbsolventenverein.Module.ReportSystem/Settings.razor @@ -0,0 +1,49 @@ +@namespace SZUAbsolventenverein.Module.ReportSystem +@inherits ModuleBase +@inject ISettingService SettingService +@inject IStringLocalizer Localizer + +
+
+ +
+ +
+
+
+ +@code { + private string resourceType = "SZUAbsolventenverein.Module.ReportSystem.Settings, SZUAbsolventenverein.Module.AdminModules.Client.Oqtane"; // for localization + public override string Title => "ReportSystem Settings"; + + string _value; + + protected override async Task OnInitializedAsync() + { + try + { + Dictionary settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId); + _value = SettingService.GetSetting(settings, "SettingName", ""); + } + catch (Exception ex) + { + AddModuleMessage(ex.Message, MessageType.Error); + } + } + + public async Task UpdateSettings() + { + try + { + Dictionary settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId); + SettingService.SetSetting(settings, "SettingName", _value); + await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); + } + catch (Exception ex) + { + AddModuleMessage(ex.Message, MessageType.Error); + } + } + +} diff --git a/Client/SZUAbsolventenverein.Module.AdminModules.Client.csproj b/Client/SZUAbsolventenverein.Module.AdminModules.Client.csproj index 435b883..b44f0ef 100644 --- a/Client/SZUAbsolventenverein.Module.AdminModules.Client.csproj +++ b/Client/SZUAbsolventenverein.Module.AdminModules.Client.csproj @@ -25,10 +25,18 @@ + + ..\..\interfaces\Interfaces\bin\Debug\net10.0\Interfaces.dll + ..\..\oqtane.framework\Oqtane.Server\bin\Debug\net10.0\Oqtane.Client.dll ..\..\oqtane.framework\Oqtane.Server\bin\Debug\net10.0\Oqtane.Shared.dll + + false diff --git a/Client/Services/ReportSystemReportingService.cs b/Client/Services/ReportSystemReportingService.cs new file mode 100644 index 0000000..340fc5a --- /dev/null +++ b/Client/Services/ReportSystemReportingService.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Interfaces; +using SZUAbsolventenverein.Module.ReportSystem.Models; + +namespace SZUAbsolventenverein.Module.ReportSystem.Services +{ + public interface IReportSystemReportingService + { + Task CreateReportAsync(Reporting reporting); + Task> GetReportsAsync(int ModuleId); + Task GetReportAsync(int ReportableId, int ModuleId); + Task UpdateReport(Reporting reporting); + Task DeleteReportingAsync(int ReportingId, int ModuleId); + } + + public class ReportSystemReportingService : IReportSystemReportingService, IReportingHandler + { + public void Report(IReportable reportable, string note) + { + CreateReportAsync(new Reporting + { ModuleId = reportable.ModuleID, EntityId = reportable.EntityID, Note = note, Reason = "Default Reason" }); + } + + public Task CreateReportAsync(Reporting reporting) + { + throw new System.NotImplementedException(); + } + + public Task> GetReportsAsync(int ModuleId) + { + throw new System.NotImplementedException(); + } + + public Task GetReportAsync(int ReportableId, int ModuleId) + { + throw new System.NotImplementedException(); + } + + public Task UpdateReport(Reporting Reporting) + { + throw new System.NotImplementedException(); + } + + public Task DeleteReportingAsync(int ReportingId, int ModuleId) + { + throw new System.NotImplementedException(); + } + } +} + diff --git a/Client/Startup/ClientStartup.cs b/Client/Startup/ClientStartup.cs index 08c22eb..0b0e928 100644 --- a/Client/Startup/ClientStartup.cs +++ b/Client/Startup/ClientStartup.cs @@ -1,7 +1,9 @@ using Microsoft.Extensions.DependencyInjection; using System.Linq; +using Interfaces; using Oqtane.Services; using SZUAbsolventenverein.Module.AdminModules.Services; +using SZUAbsolventenverein.Module.ReportSystem.Services; namespace SZUAbsolventenverein.Module.AdminModules.Startup { @@ -13,6 +15,15 @@ namespace SZUAbsolventenverein.Module.AdminModules.Startup { services.AddScoped(); } + + if (!services.Any(s => s.ServiceType == typeof(IReportingHandler))) + { + services.AddScoped(); + } + if (!services.Any(s => s.ServiceType == typeof(IReportSystemReportingService))) + { + services.AddScoped(); + } } } } diff --git a/Package/debug.sh b/Package/debug.sh index 4a8b343..058d474 100644 --- a/Package/debug.sh +++ b/Package/debug.sh @@ -3,10 +3,10 @@ TargetFramework=$1 ProjectName=$2 -cp -f "../Client/bin/Debug/$TargetFramework/$ProjectName$.Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" -cp -f "../Client/bin/Debug/$TargetFramework/$ProjectName$.Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" -cp -f "../Server/bin/Debug/$TargetFramework/$ProjectName$.Server.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" -cp -f "../Server/bin/Debug/$TargetFramework/$ProjectName$.Server.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" -cp -f "../Shared/bin/Debug/$TargetFramework/$ProjectName$.Shared.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" -cp -f "../Shared/bin/Debug/$TargetFramework/$ProjectName$.Shared.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" -cp -rf "../Server/wwwroot/"* "../../oqtane.framework/Oqtane.Server/wwwroot/_content/%ProjectName%/" +cp -f "../Client/bin/Debug/$TargetFramework/$ProjectName.Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" +cp -f "../Client/bin/Debug/$TargetFramework/$ProjectName.Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" +cp -f "../Server/bin/Debug/$TargetFramework/$ProjectName.Server.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" +cp -f "../Server/bin/Debug/$TargetFramework/$ProjectName.Server.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" +cp -f "../Shared/bin/Debug/$TargetFramework/$ProjectName.Shared.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" +cp -f "../Shared/bin/Debug/$TargetFramework/$ProjectName.Shared.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/$TargetFramework/" +cp -rf "../Server/wwwroot/"* "../../oqtane.framework/Oqtane.Server/wwwroot/_content/$ProjectName/" diff --git a/SZUAbsolventenverein.Module.AdminModules.sln.DotSettings.user b/SZUAbsolventenverein.Module.AdminModules.sln.DotSettings.user new file mode 100644 index 0000000..69b84c8 --- /dev/null +++ b/SZUAbsolventenverein.Module.AdminModules.sln.DotSettings.user @@ -0,0 +1,7 @@ + + True + True + ForceIncluded + <AssemblyExplorer> + <Assembly Path="/home/kocoder/alumnihub_10.0_amd64/SZUAbsolventenverein/Interfaces/bin/Debug/net10.0/Interfaces.dll" /> +</AssemblyExplorer> \ No newline at end of file diff --git a/Server/Controllers/ReportSystemController.cs b/Server/Controllers/ReportSystemController.cs new file mode 100644 index 0000000..e23e39e --- /dev/null +++ b/Server/Controllers/ReportSystemController.cs @@ -0,0 +1,117 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using System.Collections.Generic; +using Microsoft.AspNetCore.Http; +using Oqtane.Shared; +using Oqtane.Enums; +using Oqtane.Infrastructure; +using SZUAbsolventenverein.Module.AdminModules.Services; +using Oqtane.Controllers; +using System.Net; +using System.Threading.Tasks; +using SZUAbsolventenverein.Module.AdminModules.Models; +using Oqtane.Models; +using SZUAbsolventenverein.Module.ReportSystem.Models; +using SZUAbsolventenverein.Module.ReportSystem.Services; + +namespace SZUAbsolventenverein.Module.ReportSystem.Controllers +{ + [Route(ControllerRoutes.ApiRoute)] + public class ReportSystemController : ModuleControllerBase + { + private readonly IReportSystemReportingService _reportSystemReportingService; + + public ReportSystemController(IReportSystemReportingService reportSystemReportingService, ILogManager logger, IHttpContextAccessor accessor) : base(logger, accessor) + { + _reportSystemReportingService = reportSystemReportingService; + } + + // GET: api/?moduleid=x + [HttpGet] + [Authorize(Policy = PolicyNames.ViewModule)] + public async Task> Get(string moduleid) + { + int ModuleId; + if (int.TryParse(moduleid, out ModuleId) && IsAuthorizedEntityId(EntityNames.Module, ModuleId)) + { + return await _reportSystemReportingService.GetReportsAsync(ModuleId); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reporting Get Attempt {ModuleId}", moduleid); + HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; + return null; + } + } + + // GET api//5 + [HttpGet("get/{id}/{moduleid}")] + [Authorize(Policy = PolicyNames.ViewModule)] + public async Task Get(int id, int moduleid) + { + if (IsAuthorizedEntityId(EntityNames.Module, moduleid)) + { + return await _reportSystemReportingService.GetReportAsync(id, moduleid); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reporting Get Attempt {Reporting} {ModuleId}", id, moduleid); + HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; + return null; + } + } + + // POST api/ + [HttpPost] + [Authorize(Policy = PolicyNames.EditModule)] + public async Task Post([FromBody] Reporting Reporting) + { + if (ModelState.IsValid && IsAuthorizedEntityId(EntityNames.Module, Reporting.ModuleId)) + { + Reporting = await _reportSystemReportingService.CreateReportAsync(Reporting); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reporting Post Attempt {Reporting}", Reporting); + HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; + Reporting = null; + } + return Reporting; + } + + // PUT api//5 + [HttpPut("{id}")] + [Authorize(Policy = PolicyNames.EditModule)] + public async Task Put(int id, [FromBody] Reporting Reporting) + { + if (ModelState.IsValid && Reporting.ReportingID == id && IsAuthorizedEntityId(EntityNames.Module, Reporting.ReportingID)) + { + Reporting = await _reportSystemReportingService.UpdateReport(Reporting); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reporting Put Attempt {Reporting}", Reporting); + HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; + Reporting = null; + } + return Reporting; + } + + // DELETE api//5 + [HttpDelete("{id}/{moduleid}")] + [Authorize(Policy = PolicyNames.EditModule)] + public async Task Delete(int id, int moduleid) + { + Reporting Reporting = await _reportSystemReportingService.GetReportAsync(id, moduleid); + if (Reporting != null && IsAuthorizedEntityId(EntityNames.Module, Reporting.ReportingID)) + { + await _reportSystemReportingService.DeleteReportingAsync(id, Reporting.ReportingID); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reporting Delete Attempt {ReportingID} {ModuleId}", id, moduleid); + HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; + } + } + } +} diff --git a/Server/Manager/ReportSystemManager.cs b/Server/Manager/ReportSystemManager.cs new file mode 100644 index 0000000..1f06e08 --- /dev/null +++ b/Server/Manager/ReportSystemManager.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using Oqtane.Modules; +using Oqtane.Models; +using Oqtane.Infrastructure; +using Oqtane.Interfaces; +using Oqtane.Enums; +using Oqtane.Repository; +using SZUAbsolventenverein.Module.AdminModules.Repository; +using System.Threading.Tasks; +using SZUAbsolventenverein.Module.ReportSystem.Models; +using SZUAbsolventenverein.Module.ReportSystem.Repository; +using SZUAbsolventenverein.Module.ReportSystem.Services; +using Oqtane.Shared; + +namespace SZUAbsolventenverein.Module.ReportSystem.Manager +{ + public class ReportSystemManager : MigratableModuleBase, IInstallable, IPortable, ISearchable + { + private readonly IReportingRepository _reportSystemRepository; + private readonly IDBContextDependencies _DBContextDependencies; + + public ReportSystemManager(IReportingRepository reportSystemRepository, IDBContextDependencies DBContextDependencies) + { + _reportSystemRepository = reportSystemRepository; + _DBContextDependencies = DBContextDependencies; + } + + public bool Install(Tenant tenant, string version) + { + Console.WriteLine("Installing ReportSystem module for tenant {TenantId}"); + return Migrate(new ReportingContext(_DBContextDependencies), tenant, MigrationType.Up); + } + + public bool Uninstall(Tenant tenant) + { + return Migrate(new ReportingContext(_DBContextDependencies), tenant, MigrationType.Down); + } + + public string ExportModule(Oqtane.Models.Module module) + { + string content = ""; + List reportings = _reportSystemRepository.GetReportings().ToList(); + if (reportings != null) + { + content = JsonSerializer.Serialize(reportings); + } + return content; + } + + public void ImportModule(Oqtane.Models.Module module, string content, string version) + { + List reportings = null; + if (!string.IsNullOrEmpty(content)) + { + reportings = JsonSerializer.Deserialize>(content); + } + if (reportings != null) + { + foreach(var reporting in reportings) + { + _reportSystemRepository.AddReporting(reporting); + } + } + } + + public Task> GetSearchContentsAsync(PageModule pageModule, DateTime lastIndexedOn) + { + var searchContentList = new List(); + + return Task.FromResult(searchContentList); + } + } +} diff --git a/Server/Migrations/EntityBuilders/ReportingEntityBuilder.cs b/Server/Migrations/EntityBuilders/ReportingEntityBuilder.cs new file mode 100644 index 0000000..630cb63 --- /dev/null +++ b/Server/Migrations/EntityBuilders/ReportingEntityBuilder.cs @@ -0,0 +1,37 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations.Operations; +using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; +using Oqtane.Databases.Interfaces; +using Oqtane.Migrations; +using Oqtane.Migrations.EntityBuilders; + +namespace SZUAbsolventenverein.Module.AdminModules.Migrations.EntityBuilders; + +public class ReportingEntityBuilder : AuditableBaseEntityBuilder +{ + private const string _entityTableName = "SZUAbsolventenvereinReportings"; + private readonly PrimaryKey _primaryKey = new ("PK_ReportingEntityBuilder", x => x.ReportingID); + + public ReportingEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database) + { + EntityTableName = _entityTableName; + PrimaryKey = _primaryKey; + } + + protected override ReportingEntityBuilder BuildTable(ColumnsBuilder table) + { + ReportingID = AddAutoIncrementColumn(table, "ReportingID"); + ModuleId = AddIntegerColumn(table, "ModuleId"); + EntityId = AddIntegerColumn(table, "EntityId"); + Note = AddMaxStringColumn(table, "Note"); + Reason = AddMaxStringColumn(table, "Reason"); + AddAuditableColumns(table); + return this; + } + + public OperationBuilder ReportingID { get; set; } + public OperationBuilder ModuleId { get; set; } + public OperationBuilder EntityId { get; set; } + public OperationBuilder Note { get; set; } + public OperationBuilder Reason { get; set; } +} \ No newline at end of file diff --git a/Server/Migrations/ReportSystem/01000000_InitializeModule.cs b/Server/Migrations/ReportSystem/01000000_InitializeModule.cs new file mode 100644 index 0000000..44bb062 --- /dev/null +++ b/Server/Migrations/ReportSystem/01000000_InitializeModule.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Oqtane.Databases.Interfaces; +using Oqtane.Migrations; +using SZUAbsolventenverein.Module.AdminModules.Migrations.EntityBuilders; +using SZUAbsolventenverein.Module.AdminModules.Repository; + +namespace SZUAbsolventenverein.Module.ReportSystem.Migrations +{ + [DbContext(typeof(ReportingContext))] + [Migration("SZUAbsolventenverein.Module.ReportSystem.01.00.00.00")] + public class InitializeModule : MultiDatabaseMigration + { + public InitializeModule(IDatabase database) : base(database) + { + } + + protected override void Up(MigrationBuilder migrationBuilder) + { + var entityBuilder = new ReportingEntityBuilder(migrationBuilder, ActiveDatabase); + entityBuilder.Create(); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + var entityBuilder = new ReportingEntityBuilder(migrationBuilder, ActiveDatabase); + entityBuilder.Drop(); + } + } +} diff --git a/Server/Repository/AdminModules/AdminModulesContext.cs b/Server/Repository/AdminModules/AdminModulesContext.cs new file mode 100644 index 0000000..1421ebb --- /dev/null +++ b/Server/Repository/AdminModules/AdminModulesContext.cs @@ -0,0 +1,27 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Http; +using Oqtane.Modules; +using Oqtane.Repository; +using Oqtane.Infrastructure; +using Oqtane.Repository.Databases.Interfaces; +using SZUAbsolventenverein.Module.ReportSystem.Models; + +namespace SZUAbsolventenverein.Module.AdminModules.Repository +{ + public class AdminModulesContext : DBContextBase, ITransientService, IMultiDatabase + { + public virtual DbSet AdminModules { get; set; } + + public AdminModulesContext(IDBContextDependencies DBContextDependencies) : base(DBContextDependencies) + { + // ContextBase handles multi-tenant database connections + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + + builder.Entity().ToTable(ActiveDatabase.RewriteName("SZUAbsolventenvereinAdminModules")); + } + } +} diff --git a/Server/Repository/AdminModules/AdminModulesRepository.cs b/Server/Repository/AdminModules/AdminModulesRepository.cs new file mode 100644 index 0000000..8683383 --- /dev/null +++ b/Server/Repository/AdminModules/AdminModulesRepository.cs @@ -0,0 +1,75 @@ +using Microsoft.EntityFrameworkCore; +using System.Linq; +using System.Collections.Generic; +using Oqtane.Modules; + +namespace SZUAbsolventenverein.Module.AdminModules.Repository +{ + public interface IAdminModulesRepository + { + IEnumerable GetAdminModuless(int ModuleId); + Models.AdminModules GetAdminModules(int AdminModulesId); + Models.AdminModules GetAdminModules(int AdminModulesId, bool tracking); + Models.AdminModules AddAdminModules(Models.AdminModules AdminModules); + Models.AdminModules UpdateAdminModules(Models.AdminModules AdminModules); + void DeleteAdminModules(int AdminModulesId); + } + + public class AdminModulesRepository : IAdminModulesRepository, ITransientService + { + private readonly IDbContextFactory _factory; + + public AdminModulesRepository(IDbContextFactory factory) + { + _factory = factory; + } + + public IEnumerable GetAdminModuless(int ModuleId) + { + using var db = _factory.CreateDbContext(); + return db.AdminModules.Where(item => item.ModuleId == ModuleId).ToList(); + } + + public Models.AdminModules GetAdminModules(int AdminModulesId) + { + return GetAdminModules(AdminModulesId, true); + } + + public Models.AdminModules GetAdminModules(int AdminModulesId, bool tracking) + { + using var db = _factory.CreateDbContext(); + if (tracking) + { + return db.AdminModules.Find(AdminModulesId); + } + else + { + return db.AdminModules.AsNoTracking().FirstOrDefault(item => item.AdminModulesId == AdminModulesId); + } + } + + public Models.AdminModules AddAdminModules(Models.AdminModules AdminModules) + { + using var db = _factory.CreateDbContext(); + db.AdminModules.Add(AdminModules); + db.SaveChanges(); + return AdminModules; + } + + public Models.AdminModules UpdateAdminModules(Models.AdminModules AdminModules) + { + using var db = _factory.CreateDbContext(); + db.Entry(AdminModules).State = EntityState.Modified; + db.SaveChanges(); + return AdminModules; + } + + public void DeleteAdminModules(int AdminModulesId) + { + using var db = _factory.CreateDbContext(); + Models.AdminModules AdminModules = db.AdminModules.Find(AdminModulesId); + db.AdminModules.Remove(AdminModules); + db.SaveChanges(); + } + } +} diff --git a/Server/Repository/ReportingSystem/ReportingContext.cs b/Server/Repository/ReportingSystem/ReportingContext.cs new file mode 100644 index 0000000..238e90e --- /dev/null +++ b/Server/Repository/ReportingSystem/ReportingContext.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Http; +using Oqtane.Modules; +using Oqtane.Repository; +using Oqtane.Infrastructure; +using Oqtane.Repository.Databases.Interfaces; +using SZUAbsolventenverein.Module.ReportSystem.Models; + +namespace SZUAbsolventenverein.Module.AdminModules.Repository +{ + public class ReportingContext : DBContextBase, ITransientService, IMultiDatabase + { + public virtual DbSet Reportings { get; set; } + + public ReportingContext(IDBContextDependencies DBContextDependencies) : base(DBContextDependencies) + {} + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + builder.Entity().ToTable(ActiveDatabase.RewriteName("SZUAbsolventenvereinReportings")); + } + } +} diff --git a/Server/Repository/ReportingSystem/ReportingRepository.cs b/Server/Repository/ReportingSystem/ReportingRepository.cs new file mode 100644 index 0000000..2fb5b62 --- /dev/null +++ b/Server/Repository/ReportingSystem/ReportingRepository.cs @@ -0,0 +1,77 @@ +using Microsoft.EntityFrameworkCore; +using System.Linq; +using System.Collections.Generic; +using Oqtane.Modules; +using SZUAbsolventenverein.Module.AdminModules.Repository; +using SZUAbsolventenverein.Module.ReportSystem.Models; + +namespace SZUAbsolventenverein.Module.ReportSystem.Repository +{ + public interface IReportingRepository + { + IEnumerable GetReportings(); + Reporting GetReporting(int ReportingID); + Reporting GetReporting(int ReportingID, bool tracking); + Reporting AddReporting(Reporting Reporting); + Reporting UpdateReporting(Reporting Reporting); + void DeleteReporting(int ReportingID); + } + + public class ReportingRepository : IReportingRepository, ITransientService + { + private readonly IDbContextFactory _factory; + + public ReportingRepository(IDbContextFactory factory) + { + _factory = factory; + } + + public IEnumerable GetReportings() + { + using var db = _factory.CreateDbContext(); + return db.Reportings.ToList(); + } + + public Reporting GetReporting(int ReportingID) + { + return GetReporting(ReportingID, true); + } + + public Reporting GetReporting(int ReportingID, bool tracking) + { + using var db = _factory.CreateDbContext(); + if (tracking) + { + return db.Reportings.Find(ReportingID); + } + else + { + return db.Reportings.AsNoTracking().FirstOrDefault(item => item.ReportingID == ReportingID); + } + } + + public Reporting AddReporting(Reporting Reporting) + { + using var db = _factory.CreateDbContext(); + db.Reportings.Add(Reporting); + db.SaveChanges(); + return Reporting; + } + + public Reporting UpdateReporting(Reporting Reporting) + { + using var db = _factory.CreateDbContext(); + db.Entry(Reporting).State = EntityState.Modified; + db.SaveChanges(); + return Reporting; + } + + public void DeleteReporting(int ReportingID) + { + using var db = _factory.CreateDbContext(); + var Reporting = db.Reportings.Find(ReportingID); + db.Reportings.Remove(Reporting); + db.SaveChanges(); + } + } +} diff --git a/Server/SZUAbsolventenverein.Module.AdminModules.Server.csproj b/Server/SZUAbsolventenverein.Module.AdminModules.Server.csproj index 328bb6c..e43cc1f 100644 --- a/Server/SZUAbsolventenverein.Module.AdminModules.Server.csproj +++ b/Server/SZUAbsolventenverein.Module.AdminModules.Server.csproj @@ -31,6 +31,9 @@ + + ..\..\interfaces\Interfaces\bin\Debug\net10.0\Interfaces.dll + ..\..\oqtane.framework\Oqtane.Server\bin\Debug\net10.0\Oqtane.Server.dll ..\..\oqtane.framework\Oqtane.Server\bin\Debug\net10.0\Oqtane.Shared.dll diff --git a/Server/Services/ReportSystemReportingService.cs b/Server/Services/ReportSystemReportingService.cs new file mode 100644 index 0000000..b733ca0 --- /dev/null +++ b/Server/Services/ReportSystemReportingService.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Interfaces; +using Microsoft.AspNetCore.Http; +using Oqtane.Enums; +using Oqtane.Infrastructure; +using Oqtane.Models; +using Oqtane.Security; +using Oqtane.Shared; +using SZUAbsolventenverein.Module.ReportSystem.Models; +using SZUAbsolventenverein.Module.ReportSystem.Repository; + +namespace SZUAbsolventenverein.Module.ReportSystem.Services +{ + public class ServerReportSystemReportingService : IReportSystemReportingService, IReportingHandler + { + private readonly IReportingRepository _reportSystemRepository; + private readonly IUserPermissions _userPermissions; + private readonly ILogManager _logger; + private readonly IHttpContextAccessor _accessor; + private readonly Alias _alias; + + public ServerReportSystemReportingService(IReportingRepository reportSystemRepository, IUserPermissions userPermissions, ITenantManager tenantManager, ILogManager logger, IHttpContextAccessor accessor) + { + _reportSystemRepository = reportSystemRepository; + _userPermissions = userPermissions; + _logger = logger; + _accessor = accessor; + _alias = tenantManager.GetAlias(); + } + + public Task CreateReportAsync(Reporting Reporting) + { + // true || + Console.WriteLine("HELP"); + if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.ModuleDefinition, 53, PermissionNames.Utilize)) + { + _logger.Log(LogLevel.Information, this, LogFunction.Update, "Reporting Updated {Reporting}", Reporting); + return Task.FromResult(_reportSystemRepository.AddReporting(Reporting)); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reporting Update Attempt {Reporting}", Reporting); + return null; + } + } + + public Task> GetReportsAsync(int ModuleId) + { + if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, ModuleId, PermissionNames.View)) + { + return Task.FromResult(_reportSystemRepository.GetReportings().ToList()); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reportings Get Attempt {ModuleId}", ModuleId); + return null; + } + } + + public Task GetReportAsync(int ReportableId, int ModuleId) + { + if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, ModuleId, PermissionNames.View)) + { + return Task.FromResult(_reportSystemRepository.GetReporting(ReportableId)); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reporting Get Attempt {ModuleId} {ReportableId}", ModuleId, ReportableId); + return null; + } + } + + public Task UpdateReport(Reporting Reporting) + { + if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, Reporting.ReportingID, PermissionNames.Edit)) + { + Reporting = _reportSystemRepository.UpdateReporting(Reporting); + _logger.Log(LogLevel.Information, this, LogFunction.Update, "Reporting Updated {Reporting}", Reporting); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reporting Update Attempt {Reporting}", Reporting); + Reporting = null; + } + + return Task.FromResult(Reporting); + } + + public Task DeleteReportingAsync(int ReportingId, int ModuleId) + { + if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, ModuleId, PermissionNames.Edit)) + { + _reportSystemRepository.DeleteReporting(ReportingId); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Reporting Deleted {ReportingId}", ReportingId); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reporting Delete Attempt {ReportingId} {ModuleId}", ReportingId, ModuleId); + } + return Task.CompletedTask; + } + + public async void Report(IReportable reportable, string note) + { + // if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, ModuleId, PermissionNames.Edit)) + { + Reporting reporting = await CreateReportAsync(new Reporting {ModuleId = reportable.ModuleID, EntityId = reportable.EntityID, Note = note, Reason = "Default Reason"}); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Reporting recieved {ReportingId}", reporting.ReportingID); + } + // else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Reporting Delete Attempt {EntityId} {ModuleId}", reportable.EntityID, reportable); + } + } + } +} \ No newline at end of file diff --git a/Server/Startup/ServerStartup.cs b/Server/Startup/ServerStartup.cs index d4e2e61..e1e93fb 100644 --- a/Server/Startup/ServerStartup.cs +++ b/Server/Startup/ServerStartup.cs @@ -1,9 +1,12 @@ +using Interfaces; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Oqtane.Infrastructure; using SZUAbsolventenverein.Module.AdminModules.Repository; using SZUAbsolventenverein.Module.AdminModules.Services; +using SZUAbsolventenverein.Module.ReportSystem.Repository; +using SZUAbsolventenverein.Module.ReportSystem.Services; namespace SZUAbsolventenverein.Module.AdminModules.Startup { @@ -22,7 +25,10 @@ namespace SZUAbsolventenverein.Module.AdminModules.Startup public void ConfigureServices(IServiceCollection services) { services.AddTransient(); + services.AddTransient(); + services.AddTransient(); services.AddDbContextFactory(opt => { }, ServiceLifetime.Transient); + services.AddDbContextFactory(opt => { }, ServiceLifetime.Transient); } } } diff --git a/Shared/Models/ReportSystem/Reporting.cs b/Shared/Models/ReportSystem/Reporting.cs new file mode 100644 index 0000000..2db78bf --- /dev/null +++ b/Shared/Models/ReportSystem/Reporting.cs @@ -0,0 +1,20 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Oqtane.Models; + +namespace SZUAbsolventenverein.Module.ReportSystem.Models; + +public class Reporting : IAuditable +{ + [Key] + public int ReportingID { get; set; } + public int ModuleId { get; set; } + public int EntityId { get; set; } + public string Note { get; set; } + public string Reason { get; set; } + + public string CreatedBy { get; set; } + public DateTime CreatedOn { get; set; } + public string ModifiedBy { get; set; } + public DateTime ModifiedOn { get; set; } +} \ No newline at end of file