#region License Information /* HeuristicLab * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Security; using HeuristicLab.Services.Access; using HeuristicLab.Services.Hive.DataAccess; using HeuristicLab.Services.Hive.DataAccess.Interfaces; using DA = HeuristicLab.Services.Hive.DataAccess; using DT = HeuristicLab.Services.Hive.DataTransfer; using System.Collections.Generic; using System.Linq; namespace HeuristicLab.Services.Hive { public class AuthorizationManager : IAuthorizationManager { private const string NOT_AUTHORIZED_USERRESOURCE = "Current user is not authorized to access the requested resource"; private const string NOT_AUTHORIZED_USERPROJECT = "Current user is not authorized to access the requested project"; private const string NOT_AUTHORIZED_PROJECTRESOURCE = "Selected project is not authorized to access the requested resource"; private IPersistenceManager PersistenceManager { get { return ServiceLocator.Instance.PersistenceManager; } } private IUserManager UserManager { get { return ServiceLocator.Instance.UserManager; } } private IRoleVerifier RoleVerifier { get { return ServiceLocator.Instance.RoleVerifier; } } public void Authorize(Guid userId) { if (userId != ServiceLocator.Instance.UserManager.CurrentUserId) throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE); } public void AuthorizeForTask(Guid taskId, DT.Permission requiredPermission) { if (ServiceLocator.Instance.RoleVerifier.IsInRole(HiveRoles.Slave)) return; // slave-users can access all tasks var pm = PersistenceManager; var taskDao = pm.TaskDao; pm.UseTransaction(() => { var task = taskDao.GetById(taskId); if (task == null) throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE); AuthorizeJob(pm, task.JobId, requiredPermission); }); } public void AuthorizeForJob(Guid jobId, DT.Permission requiredPermission) { var pm = PersistenceManager; pm.UseTransaction(() => { AuthorizeJob(pm, jobId, requiredPermission); }); } public void AuthorizeForResourceAdministration(Guid resourceId) { var pm = PersistenceManager; var resourceDao = pm.ResourceDao; pm.UseTransaction(() => { var resource = resourceDao.GetById(resourceId); if (resource == null) throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE); if (resource.OwnerUserId != UserManager.CurrentUserId && !RoleVerifier.IsInRole(HiveRoles.Administrator)) { throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE); } }); } public void AuthorizeForProjectAdministration(Guid projectId) { var pm = PersistenceManager; var projectDao = pm.ProjectDao; pm.UseTransaction(() => { var project = projectDao.GetById(projectId); if (project == null) throw new SecurityException(NOT_AUTHORIZED_USERPROJECT); var projectTree = projectDao.GetCurrentAndParentProjectsById(projectId); if(!projectTree.Select(x => x.OwnerUserId).Contains(UserManager.CurrentUserId) && !RoleVerifier.IsInRole(HiveRoles.Administrator)) { throw new SecurityException(NOT_AUTHORIZED_USERPROJECT); } }); } // Check if a project is authorized to use a list of resources public void AuthorizeProjectForResourcesUse(Guid projectId, IEnumerable resourceIds) { var pm = PersistenceManager; var assignedProjectResourceDao = pm.AssignedProjectResourceDao; if (!assignedProjectResourceDao.CheckProjectGrantedForResources(projectId, resourceIds)) throw new SecurityException(NOT_AUTHORIZED_PROJECTRESOURCE); } // Check if current user is authorized to use an explicit project (e.g. in order to add a job) // note: administrators and project owner are NOT automatically granted public void AuthorizeUserForProjectUse(Guid userId, Guid projectId) { var pm = PersistenceManager; // collect current and group membership Ids var userAndGroupIds = new List() { userId }; userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(userId)); // perform the actual check var projectPermissionDao = pm.ProjectPermissionDao; if (!projectPermissionDao.CheckUserGrantedForProject(projectId, userAndGroupIds)) { throw new SecurityException(NOT_AUTHORIZED_USERPROJECT); } } private DA.Permission GetPermissionForJob(IPersistenceManager pm, Guid jobId, Guid userId) { var jobDao = pm.JobDao; var jobPermissionDao = pm.JobPermissionDao; var job = jobDao.GetById(jobId); if (job == null) return DA.Permission.NotAllowed; if (job.OwnerUserId == userId) return DA.Permission.Full; var jobPermission = jobPermissionDao.GetByJobAndUserId(jobId, userId); if (jobPermission == null) return DA.Permission.NotAllowed; return jobPermission.Permission; } private void AuthorizeJob(IPersistenceManager pm, Guid jobId, DT.Permission requiredPermission) { var requiredPermissionEntity = requiredPermission.ToEntity(); DA.Permission permission = GetPermissionForJob(pm, jobId, UserManager.CurrentUserId); if (permission == Permission.NotAllowed || ((permission != requiredPermissionEntity) && requiredPermissionEntity == Permission.Full)) { throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE); } } } }