Skip to content

Commit

Permalink
chore: Refactor IUserService (#476)
Browse files Browse the repository at this point in the history
Does to much, splitting it up in three registries. #403
  • Loading branch information
oskogstad authored Feb 26, 2024
1 parent 9272d34 commit ca80d36
Show file tree
Hide file tree
Showing 20 changed files with 223 additions and 146 deletions.
11 changes: 8 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ insert_final_newline = true
[*.cs]

# CA1848: Use the LoggerMessage delegates
# TODO: Possible performance improvement
# TODO: Possible performance improvement
dotnet_diagnostic.CA1848.severity = none

# Identifiers should not match keywords
Expand All @@ -25,7 +25,7 @@ dotnet_diagnostic.CA1716.severity = none
# Style faults should be warnings
dotnet_analyzer_diagnostic.category-Style.severity = warning

#
#
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity

# Enforce file scoped namespaces
Expand All @@ -39,7 +39,7 @@ dotnet_diagnostic.IDE0005.severity = none
# Disabling this because of https://github.com/dotnet/roslyn/issues/70826
dotnet_diagnostic.IDE0028.severity = none

# Primary constructors
# Primary constructors
dotnet_diagnostic.IDE0290.severity = none

# Disable collection expression until Rider supports it
Expand Down Expand Up @@ -68,5 +68,10 @@ dotnet_diagnostic.CA2208.severity = suggestion

[*.yml]

# Enforce indentation to be 2 spaces
indent_size = 2

[*.json]

# Enforce indentation to be 2 spaces
indent_size = 2
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public static IServiceCollection AddApplication(this IServiceCollection services
.AddScoped<ITransactionTime, TransactionTime>()

// Transient
.AddTransient<IUserService, UserService>()
.AddTransient<IUserOrganizationRegistry, UserOrganizationRegistry>()
.AddTransient<IUserResourceRegistry, UserResourceRegistry>()
.AddTransient<IUserNameRegistry, UserNameRegistry>()
.AddTransient<IClock, Clock>()
.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>))
.AddTransient(typeof(IPipelineBehavior<,>), typeof(DomainContextBehaviour<,>));
Expand All @@ -47,11 +49,21 @@ public static IServiceCollection AddApplication(this IServiceCollection services
}

var localDeveloperSettings = configuration.GetLocalDevelopmentSettings();
services.Decorate<IUserService, LocalDevelopmentUserServiceDecorator>(
services.Decorate<IUserResourceRegistry, LocalDevelopmentUserResourceRegistryDecorator>(
predicate:
localDeveloperSettings.UseLocalDevelopmentUser ||
localDeveloperSettings.UseLocalDevelopmentResourceRegister);

services.Decorate<IUserOrganizationRegistry, LocalDevelopmentUserOrganizationRegistryDecorator>(
predicate:
localDeveloperSettings.UseLocalDevelopmentUser ||
localDeveloperSettings.UseLocalDevelopmentOrganizationRegister);

services.Decorate<IUserNameRegistry, LocalDevelopmentUserNameRegistryDecorator>(
predicate:
localDeveloperSettings.UseLocalDevelopmentUser ||
localDeveloperSettings.UseLocalDevelopmentNameRegister);

return services;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Diagnostics.CodeAnalysis;
using Digdir.Domain.Dialogporten.Application.Common.Extensions;
using Digdir.Domain.Dialogporten.Application.Externals;
using Digdir.Domain.Dialogporten.Application.Externals.Presentation;

namespace Digdir.Domain.Dialogporten.Application.Common;

public interface IUserNameRegistry
{
bool TryGetCurrentUserPid([NotNullWhen(true)] out string? userPid);
Task<string?> GetCurrentUserName(string personalIdentificationNumber, CancellationToken cancellationToken);
}

public class UserNameRegistry : IUserNameRegistry
{
private readonly IUser _user;
private readonly INameRegistry _nameRegistry;

public UserNameRegistry(IUser user, INameRegistry nameRegistry)
{
_user = user ?? throw new ArgumentNullException(nameof(user));
_nameRegistry = nameRegistry ?? throw new ArgumentNullException(nameof(nameRegistry));
}

public bool TryGetCurrentUserPid([NotNullWhen(true)] out string? userPid) => _user.TryGetPid(out userPid);

public async Task<string?> GetCurrentUserName(string personalIdentificationNumber, CancellationToken cancellationToken) =>
await _nameRegistry.GetName(personalIdentificationNumber, cancellationToken);
}

internal sealed class LocalDevelopmentUserNameRegistryDecorator : IUserNameRegistry
{
private readonly IUserNameRegistry _userNameRegistry;

public LocalDevelopmentUserNameRegistryDecorator(IUserNameRegistry userNameRegistry)
{
_userNameRegistry = userNameRegistry ?? throw new ArgumentNullException(nameof(userNameRegistry));
}

public bool TryGetCurrentUserPid([NotNullWhen(true)] out string? userPid) =>
_userNameRegistry.TryGetCurrentUserPid(out userPid);

public async Task<string?> GetCurrentUserName(string personalIdentificationNumber, CancellationToken cancellationToken)
=> await Task.FromResult("Local Development User");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Digdir.Domain.Dialogporten.Application.Common.Extensions;
using Digdir.Domain.Dialogporten.Application.Externals;
using Digdir.Domain.Dialogporten.Application.Externals.Presentation;

namespace Digdir.Domain.Dialogporten.Application.Common;

public interface IUserOrganizationRegistry
{
Task<string?> GetCurrentUserOrgShortName(CancellationToken cancellationToken);
}

public class UserOrganizationRegistry : IUserOrganizationRegistry
{
private readonly IUser _user;
private readonly IOrganizationRegistry _organizationRegistry;

public UserOrganizationRegistry(IUser user, IOrganizationRegistry organizationRegistry)
{
_user = user ?? throw new ArgumentNullException(nameof(user));
_organizationRegistry = organizationRegistry ?? throw new ArgumentNullException(nameof(organizationRegistry));
}

public async Task<string?> GetCurrentUserOrgShortName(CancellationToken cancellationToken)
{
if (_user.TryGetOrgShortName(out var orgShortName))
{
return orgShortName;
}

if (!_user.TryGetOrgNumber(out var orgNumber))
{
return null;
}

return await _organizationRegistry.GetOrgShortName(orgNumber, cancellationToken);
}
}

internal sealed class LocalDevelopmentUserOrganizationRegistryDecorator : IUserOrganizationRegistry
{
private readonly IUserOrganizationRegistry _userOrganizationRegistry;

public LocalDevelopmentUserOrganizationRegistryDecorator(IUserOrganizationRegistry userOrganizationRegistry)
{
_userOrganizationRegistry = userOrganizationRegistry ?? throw new ArgumentNullException(nameof(userOrganizationRegistry));
}

public Task<string?> GetCurrentUserOrgShortName(CancellationToken cancellationToken) => Task.FromResult("digdir")!;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System.Diagnostics;
using Digdir.Domain.Dialogporten.Application.Common.Extensions;
using Digdir.Domain.Dialogporten.Application.Externals;
using Digdir.Domain.Dialogporten.Application.Externals.Presentation;

namespace Digdir.Domain.Dialogporten.Application.Common;

public interface IUserResourceRegistry
{
Task<bool> CurrentUserIsOwner(string serviceResource, CancellationToken cancellationToken);
Task<IReadOnlyCollection<string>> GetCurrentUserResourceIds(CancellationToken cancellationToken);
}

public class UserResourceRegistry : IUserResourceRegistry
{
private readonly IUser _user;
private readonly IResourceRegistry _resourceRegistry;

public UserResourceRegistry(IUser user, IResourceRegistry resourceRegistry)
{
_user = user ?? throw new ArgumentNullException(nameof(user));
_resourceRegistry = resourceRegistry ?? throw new ArgumentNullException(nameof(resourceRegistry));
}

public async Task<bool> CurrentUserIsOwner(string serviceResource, CancellationToken cancellationToken)
{
var resourceIds = await GetCurrentUserResourceIds(cancellationToken);
return resourceIds.Contains(serviceResource);
}

public Task<IReadOnlyCollection<string>> GetCurrentUserResourceIds(CancellationToken cancellationToken) =>
!_user.TryGetOrgNumber(out var orgNumber)
? throw new UnreachableException()
: _resourceRegistry.GetResourceIds(orgNumber, cancellationToken);
}

internal sealed class LocalDevelopmentUserResourceRegistryDecorator : IUserResourceRegistry
{
private readonly IUserResourceRegistry _userResourceRegistry;

public LocalDevelopmentUserResourceRegistryDecorator(IUserResourceRegistry userResourceRegistry)
{
_userResourceRegistry = userResourceRegistry ?? throw new ArgumentNullException(nameof(userResourceRegistry));
}

public Task<bool> CurrentUserIsOwner(string serviceResource, CancellationToken cancellationToken) =>
Task.FromResult(true);

public Task<IReadOnlyCollection<string>> GetCurrentUserResourceIds(CancellationToken cancellationToken) =>
_userResourceRegistry.GetCurrentUserResourceIds(cancellationToken);
}
93 changes: 0 additions & 93 deletions src/Digdir.Domain.Dialogporten.Application/Common/IUserService.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,28 @@ internal sealed class GetDialogQueryHandler : IRequestHandler<GetDialogQuery, Ge
private readonly IMapper _mapper;
private readonly IUnitOfWork _unitOfWork;
private readonly IClock _clock;
private readonly IUserService _userService;
private readonly IUserNameRegistry _userNameRegistry;
private readonly IAltinnAuthorization _altinnAuthorization;

public GetDialogQueryHandler(
IDialogDbContext db,
IMapper mapper,
IUnitOfWork unitOfWork,
IClock clock,
IUserService userService,
IUserNameRegistry userNameRegistry,
IAltinnAuthorization altinnAuthorization)
{
_db = db ?? throw new ArgumentNullException(nameof(db));
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
_unitOfWork = unitOfWork ?? throw new ArgumentNullException(nameof(unitOfWork));
_clock = clock ?? throw new ArgumentNullException(nameof(clock));
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
_userNameRegistry = userNameRegistry ?? throw new ArgumentNullException(nameof(userNameRegistry));
_altinnAuthorization = altinnAuthorization ?? throw new ArgumentNullException(nameof(altinnAuthorization));
}

public async Task<GetDialogResult> Handle(GetDialogQuery request, CancellationToken cancellationToken)
{
if (!_userService.TryGetCurrentUserPid(out var userPid))
if (!_userNameRegistry.TryGetCurrentUserPid(out var userPid))
{
return new Forbidden("No valid user pid found.");
}
Expand Down Expand Up @@ -92,7 +92,7 @@ public async Task<GetDialogResult> Handle(GetDialogQuery request, CancellationTo
return new EntityDeleted<DialogEntity>(request.DialogId);
}

var userName = await _userService.GetCurrentUserName(userPid, cancellationToken);
var userName = await _userNameRegistry.GetCurrentUserName(userPid, cancellationToken);
// TODO: What if name lookup fails
// https://github.com/digdir/dialogporten/issues/387
dialog.UpdateSeenAt(userPid, userName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,26 +115,26 @@ internal sealed class SearchDialogQueryHandler : IRequestHandler<SearchDialogQue
private readonly IDialogDbContext _db;
private readonly IMapper _mapper;
private readonly IClock _clock;
private readonly IUserService _userService;
private readonly IUserNameRegistry _userNameRegistry;
private readonly IAltinnAuthorization _altinnAuthorization;

public SearchDialogQueryHandler(
IDialogDbContext db,
IMapper mapper,
IClock clock,
IUserService userService,
IUserNameRegistry userNameRegistry,
IAltinnAuthorization altinnAuthorization)
{
_db = db ?? throw new ArgumentNullException(nameof(db));
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
_clock = clock ?? throw new ArgumentNullException(nameof(clock));
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
_userNameRegistry = userNameRegistry ?? throw new ArgumentNullException(nameof(userNameRegistry));
_altinnAuthorization = altinnAuthorization ?? throw new ArgumentNullException(nameof(altinnAuthorization));
}

public async Task<SearchDialogResult> Handle(SearchDialogQuery request, CancellationToken cancellationToken)
{
if (!_userService.TryGetCurrentUserPid(out var userPid))
if (!_userNameRegistry.TryGetCurrentUserPid(out var userPid))
{
return new Forbidden("No valid user pid found.");
}
Expand Down
Loading

0 comments on commit ca80d36

Please sign in to comment.