IdentityRoleWriter.cs 3.6 KB

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