From f05001c910db5934753943309b7fdbc6a67902f4 Mon Sep 17 00:00:00 2001 From: Kjetil Haugland Date: Wed, 30 Oct 2024 10:13:45 +0100 Subject: [PATCH] . --- .../Cache/FusionAppsCache.cs | 21 +++++-- .../AddContextType/AddContextTypeCommand.cs | 28 ++++++--- .../OnboardApp/OnboardAppCommand.cs | 43 +++++++++----- .../UpdateOnboardedAppCommand.cs | 31 +++++++--- .../AddContextAppToPortalCommand.cs | 38 +++++++++---- .../CreatePortal/CreatePortalCommand.cs | 57 ++++++++++++------- .../Middleware/CurrentUserMiddleware.cs | 13 ++++- .../Setup/IntegrationTestAuthHandler.cs | 18 +++--- 8 files changed, 171 insertions(+), 78 deletions(-) diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/FusionAppsCache.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/FusionAppsCache.cs index 2143a4b6..53a4fd26 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/FusionAppsCache.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/FusionAppsCache.cs @@ -3,16 +3,25 @@ namespace Equinor.ProjectExecutionPortal.Application.Cache; -public class FusionAppsCache(ICacheManager cacheManager, IAppsClient fusionAppsClient) : IFusionAppsCache +public class FusionAppsCache : IFusionAppsCache { + private readonly ICacheManager _cacheManager; + private readonly IAppsClient _fusionAppsClient; + + public FusionAppsCache(ICacheManager cacheManager, IAppsClient fusionAppsClient) + { + _cacheManager = cacheManager; + _fusionAppsClient = fusionAppsClient; + } + // TODO: Move cache duration to app settings public async Task> GetFusionApps() { - return await cacheManager.GetOrCreateAsync("FUSION_APP", + return await _cacheManager.GetOrCreateAsync("FUSION_APP", async () => { - var fusionApps = await fusionAppsClient.GetAppsAsync(); + var fusionApps = await _fusionAppsClient.GetAppsAsync(); return fusionApps.ToList(); }, @@ -22,9 +31,9 @@ public async Task> GetFusionApps() public async Task GetFusionApp(string appKey) { - return await cacheManager.GetOrCreateAsync("FUSION_APP", - async () => await fusionAppsClient.GetAppAsync(appKey), + return await _cacheManager.GetOrCreateAsync("FUSION_APP", + async () => await _fusionAppsClient.GetAppAsync(appKey), CacheDuration.Minutes, 60); } -} +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/ContextTypes/AddContextType/AddContextTypeCommand.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/ContextTypes/AddContextType/AddContextTypeCommand.cs index e38418ee..d64cc009 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/ContextTypes/AddContextType/AddContextTypeCommand.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/ContextTypes/AddContextType/AddContextTypeCommand.cs @@ -7,15 +7,27 @@ namespace Equinor.ProjectExecutionPortal.Application.Commands.ContextTypes.AddContextType; -public class AddContextTypeCommand(string contextTypeKey) : IRequest +public class AddContextTypeCommand : IRequest { - public string ContextTypeKey { get; } = contextTypeKey; + public AddContextTypeCommand(string contextTypeKey) + { + ContextTypeKey = contextTypeKey; + } - public class Handler(IReadWriteContext readWriteContext) : IRequestHandler + public string ContextTypeKey { get; } + + public class Handler : IRequestHandler { + private readonly IReadWriteContext _readWriteContext; + + public Handler(IReadWriteContext readWriteContext) + { + _readWriteContext = readWriteContext; + } + public async Task Handle(AddContextTypeCommand command, CancellationToken cancellationToken) { - var contextTypeExists = await readWriteContext.Set() + var contextTypeExists = await _readWriteContext.Set() .AsNoTracking() .AnyAsync(x => x.ContextTypeKey == command.ContextTypeKey, cancellationToken); @@ -27,15 +39,15 @@ public async Task Handle(AddContextTypeCommand command, CancellationToken if (!FusionContextType.IsValid(command.ContextTypeKey)) { throw new NotFoundException($"ContextType: {command.ContextTypeKey} is not a valid Context type"); - } + } var contextType = new ContextType(command.ContextTypeKey); - readWriteContext.Set().Add(contextType); + _readWriteContext.Set().Add(contextType); - await readWriteContext.SaveChangesAsync(cancellationToken); + await _readWriteContext.SaveChangesAsync(cancellationToken); return contextType.Id; } } -} +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/OnboardedApps/OnboardApp/OnboardAppCommand.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/OnboardedApps/OnboardApp/OnboardAppCommand.cs index 03b82a94..920a5410 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/OnboardedApps/OnboardApp/OnboardAppCommand.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/OnboardedApps/OnboardApp/OnboardAppCommand.cs @@ -8,25 +8,38 @@ namespace Equinor.ProjectExecutionPortal.Application.Commands.OnboardedApps.OnboardApp; -public class OnboardAppCommand(string appKey, IList? contextTypes) : IRequest +public class OnboardAppCommand : IRequest { - public string AppKey { get; } = appKey; - public IList? ContextTypes { get; set; } = contextTypes; - - public class Handler( - IReadWriteContext readWriteContext, - IFusionAppsService fusionAppsService, - IContextTypeService contextTypeService) - : IRequestHandler + public OnboardAppCommand(string appKey, IList? contextTypes) { + AppKey = appKey; + ContextTypes = contextTypes; + } + + public string AppKey { get; } + public IList? ContextTypes { get; set; } + + public class Handler : IRequestHandler + { + private readonly IReadWriteContext _readWriteContext; + private readonly IFusionAppsService _fusionAppsService; + private readonly IContextTypeService _contextTypeService; + + public Handler(IReadWriteContext readWriteContext, IFusionAppsService fusionAppsService, IContextTypeService contextTypeService) + { + _readWriteContext = readWriteContext; + _fusionAppsService = fusionAppsService; + _contextTypeService = contextTypeService; + } + public async Task Handle(OnboardAppCommand command, CancellationToken cancellationToken) { - if (!await fusionAppsService.FusionAppExist(command.AppKey, cancellationToken)) + if (!await _fusionAppsService.FusionAppExist(command.AppKey, cancellationToken)) { throw new NotFoundException($"Could not locate app '{command.AppKey}' in Fusion."); } - var onboardedAppExists = await readWriteContext.Set() + var onboardedAppExists = await _readWriteContext.Set() .AsNoTracking() .AnyAsync(x => x.AppKey == command.AppKey, cancellationToken); @@ -39,18 +52,18 @@ public async Task Handle(OnboardAppCommand command, CancellationToken canc try { - onboardedApp.AddContextTypes(await contextTypeService.GetAllowedContextTypesByKeys(command.ContextTypes, cancellationToken)); + onboardedApp.AddContextTypes(await _contextTypeService.GetAllowedContextTypesByKeys(command.ContextTypes, cancellationToken)); } catch (InvalidActionException ex) { throw new InvalidOperationException(ex.Message); } - readWriteContext.Set().Add(onboardedApp); + _readWriteContext.Set().Add(onboardedApp); - await readWriteContext.SaveChangesAsync(cancellationToken); + await _readWriteContext.SaveChangesAsync(cancellationToken); return onboardedApp.Id; } } -} +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/OnboardedApps/UpdateOnboardedApp/UpdateOnboardedAppCommand.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/OnboardedApps/UpdateOnboardedApp/UpdateOnboardedAppCommand.cs index 94c39438..ce0d1a76 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/OnboardedApps/UpdateOnboardedApp/UpdateOnboardedAppCommand.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/OnboardedApps/UpdateOnboardedApp/UpdateOnboardedAppCommand.cs @@ -7,16 +7,31 @@ namespace Equinor.ProjectExecutionPortal.Application.Commands.OnboardedApps.UpdateOnboardedApp; -public class UpdateOnboardedAppCommand(string appKey, IList? contextTypes) : IRequest +public class UpdateOnboardedAppCommand : IRequest { - public string AppKey { get; } = appKey; - public IList? ContextTypes { get; set; } = contextTypes; + public UpdateOnboardedAppCommand(string appKey, IList? contextTypes) + { + AppKey = appKey; + ContextTypes = contextTypes; + } - public class Handler(IReadWriteContext readWriteContext, IContextTypeService contextTypeService) : IRequestHandler + public string AppKey { get; } + public IList? ContextTypes { get; set; } + + public class Handler : IRequestHandler { + private readonly IReadWriteContext _readWriteContext; + private readonly IContextTypeService _contextTypeService; + + public Handler(IReadWriteContext readWriteContext, IContextTypeService contextTypeService) + { + _readWriteContext = readWriteContext; + _contextTypeService = contextTypeService; + } + public async Task Handle(UpdateOnboardedAppCommand command, CancellationToken cancellationToken) { - var entity = await readWriteContext.Set() + var entity = await _readWriteContext.Set() .Include(x => x.ContextTypes) .FirstOrDefaultAsync(x => x.AppKey == command.AppKey, cancellationToken); @@ -27,16 +42,16 @@ public async Task Handle(UpdateOnboardedAppCommand command, CancellationTo try { - entity.AddContextTypes(await contextTypeService.GetAllowedContextTypesByKeys(command.ContextTypes, cancellationToken)); + entity.AddContextTypes(await _contextTypeService.GetAllowedContextTypesByKeys(command.ContextTypes, cancellationToken)); } catch (InvalidActionException ex) { throw new InvalidOperationException(ex.Message); } - await readWriteContext.SaveChangesAsync(cancellationToken); + await _readWriteContext.SaveChangesAsync(cancellationToken); return entity.Id; } } -} +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/Portals/AddContextAppToPortal/AddContextAppToPortalCommand.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/Portals/AddContextAppToPortal/AddContextAppToPortalCommand.cs index 10815154..19ef0453 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/Portals/AddContextAppToPortal/AddContextAppToPortalCommand.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/Portals/AddContextAppToPortal/AddContextAppToPortalCommand.cs @@ -7,33 +7,49 @@ namespace Equinor.ProjectExecutionPortal.Application.Commands.Portals.AddContextAppToPortal; -public class AddContextAppToPortalCommand(Guid portalId, Guid contextId, string appKey) : IRequest +public class AddContextAppToPortalCommand : IRequest { - public Guid PortalId { get; } = portalId; - public Guid ContextId { get; } = contextId; - public string AppKey { get; } = appKey; + public AddContextAppToPortalCommand(Guid portalId, Guid contextId, string appKey) + { + PortalId = portalId; + ContextId = contextId; + AppKey = appKey; + } - public class Handler(IReadWriteContext readWriteContext, IContextService contextService) : IRequestHandler + public Guid PortalId { get; } + public Guid ContextId { get; } + public string AppKey { get; } + + public class Handler : IRequestHandler { + private readonly IReadWriteContext _readWriteContext; + private readonly IContextService _contextService; + + public Handler(IReadWriteContext readWriteContext, IContextService contextService) + { + _readWriteContext = readWriteContext; + _contextService = contextService; + } + public async Task Handle(AddContextAppToPortalCommand command, CancellationToken cancellationToken) { - var fusionContext = await contextService.GetFusionContext(command.ContextId, cancellationToken) + var fusionContext = await _contextService.GetFusionContext(command.ContextId, cancellationToken) ?? throw new InvalidOperationException($"Cannot add app '{command.AppKey} to '{command.PortalId}'. Missing context parameter."); - var onboardedContext = await readWriteContext.Set() + var onboardedContext = await _readWriteContext.Set() .AsNoTracking() .FirstOrDefaultAsync(x => x.ExternalId == fusionContext.ExternalId && x.Type == fusionContext.Type.Name, cancellationToken) ?? throw new NotFoundException("Could not find any onboarded context with id", command.ContextId); - var onboardedApp = await readWriteContext.Set() + var onboardedApp = await _readWriteContext.Set() .AsNoTracking() .FirstOrDefaultAsync(x => x.AppKey == command.AppKey, cancellationToken) ?? throw new NotFoundException("Could not find any onboarded app with id", command.AppKey); - var portalWithAllApps = await readWriteContext.Set() + var portalWithAllApps = await _readWriteContext.Set() .Include(x => x.Apps .Where(wsApp => wsApp.OnboardedContext == null || wsApp.OnboardedContext.Id == onboardedContext.Id)) .ThenInclude(x => x.OnboardedContext) @@ -55,9 +71,9 @@ public async Task Handle(AddContextAppToPortalCommand command, Cancellatio portalWithAllApps.AddApp(portalApp); - await readWriteContext.SaveChangesAsync(cancellationToken); + await _readWriteContext.SaveChangesAsync(cancellationToken); return Unit.Value; } } -} +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/Portals/CreatePortal/CreatePortalCommand.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/Portals/CreatePortal/CreatePortalCommand.cs index 4f3d63f0..2fff41c0 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/Portals/CreatePortal/CreatePortalCommand.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Commands/Portals/CreatePortal/CreatePortalCommand.cs @@ -6,37 +6,54 @@ namespace Equinor.ProjectExecutionPortal.Application.Commands.Portals.CreatePortal; -public class CreatePortalCommand( - string name, - string shortName, - string subText, - string? description, - string icon, - IList contextTypes) - : IRequest +public class CreatePortalCommand : IRequest { - public string Name { get; set; } = name; - public string ShortName { get; set; } = shortName; - public string SubText { get; set; } = subText; - public string? Description { get; set; } = description; - public string Icon { get; set; } = icon; - public IList ContextTypes { get; set; } = contextTypes; - - public class Handler(IReadWriteContext readWriteContext, IContextTypeService contextTypeService) : IRequestHandler + public CreatePortalCommand(string name, + string shortName, + string subText, + string? description, + string icon, + IList contextTypes) { + Name = name; + ShortName = shortName; + SubText = subText; + Description = description; + Icon = icon; + ContextTypes = contextTypes; + } + + public string Name { get; set; } + public string ShortName { get; set; } + public string SubText { get; set; } + public string? Description { get; set; } + public string Icon { get; set; } + public IList ContextTypes { get; set; } + + public class Handler : IRequestHandler + { + private readonly IReadWriteContext _readWriteContext; + private readonly IContextTypeService _contextTypeService; + + public Handler(IReadWriteContext readWriteContext, IContextTypeService contextTypeService) + { + _readWriteContext = readWriteContext; + _contextTypeService = contextTypeService; + } + public async Task Handle(CreatePortalCommand command, CancellationToken cancellationToken) { var slug = SlugHelper.Sluggify(command.Name); var portal = new Portal(slug, command.Name, command.ShortName, command.SubText, command.Description, command.Icon); - portal.AddContextTypes(await contextTypeService.GetAllowedContextTypesByKeys(command.ContextTypes, cancellationToken)); + portal.AddContextTypes(await _contextTypeService.GetAllowedContextTypesByKeys(command.ContextTypes, cancellationToken)); - await readWriteContext.Set().AddAsync(portal, cancellationToken); + await _readWriteContext.Set().AddAsync(portal, cancellationToken); - await readWriteContext.SaveChangesAsync(cancellationToken); + await _readWriteContext.SaveChangesAsync(cancellationToken); return portal.Id; } } -} +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/Middleware/CurrentUserMiddleware.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/Middleware/CurrentUserMiddleware.cs index c24fcadf..6d6ed85d 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/Middleware/CurrentUserMiddleware.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/Middleware/CurrentUserMiddleware.cs @@ -3,8 +3,15 @@ namespace Equinor.ProjectExecutionPortal.WebApi.Middleware; -public class CurrentUserMiddleware(RequestDelegate next) +public class CurrentUserMiddleware { + private readonly RequestDelegate _next; + + public CurrentUserMiddleware(RequestDelegate next) + { + _next = next; + } + public async Task InvokeAsync(HttpContext context, IHttpContextAccessor httpContextAccessor, ICurrentUserSetter currentUserSetter, ILogger logger) { logger.LogInformation($"----- {GetType().Name} start"); @@ -18,6 +25,6 @@ public async Task InvokeAsync(HttpContext context, IHttpContextAccessor httpCont logger.LogInformation($"----- {GetType().Name} complete"); // Call the next delegate/middleware in the pipeline - await next(context); + await _next(context); } -} +} \ No newline at end of file diff --git a/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/Setup/IntegrationTestAuthHandler.cs b/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/Setup/IntegrationTestAuthHandler.cs index c3c40ca8..77350496 100644 --- a/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/Setup/IntegrationTestAuthHandler.cs +++ b/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/Setup/IntegrationTestAuthHandler.cs @@ -9,13 +9,17 @@ namespace Equinor.ProjectExecutionPortal.Tests.WebApi.Setup { - internal class IntegrationTestAuthHandler( - IOptionsMonitor options, - ILoggerFactory logger, - UrlEncoder encoder, - ISystemClock clock) - : AuthenticationHandler(options, logger, encoder, clock) + internal class IntegrationTestAuthHandler : AuthenticationHandler { + public IntegrationTestAuthHandler( + IOptionsMonitor options, + ILoggerFactory logger, + UrlEncoder encoder, + ISystemClock clock) + : base(options, logger, encoder, clock) + { + } + public static string TestAuthenticationScheme = "AuthScheme"; private enum AuthType @@ -92,4 +96,4 @@ private Task> GatherTestUserClaimsAsync() return Task.FromResult(claims); } } -} +} \ No newline at end of file