Add administrator editing
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Mvc;
|
||||
using AutoMapper;
|
||||
using AutoMapper.QueryableExtensions;
|
||||
using InventoryTraker.Web.Attributes;
|
||||
using InventoryTraker.Web.Core;
|
||||
using InventoryTraker.Web.Identity;
|
||||
@@ -11,6 +10,7 @@ using Microsoft.AspNet.Identity;
|
||||
|
||||
namespace InventoryTraker.Web.Controllers
|
||||
{
|
||||
[Authorize(Roles = ApplicationRoleManager.AdminRoleName)]
|
||||
public class UserController : ControllerBase
|
||||
{
|
||||
private readonly ApplicationUserManager _userManager;
|
||||
@@ -30,12 +30,17 @@ namespace InventoryTraker.Web.Controllers
|
||||
public JsonResult All()
|
||||
{
|
||||
var users =
|
||||
_userManager
|
||||
.Users
|
||||
.ProjectTo<UserViewModel>(_mapper.ConfigurationProvider)
|
||||
.OrderBy(u => u.UserName);
|
||||
from u in _userManager.Users.ToList()
|
||||
let ad = _userManager.GetRoles(u.Id).Contains(ApplicationRoleManager.AdminRoleName)
|
||||
orderby u.UserName
|
||||
select new UserViewModel
|
||||
{
|
||||
UserName = u.UserName,
|
||||
Email = u.Email,
|
||||
Administrator = ad
|
||||
};
|
||||
|
||||
return BetterJson(users);
|
||||
return BetterJson(users.ToList());
|
||||
}
|
||||
|
||||
[ActionLog]
|
||||
@@ -57,7 +62,17 @@ namespace InventoryTraker.Web.Controllers
|
||||
if (!identityResult.Succeeded)
|
||||
return GetErrorListJson(identityResult.Errors.ToArray());
|
||||
|
||||
return BetterJson(_mapper.Map<UserViewModel>(user));
|
||||
user = _userManager.FindByEmail(form.Email);
|
||||
if (form.Administrator)
|
||||
{
|
||||
var result = _userManager.AddToRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||
if (!result.Succeeded)
|
||||
return GetErrorListJson(result.Errors.ToArray());
|
||||
}
|
||||
|
||||
var userViewModel = _mapper.Map<UserViewModel>(user);
|
||||
userViewModel.Administrator = _userManager.IsInRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||
return BetterJson(userViewModel);
|
||||
}
|
||||
|
||||
[ActionLog]
|
||||
@@ -79,12 +94,33 @@ namespace InventoryTraker.Web.Controllers
|
||||
return GetErrorListJson(resetResult.Errors.ToArray());
|
||||
}
|
||||
|
||||
var rolesForUser = _userManager.GetRoles(user.Id);
|
||||
|
||||
if (rolesForUser.Contains(ApplicationRoleManager.AdminRoleName) && !form.Administrator)
|
||||
{
|
||||
var currentUser = _userManager.FindById(User.Identity.GetUserId());
|
||||
if (currentUser == user)
|
||||
return GetErrorListJson("Cannot remove admin from yourself");
|
||||
|
||||
var result = _userManager.RemoveFromRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||
if (!result.Succeeded)
|
||||
return GetErrorListJson(result.Errors.ToArray());
|
||||
}
|
||||
else if (!rolesForUser.Contains(ApplicationRoleManager.AdminRoleName) && form.Administrator)
|
||||
{
|
||||
var result = _userManager.AddToRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||
if (!result.Succeeded)
|
||||
return GetErrorListJson(result.Errors.ToArray());
|
||||
}
|
||||
|
||||
var identityResult = _userManager.Update(user);
|
||||
|
||||
if (!identityResult.Succeeded)
|
||||
return GetErrorListJson(identityResult.Errors.ToArray());
|
||||
|
||||
return BetterJson(_mapper.Map<UserViewModel>(user));
|
||||
var userViewModel = _mapper.Map<UserViewModel>(user);
|
||||
userViewModel.Administrator = _userManager.IsInRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||
return BetterJson(userViewModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Optimization;
|
||||
using System.Web.Routing;
|
||||
using InventoryTraker.Web.Migrations;
|
||||
|
||||
namespace InventoryTraker.Web
|
||||
{
|
||||
@@ -14,6 +15,7 @@ namespace InventoryTraker.Web
|
||||
BundleConfig.RegisterBundles(BundleTable.Bundles);
|
||||
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
|
||||
EFConfig.Initialize();
|
||||
SeedData.AddAdminRole();
|
||||
//SeedData.Init();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,41 +75,69 @@ namespace InventoryTraker.Web.Helpers
|
||||
|
||||
var expression = ExpressionForInternal(property);
|
||||
|
||||
//Creates <div class="form-group has-feedback"
|
||||
// form-group-validation="Name">
|
||||
var formGroup = new HtmlTag("div")
|
||||
.AddClasses("form-group", "has-feedback")
|
||||
.Attr("form-group-validation", name);
|
||||
|
||||
var labelText = metadata.DisplayName ?? name.Humanize(LetterCasing.Title);
|
||||
|
||||
//Creates <label class="control-label" for="Name">Name</label>
|
||||
var label = new HtmlTag("label")
|
||||
.AddClass("control-label")
|
||||
.Attr("for", name)
|
||||
.Text(labelText);
|
||||
|
||||
var tagName = metadata.DataTypeName == "MultilineText"
|
||||
var tagName =
|
||||
metadata.DataTypeName == "MultilineText"
|
||||
? "textarea"
|
||||
: "input";
|
||||
|
||||
var placeholder = metadata.Watermark ??
|
||||
(labelText + "...");
|
||||
//Creates <input ng-model="expression"
|
||||
// class="form-control" name="Name" type="text" >
|
||||
var input = new HtmlTag(tagName)
|
||||
.AddClass("form-control")
|
||||
.Attr("ng-model", expression)
|
||||
.Attr("name", name)
|
||||
.Attr("name", name);
|
||||
|
||||
var formGroup = new HtmlTag("div");
|
||||
|
||||
if (metadata.ModelType != typeof(bool))
|
||||
{
|
||||
label.AddClass("control-label");
|
||||
|
||||
var placeholder = metadata.Watermark ??
|
||||
labelText + "...";
|
||||
|
||||
input
|
||||
.AddClass("form-control")
|
||||
.Attr("type", "text")
|
||||
.Attr("placeholder", placeholder);
|
||||
|
||||
ApplyValidationToInput(input, metadata);
|
||||
|
||||
return formGroup
|
||||
//Creates <div class="form-group has-feedback"
|
||||
// form-group-validation="Name">
|
||||
formGroup
|
||||
.AddClass("form-group")
|
||||
.AddClass("has-feedback")
|
||||
.Attr("form-group-validation", name)
|
||||
.Append(label)
|
||||
.Append(input);
|
||||
}
|
||||
else if (metadata.ModelType == typeof(bool))
|
||||
{
|
||||
label.AddClass("form-check-label");
|
||||
|
||||
input
|
||||
.AddClass("form-check-input")
|
||||
.Attr("type", "checkbox");
|
||||
|
||||
label.Text("")
|
||||
.Append(input)
|
||||
.AppendHtml(" ")
|
||||
.Append(new HtmlTag("text").NoTag().Text(labelText));
|
||||
|
||||
formGroup
|
||||
.AddClass("form-check")
|
||||
.Append(label);
|
||||
}
|
||||
|
||||
return formGroup;
|
||||
}
|
||||
|
||||
private void ApplyValidationToInput(HtmlTag input, ModelMetadata metadata)
|
||||
{
|
||||
|
||||
@@ -2,11 +2,21 @@ using System;
|
||||
using System.Threading.Tasks;
|
||||
using InventoryTraker.Web.Core;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Identity.EntityFramework;
|
||||
using Microsoft.AspNet.Identity.Owin;
|
||||
using Microsoft.Owin.Security.DataProtection;
|
||||
|
||||
namespace InventoryTraker.Web.Identity
|
||||
{
|
||||
public class ApplicationRoleManager : RoleManager<IdentityRole>
|
||||
{
|
||||
public const string AdminRoleName = "Admin";
|
||||
|
||||
public ApplicationRoleManager(IRoleStore<IdentityRole, string> store) : base(store)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class ApplicationUserManager : UserManager<User>
|
||||
{
|
||||
public ApplicationUserManager(IUserStore<User> store, IDataProtectionProvider dataProtectionProvider)
|
||||
|
||||
@@ -14,6 +14,34 @@ namespace InventoryTraker.Web.Migrations
|
||||
{
|
||||
public static class SeedData
|
||||
{
|
||||
|
||||
public static void AddAdminRole()
|
||||
{
|
||||
using (var context = new AppDbContext())
|
||||
AddAdminRole(context);
|
||||
}
|
||||
|
||||
private static void AddAdminRole(AppDbContext context)
|
||||
{
|
||||
var manager = new ApplicationRoleManager(new RoleStore<IdentityRole>(context));
|
||||
if (!manager.RoleExists(ApplicationRoleManager.AdminRoleName))
|
||||
{
|
||||
var result = manager.Create(new IdentityRole(ApplicationRoleManager.AdminRoleName));
|
||||
}
|
||||
|
||||
// if no users are admins, make them all!
|
||||
var adminRole = manager.Roles.First(r => r.Name == ApplicationRoleManager.AdminRoleName);
|
||||
var userManager = new ApplicationUserManager(new UserStore<User>(context), null);
|
||||
var admins = userManager.Users.Where(u => u.Roles.Any(r => r.RoleId == adminRole.Id));
|
||||
if (!admins.Any())
|
||||
{
|
||||
foreach (var user in userManager.Users.ToList())
|
||||
{
|
||||
userManager.AddToRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
using (var context = new AppDbContext())
|
||||
|
||||
@@ -14,6 +14,9 @@ namespace InventoryTraker.Web.Models
|
||||
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
|
||||
public string Email { get; set; }
|
||||
|
||||
//[Required]
|
||||
public bool Administrator { get; set; }
|
||||
|
||||
[DataType(DataType.Password)]
|
||||
public string Password { get; set; }
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ namespace InventoryTraker.Web.Models
|
||||
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
|
||||
public string Email { get; set; }
|
||||
|
||||
public bool Administrator { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"UserName: {UserName}, email: {Email}";
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>@ViewBag.Title - Inventory Traker</title>
|
||||
@Styles.Render("~/Content/all-styles")
|
||||
@RenderSection("Styles", required: false)
|
||||
@RenderSection("Styles", false)
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
@@ -23,11 +23,19 @@
|
||||
@RenderBody()
|
||||
</div>
|
||||
</div>
|
||||
@if (Request.IsAuthenticated)
|
||||
{
|
||||
<footer class="footer hidden-print">
|
||||
<div class="container">
|
||||
<p>Inventory Traker © 2016 Kolpack Software Consulting LLC</p>
|
||||
</div>
|
||||
</footer>
|
||||
}
|
||||
<!-- /#page-wrapper -->
|
||||
</div>
|
||||
<!-- /#wrapper -->
|
||||
@Scripts.Render("~/js/all-javascript")
|
||||
@RenderSection("Scripts", required: false)
|
||||
@RenderSection("Scripts", false)
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
@using InventoryTraker.Web.Identity
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
|
||||
@@ -7,13 +8,16 @@
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="~/">Inventory Traker</a>
|
||||
<a class="navbar-brand" href="~/"><i class="fa fa-fw fa-cubes"></i> Inventory Traker</a>
|
||||
</div>
|
||||
<!-- Top Menu Items -->
|
||||
<ul class="nav navbar-right top-nav">
|
||||
@if (User.IsInRole(ApplicationRoleManager.AdminRoleName))
|
||||
{
|
||||
<li>
|
||||
<a href="@(Html.BuildUrlFromExpression<UserController>(c => c.Index()))"><i class="fa fa-fw fa-users"></i> Users</a>
|
||||
</li>
|
||||
}
|
||||
<li class="dropdown">
|
||||
<a href="" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-user"></i> @User.Identity.Name <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="~/">Inventory Traker</a>
|
||||
<a class="navbar-brand" href="~/"><i class="fa fa-fw fa-cubes"></i> Inventory Traker</a>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -10,9 +10,31 @@ body {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
color: #aaa;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
/* Set the fixed height of the footer here */
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
#page-wrapper {
|
||||
padding-top: 50px;
|
||||
min-height: 100%;
|
||||
padding-bottom: 60px;
|
||||
margin-bottom: -60px;
|
||||
}
|
||||
|
||||
.navbar-brand i {
|
||||
color:palegreen
|
||||
}
|
||||
|
||||
.navbar-brand:link,
|
||||
.navbar-brand:visited,
|
||||
.navbar-brand:hover,
|
||||
.navbar-brand:active {
|
||||
font-weight: bolder;
|
||||
color: #92B9BD;
|
||||
}
|
||||
|
||||
.navbar.navbar-fixed-top {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<th class="control-column"></th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Administrator</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -11,6 +12,10 @@
|
||||
<td><a href="" ng-click="vm.edit(user)"><i class="fa fa-edit"></i></a></td>
|
||||
<td>{{user.userName}}</td>
|
||||
<td>{{user.email}}</td>
|
||||
<td>
|
||||
<i class="fa fa-check-square-o" ng-show="user.administrator"></i>
|
||||
<i class="fa fa-square-o" ng-show="!user.administrator"></i>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
|
||||
function edit(existingUser, editedUser) {
|
||||
return $http.post("/User/Edit", editedUser)
|
||||
.success(function(user) {
|
||||
angular.copy(user, existingUser);
|
||||
.success(function(data) {
|
||||
angular.copy(data, existingUser);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user