322 lines
14 KiB
C#
322 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Web;
|
|
using EnVisage.Code.Cache;
|
|
using EnVisage.Models.Cache;
|
|
using EnVisage.Code.BLL;
|
|
using System.Web.Mvc;
|
|
using Prevu.Core.Main;
|
|
|
|
namespace EnVisage.Code
|
|
{
|
|
/// <summary>
|
|
/// Manager for check security operations
|
|
/// </summary>
|
|
/// <remarks>Created by SA</remarks>
|
|
public class SecurityManager
|
|
{
|
|
public class DefaultPageWithArea
|
|
{
|
|
public string Action;
|
|
public string Controller;
|
|
public Areas Area;
|
|
public object Parameters;
|
|
|
|
public DefaultPageWithArea(string action, string controller)
|
|
{
|
|
this.Action = action;
|
|
this.Controller = controller;
|
|
}
|
|
|
|
public DefaultPageWithArea(string action, string controller, Areas area)
|
|
{
|
|
this.Action = action;
|
|
this.Controller = controller;
|
|
this.Area = area;
|
|
}
|
|
|
|
public DefaultPageWithArea(string action, string controller, Areas area, object parameters)
|
|
{
|
|
this.Action = action;
|
|
this.Controller = controller;
|
|
this.Area = area;
|
|
this.Parameters = parameters;
|
|
}
|
|
}
|
|
public static void tryLogin()
|
|
{
|
|
Controllers.AccountController a = new Controllers.AccountController(DependencyResolver.Current.GetService<ApplicationUserManager>(), DependencyResolver.Current.GetService<IUserManager>());
|
|
a.SSOLoginConfirmation();
|
|
}
|
|
/// <summary>
|
|
/// Returns current user Principal Id (GUID)
|
|
/// </summary>
|
|
public static Guid GetUserPrincipal()
|
|
{
|
|
string userIdAsText = HttpContext.Current.User.Identity.GetID();
|
|
Guid userId = new Guid(userIdAsText);
|
|
return userId;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if passed Area is allowed to be accessed by passed Principal with desired Type of access
|
|
/// </summary>
|
|
public static bool CheckSecurityObjectPermission(Areas area, AccessLevel type)
|
|
{
|
|
try
|
|
{
|
|
List<Areas> areas = new List<Areas> {area};
|
|
return CheckAnySecurityObjectPermission(areas, type);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if any of passed Areas is allowed to be accessed by passed Principal with desired Type of access
|
|
/// </summary>
|
|
public static bool CheckAnySecurityObjectPermission(List<Areas> areas, AccessLevel type)
|
|
{
|
|
var principalId = HttpContext.Current.User.Identity.GetID();
|
|
return CheckAnySecurityObjectPermissionForUser(areas, type, principalId);
|
|
}
|
|
|
|
private static bool CheckAnySecurityObjectPermissionForUser(List<Areas> areas, AccessLevel type, string userId)
|
|
{
|
|
List<string> stringAreas = new List<string>();
|
|
if (areas != null && areas.Count > 0)
|
|
areas.ForEach(a => stringAreas.Add(a.ToString()));
|
|
|
|
if (userId == null || userId == Guid.Empty.ToString()) return false;
|
|
SecurityAreasCache securityAreaCache = new SecurityAreasCache();
|
|
|
|
List<UserAreaAccess> s = new List<UserAreaAccess>();
|
|
foreach (var area in stringAreas)
|
|
s.AddRange(securityAreaCache.Value.Where(x => x.PrincipalId == new Guid(userId) && x.SecurityObject == area));
|
|
|
|
if (s.Any())
|
|
{
|
|
if (type == AccessLevel.Write)
|
|
{
|
|
return s.Any(x => x.Write == 1);
|
|
}
|
|
if (type == AccessLevel.Read)
|
|
{
|
|
return s.Any(x => (x.Read == 1 || x.Write == 1));
|
|
}
|
|
}
|
|
|
|
//var roles = user.AspNetRoles.Select(x => new Guid(x.Id));
|
|
var roles = new UsersCache().Value.FirstOrDefault(x => x.Id == new Guid(userId)).Roles;
|
|
s = new List<UserAreaAccess>();
|
|
foreach (var role in roles)
|
|
{
|
|
foreach (var area in stringAreas)
|
|
s.AddRange(securityAreaCache.Value.Where(x => x.PrincipalId == role && x.SecurityObject == area));
|
|
}
|
|
|
|
if (s.Any())
|
|
{
|
|
if (type == AccessLevel.Write)
|
|
return s.Any(x => x.Write == 1);
|
|
if (type == AccessLevel.Read)
|
|
return s.Any(x => (x.Read == 1 || x.Write == 1));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static bool CheckProjectPermission(Guid ProjectId, AccessLevel Type)
|
|
{
|
|
var PrincipalId = HttpContext.Current.User.Identity.GetID();
|
|
if (PrincipalId == null || ProjectId == null || PrincipalId == Guid.Empty.ToString()) return false;
|
|
|
|
var userId = new Guid(PrincipalId);
|
|
EnVisageEntities dbContext = new EnVisageEntities();
|
|
var accessGranted=CheckProjectPermission(userId, ProjectId, Type, dbContext);
|
|
//EnVisageEntities dbContext = new EnVisageEntities();
|
|
|
|
//bool accessGranted = dbContext.VW_ProjectAccessByUserExtended.Where(x =>
|
|
// x.UserId.Equals(userId) &&
|
|
// x.Id.Equals(ProjectId) &&
|
|
// (((Type == AccessLevel.Read) && ((x.Read.HasValue && (x.Read.Value == 1)) || (x.Write.HasValue && (x.Write.Value == 1)))) ||
|
|
// ((Type == AccessLevel.Write) && x.Write.HasValue && (x.Write == 1)))).Any();
|
|
|
|
//if (!accessGranted)
|
|
//{
|
|
// ProjectManager prMngr = new ProjectManager(dbContext);
|
|
// var projectsByAllocations = prMngr.GetAssignedProjectsByUserId(new Guid(PrincipalId));
|
|
// accessGranted = (projectsByAllocations != null) && (projectsByAllocations.Contains(ProjectId));
|
|
//}
|
|
|
|
return accessGranted;
|
|
}
|
|
public static bool CheckProjectPermission(Guid userId, Guid ProjectId, AccessLevel Type, EnVisageEntities dbContext)
|
|
{
|
|
|
|
|
|
|
|
bool accessGranted = dbContext.VW_ProjectAccessByUserExtended.Where(x =>
|
|
x.UserId.Equals(userId) &&
|
|
x.Id.Equals(ProjectId) &&
|
|
(((Type == AccessLevel.Read) && ((x.Read.HasValue && (x.Read.Value == 1)) || (x.Write.HasValue && (x.Write.Value == 1)))) ||
|
|
((Type == AccessLevel.Write) && x.Write.HasValue && (x.Write == 1)))).Any();
|
|
|
|
if (!accessGranted)
|
|
{
|
|
ProjectManager prMngr = new ProjectManager(dbContext);
|
|
var projectsByAllocations = prMngr.GetAssignedProjectsByUserId(userId);
|
|
accessGranted = (projectsByAllocations != null) && (projectsByAllocations.Contains(ProjectId));
|
|
}
|
|
|
|
return accessGranted;
|
|
}
|
|
public static bool CheckScenarioPermission(Guid ScenarioId, AccessLevel Type)
|
|
{
|
|
// Get parent project (part) id for this scenario
|
|
EnVisageEntities dbContext = new EnVisageEntities();
|
|
var scenMngr = new ScenarioManager(dbContext);
|
|
Scenario scenario = scenMngr.GetScenario(ScenarioId);
|
|
|
|
if ((scenario != null) && scenario.ParentId.HasValue)
|
|
{
|
|
Guid projectId = scenario.ParentId.Value;
|
|
return CheckProjectPermission(projectId, Type);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
/// <summary>
|
|
/// Gets a dictionary of teams which user has access to. Key=<see cref="Team.Id"/>, Value=<see cref="AccessLevel"/>.
|
|
/// Method returns data from database view VW_User2Team. If it returns more than one record for tuple [UserId, TeamId] (should not)
|
|
/// then method returns Max of provided values.
|
|
/// </summary>
|
|
/// <param name="dbContext">Database context.</param>
|
|
/// <param name="userId">User.Id</param>
|
|
/// <param name="teamsFilter">A list of Team.Id values to filter by.</param>
|
|
/// <returns><see cref="Dictionary{Guid, AccessLevel}"/></returns>
|
|
public static Dictionary<Guid, AccessLevel> GetTeamPermissionsForUser(EnVisageEntities dbContext, string userId, List<Guid> teamsFilter)
|
|
{
|
|
var teamManager = new TeamManager(dbContext);
|
|
var teams = teamManager.GetTeamsByUserFiltered(userId, teamsFilter, null, null);
|
|
return teams.GroupBy(t => t.TeamId).ToDictionary(gr => gr.Key, el => el.Max(t => t.AccessLevel));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns first available Default Page for user depending on his security settings. Returnable Item format: Action, Controller
|
|
/// </summary>
|
|
public static DefaultPageWithArea RedirectToDefaultPage(string userId)
|
|
{
|
|
if (SecurityManager.IsResourceOnlyAccess(userId))
|
|
{
|
|
var mngr = new Code.BLL.AccountManager(new EnVisageEntities());
|
|
var resourceId = mngr.GetCurrentResourceId(userId);
|
|
if (resourceId.HasValue)
|
|
{
|
|
return new DefaultPageWithArea("Details", "PeopleResource", Areas.PeopleResourceDetails, new { resourceId = resourceId.Value.ToString() });
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (DefaultPageWithArea page in GetDefaultPages())
|
|
{
|
|
if (CheckAnySecurityObjectPermissionForUser(new List<Areas>() { page.Area }, AccessLevel.Read, userId))
|
|
{
|
|
return new DefaultPageWithArea(page.Action, page.Controller);
|
|
}
|
|
}
|
|
}
|
|
return new DefaultPageWithArea("AccessDenied", "Home");// this should always end with some landing page accessible by all users to prevent possible infinite cycles in client code
|
|
}
|
|
/// <summary>
|
|
/// Indicates that current user has access only to Resource Details page.
|
|
/// This way system should redirect him to the related page and deny access to all other areas.
|
|
/// </summary>
|
|
/// <returns><b>True</b> - if user has access only to resource details, otherwise - <b>false</b>.</returns>
|
|
public static bool IsResourceOnlyAccess(string userId)
|
|
{
|
|
var resourceDetailsGroupPermissions = new string[] { Areas.PeopleResourceDetails.ToString(), Areas.RD_ResourceInformation.ToString(),
|
|
Areas.RD_ResourceNonProjectTime.ToString(), Areas.RD_ResourceNPTAllocationCategory.ToString(), Areas.RD_ResourceSkills.ToString(),
|
|
Areas.RD_ResourceTimeAllocation.ToString(), Areas.RD_ResourceTimeAllocationActual.ToString(), Areas.RD_ResourceTimeAllocationProjected.ToString()
|
|
};
|
|
SecurityAreasCache securityAreaCache = new SecurityAreasCache();
|
|
var roles = new UsersCache().Value.FirstOrDefault(x => x.Id == new Guid(userId)).Roles;
|
|
// get all areas user has access to
|
|
var userAccessAreas = securityAreaCache.Value.Where(t => t.PrincipalId == new Guid(userId));
|
|
var roleAccessAreas = securityAreaCache.Value.Where(t => roles.Contains(t.PrincipalId));
|
|
var permissions = new Dictionary<string, AccessLevel>();
|
|
foreach (var item in roleAccessAreas)
|
|
{
|
|
if (!permissions.ContainsKey(item.SecurityObject))
|
|
{
|
|
if (item.Write == 1)
|
|
permissions.Add(item.SecurityObject, AccessLevel.Write);
|
|
else if (item.Read == 1)
|
|
permissions.Add(item.SecurityObject, AccessLevel.Read);
|
|
} else
|
|
{
|
|
if (item.Write == 1)
|
|
permissions[item.SecurityObject] = AccessLevel.Write;
|
|
else if (item.Read == 1)
|
|
permissions[item.SecurityObject] = AccessLevel.Read;
|
|
}
|
|
}
|
|
foreach (var item in userAccessAreas)
|
|
{
|
|
if (!permissions.ContainsKey(item.SecurityObject))
|
|
{
|
|
if (item.Write == 1)
|
|
permissions.Add(item.SecurityObject, AccessLevel.Write);
|
|
else if (item.Read == 1)
|
|
permissions.Add(item.SecurityObject, AccessLevel.Read);
|
|
}
|
|
else
|
|
{
|
|
if (item.Write == 1)
|
|
permissions[item.SecurityObject] = AccessLevel.Write;
|
|
else if (item.Read == 1)
|
|
permissions[item.SecurityObject] = AccessLevel.Read;
|
|
else if (item.Read == 0 && item.Write == 0)
|
|
permissions.Remove(item.SecurityObject);
|
|
}
|
|
}
|
|
// get user permissions other than resource details
|
|
var additionalAreas = permissions.Keys.Except(resourceDetailsGroupPermissions);
|
|
return !additionalAreas.Any();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if specific default page is accessible by current user
|
|
/// </summary>
|
|
/// <param name="userId">An ID of the current User</param>
|
|
/// <param name="action">Name of the action method of the default page</param>
|
|
/// <param name="controller">Name of the controller of the default page</param>
|
|
public static bool IsDefaultPageAvailable(string userId, string action, string controller)
|
|
{
|
|
List<DefaultPageWithArea> allPages = GetDefaultPages();
|
|
if (!allPages.Exists(p => p.Action.Equals(action, StringComparison.InvariantCultureIgnoreCase) && p.Controller.Equals(controller, StringComparison.InvariantCultureIgnoreCase)))
|
|
throw new ArgumentException(string.Format("There is no default page registered for given action ({0}) and controller ({1}) - check the GetDefaultPages method", action, controller));
|
|
|
|
DefaultPageWithArea page = allPages.First(p => p.Action.Equals(action, StringComparison.InvariantCultureIgnoreCase) && p.Controller.Equals(controller, StringComparison.InvariantCultureIgnoreCase));
|
|
return CheckAnySecurityObjectPermissionForUser(new List<Areas>() { page.Area }, AccessLevel.Read, userId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a list of all system default landing pages users should go to upon login depending on their permissions. Item format: Action, Controller, required Security Area permission (can be null - means everyone has access)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private static List<DefaultPageWithArea> GetDefaultPages()
|
|
{
|
|
List<DefaultPageWithArea> pages = new List<DefaultPageWithArea>();
|
|
pages.Add(new DefaultPageWithArea("Index", "Home", Areas.Dashboard));
|
|
pages.Add(new DefaultPageWithArea("Index", "Project", Areas.Projects));
|
|
pages.Add(new DefaultPageWithArea("ImportActuals", "Project", Areas.ImportActuals));
|
|
pages.Add(new DefaultPageWithArea("Details", "PeopleResource", Areas.PeopleResourceDetails));
|
|
return pages;
|
|
}
|
|
}
|
|
} |