Kétfaktoros első része ok
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using WorkFlowCheck.Common.DTO;
|
using WorkFlowCheck.Common.DTO;
|
||||||
using WorkFlowCheck.BL.Services.Interfaces;
|
using WorkFlowCheck.BL.Services.Interfaces;
|
||||||
@@ -114,6 +114,7 @@ namespace WorkFlowCheck.API.Controllers
|
|||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("Authenticate")]
|
[HttpPost("Authenticate")]
|
||||||
public async Task<ApiResponseDTO<UserDTO>> Authenticate([FromBody] UserSimpleDTO userSimpleDTO)
|
public async Task<ApiResponseDTO<UserDTO>> Authenticate([FromBody] UserSimpleDTO userSimpleDTO)
|
||||||
{
|
{
|
||||||
@@ -124,7 +125,7 @@ namespace WorkFlowCheck.API.Controllers
|
|||||||
if (string.IsNullOrEmpty(userSimpleDTO.UserName) || string.IsNullOrEmpty(userSimpleDTO.Password))
|
if (string.IsNullOrEmpty(userSimpleDTO.UserName) || string.IsNullOrEmpty(userSimpleDTO.Password))
|
||||||
{
|
{
|
||||||
retVal.IsSuccess = false;
|
retVal.IsSuccess = false;
|
||||||
retVal.Errors.Add("Nem megfelelo felhasználói név vagy jelszó");
|
retVal.Errors.Add("Nem megfelelo felhasználói név vagy jelszó");
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
@@ -136,11 +137,11 @@ namespace WorkFlowCheck.API.Controllers
|
|||||||
{
|
{
|
||||||
retVal.IsSuccess = true;
|
retVal.IsSuccess = true;
|
||||||
retVal.Data = userDTO_Response;
|
retVal.Data = userDTO_Response;
|
||||||
Log.Information($"Sikeres azonosítás! {userSimpleDTO.UserName}");
|
Log.Information($"Sikeres azonosítás! {userSimpleDTO.UserName}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var error = $"Nem megfelelo felhasználó vagy jelszó! {userSimpleDTO.UserName}";
|
var error = $"Nem megfelelo felhasználó vagy jelszó! {userSimpleDTO.UserName}";
|
||||||
retVal.IsSuccess = false;
|
retVal.IsSuccess = false;
|
||||||
retVal.Errors.Add(error);
|
retVal.Errors.Add(error);
|
||||||
Log.Information(error);
|
Log.Information(error);
|
||||||
@@ -148,7 +149,49 @@ namespace WorkFlowCheck.API.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var error = $"Nem megfelelo felhasználó vagy jelszó! {userSimpleDTO.UserName}";
|
var error = $"Nem megfelelo felhasználó vagy jelszó! {userSimpleDTO.UserName}";
|
||||||
|
retVal.IsSuccess = false;
|
||||||
|
retVal.Errors.Add(error);
|
||||||
|
Log.Information(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
Log.Error(ex.Message);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Ez a 2 faktoros első lépése.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userSimpleDTO"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("Authenticate2F1")]
|
||||||
|
public async Task<ApiResponseDTO<string>> Authenticate2F1([FromBody] UserSimpleDTO userSimpleDTO)
|
||||||
|
{
|
||||||
|
var retVal = new ApiResponseDTO<string>()
|
||||||
|
{
|
||||||
|
IsSuccess = true
|
||||||
|
};
|
||||||
|
if (string.IsNullOrEmpty(userSimpleDTO.UserName) || string.IsNullOrEmpty(userSimpleDTO.Password))
|
||||||
|
{
|
||||||
|
retVal.IsSuccess = false;
|
||||||
|
retVal.Errors.Add("Nem megfelelo felhasználói név vagy jelszó");
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = await _userService.Authenticate2F1(userSimpleDTO.UserName, userSimpleDTO.Password);
|
||||||
|
if (response != null)
|
||||||
|
{
|
||||||
|
retVal.IsSuccess = true;
|
||||||
|
retVal.Data = response;
|
||||||
|
Log.Information($"Sikeres azonosítás! {userSimpleDTO.UserName}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var error = $"Nem megfelelo felhasználó vagy jelszó! {userSimpleDTO.UserName}";
|
||||||
retVal.IsSuccess = false;
|
retVal.IsSuccess = false;
|
||||||
retVal.Errors.Add(error);
|
retVal.Errors.Add(error);
|
||||||
Log.Information(error);
|
Log.Information(error);
|
||||||
@@ -171,7 +214,7 @@ namespace WorkFlowCheck.API.Controllers
|
|||||||
if (string.IsNullOrEmpty(userSimpleDTO.UserName) || string.IsNullOrEmpty(userSimpleDTO.Password))
|
if (string.IsNullOrEmpty(userSimpleDTO.UserName) || string.IsNullOrEmpty(userSimpleDTO.Password))
|
||||||
{
|
{
|
||||||
retVal.IsSuccess = false;
|
retVal.IsSuccess = false;
|
||||||
retVal.Errors.Add("Nem megfelelo felhasználói név vagy jelszó");
|
retVal.Errors.Add("Nem megfelelo felhasználói név vagy jelszó");
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
@@ -183,11 +226,11 @@ namespace WorkFlowCheck.API.Controllers
|
|||||||
{
|
{
|
||||||
retVal.IsSuccess = true;
|
retVal.IsSuccess = true;
|
||||||
retVal.Data = userDTO_Response;
|
retVal.Data = userDTO_Response;
|
||||||
Log.Information($"Sikeres azonosítás! {userSimpleDTO.UserName}");
|
Log.Information($"Sikeres azonosítás! {userSimpleDTO.UserName}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var error = $"Nem megfelelo felhasználó vagy jelszó! {userSimpleDTO.UserName}";
|
var error = $"Nem megfelelo felhasználó vagy jelszó! {userSimpleDTO.UserName}";
|
||||||
retVal.IsSuccess = false;
|
retVal.IsSuccess = false;
|
||||||
retVal.Errors.Add(error);
|
retVal.Errors.Add(error);
|
||||||
Log.Information(error);
|
Log.Information(error);
|
||||||
@@ -195,7 +238,7 @@ namespace WorkFlowCheck.API.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var error = $"Nem megfelelo felhasználó vagy jelszó! {userSimpleDTO.UserName}";
|
var error = $"Nem megfelelo felhasználó vagy jelszó! {userSimpleDTO.UserName}";
|
||||||
retVal.IsSuccess = false;
|
retVal.IsSuccess = false;
|
||||||
retVal.Errors.Add(error);
|
retVal.Errors.Add(error);
|
||||||
Log.Information(error);
|
Log.Information(error);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"SecretKey": "9aLxV2t7RpM8BfKqZwXy3GehYJDUNTCrHkVZ",
|
"SecretKey": "9aLxV2t7RpM8BfKqZwXy3GehYJDUNTCrHkVZ",
|
||||||
"Issuer": "https://wfcapi.nuvolar.hu/",
|
"Issuer": "https://wfcapi.nuvolar.hu/",
|
||||||
"Audience": "wfc-application",
|
"Audience": "wfc-application",
|
||||||
"TokenLifetimeMinutes": 30
|
"TokenLifetimeMinutes": 720
|
||||||
},
|
},
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="hu">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Megerősítő kód</title>
|
||||||
|
</head>
|
||||||
|
<body style="font-family: Arial, sans-serif; background-color: #f9f9f9; padding: 20px;">
|
||||||
|
|
||||||
|
<p style="font-size: 18px;">
|
||||||
|
<strong>Workflow Check Application Web</strong> megerősítő kódja:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="font-size: 28px; font-weight: bold; color: #333; margin-top: 10px;">
|
||||||
|
#token2F#
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -14,6 +14,8 @@ namespace WorkFlowCheck.BL.Services.Interfaces
|
|||||||
Task<bool> DeleteUserAsync(int Id);
|
Task<bool> DeleteUserAsync(int Id);
|
||||||
Task<UserDTO> UpdateUserAsync(UserDTO userDTO);
|
Task<UserDTO> UpdateUserAsync(UserDTO userDTO);
|
||||||
Task<UserDTO> Authenticate(string UserName, string Password);
|
Task<UserDTO> Authenticate(string UserName, string Password);
|
||||||
|
Task<string> Authenticate2F1(string UserName, string Password);
|
||||||
|
Task<UserDTO> Authenticate2F2(string UserName, string Password, string token2FA);
|
||||||
Task<UserDTO> AuthenticateNFC(string NFCCode);
|
Task<UserDTO> AuthenticateNFC(string NFCCode);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,17 +16,24 @@ using System.Security.Claims;
|
|||||||
using WorkFlowCheck.DL.Entities;
|
using WorkFlowCheck.DL.Entities;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using WorkFlowCheck.BL.Static;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace WorkFlowCheck.BL.Services
|
namespace WorkFlowCheck.BL.Services
|
||||||
{
|
{
|
||||||
public class UserService : BaseService, IUserService
|
public class UserService : BaseService, IUserService
|
||||||
{
|
{
|
||||||
private IConfiguration _configuration;
|
private IConfiguration _configuration;
|
||||||
|
private IMessageService _messageService;
|
||||||
|
|
||||||
public UserService(AppDbContext dbContext, IMapper mapper, IConfiguration configuration) : base(dbContext, mapper)
|
public UserService(AppDbContext dbContext,
|
||||||
|
IMapper mapper,
|
||||||
|
IConfiguration configuration,
|
||||||
|
IMessageService messageService) : base(dbContext, mapper)
|
||||||
{
|
{
|
||||||
|
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
|
_messageService = messageService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UserDTO> GetUserAsync(int Id)
|
public async Task<UserDTO> GetUserAsync(int Id)
|
||||||
@@ -90,7 +97,6 @@ namespace WorkFlowCheck.BL.Services
|
|||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
if (user != null && PasswordHasher.VerifyPassword(user.PasswordHash, password))
|
if (user != null && PasswordHasher.VerifyPassword(user.PasswordHash, password))
|
||||||
{
|
{
|
||||||
|
|
||||||
var userDTO = new UserDTO()
|
var userDTO = new UserDTO()
|
||||||
{
|
{
|
||||||
Id = user.Id,
|
Id = user.Id,
|
||||||
@@ -117,6 +123,46 @@ namespace WorkFlowCheck.BL.Services
|
|||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
public async Task<string> Authenticate2F1(string userName, string password)
|
||||||
|
{
|
||||||
|
var retVal = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var user = await _dbContext.Users
|
||||||
|
.Include(i => i.UserRoles)
|
||||||
|
.ThenInclude(i => i.Role)
|
||||||
|
.Where(w => w.UserName == userName)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
if (user != null && PasswordHasher.VerifyPassword(user.PasswordHash, password))
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(user.Email))
|
||||||
|
{
|
||||||
|
var token2F = CodeGenerator2F.GenerateSixDigitCode();
|
||||||
|
|
||||||
|
await _messageService.SendMailAsync(new List<string>()
|
||||||
|
{
|
||||||
|
user.Email,
|
||||||
|
}, "Bejelentkezés megerősítése",
|
||||||
|
Get2FConfirmationMessageBody(token2F));
|
||||||
|
|
||||||
|
retVal = CodeGenerator2F.GenerateToken2F(userName, password, token2F);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex.Message);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
public async Task<UserDTO> Authenticate2F2(string UserName, string Password, string token2FA)
|
||||||
|
{
|
||||||
|
var retVal = new UserDTO() { RoleDTO = new List<RoleDTO>() };
|
||||||
|
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
public async Task<UserDTO> AuthenticateNFC(string NFCCode)
|
public async Task<UserDTO> AuthenticateNFC(string NFCCode)
|
||||||
{
|
{
|
||||||
var retVal = new UserDTO() { RoleDTO = new List<RoleDTO>() };
|
var retVal = new UserDTO() { RoleDTO = new List<RoleDTO>() };
|
||||||
@@ -241,6 +287,20 @@ namespace WorkFlowCheck.BL.Services
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string Get2FConfirmationMessageBody(string token2F)
|
||||||
|
{
|
||||||
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
var resourceName = "WorkFlowCheck.BL.HtmlTemplates.Token2FBody.html";
|
||||||
|
|
||||||
|
using var stream = assembly.GetManifestResourceStream(resourceName);
|
||||||
|
if (stream == null)
|
||||||
|
throw new FileNotFoundException($"Nem található a beágyazott erőforrás: {resourceName}");
|
||||||
|
|
||||||
|
using var reader = new StreamReader(stream);
|
||||||
|
var html = reader.ReadToEnd();
|
||||||
|
return html.Replace("#token2F#", token2F);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<RoleDTO> GetRoleAsync(int Id)
|
public async Task<RoleDTO> GetRoleAsync(int Id)
|
||||||
{
|
{
|
||||||
var retVal = new RoleDTO();
|
var retVal = new RoleDTO();
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WorkFlowCheck.BL.Static
|
||||||
|
{
|
||||||
|
public static class CodeGenerator2F
|
||||||
|
{
|
||||||
|
private static readonly Random _random = new Random();
|
||||||
|
private const string SecretKey = "874512WcfApplicationNuvolar.hu!%mBX210jUUKL";
|
||||||
|
private static readonly byte[] KeyBytes = Encoding.UTF8.GetBytes(SecretKey);
|
||||||
|
|
||||||
|
public static string GenerateSixDigitCode()
|
||||||
|
{
|
||||||
|
return _random.Next(100000, 1000000).ToString(); // 100000 - 999999
|
||||||
|
}
|
||||||
|
public static string GenerateToken2F(string value1, string value2, string value3)
|
||||||
|
{
|
||||||
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
|
|
||||||
|
var claims = new[]
|
||||||
|
{
|
||||||
|
new Claim("val1", value1),
|
||||||
|
new Claim("val2", value2),
|
||||||
|
new Claim("val3", value3)
|
||||||
|
};
|
||||||
|
|
||||||
|
var descriptor = new SecurityTokenDescriptor
|
||||||
|
{
|
||||||
|
Subject = new ClaimsIdentity(claims),
|
||||||
|
Expires = DateTime.UtcNow.AddSeconds(60),
|
||||||
|
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(KeyBytes), SecurityAlgorithms.HmacSha256Signature)
|
||||||
|
};
|
||||||
|
|
||||||
|
var token = tokenHandler.CreateToken(descriptor);
|
||||||
|
return tokenHandler.WriteToken(token);
|
||||||
|
}
|
||||||
|
public static bool ValidateToken2F(string token, string expected1, string expected2, string expected3)
|
||||||
|
{
|
||||||
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var parameters = new TokenValidationParameters
|
||||||
|
{
|
||||||
|
ValidateIssuer = false,
|
||||||
|
ValidateAudience = false,
|
||||||
|
ValidateIssuerSigningKey = true,
|
||||||
|
IssuerSigningKey = new SymmetricSecurityKey(KeyBytes),
|
||||||
|
ClockSkew = TimeSpan.Zero // nincs türelmi idő
|
||||||
|
};
|
||||||
|
|
||||||
|
var principal = tokenHandler.ValidateToken(token, parameters, out var validatedToken);
|
||||||
|
|
||||||
|
var val1 = principal.FindFirst("val1")?.Value;
|
||||||
|
var val2 = principal.FindFirst("val2")?.Value;
|
||||||
|
var val3 = principal.FindFirst("val3")?.Value;
|
||||||
|
|
||||||
|
return val1 == expected1 && val2 == expected2 && val3 == expected3;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,14 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="HtmlTemplates\Token2FBody.html" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="HtmlTemplates\Token2FBody.html" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||||
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
|
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ namespace WorkFlowCheck.Common.DTO
|
|||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
[Required(ErrorMessage = "Az utónév kötelező.")]
|
[Required(ErrorMessage = "Az utónév kötelező.")]
|
||||||
|
[EmailAddress(ErrorMessage = "Érvénytelen email cím.")]
|
||||||
|
[RegularExpression(@"^[^@\s]+@[^@\s]+\.[^@\s]+$", ErrorMessage = "Az email formátum nem megfelelő.")]
|
||||||
[DisplayName("E-mail")]
|
[DisplayName("E-mail")]
|
||||||
public string Email { get; set; } = null!;
|
public string Email { get; set; } = null!;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
@page
|
@page
|
||||||
@model WorkFlowCheck.Web.Pages.UserAndRole.UserEditPageModel
|
@model WorkFlowCheck.Web.Pages.UserAndRole.UserEditPageModel
|
||||||
|
@using WorkFlowCheck.Common.Helper
|
||||||
|
@using WorkFlowCheck.Common.DTO
|
||||||
@using Microsoft.AspNetCore.Antiforgery
|
@using Microsoft.AspNetCore.Antiforgery
|
||||||
@inject IAntiforgery Antiforgery
|
@inject IAntiforgery Antiforgery
|
||||||
@{
|
@{
|
||||||
@@ -82,13 +84,25 @@
|
|||||||
<thead class="table-primary">
|
<thead class="table-primary">
|
||||||
<tr>
|
<tr>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Role Name</th>
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.RoleName), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.ParentRoleName), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.IsAdmin), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.CanEnableBlocked), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.CanDownloadAPK), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.CanUseMobilApp), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.CanUseWebAdmin), typeof(RoleDTO))</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tfoot class="table-light">
|
<tfoot class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Role Name</th>
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.RoleName), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.ParentRoleName), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.IsAdmin), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.CanEnableBlocked), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.CanDownloadAPK), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.CanUseMobilApp), typeof(RoleDTO))</th>
|
||||||
|
<th>@DisplayNameHelper.GetDisplayName(nameof(RoleDTO.CanUseWebAdmin), typeof(RoleDTO))</th>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
@@ -106,7 +120,57 @@
|
|||||||
},
|
},
|
||||||
columns: [
|
columns: [
|
||||||
{ data: "id" },
|
{ data: "id" },
|
||||||
{ data: "roleName" }
|
{ data: "roleName" },
|
||||||
|
{ data: "parentRoleName" },
|
||||||
|
{
|
||||||
|
data: "isAdmin",
|
||||||
|
searchable: false,
|
||||||
|
sortable: false,
|
||||||
|
className: "text-center",
|
||||||
|
render: function ( data, type, row ) {
|
||||||
|
return renderCheckBox(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "canEnableBlocked",
|
||||||
|
searchable: false,
|
||||||
|
sortable: false,
|
||||||
|
className: "text-center",
|
||||||
|
render: function ( data, type, row ) {
|
||||||
|
return renderCheckBox(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "canDownloadAPK",
|
||||||
|
searchable: false,
|
||||||
|
sortable: false,
|
||||||
|
className: "text-center",
|
||||||
|
render: function ( data, type, row ) {
|
||||||
|
return renderCheckBox(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "canUseMobilApp",
|
||||||
|
searchable: false,
|
||||||
|
sortable: false,
|
||||||
|
className: "text-center",
|
||||||
|
render: function ( data, type, row ) {
|
||||||
|
return renderCheckBox(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: "canUseWebAdmin",
|
||||||
|
searchable: false,
|
||||||
|
sortable: false,
|
||||||
|
className: "text-center",
|
||||||
|
render: function ( data, type, row ) {
|
||||||
|
return renderCheckBox(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
],
|
],
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user