Skip to content

Commit b5bd163

Browse files
committed
Make Role and UserRole contollers generic to support customized user and role.
1 parent e66a6e5 commit b5bd163

File tree

9 files changed

+101
-42
lines changed

9 files changed

+101
-42
lines changed

src/DynamicAuthorization.Mvc.Ui/Controllers/RoleController.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,27 @@
99
using System.ComponentModel;
1010
using System.Linq;
1111
using System.Threading.Tasks;
12-
using Microsoft.EntityFrameworkCore;
1312

1413
namespace DynamicAuthorization.Mvc.Ui.Controllers
1514
{
1615
[Authorize, AddResourcesToViewFilter]
1716
[DisplayName("Role Management")]
18-
public class RoleController : Controller
17+
public class RoleController<TRole, TKey> : Controller
18+
where TRole : IdentityRole<TKey>
19+
where TKey : IEquatable<TKey>
1920
{
20-
private readonly dynamic _roleManager;
21+
private readonly RoleManager<TRole> _roleManager;
2122
private readonly IMvcControllerDiscovery _mvcControllerDiscovery;
2223
private readonly IRoleAccessStore _roleAccessStore;
2324

2425
public RoleController(
2526
IMvcControllerDiscovery mvcControllerDiscovery,
2627
IRoleAccessStore roleAccessStore,
27-
IServiceProvider serviceProvider
28-
)
28+
RoleManager<TRole> roleManager)
2929
{
3030
_mvcControllerDiscovery = mvcControllerDiscovery;
3131
_roleAccessStore = roleAccessStore;
32-
_roleManager = serviceProvider.GetService(typeof(RoleManager<>).MakeGenericType(DynamicAuthorizationOptions.RoleType));
32+
_roleManager = roleManager;
3333
}
3434

3535
// GET: Role
@@ -61,7 +61,10 @@ public async Task<ActionResult> Create(RoleViewModel viewModel)
6161
return View(viewModel);
6262
}
6363

64-
var role = new IdentityRole { Name = viewModel.Name };
64+
//var role1 = new IdentityRole { Name = viewModel.Name };
65+
var role = (TRole)Activator.CreateInstance(DynamicAuthorizationOptions.RoleType);
66+
role.GetType().GetProperty("Name")?.SetValue(role, viewModel.Name, null);
67+
6568
var result = await _roleManager.CreateAsync(role);
6669

6770
if (!result.Succeeded)
@@ -82,7 +85,7 @@ public async Task<ActionResult> Create(RoleViewModel viewModel)
8285
var roleAccess = new RoleAccess
8386
{
8487
Controllers = viewModel.SelectedControllers.ToList(),
85-
RoleId = role.Id
88+
RoleId = role.GetType().GetProperty("Id")?.GetValue(role).ToString()
8689
};
8790
await _roleAccessStore.AddRoleAccessAsync(roleAccess);
8891
}
@@ -99,7 +102,7 @@ public async Task<ActionResult> Edit(string id)
99102
if (role == null)
100103
return NotFound();
101104

102-
var accessList = await _roleAccessStore.GetRoleAccessAsync(role.Id);
105+
var accessList = await _roleAccessStore.GetRoleAccessAsync(role.Id.ToString());
103106
var viewModel = new RoleViewModel
104107
{
105108
Name = role.Name,
@@ -154,7 +157,7 @@ public async Task<ActionResult> Edit(string id, RoleViewModel viewModel)
154157
var roleAccess = new RoleAccess
155158
{
156159
Controllers = viewModel.SelectedControllers?.ToList(),
157-
RoleId = role.Id
160+
RoleId = role.Id.ToString()
158161
};
159162
await _roleAccessStore.EditRoleAccessAsync(roleAccess);
160163

@@ -181,7 +184,7 @@ public async Task<ActionResult> Delete(string id)
181184
return BadRequest(ModelState);
182185
}
183186

184-
await _roleAccessStore.RemoveRoleAccessAsync(role.Id);
187+
await _roleAccessStore.RemoveRoleAccessAsync(role.Id.ToString());
185188

186189
return Ok(new { });
187190
}

src/DynamicAuthorization.Mvc.Ui/Controllers/UserRoleController.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
using DynamicAuthorization.Mvc.Core.Models;
2-
using DynamicAuthorization.Mvc.Ui.Filters;
1+
using DynamicAuthorization.Mvc.Ui.Filters;
32
using DynamicAuthorization.Mvc.Ui.Services;
43
using DynamicAuthorization.Mvc.Ui.ViewModels;
54
using Microsoft.AspNetCore.Authorization;
65
using Microsoft.AspNetCore.Identity;
76
using Microsoft.AspNetCore.Mvc;
8-
using Microsoft.EntityFrameworkCore.Internal;
97
using System;
10-
using System.Collections.Generic;
118
using System.ComponentModel;
129
using System.Linq;
1310
using System.Threading.Tasks;
@@ -16,15 +13,18 @@ namespace DynamicAuthorization.Mvc.Ui.Controllers
1613
{
1714
[Authorize, AddResourcesToViewFilter]
1815
[DisplayName("User Role Management")]
19-
public class UserRoleController : Controller
16+
public class UserRoleController<TRole, TUser, TKey> : Controller
17+
where TRole : IdentityRole<TKey>
18+
where TUser : IdentityUser<TKey>
19+
where TKey : IEquatable<TKey>
2020
{
21-
private readonly dynamic _roleManager;
22-
private readonly dynamic _userManager;
21+
private readonly RoleManager<TRole> _roleManager;
22+
private readonly UserManager<TUser> _userManager;
2323

24-
public UserRoleController(IServiceProvider serviceProvider)
24+
public UserRoleController(RoleManager<TRole> roleManager, UserManager<TUser> userManager)
2525
{
26-
_roleManager = serviceProvider.GetService(typeof(RoleManager<>).MakeGenericType(DynamicAuthorizationOptions.RoleType));
27-
_userManager = serviceProvider.GetService(typeof(UserManager<>).MakeGenericType(DynamicAuthorizationOptions.UserType));
26+
_roleManager = roleManager;
27+
_userManager = userManager;
2828
}
2929

3030
// GET: Access
@@ -47,7 +47,7 @@ public async Task<ActionResult> Edit(string id)
4747
var userRoles = await _userManager.GetRolesAsync(user);
4848
var userViewModel = new UserRoleViewModel
4949
{
50-
UserId = user.Id,
50+
UserId = user.Id.ToString(),
5151
UserName = user.UserName,
5252
Roles = userRoles
5353
};
@@ -77,7 +77,7 @@ public async Task<ActionResult> Edit(UserRoleViewModel viewModel)
7777
return View();
7878
}
7979

80-
List<string> userRoles = await _userManager.GetRolesAsync(user);
80+
var userRoles = await _userManager.GetRolesAsync(user);
8181
if (userRoles.Any())
8282
await _userManager.RemoveFromRolesAsync(user, userRoles);
8383

src/DynamicAuthorization.Mvc.Ui/Extensions/ServiceCollectionExtensions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using DynamicAuthorization.Mvc.Core.Models;
33
using DynamicAuthorization.Mvc.Ui.Filters;
44
using DynamicAuthorization.Mvc.Ui.Services;
5+
using Microsoft.AspNetCore.Mvc;
56
using Microsoft.AspNetCore.Mvc.ApplicationParts;
67
using Microsoft.Extensions.DependencyInjection;
78
using System;
@@ -57,6 +58,16 @@ public static IDynamicAuthorizationBuilder AddUi(this IDynamicAuthorizationBuild
5758
DynamicAuthorizationOptions.UserTokenType
5859
));
5960

61+
mvcBuilder.ConfigureApplicationPartManager(c =>
62+
{
63+
c.FeatureProviders.Add(new GenericRestControllerFeatureProvider());
64+
});
65+
66+
builder.Services.Configure<MvcOptions>(mvcOptions =>
67+
{
68+
mvcOptions.Conventions.Add(new GenericRestControllerNameConvention());
69+
});
70+
6071
return builder;
6172
}
6273
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using DynamicAuthorization.Mvc.Core.Models;
2+
using DynamicAuthorization.Mvc.Ui.Controllers;
3+
using Microsoft.AspNetCore.Mvc.ApplicationParts;
4+
using Microsoft.AspNetCore.Mvc.Controllers;
5+
using System.Collections.Generic;
6+
using System.Reflection;
7+
8+
namespace DynamicAuthorization.Mvc.Ui
9+
{
10+
public class GenericRestControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
11+
{
12+
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
13+
{
14+
var roleControllerType = typeof(RoleController<,>).MakeGenericType(DynamicAuthorizationOptions.RoleType,
15+
DynamicAuthorizationOptions.KeyType).GetTypeInfo();
16+
17+
var userRoleControllerType = typeof(UserRoleController<,,>).MakeGenericType(
18+
DynamicAuthorizationOptions.RoleType,
19+
DynamicAuthorizationOptions.UserType,
20+
DynamicAuthorizationOptions.KeyType).GetTypeInfo();
21+
22+
feature.Controllers.Add(roleControllerType);
23+
feature.Controllers.Add(userRoleControllerType);
24+
}
25+
}
26+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Microsoft.AspNetCore.Mvc.ApplicationModels;
2+
using System;
3+
4+
namespace DynamicAuthorization.Mvc.Ui
5+
{
6+
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
7+
public class GenericRestControllerNameConvention : Attribute, IControllerModelConvention
8+
{
9+
public void Apply(ControllerModel controller)
10+
{
11+
if (!controller.ControllerType.IsGenericType &&
12+
controller.ControllerType.Namespace != "DynamicAuthorization.Mvc.Ui.Controllers")
13+
return;
14+
15+
if (controller.ControllerName.StartsWith("role", StringComparison.CurrentCultureIgnoreCase))
16+
controller.RouteValues["Controller"] = "Role";
17+
else if (controller.ControllerName.StartsWith("userrole", StringComparison.CurrentCultureIgnoreCase))
18+
controller.RouteValues["Controller"] = "UserRole";
19+
}
20+
}
21+
}

src/DynamicAuthorization.Mvc.Ui/Services/IdentityService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ from role in roles.DefaultIfEmpty()
7777
{
7878
UserId = first.user.Id.ToString(),
7979
UserName = first.user.UserName,
80-
Roles = first.role != null ? grp.Select(g => g.role).Select(r => r.Name) : new List<string>()
80+
Roles = first.role != null ? grp.Select(g => g.role).Select(r => r.Name).ToList() : new List<string>()
8181
});
8282
}
8383

src/DynamicAuthorization.Mvc.Ui/ViewModels/UserRoleViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ public class UserRoleViewModel
1010

1111
public string UserName { get; set; }
1212

13-
public IEnumerable<string> Roles { get; set; }
13+
public IList<string> Roles { get; set; }
1414
}
1515
}

src/DynamicAuthorization.Mvc.Ui/Views/Role/Index.cshtml

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
@using Microsoft.AspNetCore.Identity
2-
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
3-
@model IEnumerable<IdentityRole>
1+
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
2+
@model IEnumerable<dynamic>
43

54
@{
65
ViewData["Title"] = "Role List";
@@ -15,26 +14,26 @@
1514
<table class="table table-bordered">
1615
<thead>
1716
<tr>
18-
<th scope="col"> @Html.DisplayNameFor(m => m.Name) </th>
17+
<th scope="col"> Name </th>
1918
<th scope="col">Actions</th>
2019
</tr>
2120
</thead>
2221
<tbody>
2322
@if (!Model.Any())
2423
{
25-
<tr>
26-
<td colspan="2">There is no role!</td>
27-
</tr>
24+
<tr>
25+
<td colspan="2">There is no role!</td>
26+
</tr>
2827
}
2928
@foreach (var role in Model)
3029
{
31-
<tr>
32-
<td>@Html.DisplayFor(m => role.Name)</td>
33-
<td>
34-
<a asp-action="Edit" asp-route-id="@role.Id">Edit</a> |
35-
<a asp-action="Delete" asp-route-id="@role.Id" class="delete-item">Delete</a>
36-
</td>
37-
</tr>
30+
<tr>
31+
<td>@role.Name</td>
32+
<td>
33+
<a asp-action="Edit" asp-route-id="@role.Id">Edit</a> |
34+
<a asp-action="Delete" asp-route-id="@role.Id" class="delete-item">Delete</a>
35+
</td>
36+
</tr>
3837
}
3938
</tbody>
4039
</table>

src/DynamicAuthorization.Mvc.Ui/Views/UserRole/Edit.cshtml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
@using DynamicAuthorization.Mvc.Ui.ViewModels
2-
@using Microsoft.AspNetCore.Identity
32
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
43
@model UserRoleViewModel
54
@{
65
ViewData["Title"] = "Edit User Access";
76
Layout = "~/Views/Shared/_AuthLayout.cshtml";
8-
var roles = (IEnumerable<IdentityRole>)ViewData["Roles"];
7+
var roles = (IEnumerable<dynamic>)ViewData["Roles"];
98
}
109

1110
@*@section header{
@@ -40,7 +39,7 @@
4039
{
4140
<label>
4241
<input type="checkbox" name="Roles[]" value="@role.Name"
43-
@if (Model?.Roles != null && Model.Roles.Contains(role.Name)) { <text> checked="checked" </text> } />
42+
@if (Model?.Roles != null && Model.Roles.Contains(role.Name.ToString())) { <text> checked="checked" </text> } />
4443
&nbsp;@role.Name&nbsp;&nbsp;
4544
</label>
4645
}

0 commit comments

Comments
 (0)