Changeset 15508


Ignore:
Timestamp:
12/11/17 16:56:19 (5 years ago)
Author:
jzenisek
Message:

#2839 finalized permission checks in AddTask and revised implementation of ResourcePermission methods

Location:
branches/HiveProjectManagement
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectDao.cs

    r15379 r15508  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using System.Data.Linq;
    2425using System.Linq;
     
    3233    }
    3334
     35    public IEnumerable<Project> GetProjectsByChildId(Guid id) {
     36      return DataContext.ExecuteQuery<Project>(GetProjectsByChildIdQuery, id);
     37    }
     38
     39    public IEnumerable<Guid> GetProjectIdsByChildId(Guid id) {
     40      return DataContext.ExecuteQuery<Guid>(GetProjectIdsByChildIdQuery, id);
     41    }
     42
    3443    #region Compiled queries
    3544    private static readonly Func<DataContext, Guid, Project> GetByIdQuery =
     
    3948         select project).SingleOrDefault());
    4049    #endregion
     50
     51    #region String queries
     52    private const string GetProjectsByChildIdQuery = @"
     53      WITH ptree AS
     54      (
     55        SELECT ProjectId, ParentProjectId
     56        FROM [Project]
     57        UNION ALL
     58        SELECT pt.ProjectId, p.ParentProjectId
     59        FROM [Project] p
     60        JOIN ptree pt ON pt.ParentProjectId = p.ProjectId AND p.ParentProjectId <> p.ProjectId AND pt.ParentProjectId <> pt.ProjectId
     61      )
     62      SELECT DISTINCT pro.*
     63      FROM ptree, [Project] pro
     64      WHERE ptree.ProjectId = {0}
     65      AND ptree.ParentProjectId = pro.ProjectId
     66    ";
     67    private const string GetProjectIdsByChildIdQuery = @"
     68      WITH ptree AS
     69      (
     70        SELECT ProjectId, ParentProjectId
     71        FROM [Project]
     72        UNION ALL
     73        SELECT pt.ProjectId, p.ParentProjectId
     74        FROM [Project] p
     75        JOIN ptree pt ON pt.ParentProjectId = p.ProjectId AND p.ParentProjectId <> p.ProjectId AND pt.ParentProjectId <> pt.ProjectId
     76      )
     77      SELECT DISTINCT ptree.ParentProjectId
     78      FROM ptree
     79      WHERE ptree.ProjectId = {0}
     80    ";
     81    #endregion
    4182  }
    4283}
  • branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj

    r15411 r15508  
    123123    <Compile Include="Daos\RequiredPluginDao.cs" />
    124124    <Compile Include="Daos\ResourceDao.cs" />
     125    <Compile Include="Daos\ResourcePermissionDao.cs" />
    125126    <Compile Include="Daos\SlaveDao.cs" />
    126127    <Compile Include="Daos\SlaveGroupDao.cs" />
  • branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj

    r15411 r15508  
    151151    <Compile Include="Scheduler\JobInfoForScheduler.cs" />
    152152    <Compile Include="Scheduler\RoundRobinTaskScheduler.cs" />
    153     <None Include="app.config" />
     153    <None Include="app.config">
     154      <SubType>Designer</SubType>
     155    </None>
    154156    <None Include="Plugin.cs.frame" />
    155157    <None Include="Properties\AssemblyInfo.cs.frame" />
  • branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs

    r15503 r15508  
    7676        var stateLogDao = pm.StateLogDao;
    7777
    78         var resourceDao = pm.ResourceDao;
    79         var resourcePermissionDao = pm.ResourcePermissionDao;
    80         var currentUserId = UserManager.CurrentUserId;
    81 
    82         //// V1 user grant check
    83         //// get granted (parent) resources
    84         //var allGrantedResourceIds = pm.UseTransaction(() => {
    85         //  return resourcePermissionDao.GetAll().ToList()
    86         //    .Where(x => x.GrantedUserId == currentUserId
    87         //      || UserManager.VerifyUser(currentUserId, new List<Guid> { x.GrantedUserId }))
    88         //    .Select(y => y.ResourceId)
    89         //    .ToList();
    90         //});
    91 
    92         //// get children of granted parent resources
    93         //var userGrantedChildResourceIds = pm.UseTransaction(() => {
    94         //  return allGrantedResourceIds
    95         //  .SelectMany(x => resourceDao.GetResourcesByParentId(x))
    96         //  .Select(y => y.ResourceId);
    97         //});
    98 
    99         //// join list of parent and child resources
    100         //allGrantedResourceIds.AddRange(userGrantedChildResourceIds);
    101 
    102         // V2 user grant check
    103         var allGrantedResourceIds = pm.UseTransaction(() => {
    104           var groupAndGroupIds = new List<Guid> { currentUserId };
    105           groupAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
    106           return resourcePermissionDao.GetByUserAndGroupIds(groupAndGroupIds).ToList();
    107         });
    108 
    109         // get all owned resourceIds
    110         var ownedResourceIds = resourceDao.GetAll()
    111           .Where(x => x.OwnerUserId == currentUserId)
    112           .Select(x => x.ResourceId).ToList();
    113 
    114         // join list of owned and granted resourceIds
    115         allGrantedResourceIds.AddRange(ownedResourceIds);
    116 
    117         // filter initial resourceId list with the list of the granted ones
    118         var filteredResourceIds = resourceIds
    119           .Where(x => allGrantedResourceIds.Contains(x))
    120           .Distinct().ToList();
    121 
    122         // TODO-JAN: Additional Filtering:
    123         // TODO-JAN: user - project check; project - resource check
    124 
     78        pm.UseTransaction(() => {
     79          CheckTaskPermissions(pm, task, resourceIds);
     80        });
    12581
    12682        var newTask = task.ToEntity();
    12783        newTask.JobData = taskData.ToEntity();
    12884        newTask.JobData.LastUpdate = DateTime.Now;
    129         newTask.AssignedTaskResources.AddRange(filteredResourceIds.Select(
     85        newTask.AssignedTaskResources.AddRange(resourceIds.Select(
    13086          x => new DA.AssignedTaskResource {
    13187            ResourceId = x
     
    739695      var pm = PersistenceManager;
    740696      using (new PerformanceLogger("GrantProjectPermissions")) {
    741         pm.UseTransaction(() => {
    742           var project = AuthorizeForProject(pm, projectId);
     697        var projectDao = pm.ProjectDao;
     698        pm.UseTransaction(() => {
     699          var project = projectDao.GetById(projectId);
    743700          var projectPermissions = project.ProjectPermissions.ToList();
    744701          foreach (var id in grantedUserIds) {
     
    787744      var pm = PersistenceManager;
    788745      using (new PerformanceLogger("AssignProjectResources")) {
    789         pm.UseTransaction(() => {
    790           var project = AuthorizeForProject(pm, projectId);
     746        var projectDao = pm.ProjectDao;
     747        pm.UseTransaction(() => {
     748          var project = projectDao.GetById(projectId);
    791749          var assignedProjectResources = project.AssignedProjectResources.ToList();
     750
     751          if (!RoleVerifier.IsInRole(HiveRoles.Administrator))
     752            AuthorizeForResources(pm, project, resourceIds);
     753
    792754          foreach (var id in resourceIds) {
    793755            if (assignedProjectResources.All(x => x.ResourceId != id)) {
     
    10781040    }
    10791041
    1080     // only for authorized Administrator/ResourceOwner/(Sub)ProjectOwner to which the Resource (i.e. resourceId) is assigned
    1081     public void GrantResourcePermissions(Guid resourceId, Guid projectId, Guid[] grantedUserIds) {
    1082       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    1083       AuthorizationManager.AuthorizeForResourceAdministration(resourceId);
    1084       var pm = PersistenceManager;
    1085       using (new PerformanceLogger("GrantResourcePermissions")) {
    1086         pm.UseTransaction(() => {
    1087 
    1088 
    1089           // TODO-JAN
    1090 
    1091 
    1092           pm.SubmitChanges();
    1093         });
    1094       }
    1095     }
    10961042
    10971043    // only for authorized Administrator/ResourceOwner
     
    11091055    }
    11101056
     1057
     1058    // OBSOLETE (change to public if...)
    11111059    // only for authorized Administrator/ResourceOwner/(Sub)ProjectOwner to which the Resource (i.e. resourceId) is assigned
    1112     public void RevokeResourcePermissions(Guid resourceId, Guid projectId, Guid[] grantedUserIds) {
     1060    private void GrantResourcePermissions(Guid resourceId, Guid projectId, Guid[] grantedUserIds) {
     1061      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1062      //AuthorizationManager.AuthorizeForResourceAdministration(resourceId);
     1063      var pm = PersistenceManager;
     1064      using (new PerformanceLogger("GrantResourcePermissions")) {
     1065        pm.UseTransaction(() => {
     1066          // TODO-JAN
     1067          pm.SubmitChanges();
     1068        });
     1069      }
     1070    }
     1071
     1072    // OBSOLETE (change to public if...)
     1073    // only for authorized Administrator/ResourceOwner/(Sub)ProjectOwner to which the Resource (i.e. resourceId) is assigned
     1074    private void RevokeResourcePermissions(Guid resourceId, Guid projectId, Guid[] grantedUserIds) {
    11131075      // TODO-JAN
    11141076    }
     
    12291191    }
    12301192
    1231     private DA.Project AuthorizeForProject(IPersistenceManager pm, Guid projectId) {
     1193    // OBSOLETE
     1194    // reason: only used for double checking! AuthorizationManager.AuthorizeForProjectAdministration(..) does the same!
     1195    //private DA.Project AuthorizeForProject(IPersistenceManager pm, Guid projectId) {
     1196    //  var projectDao = pm.ProjectDao;
     1197    //  var project = projectDao.GetById(projectId);
     1198    //  if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT);
     1199    //  if (project.OwnerUserId != UserManager.CurrentUserId
     1200    //      && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
     1201    //    throw new SecurityException(NOT_AUTHORIZED_PROJECT);
     1202    //  }
     1203    //  return project;
     1204    //}
     1205
     1206   private void CheckTaskPermissions(IPersistenceManager pm, DT.Task task, IEnumerable<Guid> resourceIds) {
     1207      var jobDao = pm.JobDao;
    12321208      var projectDao = pm.ProjectDao;
    1233       var project = projectDao.GetById(projectId);
    1234       if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT);
    1235       if (project.OwnerUserId != UserManager.CurrentUserId
    1236           && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
     1209      var resourceDao = pm.ResourceDao;
     1210      var resourcePermissionDao = pm.ResourcePermissionDao;
     1211      var projectPermissionDao = pm.ProjectPermissionDao;
     1212      var currentUserId = UserManager.CurrentUserId;
     1213
     1214      //// PART 1: user-resource permission check (V1)
     1215      //// get granted (parent) resources
     1216      //var allGrantedResourceIds = pm.UseTransaction(() => {
     1217      //  return resourcePermissionDao.GetAll().ToList()
     1218      //    .Where(x => x.GrantedUserId == currentUserId
     1219      //      || UserManager.VerifyUser(currentUserId, new List<Guid> { x.GrantedUserId }))
     1220      //    .Select(y => y.ResourceId)
     1221      //    .ToList();
     1222      //});
     1223
     1224      //// get children of granted parent resources
     1225      //var userGrantedChildResourceIds = pm.UseTransaction(() => {
     1226      //  return allGrantedResourceIds
     1227      //  .SelectMany(x => resourceDao.GetResourcesByParentId(x))
     1228      //  .Select(y => y.ResourceId);
     1229      //});
     1230
     1231      //// join list of parent and child resources
     1232      //allGrantedResourceIds.AddRange(userGrantedChildResourceIds);
     1233
     1234      // PART 1: user-resource permission check (V2)
     1235      // collect the current currentUserId and all Ids of affiliated groups
     1236      var userAndGroupIds = new List<Guid> { currentUserId };
     1237      userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     1238
     1239      // get all granted resourceIds
     1240      var allGrantedResourceIds = resourcePermissionDao.GetByUserAndGroupIds(userAndGroupIds).ToList();
     1241
     1242      // get all owned resourceIds (including child resourceIds)
     1243      var ownedResourceIds = resourceDao.GetAll()
     1244        .Where(x => x.OwnerUserId == currentUserId)
     1245        .Select(x => x.ResourceId).ToList();
     1246      var ownedChildResourceIds = ownedResourceIds.SelectMany(x => resourceDao.GetResourceIdsByParentId(x));
     1247      ownedResourceIds.AddRange(ownedChildResourceIds);
     1248
     1249      // join list of owned into the list with granted resourceIds
     1250      allGrantedResourceIds.AddRange(ownedResourceIds);
     1251
     1252      // check the argument resourceIds against the list of granted (and owned) ones
     1253      if (resourceIds.Except(allGrantedResourceIds).Any()) {
     1254        throw new SecurityException(NOT_AUTHORIZED_RESOURCE);
     1255      }
     1256
     1257      // PART 2: user-project permission check
     1258      var job = jobDao.GetById(task.JobId);
     1259      var project = projectDao.GetById(job.ProjectId);
     1260      AuthorizeForProjectTask(pm, project);
     1261
     1262      // PART 3: project-resource permission check
     1263      var assignedResourceIds = project.AssignedProjectResources.Select(x => x.ResourceId).ToList();
     1264      var assignedChildResourceIds = assignedResourceIds.SelectMany(x => resourceDao.GetResourceIdsByParentId(x));
     1265      assignedResourceIds.AddRange(assignedChildResourceIds);
     1266      if (resourceIds.Except(assignedResourceIds).Any()) {
    12371267        throw new SecurityException(NOT_AUTHORIZED_PROJECT);
    12381268      }
    1239       return project;
     1269    }
     1270
     1271    // Check if current user is authorized to add a task on a explicit project
     1272    // case 1: user is administrator
     1273    // case 2: user is owner of project or parent project
     1274    // case 3: user has explicit permission on project or parent project
     1275    private void AuthorizeForProjectTask(IPersistenceManager pm, DA.Project project) {
     1276      if (RoleVerifier.IsInRole(HiveRoles.Administrator)) return; // case 1
     1277
     1278      // case 2
     1279      var projectDao = pm.ProjectDao;
     1280      var projectBranch = new List<DA.Project>() { project };
     1281      projectBranch.AddRange(projectDao.GetProjectsByChildId(project.ProjectId));
     1282      if (projectBranch
     1283        .Select(x => x.OwnerUserId)
     1284        .Contains(UserManager.CurrentUserId)) {
     1285        return; 
     1286      }
     1287
     1288      // case 3
     1289      if(project.ProjectPermissions
     1290        .Select(x => x.GrantedUserId)
     1291        .Contains(UserManager.CurrentUserId)) {
     1292        return;
     1293      }
     1294      if(projectBranch
     1295        .SelectMany(x => x.ProjectPermissions)
     1296        .Select(x => x.GrantedUserId)
     1297        .Contains(UserManager.CurrentUserId)) {
     1298        return;
     1299      }
     1300
     1301      throw new SecurityException(NOT_AUTHORIZED_PROJECT);
     1302    }
     1303
     1304    // Check if the current user is authorized to administer resourceIds
     1305    private void AuthorizeForResources(IPersistenceManager pm, DA.Project project, Guid[] resourceIds) {
     1306      var projectDao = pm.ProjectDao;
     1307      var resourceDao = pm.ResourceDao;
     1308
     1309      var projectBranch = new List<DA.Project> { project };
     1310      projectBranch.AddRange(projectDao.GetProjectsByChildId(project.ProjectId));
     1311      var ownedProjects = projectBranch.Where(x => x.OwnerUserId == UserManager.CurrentUserId).ToList();
     1312
     1313      // get all assigned resourceIds (including children) of owned projects in this branch
     1314      var assignedResourceIds = ownedProjects.SelectMany(x => x.AssignedProjectResources).Select(x => x.ResourceId).ToList();
     1315      var assignedChildResourceIds = assignedResourceIds.SelectMany(x => resourceDao.GetResourceIdsByChildId(x));
     1316      assignedResourceIds.AddRange(assignedChildResourceIds);
     1317
     1318      // look up if all resourceIds are among the assigned ones
     1319      if(resourceIds.Except(assignedResourceIds).Any()) {
     1320        throw new SecurityException(NOT_AUTHORIZED_RESOURCE);
     1321      }
    12401322    }
    12411323
     
    12451327      var projectDao = pm.ProjectDao;
    12461328      var project = projectDao.GetById(projectId);
    1247       if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT);
     1329      if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT); // if project does not exist
    12481330
    12491331      var resourceDao = pm.ResourceDao;
    12501332      var resource = resourceDao.GetById(resourceId);
    1251       if (resource == null) throw new SecurityException(NOT_AUTHORIZED_RESOURCE);
    1252 
    1253 
    1254       if (project.OwnerUserId != UserManager.CurrentUserId
     1333      if (resource == null) throw new SecurityException(NOT_AUTHORIZED_RESOURCE); // if resource does not exist
     1334
     1335
     1336      // check if user is administrator, owner of the project or any parent project
     1337      var projectTree = new List<DA.Project> { project };
     1338      projectTree.AddRange(projectDao.GetProjectsByChildId(projectId));
     1339      if(!projectTree.Select(x => x.OwnerUserId).Contains(UserManager.CurrentUserId)
    12551340        && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
    12561341        throw new SecurityException(NOT_AUTHORIZED_PROJECT);
  • branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs

    r15380 r15508  
    2727using DA = HeuristicLab.Services.Hive.DataAccess;
    2828using DT = HeuristicLab.Services.Hive.DataTransfer;
    29 
     29using System.Collections.Generic;
     30using System.Linq;
    3031
    3132namespace HeuristicLab.Services.Hive {
     
    8788        var project = projectDao.GetById(projectId);
    8889        if (project == null) throw new SecurityException(NOT_AUTHORIZED);
    89         if (project.OwnerUserId != UserManager.CurrentUserId
     90
     91        var projectTree = new List<Project>() { project };
     92        projectTree.AddRange(projectDao.GetProjectsByChildId(projectId));
     93        if(!projectTree.Select(x => x.OwnerUserId).Contains(UserManager.CurrentUserId)
    9094            && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
    9195          throw new SecurityException(NOT_AUTHORIZED);
Note: See TracChangeset for help on using the changeset viewer.