Skip to content

Commit 60178dc

Browse files
committed
Implemented user deletion service and IUserDeleteHandler for plugins to hook into
1 parent 8a63a34 commit 60178dc

File tree

5 files changed

+96
-2
lines changed

5 files changed

+96
-2
lines changed

Moonlight.ApiServer/Http/Controllers/Admin/Users/UsersController.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
using Microsoft.AspNetCore.Authorization;
33
using Microsoft.AspNetCore.Mvc;
44
using Microsoft.EntityFrameworkCore;
5+
using Microsoft.Extensions.DependencyInjection;
56
using MoonCore.Exceptions;
67
using MoonCore.Extended.Abstractions;
78
using MoonCore.Extended.Helpers;
89
using MoonCore.Models;
910
using Moonlight.ApiServer.Database.Entities;
11+
using Moonlight.ApiServer.Services;
1012
using Moonlight.Shared.Http.Requests.Admin.Users;
1113
using Moonlight.Shared.Http.Responses.Admin.Users;
1214

@@ -166,7 +168,7 @@ public async Task<UserResponse> Update([FromRoute] int id, [FromBody] UpdateUser
166168

167169
[HttpDelete("{id}")]
168170
[Authorize(Policy = "permissions:admin.users.delete")]
169-
public async Task Delete([FromRoute] int id)
171+
public async Task Delete([FromRoute] int id, [FromQuery] bool force = false)
170172
{
171173
var user = await UserRepository
172174
.Get()
@@ -175,6 +177,16 @@ public async Task Delete([FromRoute] int id)
175177
if (user == null)
176178
throw new HttpApiException("No user with that id found", 404);
177179

178-
await UserRepository.Remove(user);
180+
var deletionService = HttpContext.RequestServices.GetRequiredService<UserDeletionService>();
181+
182+
if (!force)
183+
{
184+
var validationResult = await deletionService.Validate(user);
185+
186+
if (!validationResult.IsAllowed)
187+
throw new HttpApiException($"Unable to delete user", 400, validationResult.Reason);
188+
}
189+
190+
await deletionService.Delete(user, force);
179191
}
180192
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Moonlight.ApiServer.Database.Entities;
2+
using Moonlight.ApiServer.Models;
3+
4+
namespace Moonlight.ApiServer.Interfaces;
5+
6+
public interface IUserDeleteHandler
7+
{
8+
public Task<UserDeleteValidationResult> Validate(User user);
9+
public Task Delete(User user, bool force);
10+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace Moonlight.ApiServer.Models;
2+
3+
public class UserDeleteValidationResult
4+
{
5+
public bool IsAllowed { get; set; }
6+
public string Reason { get; set; }
7+
8+
public static UserDeleteValidationResult Allow()
9+
{
10+
return new UserDeleteValidationResult()
11+
{
12+
IsAllowed = true
13+
};
14+
}
15+
16+
public static UserDeleteValidationResult Deny()
17+
=> Deny("No reason provided");
18+
19+
public static UserDeleteValidationResult Deny(string reason)
20+
{
21+
return new UserDeleteValidationResult()
22+
{
23+
IsAllowed = false,
24+
Reason = reason
25+
};
26+
}
27+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using MoonCore.Extended.Abstractions;
2+
using Moonlight.ApiServer.Database.Entities;
3+
using Moonlight.ApiServer.Interfaces;
4+
using Moonlight.ApiServer.Models;
5+
6+
namespace Moonlight.ApiServer.Services;
7+
8+
public class UserDeletionService
9+
{
10+
private readonly IUserDeleteHandler[] Handlers;
11+
private readonly DatabaseRepository<User> UserRepository;
12+
13+
public UserDeletionService(
14+
IEnumerable<IUserDeleteHandler> handlers,
15+
DatabaseRepository<User> userRepository
16+
)
17+
{
18+
UserRepository = userRepository;
19+
Handlers = handlers.ToArray();
20+
}
21+
22+
public async Task<UserDeleteValidationResult> Validate(User user)
23+
{
24+
foreach (var handler in Handlers)
25+
{
26+
var result = await handler.Validate(user);
27+
28+
if (!result.IsAllowed)
29+
return result;
30+
}
31+
32+
return UserDeleteValidationResult.Allow();
33+
}
34+
35+
public async Task Delete(User user, bool force)
36+
{
37+
foreach (var handler in Handlers)
38+
await Delete(user, force);
39+
40+
await UserRepository.Remove(user);
41+
}
42+
}

Moonlight.ApiServer/Startup/Startup.Auth.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using MoonCore.Permissions;
77
using Moonlight.ApiServer.Implementations;
88
using Moonlight.ApiServer.Interfaces;
9+
using Moonlight.ApiServer.Services;
910

1011
namespace Moonlight.ApiServer.Startup;
1112

@@ -47,6 +48,8 @@ private Task RegisterAuth()
4748
if (Configuration.Authentication.EnableLocalOAuth2)
4849
WebApplicationBuilder.Services.AddScoped<IOAuth2Provider, LocalOAuth2Provider>();
4950

51+
WebApplicationBuilder.Services.AddScoped<UserDeletionService>();
52+
5053
return Task.CompletedTask;
5154
}
5255

0 commit comments

Comments
 (0)