< Summary

Information
Class: LGDXRobotCloud.API.Services.Administration.RoleService
Assembly: LGDXRobotCloud.API
File(s): /builds/yukaitung/lgdxrobot2-cloud/LGDXRobotCloud.API/Services/Administration/RoleService.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 138
Coverable lines: 138
Total lines: 189
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 38
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)0%2040%
GetRolesAsync()0%620%
GetRoleAsync()0%620%
CreateRoleAsync()0%7280%
UpdateRoleAsync()0%210140%
DeleteRoleAsync()0%4260%
SearchRoleAsync()0%620%

File(s)

/builds/yukaitung/lgdxrobot2-cloud/LGDXRobotCloud.API/Services/Administration/RoleService.cs

#LineLine coverage
 1using System.Security.Claims;
 2using LGDXRobotCloud.API.Exceptions;
 3using LGDXRobotCloud.Data.DbContexts;
 4using LGDXRobotCloud.Data.Entities;
 5using LGDXRobotCloud.Data.Models.Business.Administration;
 6using LGDXRobotCloud.Utilities.Helpers;
 7using Microsoft.AspNetCore.Identity;
 8using Microsoft.EntityFrameworkCore;
 9
 10namespace LGDXRobotCloud.API.Services.Administration;
 11
 12public interface IRoleService
 13{
 14  Task<(IEnumerable<LgdxRoleListBusinessModel>, PaginationHelper)> GetRolesAsync(string? name, int pageNumber, int pageS
 15  Task<LgdxRoleBusinessModel> GetRoleAsync(Guid id);
 16  Task<LgdxRoleBusinessModel> CreateRoleAsync(LgdxRoleCreateBusinessModel lgdxRoleBusinessModel);
 17  Task<bool> UpdateRoleAsync(Guid id, LgdxRoleUpdateBusinessModel lgdxRoleUpdateBusinessModel);
 18  Task<bool> DeleteRoleAsync(Guid id);
 19
 20  Task<IEnumerable<LgdxRoleSearchBusinessModel>> SearchRoleAsync(string? name);
 21}
 22
 023public class RoleService(
 024    LgdxContext context,
 025    RoleManager<LgdxRole> roleManager
 026  ) : IRoleService
 27{
 028  private readonly LgdxContext _context = context ?? throw new ArgumentNullException(nameof(context));
 029  private readonly RoleManager<LgdxRole> _roleManager = roleManager ?? throw new ArgumentNullException(nameof(roleManage
 30
 31  public async Task<(IEnumerable<LgdxRoleListBusinessModel>, PaginationHelper)> GetRolesAsync(string? name, int pageNumb
 032  {
 033    var query = _context.Roles as IQueryable<LgdxRole>;
 034    if (!string.IsNullOrWhiteSpace(name))
 035    {
 036      name = name.Trim().ToUpper();
 037      query = query.Where(u => u.NormalizedName!.Contains(name));
 038    }
 039    var itemCount = await query.CountAsync();
 040    var PaginationHelper = new PaginationHelper(itemCount, pageNumber, pageSize);
 041    var roles = await query.AsNoTracking()
 042      .OrderBy(t => t.Id)
 043      .Skip(pageSize * (pageNumber - 1))
 044      .Take(pageSize)
 045      .Select(t => new LgdxRoleListBusinessModel {
 046        Id = Guid.Parse(t.Id!),
 047        Name = t.Name!,
 048        Description = t.Description,
 049      })
 050      .ToListAsync();
 051    return (roles, PaginationHelper);
 052  }
 53
 54  public async Task<LgdxRoleBusinessModel> GetRoleAsync(Guid id)
 055  {
 056    var role = await _context.Roles.AsNoTracking()
 057      .Where(r => r.Id == id.ToString())
 058      .Select(r => new{
 059        r.Id,
 060        r.Name,
 061        r.Description,
 062      })
 063      .FirstOrDefaultAsync()
 064        ?? throw new LgdxNotFound404Exception();
 65
 066    var claims = await _context.RoleClaims.AsNoTracking()
 067      .Where(c => c.RoleId == id.ToString())
 068      .Where(c => c.ClaimType == "scope")
 069      .Select(r => new {
 070        ClaimValue = r.ClaimValue!,
 071      }).ToListAsync();
 72
 073    return new LgdxRoleBusinessModel {
 074      Id = Guid.Parse(role.Id),
 075      Name = role.Name!,
 076      Description = role.Description,
 077      Scopes = claims.Select(c => c.ClaimValue!),
 078    };
 079  }
 80
 81  public async Task<LgdxRoleBusinessModel> CreateRoleAsync(LgdxRoleCreateBusinessModel lgdxRoleBusinessModel)
 082  {
 083    var role = new LgdxRole {
 084      Id = Guid.CreateVersion7().ToString(),
 085      Name = lgdxRoleBusinessModel.Name,
 086      Description = lgdxRoleBusinessModel.Description,
 087      NormalizedName = lgdxRoleBusinessModel.Name.ToUpper(),
 088    };
 089    var result = await _roleManager.CreateAsync(role);
 090    if (!result.Succeeded)
 091    {
 092      throw new LgdxIdentity400Expection(result.Errors);
 93    }
 94
 095    if (lgdxRoleBusinessModel.Scopes.Any())
 096    {
 097      foreach (var scope in lgdxRoleBusinessModel.Scopes)
 098      {
 099        var addScopeResult = await _roleManager.AddClaimAsync(role, new Claim("scope", scope));
 0100        if (!addScopeResult.Succeeded)
 0101        {
 0102          throw new LgdxIdentity400Expection(addScopeResult.Errors);
 103        }
 0104      }
 0105    }
 106
 0107    return new LgdxRoleBusinessModel {
 0108      Id = Guid.Parse(role.Id),
 0109      Name = role.Name!,
 0110      Description = role.Description,
 0111      Scopes = lgdxRoleBusinessModel.Scopes,
 0112    };
 0113  }
 114
 115  public async Task<bool> UpdateRoleAsync(Guid id, LgdxRoleUpdateBusinessModel lgdxRoleUpdateBusinessModel)
 0116  {
 0117    if (LgdxRolesHelper.IsSystemRole(id))
 0118    {
 0119      throw new LgdxValidation400Expection(nameof(lgdxRoleUpdateBusinessModel.Name), "Cannot update system role.");
 120    }
 0121    var role = await _roleManager.FindByIdAsync(id.ToString()) ?? throw new LgdxNotFound404Exception();
 122
 0123    role.Name = lgdxRoleUpdateBusinessModel.Name;
 0124    role.Description = lgdxRoleUpdateBusinessModel.Description;
 0125    role.NormalizedName = lgdxRoleUpdateBusinessModel.Name.ToUpper();
 126
 0127    var result = await _roleManager.UpdateAsync(role);
 0128    if (!result.Succeeded)
 0129    {
 0130      throw new LgdxIdentity400Expection(result.Errors);
 131    }
 132
 0133    var scopes = await _context.RoleClaims
 0134      .Where(r => r.RoleId == id.ToString())
 0135      .Where(r => r.ClaimType == "scope")
 0136      .Select(r => new {
 0137        r.ClaimValue
 0138      })
 0139      .ToListAsync();
 0140    var scopesList = scopes.Select(s => s.ClaimValue).ToList();
 0141    var scopeToAdd = lgdxRoleUpdateBusinessModel.Scopes.Except(scopesList);
 0142    foreach (var scope in scopeToAdd)
 0143    {
 0144      var addScopeResult = await _roleManager.AddClaimAsync(role, new Claim("scope", scope!));
 0145      if (!addScopeResult.Succeeded)
 0146      {
 0147        throw new LgdxIdentity400Expection(addScopeResult.Errors);
 148      }
 0149    }
 0150    var scopeToRemove = scopesList.Except(lgdxRoleUpdateBusinessModel.Scopes);
 0151    foreach (var scope in scopeToRemove)
 0152    {
 0153      var removeScopeResult = await _roleManager.RemoveClaimAsync(role, new Claim("scope", scope!));
 0154      if (!removeScopeResult.Succeeded)
 0155      {
 0156        throw new LgdxIdentity400Expection(removeScopeResult.Errors);
 157      }
 0158    }
 0159    return true; // Error is handled in the Identity service
 0160  }
 161
 162  public async Task<bool> DeleteRoleAsync(Guid id)
 0163  {
 0164    if (LgdxRolesHelper.IsSystemRole(id))
 0165    {
 0166      throw new LgdxValidation400Expection(nameof(id), "Cannot delete system role.");
 167    }
 0168    var role = await _roleManager.FindByIdAsync(id.ToString()) ?? throw new LgdxNotFound404Exception();
 0169    var result = await _roleManager.DeleteAsync(role);
 0170    if (!result.Succeeded)
 0171    {
 0172      throw new LgdxIdentity400Expection(result.Errors);
 173    }
 0174    return true; // Error is handled in the Identity service
 0175  }
 176
 177  public async Task<IEnumerable<LgdxRoleSearchBusinessModel>> SearchRoleAsync(string? name)
 0178  {
 0179    var n = name ?? string.Empty;
 0180    return await _context.Roles.AsNoTracking()
 0181      .Where(w => w.Name!.ToLower().Contains(n.ToLower()))
 0182      .Take(10)
 0183      .Select(t => new LgdxRoleSearchBusinessModel {
 0184        Id = Guid.Parse(t.Id!),
 0185        Name = t.Name!,
 0186      })
 0187      .ToListAsync();
 0188  }
 189}