Skip to content

Commit

Permalink
Merge branch 'master' into chore/package-update-230824
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathanio123 authored Sep 13, 2024
2 parents 7e48d61 + 7a6a86d commit bb9e0e6
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,7 @@ private static async Task CheckDelegatedDepartmentResponsibleExpirationAsync(Tel

db.DelegatedDepartmentResponsibles.RemoveRange(toExpire);

var expiredRecords = toExpire.Select(x => new DbDelegatedDepartmentResponsibleHistory
{
Id = Guid.NewGuid(),
Archived = DateTimeOffset.UtcNow,
DateTo = x.DateTo,
DepartmentId = x.DepartmentId,
ResponsibleAzureObjectId = x.ResponsibleAzureObjectId,
DateCreated = x.DateCreated,
DateFrom = x.DateFrom,
DateUpdated = x.DateUpdated,
Reason = x.Reason,
UpdatedBy = x.UpdatedBy
});
var expiredRecords = toExpire.Select(x => new DbDelegatedDepartmentResponsibleHistory(x));
await db.DelegatedDepartmentResponsiblesHistory.AddRangeAsync(expiredRecords);
await db.SaveChangesAsync();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@ public class DbDelegatedDepartmentResponsibleHistory
public Guid? UpdatedBy { get; set; }
public string? Reason { get; set; }

public DbDelegatedDepartmentResponsibleHistory()
{
}

public DbDelegatedDepartmentResponsibleHistory(DbDelegatedDepartmentResponsible dbDelegatedDepartmentResponsible)
{
Id = Guid.NewGuid();
Archived = DateTimeOffset.UtcNow;
DepartmentId = dbDelegatedDepartmentResponsible.DepartmentId;
ResponsibleAzureObjectId = dbDelegatedDepartmentResponsible.ResponsibleAzureObjectId;
DateFrom = dbDelegatedDepartmentResponsible.DateFrom;
DateTo = dbDelegatedDepartmentResponsible.DateTo;
DateCreated = dbDelegatedDepartmentResponsible.DateCreated;
DateUpdated = dbDelegatedDepartmentResponsible.DateUpdated;
UpdatedBy = dbDelegatedDepartmentResponsible.UpdatedBy;
Reason = dbDelegatedDepartmentResponsible.Reason;
}


internal static void OnModelCreating(ModelBuilder modelBuilder)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Fusion.Integration.Profile;
using Fusion.Integration.Roles;
using Fusion.Resources.Database;
using Fusion.Resources.Database.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Fusion.Resources.Domain.Commands.Departments;

/// Archive delegated resource owners for the department and remove their roles.
public class ArchiveDelegatedResourceOwners : TrackableRequest
{
public LineOrgId DepartmentId { get; private init; }
public ICollection<Guid>? ResourceOwnersToArchive { get; private set; }


public ArchiveDelegatedResourceOwners(LineOrgId departmentId)
{
DepartmentId = departmentId;
}

/// Only archive the resource owners with the provided Azure Object Ids
public ArchiveDelegatedResourceOwners WhereResourceOwnersAzureId(ICollection<Guid> resourceOwners)
{
ArgumentNullException.ThrowIfNull(resourceOwners);
ResourceOwnersToArchive = resourceOwners;
return this;
}


public class ArchiveDelegatedResourceOwnersHandler : IRequestHandler<ArchiveDelegatedResourceOwners>
{
private readonly ResourcesDbContext db;
private readonly IFusionRolesClient rolesClient;


public ArchiveDelegatedResourceOwnersHandler(ResourcesDbContext db, IFusionRolesClient rolesClient)
{
this.db = db;
this.rolesClient = rolesClient;
}

public async Task Handle(ArchiveDelegatedResourceOwners request, CancellationToken cancellationToken)
{
var delegatedResourceOwnersToArchive = await db.DelegatedDepartmentResponsibles
.Where(r => r.DepartmentId == request.DepartmentId.FullDepartment)
.Where(r => request.ResourceOwnersToArchive == null || request.ResourceOwnersToArchive.Contains(r.ResponsibleAzureObjectId))
.ToListAsync(cancellationToken);

foreach (var resourceOwner in delegatedResourceOwnersToArchive)
{
await rolesClient.DeleteRolesAsync(
new PersonIdentifier(resourceOwner.ResponsibleAzureObjectId),
q => q.WhereRoleName(AccessRoles.ResourceOwner).WhereScopeValue(request.DepartmentId.FullDepartment)
);

db.DelegatedDepartmentResponsibles.Remove(resourceOwner);

var archivedDelegateResourceOwner = new DbDelegatedDepartmentResponsibleHistory(resourceOwner);

db.DelegatedDepartmentResponsiblesHistory.Add(archivedDelegateResourceOwner);

await db.SaveChangesAsync(CancellationToken.None);
cancellationToken.ThrowIfCancellationRequested();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using Fusion.Resources.Database;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Fusion.Integration.Profile;
using Fusion.Integration.Roles;
using Fusion.Resources.Database.Entities;
using Fusion.Resources.Domain.Commands.Departments;

namespace Fusion.Resources.Domain.Notifications.System;

public partial class OrgUnitDeleted
{
/// <summary>
/// Archive all delegated resource owners for the deleted department and remove their roles.
/// </summary>
public class ArchiveDelegatedResourceOwnersHandler : INotificationHandler<OrgUnitDeleted>
{
private readonly ILogger<ArchiveDelegatedResourceOwnersHandler> logger;
private readonly IMediator mediator;

public ArchiveDelegatedResourceOwnersHandler(ILogger<ArchiveDelegatedResourceOwnersHandler> logger, IMediator mediator)
{
this.logger = logger;
this.mediator = mediator;
}

public async Task Handle(OrgUnitDeleted notification, CancellationToken cancellationToken)
{
logger.LogInformation("Archiving delegated resource owners for deleted department {FullDepartment}", notification.FullDepartment);

using var systemAccountScope = mediator.SystemAccountScope();

await mediator.Send(new ArchiveDelegatedResourceOwners(new LineOrgId()
{
FullDepartment = notification.FullDepartment,
SapId = notification.SapId
}), cancellationToken);
}
}
}
65 changes: 65 additions & 0 deletions src/backend/tests/Fusion.Resources.Domain.Tests/DepartmentTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
using Fusion.Resources.Database;
using Fusion.Resources.Domain.Commands.Departments;
using Fusion.Resources.Test.Core;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

namespace Fusion.Resources.Domain.Tests;

public class DepartmentTests : DbTestFixture
{
[Fact]
public async Task ArchiveDelegatedResourceOwners_ShouldArchiveResourceOwners()
{
var mediator = serviceProvider.GetRequiredService<IMediator>();
var db = serviceProvider.GetRequiredService<ResourcesDbContext>();

var departmentId = new LineOrgId()
{
FullDepartment = "PRD TDI",
SapId = "123456"
};
var toBeArchivedResourceOwner = CreateTestPerson("toBeArchivedResourceOwner");
var resourceOwner = CreateTestPerson("resourceOwner");

var createCommand = new AddDelegatedResourceOwner(departmentId, toBeArchivedResourceOwner.AzureUniqueId)
{
Reason = "Test",
DateFrom = DateTimeOffset.Now,
DateTo = DateTimeOffset.Now.AddMonths(1)
};


var createCommand2 = new AddDelegatedResourceOwner(departmentId, resourceOwner.AzureUniqueId)
{
Reason = "Test2",
DateFrom = DateTimeOffset.Now,
DateTo = DateTimeOffset.Now.AddMonths(1)
};

await mediator.Send(createCommand);
await mediator.Send(createCommand2);

var command = new ArchiveDelegatedResourceOwners(departmentId).WhereResourceOwnersAzureId([toBeArchivedResourceOwner.AzureUniqueId]);

await mediator.Send(command);

var remainingResourceOwners = await db.DelegatedDepartmentResponsibles
.Where(r => r.DepartmentId == departmentId.FullDepartment)
.ToListAsync();

remainingResourceOwners.Should().HaveCount(1);
remainingResourceOwners.Should().ContainSingle(r => r.ResponsibleAzureObjectId == resourceOwner.AzureUniqueId);

var archivedResourceOwners = await db.DelegatedDepartmentResponsiblesHistory.ToListAsync();

archivedResourceOwners.Should().HaveCount(1);
archivedResourceOwners.Should().ContainSingle(r => r.ResponsibleAzureObjectId == toBeArchivedResourceOwner.AzureUniqueId);
}
}
2 changes: 2 additions & 0 deletions src/backend/tests/Fusion.Resources.Test.Core/DbTestFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Fusion.Integration.Roles;

namespace Fusion.Resources.Test.Core
{
Expand Down Expand Up @@ -50,6 +51,7 @@ protected virtual void ConfigureServices(ServiceCollection services)
services.AddSingleton(new Mock<IProjectOrgResolver>(MockBehavior.Loose).Object);
services.AddSingleton(new Mock<IFusionProfileResolver>(MockBehavior.Loose).Object);
services.AddSingleton(new Mock<IOrgApiClientFactory>(MockBehavior.Loose).Object);
services.AddSingleton(new Mock<IFusionRolesClient>(MockBehavior.Loose).Object);

services.AddTransient(typeof(IPipelineBehavior<,>), typeof(TestTrackableRequestBehaviour<,>));

Expand Down

0 comments on commit bb9e0e6

Please sign in to comment.