Skip to content

Commit 0622a83

Browse files
committed
Add ASP.NET Core 2.2 sample project.
1 parent 4422d24 commit 0622a83

File tree

92 files changed

+42490
-25
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+42490
-25
lines changed

DynamicRoleBasedAuthorization.sln

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.29613.14
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynamicAuthorization.Mvc.Core", "src\DynamicAuthorization.Mvc.Core\DynamicAuthorization.Mvc.Core.csproj", "{89E57FDC-5AF7-4AAF-A40B-FBA91D41ECF4}"
77
EndProject
8-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynamicRoleBasedAuthorization", "src\DynamicRoleBasedAuthorization\DynamicRoleBasedAuthorization.csproj", "{1C9180AD-3F20-4F16-9C2F-5DFB502A7FD5}"
9-
EndProject
108
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynamicAuthorization.Mvc.JsonStore", "src\DynamicAuthorization.Mvc.JsonStore\DynamicAuthorization.Mvc.JsonStore.csproj", "{3E397C28-EDC7-4DCC-896F-476A9EE74E76}"
119
EndProject
1210
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A7EEBB7E-C64D-4475-93D0-872E080A4E03}"
@@ -17,6 +15,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "netcore3.x", "netcore3.x",
1715
EndProject
1816
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleMvcWebApp", "samples\netcore3.x\SampleMvcWebApp\SampleMvcWebApp.csproj", "{0833E296-398F-42A4-9531-D125483AB019}"
1917
EndProject
18+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "netcore2.2", "netcore2.2", "{11B88EB7-66BE-402A-A4E0-144220EBD8B9}"
19+
EndProject
20+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleMvc2WebApp", "samples\netcore2.2\SampleMvc2WebApp\SampleMvc2WebApp.csproj", "{A3124728-6766-48A3-BA1A-5CB119924395}"
21+
EndProject
2022
Global
2123
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2224
Debug|Any CPU = Debug|Any CPU
@@ -27,10 +29,6 @@ Global
2729
{89E57FDC-5AF7-4AAF-A40B-FBA91D41ECF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
2830
{89E57FDC-5AF7-4AAF-A40B-FBA91D41ECF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
2931
{89E57FDC-5AF7-4AAF-A40B-FBA91D41ECF4}.Release|Any CPU.Build.0 = Release|Any CPU
30-
{1C9180AD-3F20-4F16-9C2F-5DFB502A7FD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31-
{1C9180AD-3F20-4F16-9C2F-5DFB502A7FD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
32-
{1C9180AD-3F20-4F16-9C2F-5DFB502A7FD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
33-
{1C9180AD-3F20-4F16-9C2F-5DFB502A7FD5}.Release|Any CPU.Build.0 = Release|Any CPU
3432
{3E397C28-EDC7-4DCC-896F-476A9EE74E76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
3533
{3E397C28-EDC7-4DCC-896F-476A9EE74E76}.Debug|Any CPU.Build.0 = Debug|Any CPU
3634
{3E397C28-EDC7-4DCC-896F-476A9EE74E76}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -39,6 +37,10 @@ Global
3937
{0833E296-398F-42A4-9531-D125483AB019}.Debug|Any CPU.Build.0 = Debug|Any CPU
4038
{0833E296-398F-42A4-9531-D125483AB019}.Release|Any CPU.ActiveCfg = Release|Any CPU
4139
{0833E296-398F-42A4-9531-D125483AB019}.Release|Any CPU.Build.0 = Release|Any CPU
40+
{A3124728-6766-48A3-BA1A-5CB119924395}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41+
{A3124728-6766-48A3-BA1A-5CB119924395}.Debug|Any CPU.Build.0 = Debug|Any CPU
42+
{A3124728-6766-48A3-BA1A-5CB119924395}.Release|Any CPU.ActiveCfg = Release|Any CPU
43+
{A3124728-6766-48A3-BA1A-5CB119924395}.Release|Any CPU.Build.0 = Release|Any CPU
4244
EndGlobalSection
4345
GlobalSection(SolutionProperties) = preSolution
4446
HideSolutionNode = FALSE
@@ -48,6 +50,8 @@ Global
4850
{3E397C28-EDC7-4DCC-896F-476A9EE74E76} = {A7EEBB7E-C64D-4475-93D0-872E080A4E03}
4951
{5FEB9007-1EFA-4814-BC15-DB0370B84E22} = {BAAF9837-1DB5-4032-AB2A-2901E6EE6EF8}
5052
{0833E296-398F-42A4-9531-D125483AB019} = {5FEB9007-1EFA-4814-BC15-DB0370B84E22}
53+
{11B88EB7-66BE-402A-A4E0-144220EBD8B9} = {BAAF9837-1DB5-4032-AB2A-2901E6EE6EF8}
54+
{A3124728-6766-48A3-BA1A-5CB119924395} = {11B88EB7-66BE-402A-A4E0-144220EBD8B9}
5155
EndGlobalSection
5256
GlobalSection(ExtensibilityGlobals) = postSolution
5357
SolutionGuid = {18C80710-C9E9-488B-9100-1E4BF8B18038}
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
using DynamicAuthorization.Mvc.Core;
2+
using Microsoft.AspNetCore.Authorization;
3+
using Microsoft.AspNetCore.Identity;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.EntityFrameworkCore;
6+
using SampleMvc2WebApp.Areas.Access.Models;
7+
using System.ComponentModel;
8+
using System.Linq;
9+
using System.Threading.Tasks;
10+
11+
namespace SampleMvc2WebApp.Areas.Access.Controllers
12+
{
13+
[Area("Access"), Authorize]
14+
[DisplayName("Role Management")]
15+
public class RoleController : Controller
16+
{
17+
private readonly IMvcControllerDiscovery _mvcControllerDiscovery;
18+
private readonly IRoleAccessStore _roleAccessStore;
19+
private readonly RoleManager<IdentityRole> _roleManager;
20+
21+
public RoleController(
22+
IMvcControllerDiscovery mvcControllerDiscovery,
23+
IRoleAccessStore roleAccessStore,
24+
RoleManager<IdentityRole> roleManager
25+
)
26+
{
27+
_mvcControllerDiscovery = mvcControllerDiscovery;
28+
_roleManager = roleManager;
29+
_roleAccessStore = roleAccessStore;
30+
}
31+
32+
// GET: Role
33+
[DisplayName("Role List")]
34+
public async Task<ActionResult> Index()
35+
{
36+
var roles = await _roleManager.Roles.ToListAsync();
37+
38+
return View(roles);
39+
}
40+
41+
[DisplayName("Create Role")]
42+
// GET: Role/Create
43+
public ActionResult Create()
44+
{
45+
var controllers = _mvcControllerDiscovery.GetControllers();
46+
ViewData["Controllers"] = controllers;
47+
48+
return View();
49+
}
50+
51+
// POST: Role/Create
52+
[HttpPost, ValidateAntiForgeryToken]
53+
public async Task<ActionResult> Create(RoleViewModel viewModel)
54+
{
55+
if (!ModelState.IsValid)
56+
{
57+
ViewData["Controllers"] = _mvcControllerDiscovery.GetControllers();
58+
return View(viewModel);
59+
}
60+
61+
var role = new IdentityRole { Name = viewModel.Name };
62+
var result = await _roleManager.CreateAsync(role);
63+
64+
if (!result.Succeeded)
65+
{
66+
foreach (var error in result.Errors)
67+
ModelState.AddModelError("", error.Description);
68+
69+
ViewData["Controllers"] = _mvcControllerDiscovery.GetControllers();
70+
return View(viewModel);
71+
}
72+
73+
if (viewModel.SelectedControllers != null && viewModel.SelectedControllers.Any())
74+
{
75+
foreach (var controller in viewModel.SelectedControllers)
76+
foreach (var action in controller.Actions)
77+
action.ControllerId = controller.Id;
78+
79+
var roleAccess = new RoleAccess
80+
{
81+
Controllers = viewModel.SelectedControllers.ToList(),
82+
RoleId = role.Id
83+
};
84+
await _roleAccessStore.AddRoleAccessAsync(roleAccess);
85+
}
86+
87+
return RedirectToAction(nameof(Index));
88+
}
89+
90+
// GET: Role/Edit/5
91+
[DisplayName("Edit Role")]
92+
public async Task<ActionResult> Edit(string id)
93+
{
94+
ViewData["Controllers"] = _mvcControllerDiscovery.GetControllers();
95+
var role = await _roleManager.FindByIdAsync(id);
96+
if (role == null)
97+
return NotFound();
98+
99+
var accessList = await _roleAccessStore.GetRoleAccessAsync(role.Id);
100+
var viewModel = new RoleViewModel
101+
{
102+
Name = role.Name,
103+
SelectedControllers = accessList?.Controllers
104+
};
105+
106+
return View(viewModel);
107+
}
108+
109+
// POST: Role/Edit/5
110+
[HttpPost, ValidateAntiForgeryToken]
111+
public async Task<ActionResult> Edit(string id, RoleViewModel viewModel)
112+
{
113+
if (!ModelState.IsValid)
114+
{
115+
ViewData["Controllers"] = _mvcControllerDiscovery.GetControllers();
116+
return View(viewModel);
117+
}
118+
119+
// Check role exit
120+
var role = await _roleManager.FindByIdAsync(id);
121+
if (role == null)
122+
{
123+
ModelState.AddModelError("", "Role not found");
124+
ViewData["Controllers"] = _mvcControllerDiscovery.GetControllers();
125+
return View();
126+
}
127+
128+
// Update role if role's name is changed
129+
if (role.Name != viewModel.Name)
130+
{
131+
role.Name = viewModel.Name;
132+
var result = await _roleManager.UpdateAsync(role);
133+
if (!result.Succeeded)
134+
{
135+
foreach (var error in result.Errors)
136+
ModelState.AddModelError("", error.Description);
137+
138+
ViewData["Controllers"] = _mvcControllerDiscovery.GetControllers();
139+
return View(viewModel);
140+
}
141+
}
142+
143+
// Update role access list
144+
if (viewModel.SelectedControllers != null && viewModel.SelectedControllers.Any())
145+
{
146+
foreach (var controller in viewModel.SelectedControllers)
147+
foreach (var action in controller.Actions)
148+
action.ControllerId = controller.Id;
149+
}
150+
151+
var roleAccess = new RoleAccess
152+
{
153+
Controllers = viewModel.SelectedControllers?.ToList(),
154+
RoleId = role.Id
155+
};
156+
await _roleAccessStore.EditRoleAccessAsync(roleAccess);
157+
158+
return RedirectToAction(nameof(Index));
159+
}
160+
161+
// POST: Role/Delete/5
162+
[HttpDelete("role/{id}")]
163+
public async Task<ActionResult> Delete(string id)
164+
{
165+
var role = await _roleManager.FindByIdAsync(id);
166+
if (role == null)
167+
{
168+
ModelState.AddModelError("Error", "Role not found");
169+
return BadRequest(ModelState);
170+
}
171+
172+
var result = await _roleManager.DeleteAsync(role);
173+
if (!result.Succeeded)
174+
{
175+
foreach (var error in result.Errors)
176+
ModelState.AddModelError("Error", error.Description);
177+
178+
return BadRequest(ModelState);
179+
}
180+
181+
await _roleAccessStore.RemoveRoleAccessAsync(role.Id);
182+
183+
return Ok(new { });
184+
}
185+
}
186+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
using Microsoft.AspNetCore.Identity;
3+
using Microsoft.AspNetCore.Mvc;
4+
using Microsoft.EntityFrameworkCore;
5+
using SampleMvc2WebApp.Areas.Access.Models;
6+
using SampleMvc2WebApp.Data;
7+
using System.Collections.Generic;
8+
using System.ComponentModel;
9+
using System.Linq;
10+
using System.Threading.Tasks;
11+
12+
namespace SampleMvc2WebApp.Areas.Access.Controllers
13+
{
14+
[Area("Access"), Authorize]
15+
[DisplayName("User Role Management")]
16+
public class UserRoleController : Controller
17+
{
18+
private readonly ApplicationDbContext _dbContext;
19+
private readonly RoleManager<IdentityRole> _roleManager;
20+
private readonly UserManager<IdentityUser> _userManager;
21+
22+
public UserRoleController(
23+
ApplicationDbContext dbContext,
24+
RoleManager<IdentityRole> roleManager,
25+
UserManager<IdentityUser> userManager
26+
)
27+
{
28+
_roleManager = roleManager;
29+
_userManager = userManager;
30+
_dbContext = dbContext;
31+
}
32+
33+
// GET: Access
34+
[DisplayName("User List")]
35+
public async Task<ActionResult> Index()
36+
{
37+
var query = await (
38+
from user in _dbContext.Users
39+
join ur in _dbContext.UserRoles on user.Id equals ur.UserId into userRoles
40+
from userRole in userRoles.DefaultIfEmpty()
41+
join rle in _dbContext.Roles on userRole.RoleId equals rle.Id into roles
42+
from role in roles.DefaultIfEmpty()
43+
select new { user, userRole, role }
44+
).ToListAsync();
45+
46+
var userList = new List<UserRoleViewModel>();
47+
foreach (var grp in query.GroupBy(q => q.user.Id))
48+
{
49+
var first = grp.First();
50+
userList.Add(new UserRoleViewModel
51+
{
52+
UserId = first.user.Id,
53+
UserName = first.user.UserName,
54+
Roles = first.role != null ? grp.Select(g => g.role).Select(r => r.Name) : new List<string>()
55+
});
56+
}
57+
58+
return View(userList);
59+
}
60+
61+
// GET: Access/Edit
62+
[DisplayName("Edit User Roles")]
63+
public async Task<ActionResult> Edit(string id)
64+
{
65+
var user = await _userManager.FindByIdAsync(id);
66+
if (user == null)
67+
return NotFound();
68+
69+
var userRoles = await _userManager.GetRolesAsync(user);
70+
var userViewModel = new UserRoleViewModel
71+
{
72+
UserId = user.Id,
73+
UserName = user.UserName,
74+
Roles = userRoles
75+
};
76+
77+
var roles = await _roleManager.Roles.ToListAsync();
78+
ViewData["Roles"] = roles;
79+
80+
return View(userViewModel);
81+
}
82+
83+
// POST: Access/Edit
84+
[HttpPost]
85+
[ValidateAntiForgeryToken]
86+
public async Task<ActionResult> Edit(UserRoleViewModel viewModel)
87+
{
88+
if (!ModelState.IsValid)
89+
{
90+
ViewData["Roles"] = await _roleManager.Roles.ToListAsync();
91+
return View(viewModel);
92+
}
93+
94+
var user = _dbContext.Users.Find(viewModel.UserId);
95+
if (user == null)
96+
{
97+
ModelState.AddModelError("", "User not found");
98+
ViewData["Roles"] = await _roleManager.Roles.ToListAsync();
99+
return View();
100+
}
101+
102+
var userRoles = await _userManager.GetRolesAsync(user);
103+
await _userManager.RemoveFromRolesAsync(user, userRoles);
104+
await _userManager.AddToRolesAsync(user, viewModel.Roles);
105+
106+
return RedirectToAction("Index");
107+
}
108+
}
109+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using DynamicAuthorization.Mvc.Core;
2+
using System.Collections.Generic;
3+
using System.ComponentModel.DataAnnotations;
4+
5+
namespace SampleMvc2WebApp.Areas.Access.Models
6+
{
7+
public class RoleViewModel
8+
{
9+
[Required]
10+
[StringLength(256, ErrorMessage = "The {0} must be at least {2} characters long.")]
11+
public string Name { get; set; }
12+
13+
public IEnumerable<MvcControllerInfo> SelectedControllers { get; set; }
14+
}
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Collections.Generic;
2+
using System.ComponentModel.DataAnnotations;
3+
4+
namespace SampleMvc2WebApp.Areas.Access.Models
5+
{
6+
public class UserRoleViewModel
7+
{
8+
[Required]
9+
public string UserId { get; set; }
10+
11+
public string UserName { get; set; }
12+
13+
public IEnumerable<string> Roles { get; set; }
14+
}
15+
}

0 commit comments

Comments
 (0)