Skip to content

Commit

Permalink
Require admin priviligies to view inspections
Browse files Browse the repository at this point in the history
  • Loading branch information
andchiind committed Dec 18, 2023
1 parent 9ee7098 commit 54f5a8f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 18 deletions.
4 changes: 2 additions & 2 deletions backend/api/EventHandlers/InspectionFindingEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ private async Task<List<Finding>> GenerateFindingsList(List<InspectionFinding> i

foreach (var inspectionFinding in inspectionFindings)
{
var missionRun = await InspectionFindingService.GetMissionRunByIsarStepId(inspectionFinding);
var task = await InspectionFindingService.GetMissionTaskByIsarStepId(inspectionFinding);
var missionRun = await InspectionFindingService.GetMissionRunByIsarStepId(inspectionFinding.IsarStepId);
var task = await InspectionFindingService.GetMissionTaskByIsarStepId(inspectionFinding.IsarStepId);

if (task != null && missionRun != null)
{
Expand Down
17 changes: 15 additions & 2 deletions backend/api/Services/AccessRoleService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public interface IAccessRoleService
{
public Task<List<string>> GetAllowedInstallationCodes();
public Task<List<string>> GetAllowedInstallationCodes(List<string> roles);
public bool IsUserAdmin();
public bool IsAuthenticationAvailable();
}

public class AccessRoleService(FlotillaDbContext context, IHttpContextAccessor httpContextAccessor) : IAccessRoleService
Expand All @@ -28,8 +30,6 @@ public async Task<List<string>> GetAllowedInstallationCodes()

public async Task<List<string>> GetAllowedInstallationCodes(List<string> roles)
{
var dbRoles = await context.AccessRoles.Include((r) => r.Installation).ToListAsync();

if (roles.Contains(SUPER_ADMIN_ROLE_NAME))
{
return await context.Installations.Select((i) => i.InstallationCode.ToUpperInvariant()).ToListAsync();
Expand All @@ -40,5 +40,18 @@ public async Task<List<string>> GetAllowedInstallationCodes(List<string> roles)
.Where((r) => roles.Contains(r.RoleName)).Select((r) => r.Installation != null ? r.Installation.InstallationCode.ToUpperInvariant() : "").ToListAsync();
}
}

public bool IsUserAdmin()
{
if (!IsAuthenticationAvailable())
return false;
var roles = httpContextAccessor.HttpContext!.GetRequestedRoleNames();
return roles.Contains(SUPER_ADMIN_ROLE_NAME);
}

public bool IsAuthenticationAvailable()
{
return httpContextAccessor.HttpContext != null;
}
}
}
17 changes: 10 additions & 7 deletions backend/api/Services/InspectionFindingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Api.Services
{
public class InspectionFindingService(FlotillaDbContext context)
public class InspectionFindingService(FlotillaDbContext context, IAccessRoleService accessRoleService)
{
public async Task<List<InspectionFinding>> RetrieveInspectionFindings(DateTime lastReportingTime)
{
Expand All @@ -14,20 +14,23 @@ public async Task<List<InspectionFinding>> RetrieveInspectionFindings(DateTime l
return inspectionFindings;
}

public async Task<MissionRun?> GetMissionRunByIsarStepId(InspectionFinding inspectionFinding)
public async Task<MissionRun?> GetMissionRunByIsarStepId(string isarStepId)
{
var accessibleInstallationCodes = accessRoleService.GetAllowedInstallationCodes();
#pragma warning disable CA1304
return await context.MissionRuns
.Include(missionRun => missionRun.Area).ThenInclude(area => area != null ? area.Plant : null)
.Include(missionRun => missionRun.Robot)
.Where(missionRun => missionRun.Tasks.Any(missionTask => missionTask.Inspections.Any(inspection => inspection.IsarStepId == inspectionFinding.IsarStepId)))
.Where(missionRun => missionRun.Tasks.Any(missionTask => missionTask.Inspections.Any(inspection => inspection.IsarStepId == isarStepId)))
.Where((m) => m.Area != null && accessibleInstallationCodes.Result.Contains(m.Area.Installation.InstallationCode.ToUpper()))
.FirstOrDefaultAsync();
#pragma warning restore CA1304
}

public async Task<MissionTask?> GetMissionTaskByIsarStepId(InspectionFinding inspectionFinding)
public async Task<MissionTask?> GetMissionTaskByIsarStepId(string isarStepId)
{
return await context.MissionTasks
.Where(missionTask => missionTask.Inspections.Any(inspection => inspection.IsarStepId == inspectionFinding.IsarStepId))
.FirstOrDefaultAsync();
var missionRun = await GetMissionRunByIsarStepId(isarStepId);
return missionRun?.Tasks.Where(missionTask => missionTask.Inspections.Any(inspection => inspection.IsarStepId == isarStepId)).FirstOrDefault();
}
}
}
32 changes: 25 additions & 7 deletions backend/api/Services/InspectionService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using Api.Controllers.Models;
using Api.Database.Context;
using Api.Database.Models;
Expand All @@ -20,7 +21,7 @@ public interface IInspectionService
"CA1309:Use ordinal StringComparison",
Justification = "EF Core refrains from translating string comparison overloads to SQL"
)]
public class InspectionService(FlotillaDbContext context, ILogger<InspectionService> logger) : IInspectionService
public class InspectionService(FlotillaDbContext context, ILogger<InspectionService> logger, IAccessRoleService accessRoleService) : IInspectionService
{
public async Task<Inspection> UpdateInspectionStatus(string isarStepId, IsarStepStatus isarStepStatus)
{
Expand All @@ -34,15 +35,31 @@ public async Task<Inspection> UpdateInspectionStatus(string isarStepId, IsarStep

inspection.UpdateStatus(isarStepStatus);
inspection = await Update(inspection);
// Disabled for now as we need to be able to assign it to an installation to get granular access control
// _ = signalRService.SendMessageAsync("Inspection updated", inspection);
return inspection;
}

private async Task ApplyDatabaseUpdate(Installation? installation)
{
var accessibleInstallationCodes = await accessRoleService.GetAllowedInstallationCodes();
if (installation == null || accessibleInstallationCodes.Contains(installation.InstallationCode.ToUpper(CultureInfo.CurrentCulture)))
await context.SaveChangesAsync();
else
throw new UnauthorizedAccessException($"User does not have permission to update area in installation {installation.Name}");
}

private async Task<Inspection> Update(Inspection inspection)
{
var entry = context.Update(inspection);
await context.SaveChangesAsync();

var missionRun = await context.MissionRuns
.Include(missionRun => missionRun.Area).ThenInclude(area => area != null ? area.Installation : null)
.Include(missionRun => missionRun.Robot)
.Where(missionRun => missionRun.Tasks.Any(missionTask => missionTask.Inspections.Any(i => i.Id == inspection.Id)))
.FirstOrDefaultAsync();
var installation = missionRun?.Area?.Installation;

await ApplyDatabaseUpdate(installation);

return entry.Entity;
}

Expand All @@ -53,7 +70,10 @@ private async Task<Inspection> Update(Inspection inspection)

private IQueryable<Inspection> GetInspections()
{
return context.Inspections.Include(inspection => inspection.InspectionFindings);
if (accessRoleService.IsUserAdmin() || !accessRoleService.IsAuthenticationAvailable())
return context.Inspections.Include(inspection => inspection.InspectionFindings);
else
throw new UnauthorizedAccessException($"User does not have permission to view inspections");
}

public async Task<Inspection?> AddFinding(InspectionFindingQuery inspectionFindingQuery, string isarStepId)
Expand All @@ -74,8 +94,6 @@ private IQueryable<Inspection> GetInspections()

inspection.InspectionFindings.Add(inspectionFinding);
inspection = await Update(inspection);
// Disabled for now as we need to be able to assign it to an installation to get granular access control
//_ = signalRService.SendMessageAsync("Inspection finding added", inspection);
return inspection;
}
}
Expand Down

0 comments on commit 54f5a8f

Please sign in to comment.