< 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
100%
Covered lines: 159
Uncovered lines: 0
Coverable lines: 159
Total lines: 216
Line coverage: 100%
Branch coverage
90%
Covered branches: 36
Total branches: 40
Branch coverage: 90%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%66100%
GetRolesAsync()100%22100%
GetRoleAsync()100%22100%
CreateRoleAsync()100%88100%
UpdateRoleAsync()100%1414100%
DeleteRoleAsync()100%66100%
SearchRoleAsync()50%22100%

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.Enums;
 7using LGDXRobotCloud.Utilities.Helpers;
 8using Microsoft.AspNetCore.Identity;
 9using Microsoft.EntityFrameworkCore;
 10
 11namespace LGDXRobotCloud.API.Services.Administration;
 12
 13public interface IRoleService
 14{
 15  Task<(IEnumerable<LgdxRoleListBusinessModel>, PaginationHelper)> GetRolesAsync(string? name, int pageNumber, int pageS
 16  Task<LgdxRoleBusinessModel> GetRoleAsync(Guid id);
 17  Task<LgdxRoleBusinessModel> CreateRoleAsync(LgdxRoleCreateBusinessModel lgdxRoleBusinessModel);
 18  Task<bool> UpdateRoleAsync(Guid id, LgdxRoleUpdateBusinessModel lgdxRoleUpdateBusinessModel);
 19  Task<bool> DeleteRoleAsync(Guid id);
 20
 21  Task<IEnumerable<LgdxRoleSearchBusinessModel>> SearchRoleAsync(string? name);
 22}
 23
 2324public class RoleService(
 2325    IActivityLogService activityLogService,
 2326    LgdxContext context,
 2327    RoleManager<LgdxRole> roleManager
 2328  ) : IRoleService
 29{
 2330  private readonly IActivityLogService _activityLogService = activityLogService ?? throw new ArgumentNullException(nameo
 2331  private readonly LgdxContext _context = context ?? throw new ArgumentNullException(nameof(context));
 2332  private readonly RoleManager<LgdxRole> _roleManager = roleManager ?? throw new ArgumentNullException(nameof(roleManage
 33
 34  public async Task<(IEnumerable<LgdxRoleListBusinessModel>, PaginationHelper)> GetRolesAsync(string? name, int pageNumb
 435  {
 436    var query = _context.Roles as IQueryable<LgdxRole>;
 437    if (!string.IsNullOrWhiteSpace(name))
 338    {
 339      name = name.Trim().ToUpper();
 340      query = query.Where(u => u.NormalizedName!.Contains(name.ToUpper()));
 341    }
 442    var itemCount = await query.CountAsync();
 443    var PaginationHelper = new PaginationHelper(itemCount, pageNumber, pageSize);
 444    var roles = await query.AsNoTracking()
 445      .OrderBy(t => t.Id)
 446      .Skip(pageSize * (pageNumber - 1))
 447      .Take(pageSize)
 448      .Select(t => new LgdxRoleListBusinessModel {
 449        Id = Guid.Parse(t.Id!),
 450        Name = t.Name!,
 451        Description = t.Description,
 452      })
 453      .ToListAsync();
 454    return (roles, PaginationHelper);
 455  }
 56
 57  public async Task<LgdxRoleBusinessModel> GetRoleAsync(Guid id)
 258  {
 259    var role = await _context.Roles.AsNoTracking()
 260      .Where(r => r.Id == id.ToString())
 261      .Select(r => new{
 262        r.Id,
 263        r.Name,
 264        r.Description,
 265      })
 266      .FirstOrDefaultAsync()
 267        ?? throw new LgdxNotFound404Exception();
 68
 169    var claims = await _context.RoleClaims.AsNoTracking()
 170      .Where(c => c.RoleId == id.ToString())
 171      .Where(c => c.ClaimType == "scope")
 172      .Select(r => new {
 173        ClaimValue = r.ClaimValue!,
 174      }).ToListAsync();
 75
 176    return new LgdxRoleBusinessModel {
 177      Id = Guid.Parse(role.Id),
 178      Name = role.Name!,
 179      Description = role.Description,
 280      Scopes = claims.Select(c => c.ClaimValue!),
 181    };
 182  }
 83
 84  public async Task<LgdxRoleBusinessModel> CreateRoleAsync(LgdxRoleCreateBusinessModel lgdxRoleBusinessModel)
 385  {
 386    var role = new LgdxRole {
 387      Id = Guid.CreateVersion7().ToString(),
 388      Name = lgdxRoleBusinessModel.Name,
 389      Description = lgdxRoleBusinessModel.Description,
 390      NormalizedName = lgdxRoleBusinessModel.Name.ToUpper(),
 391    };
 392    var result = await _roleManager.CreateAsync(role);
 393    if (!result.Succeeded)
 194    {
 195      throw new LgdxIdentity400Expection(result.Errors);
 96    }
 97
 298    if (lgdxRoleBusinessModel.Scopes.Any())
 299    {
 9100      foreach (var scope in lgdxRoleBusinessModel.Scopes)
 2101      {
 2102        var addScopeResult = await _roleManager.AddClaimAsync(role, new Claim("scope", scope));
 2103        if (!addScopeResult.Succeeded)
 1104        {
 1105          throw new LgdxIdentity400Expection(addScopeResult.Errors);
 106        }
 1107      }
 1108    }
 109
 1110    await _activityLogService.CreateActivityLogAsync(new ActivityLogCreateBusinessModel
 1111    {
 1112      EntityName = nameof(LgdxRole),
 1113      EntityId = role.Id,
 1114      Action = ActivityAction.Create,
 1115    });
 116
 1117    return new LgdxRoleBusinessModel
 1118    {
 1119      Id = Guid.Parse(role.Id),
 1120      Name = role.Name!,
 1121      Description = role.Description,
 1122      Scopes = lgdxRoleBusinessModel.Scopes,
 1123    };
 1124  }
 125
 126  public async Task<bool> UpdateRoleAsync(Guid id, LgdxRoleUpdateBusinessModel lgdxRoleUpdateBusinessModel)
 6127  {
 6128    if (LgdxRolesHelper.IsSystemRole(id))
 1129    {
 1130      throw new LgdxValidation400Expection(nameof(lgdxRoleUpdateBusinessModel.Name), "Cannot update system role.");
 131    }
 5132    var role = await _roleManager.FindByIdAsync(id.ToString()) ?? throw new LgdxNotFound404Exception();
 133
 4134    role.Name = lgdxRoleUpdateBusinessModel.Name;
 4135    role.Description = lgdxRoleUpdateBusinessModel.Description;
 4136    role.NormalizedName = lgdxRoleUpdateBusinessModel.Name.ToUpper();
 137
 4138    var result = await _roleManager.UpdateAsync(role);
 4139    if (!result.Succeeded)
 1140    {
 1141      throw new LgdxIdentity400Expection(result.Errors);
 142    }
 143
 3144    var scopes = await _context.RoleClaims
 3145      .Where(r => r.RoleId == id.ToString())
 3146      .Where(r => r.ClaimType == "scope")
 3147      .Select(r => new {
 3148        r.ClaimValue
 3149      })
 3150      .ToListAsync();
 6151    var scopesList = scopes.Select(s => s.ClaimValue).ToList();
 3152    var scopeToAdd = lgdxRoleUpdateBusinessModel.Scopes.Except(scopesList);
 14153    foreach (var scope in scopeToAdd)
 3154    {
 3155      var addScopeResult = await _roleManager.AddClaimAsync(role, new Claim("scope", scope!));
 3156      if (!addScopeResult.Succeeded)
 1157      {
 1158        throw new LgdxIdentity400Expection(addScopeResult.Errors);
 159      }
 2160    }
 2161    var scopeToRemove = scopesList.Except(lgdxRoleUpdateBusinessModel.Scopes);
 9162    foreach (var scope in scopeToRemove)
 2163    {
 2164      var removeScopeResult = await _roleManager.RemoveClaimAsync(role, new Claim("scope", scope!));
 2165      if (!removeScopeResult.Succeeded)
 1166      {
 1167        throw new LgdxIdentity400Expection(removeScopeResult.Errors);
 168      }
 1169    }
 170
 1171    await _activityLogService.CreateActivityLogAsync(new ActivityLogCreateBusinessModel
 1172    {
 1173      EntityName = nameof(LgdxRole),
 1174      EntityId = role.Id,
 1175      Action = ActivityAction.Update,
 1176    });
 177
 1178    return true; // Error is handled in the Identity service
 1179  }
 180
 181  public async Task<bool> DeleteRoleAsync(Guid id)
 4182  {
 4183    if (LgdxRolesHelper.IsSystemRole(id))
 1184    {
 1185      throw new LgdxValidation400Expection(nameof(id), "Cannot delete system role.");
 186    }
 3187    var role = await _roleManager.FindByIdAsync(id.ToString()) ?? throw new LgdxNotFound404Exception();
 2188    var result = await _roleManager.DeleteAsync(role);
 2189    if (!result.Succeeded)
 1190    {
 1191      throw new LgdxIdentity400Expection(result.Errors);
 192    }
 193
 1194    await _activityLogService.CreateActivityLogAsync(new ActivityLogCreateBusinessModel
 1195    {
 1196      EntityName = nameof(LgdxRole),
 1197      EntityId = role.Id,
 1198      Action = ActivityAction.Delete,
 1199    });
 200
 1201    return true; // Error is handled in the Identity service
 1202  }
 203
 204  public async Task<IEnumerable<LgdxRoleSearchBusinessModel>> SearchRoleAsync(string? name)
 4205  {
 4206    var n = name ?? string.Empty;
 4207    return await _context.Roles.AsNoTracking()
 4208      .Where(r => r.NormalizedName!.Contains(n.ToUpper()))
 4209      .Take(10)
 4210      .Select(t => new LgdxRoleSearchBusinessModel {
 4211        Id = Guid.Parse(t.Id!),
 4212        Name = t.Name!,
 4213      })
 4214      .ToListAsync();
 4215  }
 216}