ShareController.cs 7.05 KB
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using CWA.CpoOnline.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using CWA.CpoOnline.Extensions;
using CWA.CpoOnline.Helpers;
using Omu.ValueInjecter;

namespace CWA.CpoOnline.Controllers
{
	
	[Authorize(Roles = CpoRoles.Admin)]
	public class UsersController : Controller
    {

		private ApplicationDbContext _appDbContext;
		private ApplicationUserManager _userManager;

		public ApplicationDbContext AppDbContext
		{
			get
			{
				return _appDbContext ?? HttpContext.GetOwinContext().Get<ApplicationDbContext>();
			}
			private set
			{
				_appDbContext = value;
			}
		}

		public ApplicationUserManager UserManager
		{
			get
			{
				return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
			}
			private set
			{
				_userManager = value;
			}
		}

		public UsersController()
		{ }

		public UsersController(ApplicationUserManager userManager, ApplicationDbContext appDbContext)
		{
			_userManager = userManager;
			_appDbContext = appDbContext;
		}

		// GET: Users
		public ActionResult Index()
		{
			var allAppUsers = AppDbContext.Users.ToList();
			var model = new List<CpoUserViewModel>();
			foreach (var appUser in allAppUsers)
			{
				var muser = new CpoUserViewModel();
				muser.InjectFrom(appUser);
				muser.IsAdministrator = appUser.IsInRole(CpoRoles.Admin);
				model.Add(muser);
			}
           return View(model);
        }

	    public async Task<ActionResult> Access(string id)
	    {
			// Validate user id
		    var appUser = await UserManager.FindByIdAsync(id);
		    if (null == appUser) return RedirectToAction("index");

			// Load user and set up view's model
			var model = new UserAccessViewModel { UserId = id };
			var cpoUser = new CpoUserViewModel();
		    cpoUser.InjectFrom(appUser);
			model.User = cpoUser;

			// Load all available sectors and symbols
			ViewBag.AllSectors = HardCode.AllSectors;
			ViewBag.AllSymbols = HardCode.AllSectors.SelectMany(sector => sector.Symbols).ToList();

			// Load user's current access claims
			var allClaims = await UserManager.GetClaimsAsync(id);

			// Sector claims
		    foreach (var sectorClaim in allClaims.Where(c => c.Type.Equals(CpoClaimTypes.Sector, StringComparison.InvariantCultureIgnoreCase)))
		    {
			    model.SectorIdList.Add(sectorClaim.Value);
		    }

			// Symbol claims
			foreach (var symbolClaim in allClaims.Where(c => c.Type.Equals(CpoClaimTypes.Symbol, StringComparison.InvariantCultureIgnoreCase)))
			{
				model.SymbolIdList.Add(symbolClaim.Value);
			}

			return View(model);
	    }

	    [HttpPost]
	    [ValidateAntiForgeryToken]
	    public async Task<ActionResult> Access(UserAccessViewModel model)
	    {
			if (ModelState.IsValid)
		    {
				// Remove existing sectors and symbols from user access
				var allClaims = await UserManager.GetClaimsAsync(model.UserId);

				// Get claims for sectors and symbols
			    var sectorsAndSymbols = new[] {CpoClaimTypes.Sector, CpoClaimTypes.Symbol};
			    var filteredCliams = allClaims.Where(c => sectorsAndSymbols.Contains(c.Type));
				// Remove existing claims for sectors and symbols
				foreach (var claim in filteredCliams)
				{
					await UserManager.RemoveClaimAsync(model.UserId, claim);
				}

				// Add new sector access claims
			    foreach (var sectorId in model.SectorIdList)
			    {
					await UserManager.AddClaimAsync(model.UserId, new Claim(CpoClaimTypes.Sector, sectorId, ClaimValueTypes.String));
				}
				
				// Add new symbol access claims
			    foreach (var symbolId in model.SymbolIdList)
			    {
					await UserManager.AddClaimAsync(model.UserId, new Claim(CpoClaimTypes.Symbol, symbolId, ClaimValueTypes.String));
				}

				return RedirectToAction("index");
			}

			// Error has occurred
			ViewBag.AllSectors = HardCode.AllSectors;
			ViewBag.AllSymbols = HardCode.AllSectors.SelectMany(sector => sector.Symbols).ToList();
			var appUser = await UserManager.FindByIdAsync(model.UserId);
			if (null == appUser) return RedirectToAction("index");
			var cpoUser = new CpoUserViewModel();
			cpoUser.InjectFrom(appUser);
			model.User = cpoUser;
			return View(model);
		}


		//
		// GET: /User/Add
		public ActionResult Add()
		{
			return View();
		}

		//
		// POST: /User/Add
		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<ActionResult> Add(CpoUserViewModelWithPassword model)
		{
			if (ModelState.IsValid)
			{
				var user = new ApplicationUser
				{
					UserName = model.Email,
					Email = model.Email,
					FirstName = model.FirstName,
					LastName = model.LastName,
					Created = DateTime.UtcNow,
					LastLogin = DateTime.UtcNow,
					Modified = DateTime.UtcNow
				};

				var result = UserManager.Create(user, model.Password);
				if (result.Succeeded)
				{
					model.Id = user.Id;
					await AddUserClaims(model);
					return RedirectToAction("index", "users");
				}
				AddErrors(result);
			}

			// If we got this far, something failed, redisplay form
			return View(model);
		}


		public async Task<ActionResult> Edit(string id)
	    {
		    var appUser = await UserManager.FindByIdAsync(id);
		    if (null == appUser) return RedirectToAction("index","users");
		    var model = new CpoUserViewModel();
		    model.InjectFrom(appUser);
		    model.IsAdministrator = appUser.IsInRole(CpoRoles.Admin);
		    return View(model);
	    }

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<ActionResult> Edit(CpoUserViewModel model)
		{
			if (ModelState.IsValid)
			{

				var user = UserManager.FindById(model.Id);
				user.InjectFrom(model);
				user.UserName = user.Email;
				user.Modified = DateTime.UtcNow;

				var result = await UserManager.UpdateAsync(user);
				if (result.Succeeded)
				{
					await RemoveExistingClaims(model.Id);
					await AddUserClaims(model);
					return RedirectToAction("index", "users");
				}
				AddErrors(result);
			}

			// If we got this far, something failed, redisplay form
			return View(model);
		}



		public async Task<ActionResult> DeleteUser(string id)
	    {
		    var user = await UserManager.FindByIdAsync(id);
		    if (null != user)
		    {
				await UserManager.DeleteAsync(user);
			}
		    return RedirectToAction("index");
	    }


		#region Helpers

		private void AddErrors(IdentityResult result)
		{
			foreach (var error in result.Errors)
			{
				ModelState.AddModelError("", error);
			}
		}

		private async Task AddUserClaims(CpoUserViewModel model)
		{
			await UserManager.AddClaimAsync(model.Id, new Claim("FullName", $"{model.FirstName} {model.LastName}", ClaimValueTypes.String));
			if (model.IsAdministrator)
			{
				await UserManager.AddClaimAsync(model.Id, new Claim(ClaimTypes.Role, CpoRoles.Admin));
			}
		}

		private async Task RemoveExistingClaims(string modelId)
		{
			var claims = await UserManager.GetClaimsAsync(modelId);
			foreach (var claim in claims)
			{
				await UserManager.RemoveClaimAsync(modelId, claim);
			}

		}
		#endregion Helpers
	}
}