IdentityRoleWriter.cs 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using Application.Abstractions.Identity;
  2. using Application.Abstractions.Identity.Models;
  3. using Microsoft.AspNetCore.Identity;
  4. using System.Security.Claims;
  5. namespace Infrastructure.Persistence.Identity;
  6. public sealed class IdentityRoleWriter(RoleManager<IdentityRole> roleManager) : IIdentityRoleWriter
  7. {
  8. public async Task CreateRoleAsync(string roleName, CancellationToken ct)
  9. {
  10. var name = roleName?.Trim();
  11. if (string.IsNullOrWhiteSpace(name))
  12. {
  13. throw new InvalidOperationException("역할 이름은 필수입니다.");
  14. }
  15. if (name.Length > 256)
  16. {
  17. throw new InvalidOperationException("역할 이름은 256자를 초과할 수 없습니다.");
  18. }
  19. if (await roleManager.RoleExistsAsync(name))
  20. {
  21. throw new InvalidOperationException($"{name} 은 이미 존재합니다.");
  22. }
  23. var result = await roleManager.CreateAsync(new IdentityRole(name));
  24. if (!result.Succeeded)
  25. {
  26. throw new InvalidOperationException(string.Join(Environment.NewLine, result.Errors.Select(e => e.Description)));
  27. }
  28. }
  29. public async Task DeleteRoleAsync(string roleID, CancellationToken ct)
  30. {
  31. if (string.IsNullOrWhiteSpace(roleID))
  32. {
  33. throw new InvalidOperationException("Role ID는 필수입니다.");
  34. }
  35. var role = await roleManager.FindByIdAsync(roleID);
  36. if (role is null)
  37. {
  38. throw new InvalidOperationException("역할을 찾을 수 없습니다.");
  39. }
  40. var result = await roleManager.DeleteAsync(role);
  41. if (!result.Succeeded)
  42. {
  43. throw new InvalidOperationException(string.Join(Environment.NewLine, result.Errors.Select(e => e.Description)));
  44. }
  45. }
  46. public async Task UpdateRoleAsync(string roleID, PermissionDto permission, CancellationToken ct)
  47. {
  48. if (string.IsNullOrWhiteSpace(roleID))
  49. {
  50. throw new InvalidOperationException("Role ID는 필수입니다.");
  51. }
  52. var role = await roleManager.FindByIdAsync(roleID);
  53. if (role == null)
  54. {
  55. throw new InvalidOperationException("역할을 찾을 수 없습니다.");
  56. }
  57. // 기존 권한 제거
  58. var existingRoleClaims = await roleManager.GetClaimsAsync(role);
  59. foreach (var claim in existingRoleClaims.Where(c => c.Type == "Permission"))
  60. {
  61. var removed = await roleManager.RemoveClaimAsync(role, claim);
  62. if (!removed.Succeeded)
  63. {
  64. throw new InvalidOperationException(string.Join(Environment.NewLine, removed.Errors.Select(e => e.Description)));
  65. }
  66. }
  67. // 선택된 권한 추출
  68. var selectedClaims = permission.RoleClaims.SelectMany(c => c.Permissions).Where(c => c.IsSelected).Select(c => c.DisplayValue).Where(v => !string.IsNullOrWhiteSpace(v)).ToList();
  69. if (selectedClaims is not null)
  70. {
  71. foreach (var value in selectedClaims)
  72. {
  73. var added = await roleManager.AddClaimAsync(role, new Claim("Permission", value!));
  74. if (!added.Succeeded)
  75. {
  76. throw new InvalidOperationException(string.Join(Environment.NewLine, added.Errors.Select(e => e.Description)));
  77. }
  78. }
  79. }
  80. }
  81. }