Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/30/18 11:32:56 (6 years ago)
Author:
jkarder
Message:

#2839: merged [15377-16116/branches/2839_HiveProjectManagement] into trunk

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/HeuristicLab.Services.Hive

  • trunk/HeuristicLab.Services.Hive/3.3/HiveService.cs

    r15583 r16117  
    4141  [HiveOperationContextBehavior]
    4242  public class HiveService : IHiveService {
     43    private const string NOT_AUTHORIZED_PROJECTRESOURCE = "Selected project is not authorized to access the requested resource";
     44    private const string NOT_AUTHORIZED_USERPROJECT = "Current user is not authorized to access the requested project";
     45    private const string NOT_AUTHORIZED_PROJECTOWNER = "The set user is not authorized to own the project";
     46    private const string NO_JOB_UPDATE_POSSIBLE = "This job has already been flagged for deletion, thus, it can not be updated anymore.";
     47
    4348    private static readonly DA.TaskState[] CompletedStates = { DA.TaskState.Finished, DA.TaskState.Aborted, DA.TaskState.Failed };
    4449
     
    6671
    6772    #region Task Methods
    68     public Guid AddTask(DT.Task task, DT.TaskData taskData, IEnumerable<Guid> resourceIds) {
    69       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     73
     74    public Guid AddTask(DT.Task task, DT.TaskData taskData) {
     75      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     76      AuthorizationManager.AuthorizeForJob(task.JobId, DT.Permission.Full);
    7077      var pm = PersistenceManager;
    7178      using (new PerformanceLogger("AddTask")) {
     
    7582        newTask.JobData = taskData.ToEntity();
    7683        newTask.JobData.LastUpdate = DateTime.Now;
    77         newTask.AssignedResources.AddRange(resourceIds.Select(
    78           x => new DA.AssignedResource {
    79             ResourceId = x
    80           }));
    8184        newTask.State = DA.TaskState.Waiting;
    8285        return pm.UseTransaction(() => {
     
    99102    public Guid AddChildTask(Guid parentTaskId, DT.Task task, DT.TaskData taskData) {
    100103      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    101       IEnumerable<Guid> resourceIds;
    102       var pm = PersistenceManager;
    103       using (new PerformanceLogger("AddChildTask")) {
    104         var assignedResourceDao = pm.AssignedResourceDao;
    105         resourceIds = pm.UseTransaction(() => {
    106           return assignedResourceDao.GetByTaskId(parentTaskId)
    107             .Select(x => x.ResourceId)
    108             .ToList();
    109         });
    110       }
    111104      task.ParentTaskId = parentTaskId;
    112       return AddTask(task, taskData, resourceIds);
     105      return AddTask(task, taskData);
    113106    }
    114107
     
    338331        return pm.UseTransaction(() => {
    339332          var jobs = jobDao.GetAll()
    340             .Where(x => x.OwnerUserId == currentUserId
    341                      || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
    342                                                  && y.GrantedUserId == currentUserId) > 0)
     333            .Where(x => x.State == DA.JobState.Online
     334                          && (x.OwnerUserId == currentUserId
     335                            || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
     336                              && y.GrantedUserId == currentUserId) > 0)
     337                          )
    343338            .Select(x => x.ToDto())
    344339            .ToList();
    345           var statistics = taskDao.GetAll()
    346               .GroupBy(x => x.JobId)
    347               .Select(x => new {
    348                 x.Key,
    349                 TotalCount = x.Count(),
    350                 CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
    351                 FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
    352               })
     340
     341          EvaluateJobs(pm, jobs);
     342          return jobs;
     343        });
     344      }
     345    }
     346
     347    public IEnumerable<DT.Job> GetJobsByProjectId(Guid projectId) {
     348      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     349      var pm = PersistenceManager;
     350      using (new PerformanceLogger("GetJobsByProjectId")) {
     351        var currentUserId = UserManager.CurrentUserId;
     352        var projectDao = pm.ProjectDao;
     353        var jobDao = pm.JobDao;
     354
     355        return pm.UseTransaction(() => {
     356          // check if user is granted to administer the requested projectId
     357          var administrationGrantedProjects = projectDao
     358            .GetAdministrationGrantedProjectsForUser(currentUserId)
     359            .ToList();
     360
     361          if (administrationGrantedProjects.Select(x => x.ProjectId).Contains(projectId)) {
     362            var jobs = jobDao.GetByProjectId(projectId)
     363            .Select(x => x.ToDto())
     364            .ToList();
     365
     366            EvaluateJobs(pm, jobs);
     367            return jobs;
     368          } else {
     369            return Enumerable.Empty<DT.Job>();
     370          }
     371        });
     372      }
     373    }
     374
     375    public IEnumerable<DT.Job> GetJobsByProjectIds(IEnumerable<Guid> projectIds) {
     376      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     377      var pm = PersistenceManager;
     378      using (new PerformanceLogger("GetJobsByProjectIds")) {
     379        var currentUserId = UserManager.CurrentUserId;
     380        var projectDao = pm.ProjectDao;
     381        var jobDao = pm.JobDao;
     382        return pm.UseTransaction(() => {
     383          // check for which of requested projectIds the user is granted to administer
     384          var administrationGrantedProjectIds = projectDao
     385            .GetAdministrationGrantedProjectsForUser(currentUserId)
     386            .Select(x => x.ProjectId)
     387            .ToList();
     388          var requestedAndGrantedProjectIds = projectIds.Intersect(administrationGrantedProjectIds);
     389
     390          if (requestedAndGrantedProjectIds.Any()) {
     391            var jobs = jobDao.GetByProjectIds(requestedAndGrantedProjectIds)
     392              .Select(x => x.ToDto())
    353393              .ToList();
    354           foreach (var job in jobs) {
    355             var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
    356             if (statistic != null) {
    357               job.JobCount = statistic.TotalCount;
    358               job.CalculatingCount = statistic.CalculatingCount;
    359               job.FinishedCount = statistic.FinishedCount;
    360             }
    361             job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
    362             if (currentUserId == job.OwnerUserId) {
    363               job.Permission = Permission.Full;
    364             } else {
    365               var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
    366               job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
    367             }
    368           }
    369           return jobs;
    370         });
    371       }
    372     }
    373 
    374     public Guid AddJob(DT.Job jobDto) {
    375       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    376       var pm = PersistenceManager;
     394
     395            EvaluateJobs(pm, jobs);
     396            return jobs;
     397          } else {
     398            return Enumerable.Empty<DT.Job>();
     399          }
     400        });
     401      }
     402    }
     403
     404    public Guid AddJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
     405      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     406      var dateCreated = DateTime.Now;
     407      var pm = PersistenceManager;
     408
     409      // check project availability (cf. duration)
     410      CheckProjectAvailability(pm, jobDto.ProjectId, dateCreated);
     411
     412      // check user - project
     413      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
     414
     415      // check project - resources
     416      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
     417
    377418      using (new PerformanceLogger("AddJob")) {
    378419        var jobDao = pm.JobDao;
    379420        var userPriorityDao = pm.UserPriorityDao;
    380         return pm.UseTransaction(() => {
    381           jobDto.OwnerUserId = UserManager.CurrentUserId;
    382           jobDto.DateCreated = DateTime.Now;
    383           var job = jobDao.Save(jobDto.ToEntity());
    384           if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
     421
     422        return pm.UseTransaction(() => {
     423          var newJob = jobDto.ToEntity();
     424          newJob.OwnerUserId = UserManager.CurrentUserId;
     425          newJob.DateCreated = dateCreated;
     426
     427          // add resource assignments
     428          if (resourceIds != null && resourceIds.Any()) {
     429            newJob.AssignedJobResources.AddRange(resourceIds.Select(
     430              x => new DA.AssignedJobResource {
     431                ResourceId = x
     432              }));
     433          }
     434
     435          var job = jobDao.Save(newJob);
     436          if (userPriorityDao.GetById(newJob.OwnerUserId) == null) {
    385437            userPriorityDao.Save(new DA.UserPriority {
    386               UserId = jobDto.OwnerUserId,
    387               DateEnqueued = jobDto.DateCreated
     438              UserId = newJob.OwnerUserId,
     439              DateEnqueued = newJob.DateCreated
    388440            });
    389441          }
     
    394446    }
    395447
    396     public void UpdateJob(DT.Job jobDto) {
     448    public void UpdateJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
    397449      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    398450      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
    399451      var pm = PersistenceManager;
     452      var dateUpdated = DateTime.Now;
     453
     454      // check project availability
     455      CheckProjectAvailability(pm, jobDto.ProjectId, dateUpdated);
     456      // check user - project permission
     457      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
     458      // check project - resources permission
     459      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
     460
    400461      using (new PerformanceLogger("UpdateJob")) {
    401462        bool exists = true;
     
    406467            exists = false;
    407468            job = new DA.Job();
    408           }
     469          } else if (job.State != DA.JobState.Online) {
     470            throw new InvalidOperationException(NO_JOB_UPDATE_POSSIBLE);
     471          }
     472
     473
    409474          jobDto.CopyToEntity(job);
     475
    410476          if (!exists) {
     477            // add resource assignments
     478            if (resourceIds != null && resourceIds.Any()) {
     479              job.AssignedJobResources.AddRange(resourceIds.Select(
     480                x => new DA.AssignedJobResource {
     481                  ResourceId = x
     482                }));
     483            }
    411484            jobDao.Save(job);
    412           }
    413           pm.SubmitChanges();
    414         });
    415       }
    416     }
    417 
    418     public void DeleteJob(Guid jobId) {
     485          } else if (resourceIds != null) {
     486            var addedJobResourceIds = resourceIds.Except(job.AssignedJobResources.Select(x => x.ResourceId));
     487            var removedJobResourceIds = job.AssignedJobResources
     488              .Select(x => x.ResourceId)
     489              .Except(resourceIds)
     490              .ToArray();
     491
     492            // remove resource assignments
     493            foreach (var rid in removedJobResourceIds) {
     494              var ajr = job.AssignedJobResources.Where(x => x.ResourceId == rid).SingleOrDefault();
     495              if (ajr != null) job.AssignedJobResources.Remove(ajr);
     496            }
     497
     498            // add resource assignments
     499            job.AssignedJobResources.AddRange(addedJobResourceIds.Select(
     500              x => new DA.AssignedJobResource {
     501                ResourceId = x
     502              }));
     503          }
     504          pm.SubmitChanges();
     505        });
     506      }
     507    }
     508
     509    public void UpdateJobState(Guid jobId, DT.JobState jobState) {
    419510      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    420511      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
    421512      var pm = PersistenceManager;
    422       using (new PerformanceLogger("DeleteJob")) {
     513      using (new PerformanceLogger("UpdateJobState")) {
    423514        var jobDao = pm.JobDao;
    424515        pm.UseTransaction(() => {
    425           // child task will be deleted by db-trigger
    426           jobDao.Delete(jobId);
    427           pm.SubmitChanges();
    428         });
     516          var job = jobDao.GetById(jobId);
     517          if (job != null) {
     518            var jobStateEntity = jobState.ToEntity();
     519            // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator
     520            // and from "StatisticsPending" to "DeletionPending" = deletion request by HiveStatisticGenerator for EventManager
     521            if (job.State == DA.JobState.Online && jobStateEntity == DA.JobState.StatisticsPending) {
     522              job.State = jobStateEntity;
     523              foreach (var task in job.Tasks
     524              .Where(x => x.State == DA.TaskState.Waiting
     525                || x.State == DA.TaskState.Paused
     526                || x.State == DA.TaskState.Offline)) {
     527                task.State = DA.TaskState.Aborted;
     528              }
     529              pm.SubmitChanges();
     530            } else if (job.State == DA.JobState.StatisticsPending && jobStateEntity == DA.JobState.DeletionPending) {
     531              job.State = jobStateEntity;
     532              pm.SubmitChanges();
     533            }
     534          }
     535        });
     536      }
     537    }
     538
     539    public void UpdateJobStates(IEnumerable<Guid> jobIds, DT.JobState jobState) {
     540      if (jobState != JobState.StatisticsPending) return; // only process requests for "StatisticsPending"
     541
     542      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     543      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     544      var currentUserId = UserManager.CurrentUserId;
     545
     546      var pm = PersistenceManager;
     547      using (new PerformanceLogger("UpdateJobStates")) {
     548        var jobDao = pm.JobDao;
     549        var projectDao = pm.ProjectDao;
     550        pm.UseTransaction(() => {
     551          foreach (var jobId in jobIds) {
     552            var job = jobDao.GetById(jobId);
     553            if (job != null) {
     554
     555              var administrationGrantedProjects = projectDao
     556                .GetAdministrationGrantedProjectsForUser(currentUserId)
     557                .ToList();
     558
     559              // check if user is granted to administer the job-parenting project
     560              if (isAdministrator || administrationGrantedProjects.Contains(job.Project)) {
     561                // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator
     562                if (job.State == DA.JobState.Online) {
     563                  job.State = DA.JobState.StatisticsPending;
     564                  foreach (var task in job.Tasks
     565                  .Where(x => x.State == DA.TaskState.Waiting
     566                    || x.State == DA.TaskState.Paused
     567                    || x.State == DA.TaskState.Offline)) {
     568                    task.State = DA.TaskState.Aborted;
     569                  }
     570                  pm.SubmitChanges();
     571                }
     572              }
     573            }
     574          }
     575        });
     576      }
     577    }
     578
     579    public IEnumerable<DT.AssignedJobResource> GetAssignedResourcesForJob(Guid jobId) {
     580      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     581      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
     582      var pm = PersistenceManager;
     583      var assignedJobResourceDao = pm.AssignedJobResourceDao;
     584      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     585        return pm.UseTransaction(() =>
     586          assignedJobResourceDao.GetByJobId(jobId)
     587          .Select(x => x.ToDto())
     588          .ToList()
     589        );
    429590      }
    430591    }
     
    532693          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
    533694        }
    534       }
    535       catch (Exception ex) {
     695      } catch (Exception ex) {
    536696        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
    537697      }
     
    604764    #endregion
    605765
    606     #region ResourcePermission Methods
    607     public void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
    608       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    609       var pm = PersistenceManager;
    610       using (new PerformanceLogger("GrantResourcePermissions")) {
    611         pm.UseTransaction(() => {
    612           var resource = AuthorizeForResource(pm, resourceId);
    613           var resourcePermissions = resource.ResourcePermissions.ToList();
     766    #region Project Methods
     767    public Guid AddProject(DT.Project projectDto) {
     768      if (projectDto == null || projectDto.Id != Guid.Empty) return Guid.Empty;
     769      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     770      // check if current (non-admin) user is owner of one of projectDto's-parents
     771      // note: non-admin users are not allowed to administer root projects (i.e. projects without parental entry)
     772      bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     773      if (!isAdmin) {
     774        if (projectDto != null && projectDto.ParentProjectId.HasValue) {
     775          AuthorizationManager.AuthorizeForProjectAdministration(projectDto.ParentProjectId.Value, false);
     776        } else {
     777          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     778        }
     779      }
     780
     781      // check that non-admins can not be set as owner of root projects
     782      if (projectDto != null && !projectDto.ParentProjectId.HasValue) {
     783        var owner = UserManager.GetUserById(projectDto.OwnerUserId);
     784        if (owner == null || !RoleVerifier.IsUserInRole(owner.UserName, HiveRoles.Administrator)) {
     785          throw new SecurityException(NOT_AUTHORIZED_PROJECTOWNER);
     786        }
     787      }
     788
     789      var pm = PersistenceManager;
     790      using (new PerformanceLogger("AddProject")) {
     791        var projectDao = pm.ProjectDao;
     792
     793        return pm.UseTransaction(() => {
     794          var project = projectDao.Save(projectDto.ToEntity());
     795
     796          var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     797          bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     798
     799          // if user is no admin, but owner of a parent project
     800          // check start/end date time boundaries of parent projects before updating child project
     801          if (!isAdmin) {
     802            var parentProject = parentProjects.Where(x => x.ProjectId == project.ParentProjectId).FirstOrDefault();
     803            if (parentProject != null) {
     804              if (project.StartDate < parentProject.StartDate) project.StartDate = parentProject.StartDate;
     805              if ((parentProject.EndDate.HasValue && project.EndDate.HasValue && project.EndDate > parentProject.EndDate)
     806              || (parentProject.EndDate.HasValue && !project.EndDate.HasValue))
     807                project.EndDate = parentProject.EndDate;
     808            }
     809          }
     810
     811
     812          project.ProjectPermissions.Clear();
     813          project.ProjectPermissions.Add(new DA.ProjectPermission {
     814            GrantedUserId = project.OwnerUserId,
     815            GrantedByUserId = UserManager.CurrentUserId
     816          });
     817
     818          pm.SubmitChanges();
     819          return project.ProjectId;
     820        });
     821      }
     822    }
     823
     824    public void UpdateProject(DT.Project projectDto) {
     825      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     826      // check if current (non-admin) user is owner of the project or the projectDto's-parents
     827      // note: non-admin users are not allowed to administer root projects (i.e. projects without parental entry)
     828      bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     829      if (!isAdmin) {
     830        if (projectDto != null && projectDto.ParentProjectId.HasValue) {
     831          AuthorizationManager.AuthorizeForProjectAdministration(projectDto.Id, false);
     832        } else {
     833          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
     834        }
     835      }
     836
     837      // check that non-admins can not be set as owner of root projects
     838      if (projectDto != null && !projectDto.ParentProjectId.HasValue) {
     839        var owner = UserManager.GetUserById(projectDto.OwnerUserId);
     840        if (owner == null || !RoleVerifier.IsUserInRole(owner.UserName, HiveRoles.Administrator)) {
     841          throw new SecurityException(NOT_AUTHORIZED_PROJECTOWNER);
     842        }
     843      }
     844
     845      var pm = PersistenceManager;
     846      using (new PerformanceLogger("UpdateProject")) {
     847        var projectDao = pm.ProjectDao;
     848        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     849        pm.UseTransaction(() => {
     850          var project = projectDao.GetById(projectDto.Id);
     851          if (project != null) { // (1) update existent project
     852            var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     853            bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     854
     855            var formerOwnerId = project.OwnerUserId;
     856            var formerStartDate = project.StartDate;
     857            var formerEndDate = project.EndDate;
     858            projectDto.CopyToEntity(project);
     859
     860            // if user is no admin, but owner of parent project(s)
     861            // check start/end date time boundaries of parent projects before updating child project
     862            if (!isAdmin && isParent) {
     863              var parentProject = parentProjects.Where(x => x.ProjectId == project.ParentProjectId).FirstOrDefault();
     864              if (parentProject != null) {
     865                if (project.StartDate < parentProject.StartDate) project.StartDate = formerStartDate;
     866                if ((parentProject.EndDate.HasValue && project.EndDate.HasValue && project.EndDate > parentProject.EndDate)
     867                || (parentProject.EndDate.HasValue && !project.EndDate.HasValue))
     868                  project.EndDate = formerEndDate;
     869              }
     870            }
     871
     872            // if user is admin or owner of parent project(s)
     873            if (isAdmin || isParent) {
     874              // if owner has changed...
     875              if (formerOwnerId != projectDto.OwnerUserId) {
     876                // Add permission for new owner if not already done
     877                if (!project.ProjectPermissions
     878                  .Select(pp => pp.GrantedUserId)
     879                  .Contains(projectDto.OwnerUserId)) {
     880                  project.ProjectPermissions.Add(new DA.ProjectPermission {
     881                    GrantedUserId = projectDto.OwnerUserId,
     882                    GrantedByUserId = UserManager.CurrentUserId
     883                  });
     884                }
     885              }
     886            } else { // if user is only owner of current project, but no admin and no owner of parent project(s)
     887              project.OwnerUserId = formerOwnerId;
     888              project.StartDate = formerStartDate;
     889              project.EndDate = formerEndDate;
     890            }
     891
     892          } else { // (2) save new project
     893            var newProject = projectDao.Save(projectDto.ToEntity());
     894
     895            var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     896            bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     897
     898            // if user is no admin, but owner of a parent project
     899            // check start/end date time boundaries of parent projects before updating child project
     900            if (!isAdmin) {
     901              var parentProject = parentProjects.Where(x => x.ProjectId == project.ParentProjectId).FirstOrDefault();
     902              if (parentProject != null) {
     903                if (project.StartDate < parentProject.StartDate) project.StartDate = parentProject.StartDate;
     904                if ((parentProject.EndDate.HasValue && project.EndDate.HasValue && project.EndDate > parentProject.EndDate)
     905                || (parentProject.EndDate.HasValue && !project.EndDate.HasValue))
     906                  project.EndDate = parentProject.EndDate;
     907              }
     908            }
     909
     910            newProject.ProjectPermissions.Clear();
     911            newProject.ProjectPermissions.Add(new DA.ProjectPermission {
     912              GrantedUserId = projectDto.OwnerUserId,
     913              GrantedByUserId = UserManager.CurrentUserId
     914            });
     915          }
     916
     917          pm.SubmitChanges();
     918        });
     919      }
     920    }
     921
     922    public void DeleteProject(Guid projectId) {
     923      if (projectId == Guid.Empty) return;
     924      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     925      // check if current (non-admin) user is owner of one of the projectDto's-parents
     926      // note: non-admin users are not allowed to administer root projects (i.e. projects without parental entry)
     927      if (!RoleVerifier.IsInRole(HiveRoles.Administrator)) {
     928        AuthorizationManager.AuthorizeForProjectAdministration(projectId, true);
     929      }
     930
     931      var pm = PersistenceManager;
     932      using (new PerformanceLogger("DeleteProject")) {
     933        var projectDao = pm.ProjectDao;
     934        var jobDao = pm.JobDao;
     935        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     936        pm.UseTransaction(() => {
     937          var projectIds = new HashSet<Guid> { projectId };
     938          projectIds.Union(projectDao.GetChildProjectIdsById(projectId));
     939
     940          var jobs = jobDao.GetByProjectIds(projectIds)
     941            .Select(x => x.ToDto())
     942            .ToList();
     943
     944          if (jobs.Count > 0) {
     945            throw new InvalidOperationException("There are " + jobs.Count + " job(s) using this project and/or child-projects. It is necessary to delete them before the project.");
     946          } else {
     947            assignedJobResourceDao.DeleteByProjectIds(projectIds);
     948            projectDao.DeleteByIds(projectIds);
     949            pm.SubmitChanges();
     950          }
     951        });
     952      }
     953    }
     954
     955    // query granted project for use (i.e. to calculate on)
     956    public DT.Project GetProject(Guid projectId) {
     957      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     958      var pm = PersistenceManager;
     959      using (new PerformanceLogger("GetProject")) {
     960        var projectDao = pm.ProjectDao;
     961        var currentUserId = UserManager.CurrentUserId;
     962        var userAndGroupIds = new List<Guid> { currentUserId };
     963        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     964        return pm.UseTransaction(() => {
     965          return projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     966          .Where(x => x.ProjectId == projectId)
     967          .Select(x => x.ToDto())
     968          .SingleOrDefault();
     969        });
     970      }
     971    }
     972
     973    // query granted projects for use (i.e. to calculate on)
     974    public IEnumerable<DT.Project> GetProjects() {
     975      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     976      var pm = PersistenceManager;
     977      using (new PerformanceLogger("GetProjects")) {
     978        var projectDao = pm.ProjectDao;
     979        var currentUserId = UserManager.CurrentUserId;
     980        var userAndGroupIds = new List<Guid> { currentUserId };
     981        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     982        return pm.UseTransaction(() => {
     983          var projects = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     984            .Select(x => x.ToDto()).ToList();
     985          var now = DateTime.Now;
     986          return projects.Where(x => x.StartDate <= now && (x.EndDate == null || x.EndDate >= now)).ToList();
     987        });
     988      }
     989    }
     990
     991    public IEnumerable<DT.Project> GetProjectsForAdministration() {
     992      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     993      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     994      var pm = PersistenceManager;
     995      using (new PerformanceLogger("GetProjectsForAdministration")) {
     996        var projectDao = pm.ProjectDao;
     997
     998        return pm.UseTransaction(() => {
     999          if (isAdministrator) {
     1000            return projectDao.GetAll().Select(x => x.ToDto()).ToList();
     1001          } else {
     1002            var currentUserId = UserManager.CurrentUserId;
     1003            return projectDao.GetAdministrationGrantedProjectsForUser(currentUserId)
     1004              .Select(x => x.ToDto()).ToList();
     1005
     1006          }
     1007        });
     1008      }
     1009    }
     1010
     1011    public IDictionary<Guid, HashSet<Guid>> GetProjectGenealogy() {
     1012      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1013      var pm = PersistenceManager;
     1014      using (new PerformanceLogger("GetProjectGenealogy")) {
     1015        var projectDao = pm.ProjectDao;
     1016        var projectAncestors = new Dictionary<Guid, HashSet<Guid>>();
     1017        return pm.UseTransaction(() => {
     1018          var projects = projectDao.GetAll().ToList();
     1019          projects.ForEach(p => projectAncestors.Add(p.ProjectId, new HashSet<Guid>()));
     1020          foreach (var p in projects) {
     1021            var parentProject = p.ParentProject;
     1022            while (parentProject != null) {
     1023              projectAncestors[p.ProjectId].Add(parentProject.ProjectId);
     1024              parentProject = parentProject.ParentProject;
     1025            }
     1026          }
     1027          return projectAncestors;
     1028        });
     1029      }
     1030    }
     1031
     1032    public IDictionary<Guid, string> GetProjectNames() {
     1033      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1034      var pm = PersistenceManager;
     1035      using (new PerformanceLogger("GetProjectNames")) {
     1036        var projectDao = pm.ProjectDao;
     1037        var projectNames = new Dictionary<Guid, string>();
     1038        return pm.UseTransaction(() => {
     1039          projectDao
     1040            .GetAll().ToList()
     1041            .ForEach(p => projectNames.Add(p.ProjectId, p.Name));
     1042          return projectNames;
     1043        });
     1044      }
     1045    }
     1046    #endregion
     1047
     1048    #region ProjectPermission Methods
     1049    public void SaveProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool reassign, bool cascading, bool reassignCascading) {
     1050      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1051      if (projectId == null || grantedUserIds == null) return;
     1052      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1053      var pm = PersistenceManager;
     1054      using (new PerformanceLogger("SaveProjectPermissions")) {
     1055        var projectDao = pm.ProjectDao;
     1056        var projectPermissionDao = pm.ProjectPermissionDao;
     1057        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1058
     1059        pm.UseTransaction(() => {
     1060          var project = projectDao.GetById(projectId);
     1061          if (project == null) return;
     1062          var projectPermissions = project.ProjectPermissions.Select(x => x.GrantedUserId).ToArray();
     1063
     1064          // guarantee that project owner is always permitted
     1065          if (!grantedUserIds.Contains(project.OwnerUserId)) {
     1066            grantedUserIds.Add(project.OwnerUserId);
     1067          }
     1068
     1069          //var addedPermissions = grantedUserIds.Except(projectPermissions);
     1070          var removedPermissions = projectPermissions.Except(grantedUserIds);
     1071
     1072          // remove job assignments and project permissions
     1073          if (reassign) {
     1074            assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
     1075            project.ProjectPermissions.Clear();
     1076          } else {
     1077
     1078            var ugt = GetUserGroupTree();
     1079            var permittedGuids = new HashSet<Guid>(); // User- and Group-Guids
     1080            var notpermittedGuids = new HashSet<Guid>();
     1081
     1082            // remove job assignments:
     1083            // (1) get all member-Guids of all still or fresh permitted user/groups
     1084            foreach (var item in grantedUserIds) {
     1085              permittedGuids.Add(item);
     1086              if (ugt.ContainsKey(item)) {
     1087                ugt[item].ToList().ForEach(x => permittedGuids.Add(x));
     1088              }
     1089            }
     1090
     1091            // (2) get all member-Guids of users and groups in removedPermissions
     1092            foreach (var item in removedPermissions) {
     1093              notpermittedGuids.Add(item);
     1094              if (ugt.ContainsKey(item)) {
     1095                ugt[item].ToList().ForEach(x => notpermittedGuids.Add(x));
     1096              }
     1097            }
     1098
     1099            // (3) get all Guids which are in removedPermissions but not in grantedUserIds
     1100            var definitelyNotPermittedGuids = notpermittedGuids.Except(permittedGuids);
     1101
     1102            // (4) delete jobs of those
     1103            assignedJobResourceDao.DeleteByProjectIdAndUserIds(project.ProjectId, definitelyNotPermittedGuids);
     1104
     1105
     1106            // remove project permissions
     1107            foreach (var item in project.ProjectPermissions
     1108              .Where(x => removedPermissions.Contains(x.GrantedUserId))
     1109              .ToList()) {
     1110              project.ProjectPermissions.Remove(item);
     1111            }
     1112          }
     1113          pm.SubmitChanges();
     1114
     1115          // add project permissions
    6141116          foreach (var id in grantedUserIds) {
    615             if (resourcePermissions.All(x => x.GrantedUserId != id)) {
    616               resource.ResourcePermissions.Add(new DA.ResourcePermission {
     1117            if (project.ProjectPermissions.All(x => x.GrantedUserId != id)) {
     1118              project.ProjectPermissions.Add(new DA.ProjectPermission {
    6171119                GrantedUserId = id,
    6181120                GrantedByUserId = UserManager.CurrentUserId
     
    6211123          }
    6221124          pm.SubmitChanges();
    623         });
    624       }
    625     }
    626 
    627     public void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
    628       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    629       var pm = PersistenceManager;
    630       using (new PerformanceLogger("RevokeResourcePermissions")) {
    631         var resourcePermissionDao = pm.ResourcePermissionDao;
    632         pm.UseTransaction(() => {
    633           AuthorizeForResource(pm, resourceId);
    634           resourcePermissionDao.DeleteByResourceAndGrantedUserId(resourceId, grantedUserIds);
    635           pm.SubmitChanges();
    636         });
    637       }
    638     }
    639 
    640     public IEnumerable<DT.ResourcePermission> GetResourcePermissions(Guid resourceId) {
    641       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    642       var pm = PersistenceManager;
    643       using (new PerformanceLogger("GetResourcePermissions")) {
    644         var resourcePermissionDao = pm.ResourcePermissionDao;
    645         return pm.UseTransaction(() => resourcePermissionDao.GetByResourceId(resourceId)
     1125
     1126          if (cascading) {
     1127            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
     1128            var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
     1129
     1130            // remove job assignments
     1131            if (reassignCascading) {
     1132              assignedJobResourceDao.DeleteByProjectIds(childProjectIds);
     1133            } else {
     1134              assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, removedPermissions);
     1135            }
     1136
     1137            foreach (var p in childProjects) {
     1138              var cpAssignedPermissions = p.ProjectPermissions.Select(x => x.GrantedUserId).ToList();
     1139              // guarantee that project owner is always permitted
     1140              if (!cpAssignedPermissions.Contains(p.OwnerUserId)) {
     1141                cpAssignedPermissions.Add(p.OwnerUserId);
     1142              }
     1143              var cpRemovedPermissions = cpAssignedPermissions.Where(x => x != p.OwnerUserId).Except(grantedUserIds);
     1144
     1145              // remove left-over job assignments (for non-reassignments)
     1146              if (!reassignCascading) {
     1147                assignedJobResourceDao.DeleteByProjectIdAndUserIds(p.ProjectId, cpRemovedPermissions);
     1148              }
     1149
     1150              // remove project permissions
     1151              if (reassignCascading) {
     1152                p.ProjectPermissions.Clear();
     1153              } else {
     1154                foreach (var item in p.ProjectPermissions
     1155                  .Where(x => x.GrantedUserId != p.OwnerUserId
     1156                    && (removedPermissions.Contains(x.GrantedUserId) || cpRemovedPermissions.Contains(x.GrantedUserId)))
     1157                  .ToList()) {
     1158                  p.ProjectPermissions.Remove(item);
     1159                }
     1160              }
     1161              pm.SubmitChanges();
     1162
     1163              // add project permissions
     1164              var cpGrantedUserIds = new HashSet<Guid>(grantedUserIds);
     1165              cpGrantedUserIds.Add(p.OwnerUserId);
     1166
     1167              foreach (var id in cpGrantedUserIds) {
     1168                if (p.ProjectPermissions.All(x => x.GrantedUserId != id)) {
     1169                  p.ProjectPermissions.Add(new DA.ProjectPermission {
     1170                    GrantedUserId = id,
     1171                    GrantedByUserId = UserManager.CurrentUserId
     1172                  });
     1173                }
     1174              }
     1175            }
     1176          }
     1177          pm.SubmitChanges();
     1178        });
     1179      }
     1180    }
     1181
     1182    //private void GrantProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
     1183    //  throw new NotImplementedException();
     1184    //}
     1185
     1186    //private void RevokeProjectPermissions(Guid projectId, List<Guid> grantedUserIds, bool cascading) {
     1187    //  RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1188    //  if (projectId == null || grantedUserIds == null || !grantedUserIds.Any()) return;
     1189    //  AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1190    //  var pm = PersistenceManager;
     1191    //  using (new PerformanceLogger("RevokeProjectPermissions")) {
     1192    //    var projectPermissionDao = pm.ProjectPermissionDao;
     1193    //    var projectDao = pm.ProjectDao;
     1194    //    var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1195    //    pm.UseTransaction(() => {
     1196    //      if (cascading) {
     1197    //        var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
     1198    //        projectPermissionDao.DeleteByProjectIdsAndGrantedUserIds(childProjectIds, grantedUserIds);
     1199    //        assignedJobResourceDao.DeleteByProjectIdsAndUserIds(childProjectIds, grantedUserIds);
     1200    //      }
     1201    //      projectPermissionDao.DeleteByProjectIdAndGrantedUserIds(projectId, grantedUserIds);
     1202    //      assignedJobResourceDao.DeleteByProjectIdAndUserIds(projectId, grantedUserIds);
     1203    //      pm.SubmitChanges();
     1204    //    });
     1205    //  }
     1206    //}
     1207
     1208    public IEnumerable<DT.ProjectPermission> GetProjectPermissions(Guid projectId) {
     1209      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1210      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1211      var pm = PersistenceManager;
     1212      using (new PerformanceLogger("GetProjectPermissions")) {
     1213        var projectPermissionDao = pm.ProjectPermissionDao;
     1214        return pm.UseTransaction(() => projectPermissionDao.GetByProjectId(projectId)
    6461215          .Select(x => x.ToDto())
    6471216          .ToList()
     
    6511220    #endregion
    6521221
     1222    #region AssignedProjectResource Methods
     1223    // basic: remove and add assignments (resourceIds) to projectId and its depending jobs
     1224    // reassign: clear all assignments from project and its depending jobs, before adding new ones (resourceIds)
     1225    // cascading: "basic" mode for child-projects
     1226    // reassignCascading: "reassign" mode for child-projects
     1227    public void SaveProjectResourceAssignments(Guid projectId, List<Guid> resourceIds, bool reassign, bool cascading, bool reassignCascading) {
     1228      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1229      if (projectId == null || resourceIds == null) return;
     1230      AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
     1231      bool isAdmin = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1232      var pm = PersistenceManager;
     1233      using (new PerformanceLogger("SaveProjectResourceAssignments")) {
     1234        var projectDao = pm.ProjectDao;
     1235        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1236        var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1237        pm.UseTransaction(() => {
     1238          var project = projectDao.GetById(projectId);
     1239
     1240          var parentProjects = projectDao.GetParentProjectsById(project.ProjectId).ToList();
     1241          bool isParent = parentProjects.Select(x => x.OwnerUserId == UserManager.CurrentUserId).Any();
     1242
     1243          var assignedResources = project.AssignedProjectResources.Select(x => x.ResourceId).ToArray();
     1244          if (!isParent) resourceIds = assignedResources.ToList();
     1245          var removedAssignments = assignedResources.Except(resourceIds);
     1246
     1247          // if user is admin or owner of parent project(s)
     1248          if (isAdmin || isParent) {
     1249            // remove job and project assignments
     1250            if (reassign) {
     1251              assignedJobResourceDao.DeleteByProjectId(project.ProjectId);
     1252              project.AssignedProjectResources.Clear();
     1253            } else {
     1254              assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, removedAssignments);
     1255              foreach (var item in project.AssignedProjectResources
     1256                .Where(x => removedAssignments.Contains(x.ResourceId))
     1257                .ToList()) {
     1258                project.AssignedProjectResources.Remove(item);
     1259              }
     1260            }
     1261            pm.SubmitChanges();
     1262
     1263            // add project assignments
     1264            foreach (var id in resourceIds) {
     1265              if (project.AssignedProjectResources.All(x => x.ResourceId != id)) {
     1266                project.AssignedProjectResources.Add(new DA.AssignedProjectResource {
     1267                  ResourceId = id
     1268                });
     1269              }
     1270            }
     1271            pm.SubmitChanges();
     1272          }
     1273
     1274          // if user is admin, project owner or owner of parent projects
     1275          if (cascading) {
     1276            var childProjects = projectDao.GetChildProjectsById(projectId).ToList();
     1277            var childProjectIds = childProjects.Select(x => x.ProjectId).ToList();
     1278
     1279            // remove job assignments
     1280            if (reassignCascading) {
     1281              assignedJobResourceDao.DeleteByProjectIds(childProjectIds);
     1282            } else {
     1283              assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, removedAssignments);
     1284            }
     1285            foreach (var p in childProjects) {
     1286              var cpAssignedResources = p.AssignedProjectResources.Select(x => x.ResourceId).ToArray();
     1287              var cpRemovedAssignments = cpAssignedResources.Except(resourceIds);
     1288
     1289              // remove left-over job assignments (for non-reassignments)
     1290              if (!reassignCascading) {
     1291                assignedJobResourceDao.DeleteByProjectIdAndResourceIds(p.ProjectId, cpRemovedAssignments);
     1292              }
     1293
     1294              // remove project assignments
     1295              if (reassignCascading) {
     1296                p.AssignedProjectResources.Clear();
     1297              } else {
     1298                foreach (var item in p.AssignedProjectResources
     1299                  .Where(x => removedAssignments.Contains(x.ResourceId) || cpRemovedAssignments.Contains(x.ResourceId))
     1300                  .ToList()) {
     1301                  p.AssignedProjectResources.Remove(item);
     1302                }
     1303              }
     1304              pm.SubmitChanges();
     1305
     1306              // add project assignments
     1307              foreach (var id in resourceIds) {
     1308                if (p.AssignedProjectResources.All(x => x.ResourceId != id)) {
     1309                  p.AssignedProjectResources.Add(new DA.AssignedProjectResource {
     1310                    ResourceId = id
     1311                  });
     1312                }
     1313              }
     1314            }
     1315          }
     1316          pm.SubmitChanges();
     1317        });
     1318      }
     1319    }
     1320
     1321    //private void AssignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
     1322    //  throw new NotImplementedException();
     1323    //}
     1324
     1325    //private void UnassignProjectResources(Guid projectId, List<Guid> resourceIds, bool cascading) {
     1326    //  RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1327    //  if (projectId == null || resourceIds == null || !resourceIds.Any()) return;
     1328    //  AuthorizationManager.AuthorizeForProjectResourceAdministration(projectId, resourceIds);
     1329    //  var pm = PersistenceManager;
     1330    //  using (new PerformanceLogger("UnassignProjectResources")) {
     1331    //    var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1332    //    var assignedJobResourceDao = pm.AssignedJobResourceDao;
     1333    //    var projectDao = pm.ProjectDao;
     1334    //    pm.UseTransaction(() => {
     1335    //      if (cascading) {
     1336    //        var childProjectIds = projectDao.GetChildProjectIdsById(projectId).ToList();
     1337    //        assignedProjectResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
     1338    //        assignedJobResourceDao.DeleteByProjectIdsAndResourceIds(childProjectIds, resourceIds);
     1339    //      }
     1340    //      assignedProjectResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
     1341    //      assignedJobResourceDao.DeleteByProjectIdAndResourceIds(projectId, resourceIds);
     1342    //      pm.SubmitChanges();
     1343    //    });
     1344    //  }
     1345    //}
     1346
     1347    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProject(Guid projectId) {
     1348      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1349      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, projectId);
     1350      var pm = PersistenceManager;
     1351      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     1352        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1353        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
     1354          .Select(x => x.ToDto())
     1355          .ToList()
     1356        );
     1357      }
     1358    }
     1359
     1360    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProjectAdministration(Guid projectId) {
     1361      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1362      AuthorizationManager.AuthorizeForProjectAdministration(projectId, false);
     1363      var pm = PersistenceManager;
     1364      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     1365        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1366        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
     1367          .Select(x => x.ToDto())
     1368          .ToList()
     1369        );
     1370      }
     1371    }
     1372
     1373    public IEnumerable<DT.AssignedProjectResource> GetAssignedResourcesForProjectsAdministration(IEnumerable<Guid> projectIds) {
     1374      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1375      foreach (var id in projectIds)
     1376        AuthorizationManager.AuthorizeForProjectAdministration(id, false);
     1377
     1378      var pm = PersistenceManager;
     1379      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
     1380        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1381        var assignments = new List<DT.AssignedProjectResource>();
     1382        pm.UseTransaction(() => {
     1383          foreach (var id in projectIds) {
     1384            assignments.AddRange(assignedProjectResourceDao.GetByProjectId(id)
     1385              .Select(x => x.ToDto()));
     1386          }
     1387        });
     1388        return assignments.Distinct();
     1389      }
     1390    }
     1391
     1392    #endregion
     1393
    6531394    #region Slave Methods
    6541395    public Guid AddSlave(DT.Slave slaveDto) {
     
    6661407
    6671408    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
    668       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1409      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
    6691410      var pm = PersistenceManager;
    6701411      using (new PerformanceLogger("AddSlaveGroup")) {
     
    6901431    }
    6911432
     1433    // query granted slaves for use (i.e. to calculate on)
    6921434    public IEnumerable<DT.Slave> GetSlaves() {
    6931435      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    694       bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
    6951436      var pm = PersistenceManager;
    6961437      using (new PerformanceLogger("GetSlaves")) {
    6971438        var slaveDao = pm.SlaveDao;
    698         var resourcePermissionDao = pm.ResourcePermissionDao;
     1439        var projectDao = pm.ProjectDao;
     1440        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1441
     1442        // collect user information
    6991443        var currentUserId = UserManager.CurrentUserId;
    700         return pm.UseTransaction(() => {
    701           var resourcePermissions = resourcePermissionDao.GetAll();
    702           return slaveDao.GetAll().ToList()
    703             .Where(x => isAdministrator
    704               || x.OwnerUserId == null
    705               || x.OwnerUserId == currentUserId
    706               || UserManager.VerifyUser(currentUserId, resourcePermissions
    707                   .Where(y => y.ResourceId == x.ResourceId)
    708                   .Select(z => z.GrantedUserId)
    709                   .ToList())
    710               )
     1444        var userAndGroupIds = new List<Guid> { currentUserId };
     1445        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     1446
     1447        return pm.UseTransaction(() => {
     1448          var slaves = slaveDao.GetAll()
    7111449            .Select(x => x.ToDto())
    7121450            .ToList();
    713         });
    714       }
    715     }
    716 
     1451          var grantedProjectIds = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     1452            .Select(x => x.ProjectId)
     1453            .ToList();
     1454          var grantedResourceIds = assignedProjectResourceDao.GetAllGrantedResourcesByProjectIds(grantedProjectIds)
     1455            .Select(x => x.ResourceId)
     1456            .ToList();
     1457
     1458          return slaves
     1459            .Where(x => grantedResourceIds.Contains(x.Id))
     1460            .ToList();
     1461        });
     1462      }
     1463    }
     1464
     1465    // query granted slave groups for use (i.e. to calculate on)
    7171466    public IEnumerable<DT.SlaveGroup> GetSlaveGroups() {
    7181467      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    719       bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
    7201468      var pm = PersistenceManager;
    7211469      using (new PerformanceLogger("GetSlaveGroups")) {
    7221470        var slaveGroupDao = pm.SlaveGroupDao;
    723         var resourcePermissionDao = pm.ResourcePermissionDao;
     1471        var projectDao = pm.ProjectDao;
     1472        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1473
     1474        // collect user information
    7241475        var currentUserId = UserManager.CurrentUserId;
    725         return pm.UseTransaction(() => {
    726           var resourcePermissions = resourcePermissionDao.GetAll();
    727           return slaveGroupDao.GetAll().ToList()
    728             .Where(x => isAdministrator
    729               || x.OwnerUserId == null
    730               || x.OwnerUserId == currentUserId
    731               || UserManager.VerifyUser(currentUserId, resourcePermissions
    732                   .Where(y => y.ResourceId == x.ResourceId)
    733                   .Select(z => z.GrantedUserId)
    734                   .ToList())
    735               )
     1476        var userAndGroupIds = new List<Guid> { currentUserId };
     1477        userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
     1478
     1479        return pm.UseTransaction(() => {
     1480          var slaveGroups = slaveGroupDao.GetAll()
    7361481            .Select(x => x.ToDto())
    7371482            .ToList();
     1483          var grantedProjectIds = projectDao.GetUsageGrantedProjectsForUser(userAndGroupIds)
     1484            .Select(x => x.ProjectId)
     1485            .ToList();
     1486          var grantedResourceIds = assignedProjectResourceDao.GetAllGrantedResourcesByProjectIds(grantedProjectIds)
     1487            .Select(x => x.ResourceId)
     1488            .ToList();
     1489
     1490          return slaveGroups
     1491            .Where(x => grantedResourceIds.Contains(x.Id))
     1492            .ToList();
     1493        });
     1494      }
     1495    }
     1496
     1497    // query granted slaves for resource administration
     1498    public IEnumerable<DT.Slave> GetSlavesForAdministration() {
     1499      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1500      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1501      var pm = PersistenceManager;
     1502      using (new PerformanceLogger("GetSlavesForAdministration")) {
     1503        var slaveDao = pm.SlaveDao;
     1504        var currentUserId = UserManager.CurrentUserId;
     1505
     1506        if (isAdministrator) {
     1507          return pm.UseTransaction(() => {
     1508            return slaveDao.GetAll()
     1509              .Select(x => x.ToDto())
     1510              .ToList();
     1511          });
     1512        } else {
     1513          var slaves = slaveDao.GetAll()
     1514            .Select(x => x.ToDto())
     1515            .ToList();
     1516          var projectDao = pm.ProjectDao;
     1517          var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1518          var projects = projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).ToList();
     1519          var resourceIds = assignedProjectResourceDao
     1520            .GetAllGrantedResourcesByProjectIds(projects.Select(x => x.ProjectId).ToList())
     1521            .Select(x => x.ResourceId)
     1522            .ToList();
     1523
     1524          return slaves
     1525            .Where(x => resourceIds.Contains(x.Id))
     1526            .ToList();
     1527        }
     1528      }
     1529    }
     1530
     1531    // query granted slave groups for resource administration
     1532    public IEnumerable<DT.SlaveGroup> GetSlaveGroupsForAdministration() {
     1533      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1534      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1535      var pm = PersistenceManager;
     1536      using (new PerformanceLogger("GetSlaveGroupsForAdministration")) {
     1537        var slaveGroupDao = pm.SlaveGroupDao;
     1538        var currentUserId = UserManager.CurrentUserId;
     1539
     1540        if (isAdministrator) {
     1541          return pm.UseTransaction(() => {
     1542            return slaveGroupDao.GetAll()
     1543              .Select(x => x.ToDto())
     1544              .ToList();
     1545          });
     1546        } else {
     1547          var slaveGroups = slaveGroupDao.GetAll()
     1548            .Select(x => x.ToDto())
     1549            .ToList();
     1550          var projectDao = pm.ProjectDao;
     1551          var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
     1552          var projects = projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).ToList();
     1553          var resourceIds = assignedProjectResourceDao
     1554            .GetAllGrantedResourcesByProjectIds(projects.Select(x => x.ProjectId).ToList())
     1555            .Select(x => x.ResourceId)
     1556            .ToList();
     1557
     1558          return slaveGroups
     1559            .Where(x => resourceIds.Contains(x.Id))
     1560            .ToList();
     1561        }
     1562      }
     1563    }
     1564
     1565    public IDictionary<Guid, HashSet<Guid>> GetResourceGenealogy() {
     1566      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1567      var pm = PersistenceManager;
     1568      using (new PerformanceLogger("GetResourceGenealogy")) {
     1569        var resourceDao = pm.ResourceDao;
     1570        var resourceAncestors = new Dictionary<Guid, HashSet<Guid>>();
     1571        return pm.UseTransaction(() => {
     1572          var resources = resourceDao.GetAll().ToList();
     1573          resources.ForEach(r => resourceAncestors.Add(r.ResourceId, new HashSet<Guid>()));
     1574
     1575          foreach (var r in resources) {
     1576            var parentResource = r.ParentResource;
     1577            while (parentResource != null) {
     1578              resourceAncestors[r.ResourceId].Add(parentResource.ResourceId);
     1579              parentResource = parentResource.ParentResource;
     1580            }
     1581          }
     1582          return resourceAncestors;
     1583        });
     1584      }
     1585    }
     1586
     1587    public IDictionary<Guid, string> GetResourceNames() {
     1588      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1589      var pm = PersistenceManager;
     1590      using (new PerformanceLogger("GetResourceNames")) {
     1591        var resourceDao = pm.ResourceDao;
     1592        var resourceNames = new Dictionary<Guid, string>();
     1593        return pm.UseTransaction(() => {
     1594          resourceDao
     1595            .GetAll().ToList()
     1596            .ForEach(p => resourceNames.Add(p.ResourceId, p.Name));
     1597          return resourceNames;
    7381598        });
    7391599      }
     
    7421602    public void UpdateSlave(DT.Slave slaveDto) {
    7431603      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1604      if (slaveDto == null) return;
     1605      AuthorizationManager.AuthorizeForResourceAdministration(slaveDto.Id);
    7441606      var pm = PersistenceManager;
    7451607      using (new PerformanceLogger("UpdateSlave")) {
     
    7591621    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
    7601622      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1623      if (slaveGroupDto == null) return;
     1624      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupDto.Id);
    7611625      var pm = PersistenceManager;
    7621626      using (new PerformanceLogger("UpdateSlaveGroup")) {
     
    7751639
    7761640    public void DeleteSlave(Guid slaveId) {
     1641      if (slaveId == Guid.Empty) return;
    7771642      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    7781643      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
     
    7881653
    7891654    public void DeleteSlaveGroup(Guid slaveGroupId) {
     1655      if (slaveGroupId == Guid.Empty) return;
    7901656      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
    7911657      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
    7921658      var pm = PersistenceManager;
    7931659      using (new PerformanceLogger("DeleteSlaveGroup")) {
    794         var slaveGroupDao = pm.SlaveGroupDao;
    795         pm.UseTransaction(() => {
    796           slaveGroupDao.Delete(slaveGroupId);
     1660        var resourceDao = pm.ResourceDao;
     1661        pm.UseTransaction(() => {
     1662          var resourceIds = new HashSet<Guid> { slaveGroupId };
     1663          resourceIds.Union(resourceDao.GetChildResourceIdsById(slaveGroupId));
     1664          resourceDao.DeleteByIds(resourceIds);
    7971665          pm.SubmitChanges();
    7981666        });
     
    9461814      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
    9471815      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
     1816    }
     1817
     1818    public Dictionary<Guid, HashSet<Guid>> GetUserGroupTree() {
     1819      var userGroupTree = new Dictionary<Guid, HashSet<Guid>>();
     1820      var userGroupMapping = UserManager.GetUserGroupMapping();
     1821
     1822      foreach (var ugm in userGroupMapping) {
     1823        if (ugm.Parent == null || ugm.Child == null) continue;
     1824
     1825        if (!userGroupTree.ContainsKey(ugm.Parent)) {
     1826          userGroupTree.Add(ugm.Parent, new HashSet<Guid>());
     1827        }
     1828        userGroupTree[ugm.Parent].Add(ugm.Child);
     1829      }
     1830
     1831      return userGroupTree;
     1832    }
     1833
     1834    public bool CheckAccessToAdminAreaGranted() {
     1835      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
     1836      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
     1837      var pm = PersistenceManager;
     1838      using (new PerformanceLogger("CheckAccessToAdminAreaGranted")) {
     1839        if (isAdministrator) {
     1840          return true;
     1841        } else {
     1842          var projectDao = pm.ProjectDao;
     1843          var currentUserId = UserManager.CurrentUserId;
     1844          return projectDao.GetAdministrationGrantedProjectsForUser(currentUserId).Any();
     1845        }
     1846      }
    9481847    }
    9491848    #endregion
     
    9901889    }
    9911890
    992     private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId) {
    993       var resourceDao = pm.ResourceDao;
    994       var resource = resourceDao.GetById(resourceId);
    995       if (resource == null) throw new SecurityException("Not authorized");
    996       if (resource.OwnerUserId != UserManager.CurrentUserId
    997           && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
    998         throw new SecurityException("Not authorized");
    999       }
    1000       return resource;
     1891    private void CheckProjectAvailability(IPersistenceManager pm, Guid projectId, DateTime date) {
     1892      var projectDao = pm.ProjectDao;
     1893      using (new PerformanceLogger("UpdateJob")) {
     1894        var project = pm.UseTransaction(() => {
     1895          return projectDao.GetById(projectId);
     1896        });
     1897        if (project != null) {
     1898          if (project.StartDate > date) throw new ArgumentException("Cannot add job to specified project. The start date of the project is still in the future.");
     1899          else if (project.EndDate != null && project.EndDate < date) throw new ArgumentException("Cannot add job to specified project. The end date of the project is already reached.");
     1900        } else {
     1901          throw new ArgumentException("Cannot add job to specified project. The project seems not to be available anymore.");
     1902        }
     1903      }
     1904    }
     1905
     1906    private void EvaluateJobs(IPersistenceManager pm, IEnumerable<DT.Job> jobs) {
     1907      if (jobs == null || !jobs.Any()) return;
     1908
     1909      var currentUserId = UserManager.CurrentUserId;
     1910      var taskDao = pm.TaskDao;
     1911      var jobPermissionDao = pm.JobPermissionDao;
     1912
     1913      var statistics = taskDao.GetAll()
     1914        .Where(x => jobs.Select(y => y.Id).Contains(x.JobId))
     1915        .GroupBy(x => x.JobId)
     1916        .Select(x => new {
     1917          x.Key,
     1918          TotalCount = x.Count(),
     1919          CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
     1920          FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
     1921        })
     1922        .ToList();
     1923
     1924      foreach (var job in jobs) {
     1925        var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
     1926        if (statistic != null) {
     1927          job.JobCount = statistic.TotalCount;
     1928          job.CalculatingCount = statistic.CalculatingCount;
     1929          job.FinishedCount = statistic.FinishedCount;
     1930        }
     1931
     1932        job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
     1933
     1934        if (currentUserId == job.OwnerUserId) {
     1935          job.Permission = Permission.Full;
     1936        } else {
     1937          var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
     1938          job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
     1939        }
     1940      }
    10011941    }
    10021942    #endregion
Note: See TracChangeset for help on using the changeset viewer.