EnVisageOnline/Beta/Source/EnVisage/Controllers/RoleController.cs

517 lines
19 KiB
C#

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using EnVisage;
using EnVisage.Code;
using EnVisage.Code.BLL;
using EnVisage.Models;
using jQuery.DataTables.Mvc;
using System.Collections.ObjectModel;
using EnVisage.App_Start;
using EnVisage.Code.HtmlHelpers;
using Microsoft.AspNet.Identity;
using EnVisage.Code.Cache;
namespace EnVisage.Controllers
{
[Authorize]
public class RoleController : BaseController
{
// GET: /Role/
[HttpGet]
[AreaSecurityAttribute(area = Areas.Roles, level = AccessLevel.Read)]
public ActionResult Index()
{
if (!HtmlHelpers.CheckSecurityObjectPermission(null, Areas.Roles, AccessLevel.Read))
return Redirect("/");
return View(DbContext.AspNetRoles.ToList());
}
/// <summary>
/// Returns JSON user list with filters and sort for jQuery DataTables
/// </summary>
[HttpPost]
[AreaSecurityAttribute(area = Areas.Roles, level = AccessLevel.Read)]
public JsonResult Index(JQueryDataTablesModel jQueryDataTablesModel)
{
int totalRecordCount;
int searchRecordCount;
var users = GetRoles(startIndex: jQueryDataTablesModel.iDisplayStart,
pageSize: jQueryDataTablesModel.iDisplayLength, sortedColumns: jQueryDataTablesModel.GetSortedColumns(),
totalRecordCount: out totalRecordCount, searchRecordCount: out searchRecordCount, searchString: jQueryDataTablesModel.sSearch);
return this.DataTablesJson(items: users,
totalRecords: totalRecordCount,
totalDisplayRecords: searchRecordCount,
sEcho: jQueryDataTablesModel.sEcho);
}
private IEnumerable<RoleModel> GetRoles(int startIndex,
int pageSize,
IEnumerable<SortedColumn> sortedColumns,
out int totalRecordCount,
out int searchRecordCount,
string searchString)
{
var query = from c in DbContext.AspNetRoles select new {
Id = c.Id,
Name = c.Name,
UsersCount = c.AspNetUsers.Count};
//filter
if (!string.IsNullOrWhiteSpace(searchString))
{
query = query.Where(c => c.Name.ToLower().Contains(searchString.ToLower()));
}
//sort
foreach (var sortedColumn in sortedColumns)
{
switch (sortedColumn.PropertyName)
{
case "Id":
if (sortedColumn.Direction == SortingDirection.Ascending)
query = query.OrderBy(c => c.Id);
else
query = query.OrderByDescending(c => c.Id);
break;
case "AspNetUsersCount":
if (sortedColumn.Direction == SortingDirection.Ascending)
query = query.OrderBy(c => c.UsersCount);
else
query = query.OrderByDescending(c => c.UsersCount);
break;
default:
if (sortedColumn.Direction == SortingDirection.Ascending)
query = query.OrderBy(c => c.Name);
else
query = query.OrderByDescending(c => c.Name);
break;
}
}
totalRecordCount = DbContext.AspNetRoles.Count();
try
{
searchRecordCount = query.Count();
}
catch (Exception ex)
{
LogException(ex);
throw;
}
searchRecordCount = query.Count();
return
query.Skip(startIndex)
.Take(pageSize)
.ToList()
.Select(t => new RoleModel { Id = new Guid(t.Id), Name = t.Name, AspNetUsersCount = t.UsersCount});
}
[HttpGet]
[AreaSecurityAttribute(area = Areas.Roles, level = AccessLevel.Write)]
public ActionResult Create()
{
var model = new RoleModel();
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
[AreaSecurityAttribute(area = Areas.Roles, level = AccessLevel.Write)]
public ActionResult Create(RoleModel model)
{
if (ContentLocker.IsLock("Role", model.Id.ToString(), User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
model.TrimStringProperties();
if (ModelState.IsValid)
{
try
{
var manager = new RoleManager(DbContext);
manager.Save(model);
DbContext.SaveChanges();
ContentLocker.RemoveLock("Role", model.Id.ToString(), User.Identity.Name);
return RedirectToAction("Index");
}
catch (BLLException blEx) // handle any system specific error
{
// display error message if required
if (blEx.DisplayError)
ModelState.AddModelError(string.Empty, blEx.Message);
else // if display not requried then display modal form with general error message
{
LogException(blEx);
SetErrorScript();
}
}
catch (Exception exception) // handle any unexpected error
{
LogException(exception);
SetErrorScript();
}
}
// return empty model with validation messages (if any)
return View(model);
}
// GET: /Role/Edit/5
[HttpGet]
[AreaSecurityAttribute(area = Areas.Roles, level = AccessLevel.Write)]
public ActionResult Edit(Guid? id)
{
var model = new RoleModel();
if (id.HasValue)
{
try
{
var manager = new RoleManager(DbContext);
model = (RoleModel)manager.Load(id) ?? new RoleModel();
}
catch (BLLException blEx)
{
if (blEx.DisplayError)
SetErrorScript(message: blEx.Message);
else
{
LogException(blEx);
SetErrorScript();
}
}
catch (Exception exception)
{
LogException(exception);
SetErrorScript();
}
}
return View(model);
}
// POST: /Role/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
[AreaSecurityAttribute(area = Areas.Roles, level = AccessLevel.Write)]
public ActionResult Edit(RoleModel model, string[] projectlistread, string[] projectlistwrite, string[] areasread, string[] areaswrite)
{
model.TrimStringProperties();
var isNewRole = Guid.Empty.Equals(model.Id);
if (projectlistread == null) projectlistread = new string[] { "0" };
if (projectlistwrite == null) projectlistwrite = new string[] { "0" };
if (!isNewRole && ContentLocker.IsLock("Role", model.Id.ToString(), User.Identity.Name))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (ModelState.IsValid)
{
var context = new EnVisageEntities();
if (isNewRole)
{
try
{
var manager = new RoleManager(context);
manager.Save(model);
context.SaveChanges();
}
catch (BLLException blEx) // handle any system specific error
{
// display error message if required
if (blEx.DisplayError)
ModelState.AddModelError(string.Empty, blEx.Message);
else // if display not requried then display modal form with general error message
{
LogException(blEx);
SetErrorScript();
}
}
catch (Exception exception) // handle any unexpected error
{
LogException(exception);
SetErrorScript();
}
}
#region Save Projects
var projects = (from pr in context.Projects
orderby pr.Name
select pr).ToList();
//if (projectlist != null)
foreach (var project in projects)
{
if (projectlistread.Contains(project.Id.ToString()) || projectlistwrite.Contains(project.Id.ToString()))
{
var pa = (from pr in context.ProjectAccesses
where pr.PrincipalId == model.Id && pr.ProjectId == project.Id
select pr).FirstOrDefault();
if (pa == null)
{
var newpa = new ProjectAccess
{
PrincipalId = model.Id,
ProjectId = project.Id,
Read = (int)(projectlistread.Contains(project.Id.ToString()) ? Permission.Allow : Permission.Deny),
Write = (int)(projectlistwrite.Contains(project.Id.ToString()) ? Permission.Allow : Permission.Deny)
};
context.ProjectAccesses.Add(newpa);
context.SaveChanges();
}
else
{
pa.Read = (int)(projectlistread.Contains(project.Id.ToString()) ? Permission.Allow : Permission.Deny);
pa.Write = (int)(projectlistwrite.Contains(project.Id.ToString()) ? Permission.Allow : Permission.Deny);
context.SaveChanges();
}
}
else
{
var pa = (from pr in context.ProjectAccesses
where pr.PrincipalId == model.Id && pr.ProjectId == project.Id
select pr).FirstOrDefault();
if (pa != null)
{
context.ProjectAccesses.Remove(pa);
context.SaveChanges();
}
}
}
new ProjectAccessCache().Invalidate();
#endregion
#region Save Areas
SecurityAreasCache securityAreasCache = new SecurityAreasCache();
var areas = Enum.GetValues(typeof(Areas)).Cast<Areas>();
foreach (var area in areas)
{
if ((areasread != null && areasread.Contains(area.ToString())) || (areaswrite != null && areaswrite.Contains(area.ToString())))
{
var pa = (from pr in context.Securities
where pr.PrincipalId == model.Id && pr.SecurityObject == area.ToString()
select pr).FirstOrDefault();
if (pa == null)
{
var newpa = new Security();
newpa.PrincipalId = model.Id;
newpa.SecurityObject = area.ToString();
newpa.Read = (int)(areasread.Contains(area.ToString()) ? Permission.Allow : Permission.Deny); ;
newpa.Write = (int)(areaswrite.Contains(area.ToString()) ? Permission.Allow : Permission.Deny);
context.Securities.Add(newpa);
context.SaveChanges();
}
else
{
pa.Read = (int)(areasread != null && areasread.Contains(area.ToString()) ? Permission.Allow : Permission.Deny);
pa.Write = (int)(areaswrite != null && areaswrite.Contains(area.ToString()) ? Permission.Allow : Permission.Deny);
context.SaveChanges();
}
}
else
{
var pa = (from pr in context.Securities
where pr.PrincipalId == model.Id && pr.SecurityObject == area.ToString()
select pr).FirstOrDefault();
if (pa != null)
{
context.Securities.Remove(pa);
context.SaveChanges();
}
}
}
securityAreasCache.Invalidate();
#endregion
if (!isNewRole)
{
var aspnetrole = DbContext.AspNetRoles.Find(model.Id.ToString());
if (aspnetrole == null)
return HttpNotFound();
model.CopyTo(aspnetrole);
DbContext.Entry(aspnetrole).State = System.Data.Entity.EntityState.Modified;
DbContext.SaveChanges();
ContentLocker.RemoveLock("Role", model.Id.ToString(), User.Identity.Name);
}
}
return RedirectToAction("Index");
}
// GET: /Role/Delete/5
[HttpGet]
[AreaSecurityAttribute(area = Areas.Roles, level = AccessLevel.Write)]
public ActionResult Delete(Guid? id)
{
if (id == null || id == Guid.Empty)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var model = new RoleModel();
try
{
var manager = new RoleManager(DbContext);
model = (RoleModel)manager.Load(id);
if (model == null)
return HttpNotFound();
if (model.AspNetUsersCount > 0)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest,
"Role has Users assigned and could not be deleted");
}
catch (BLLException blEx)
{
if (blEx.DisplayError)
SetErrorScript(message: blEx.Message);
else
{
LogException(blEx);
SetErrorScript();
}
}
catch (Exception exception)
{
LogException(exception);
SetErrorScript();
}
return View(model);
}
// POST: /Role/Delete/5
[HttpPost]
[ValidateAntiForgeryToken]
[AreaSecurityAttribute(area = Areas.Roles, level = AccessLevel.Write)]
public ActionResult Delete(RoleModel model)
{
try
{
if (ContentLocker.IsLock("Role", model.Id.ToString(), User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var dbObj = DbContext.AspNetRoles.Find(model.Id.ToString());
if (dbObj == null)
return HttpNotFound();
if (dbObj.AspNetUsers.Count > 0)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest,
"Role has Users assigned and could not be deleted");
DbContext.AspNetRoles.Remove(dbObj);
DbContext.SaveChanges();
ContentLocker.RemoveLock("Role", dbObj.Id, User.Identity.Name);
return RedirectToAction("Index");
}
catch (BLLException blEx) // handle any system specific error
{
// display error message if required
if (blEx.DisplayError)
ModelState.AddModelError(string.Empty, blEx.Message);
else // if display not requried then display modal form with general error message
{
LogException(blEx);
SetErrorScript();
}
}
catch (Exception exception) // handle any unexpected error
{
LogException(exception);
SetErrorScript();
}
return View(model);
}
protected class ListItem
{
public Guid Id { get; set; }
public string Name { get; set; }
}
protected class ProjectListItem : ListItem
{
public int Read { get;set;}
public int Write {get; set;}
}
protected class ClientListItem : ListItem
{
public List<ProjectListItem> Projects {get ;set;}
}
protected class CompanyListItem : ListItem
{
public List<ClientListItem> Clients { get; set; }
}
[HttpPost]
public JsonResult GetProjectAccessTree(Guid? roleId)
{
var result = new List<CompanyListItem>();
var companies = DbContext.Companies.Select(x => new { Id = x.Id, Name = x.Name, Clients = x.Company2Client }).ToList();
var paCache = new ProjectAccessCache();
foreach (var company in companies)
{
var clientsList = new List<ClientListItem>();
//foreach (var client in DbContext.Projects.Where(x => x.CompanyId == company.Id).Select(x => x.Client).Distinct())
foreach(var client in company.Clients.Select(x => x.Client).Distinct())
{
if (result.Any(x => x.Clients.Any(c => c.Id == client.Id)))
continue;
var projList = new List<ProjectListItem>();
foreach (var project in client.Projects)
{
int read = 0, write = 0;
if (roleId != null)
{
var perm = paCache.Value.FirstOrDefault(x => x.PrincipalId == roleId && x.ProjectId == project.Id);
if (perm != null)
{
read = perm.Read;
write = perm.Write;
}
}
projList.Add(new ProjectListItem
{
Id = project.Id,
Name = project.Name,
Read = read,
Write = write
});
}
clientsList.Add(new ClientListItem
{
Id = client.Id,
Name = client.Name,
Projects = projList
});
}
result.Add(new CompanyListItem
{
Id = company.Id,
Name = company.Name,
Clients = clientsList
});
}
return Json(result);
}
}
}