source: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs @ 15530

Last change on this file since 15530 was 15530, checked in by jzenisek, 3 years ago

#2839

  • worked on Job operations add&update
  • worked on ProjectPermission handling
  • worked on Project-Resource assignment
File size: 51.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Security;
26using System.ServiceModel;
27using HeuristicLab.Services.Access;
28using HeuristicLab.Services.Hive.DataAccess.Interfaces;
29using HeuristicLab.Services.Hive.DataTransfer;
30using HeuristicLab.Services.Hive.Manager;
31using HeuristicLab.Services.Hive.ServiceContracts;
32using DA = HeuristicLab.Services.Hive.DataAccess;
33using DT = HeuristicLab.Services.Hive.DataTransfer;
34
35namespace HeuristicLab.Services.Hive {
36  /// <summary>
37  /// Implementation of the Hive service (interface <see cref="IHiveService"/>).
38  /// We need 'IgnoreExtensionDataObject' Attribute for the slave to work.
39  /// </summary>
40  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IgnoreExtensionDataObject = true)]
41  [HiveOperationContextBehavior]
42  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
46    private static readonly DA.TaskState[] CompletedStates = { DA.TaskState.Finished, DA.TaskState.Aborted, DA.TaskState.Failed };
47
48    private IPersistenceManager PersistenceManager {
49      get { return ServiceLocator.Instance.PersistenceManager; }
50    }
51
52    private IUserManager UserManager {
53      get { return ServiceLocator.Instance.UserManager; }
54    }
55
56    private IRoleVerifier RoleVerifier {
57      get { return ServiceLocator.Instance.RoleVerifier; }
58    }
59
60    private IAuthorizationManager AuthorizationManager {
61      get { return ServiceLocator.Instance.AuthorizationManager; }
62    }
63    private IEventManager EventManager {
64      get { return ServiceLocator.Instance.EventManager; }
65    }
66    private HeartbeatManager HeartbeatManager {
67      get { return ServiceLocator.Instance.HeartbeatManager; }
68    }
69
70    #region Task Methods
71    public Guid AddTask(DT.Task task, DT.TaskData taskData, IEnumerable<Guid> resourceIds) {
72      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
73      var pm = PersistenceManager;
74      using (new PerformanceLogger("AddTask")) {
75        var taskDao = pm.TaskDao;
76        var stateLogDao = pm.StateLogDao;
77
78        var newTask = task.ToEntity();
79        newTask.JobData = taskData.ToEntity();
80        newTask.JobData.LastUpdate = DateTime.Now;
81        newTask.AssignedTaskResources.AddRange(resourceIds.Select(
82          x => new DA.AssignedTaskResource {
83            ResourceId = x
84          }));
85        newTask.State = DA.TaskState.Waiting;
86        return pm.UseTransaction(() => {
87          taskDao.Save(newTask);
88          pm.SubmitChanges();
89          stateLogDao.Save(new DA.StateLog {
90            State = DA.TaskState.Waiting,
91            DateTime = DateTime.Now,
92            TaskId = newTask.TaskId,
93            UserId = UserManager.CurrentUserId,
94            SlaveId = null,
95            Exception = null
96          });
97          pm.SubmitChanges();
98          return newTask.TaskId;
99        }, false, true);
100      }
101    }
102
103    public Guid AddTask(DT.Task task, DT.TaskData taskData) {
104      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
105      var pm = PersistenceManager;
106      using (new PerformanceLogger("AddTask")) {
107        var taskDao = pm.TaskDao;
108        var stateLogDao = pm.StateLogDao;
109        var newTask = task.ToEntity();
110        newTask.JobData = taskData.ToEntity();
111        newTask.JobData.LastUpdate = DateTime.Now;
112        newTask.State = DA.TaskState.Waiting;
113        return pm.UseTransaction(() => {
114          taskDao.Save(newTask);
115          pm.SubmitChanges();
116          stateLogDao.Save(new DA.StateLog {
117            State = DA.TaskState.Waiting,
118            DateTime = DateTime.Now,
119            TaskId = newTask.TaskId,
120            UserId = UserManager.CurrentUserId,
121            SlaveId = null,
122            Exception = null
123          });
124          pm.SubmitChanges();
125          return newTask.TaskId;
126        }, false, true);
127      }
128    }
129
130    public Guid AddChildTask(Guid parentTaskId, DT.Task task, DT.TaskData taskData) {
131      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
132      task.ParentTaskId = parentTaskId;
133      return AddTask(task, taskData);
134    }
135
136    public DT.Task GetTask(Guid taskId) {
137      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
138      AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
139      var pm = PersistenceManager;
140      using (new PerformanceLogger("GetTask")) {
141        var taskDao = pm.TaskDao;
142        return pm.UseTransaction(() => {
143          var task = taskDao.GetById(taskId);
144          return task.ToDto();
145        });
146      }
147    }
148
149    public IEnumerable<DT.LightweightTask> GetLightweightJobTasks(Guid jobId) {
150      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
151      AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
152      var pm = PersistenceManager;
153      using (new PerformanceLogger("GetLightweightJobTasks")) {
154        var taskDao = pm.TaskDao;
155        return pm.UseTransaction(() => {
156          return taskDao.GetByJobId(jobId)
157            .ToList()
158            .Select(x => new DT.LightweightTask {
159              Id = x.TaskId,
160              ExecutionTime = TimeSpan.FromMilliseconds(x.ExecutionTimeMs),
161              ParentTaskId = x.ParentTaskId,
162              StateLog = x.StateLogs.OrderBy(y => y.DateTime)
163                                    .Select(z => z.ToDto())
164                                    .ToList(),
165              State = x.State.ToDto(),
166              Command = x.Command.ToDto(),
167              LastTaskDataUpdate = x.JobData.LastUpdate
168            })
169            .ToList();
170        }, false, true);
171      }
172    }
173
174    public IEnumerable<DT.LightweightTask> GetLightweightJobTasksWithoutStateLog(Guid jobId) {
175      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
176      AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
177      var pm = PersistenceManager;
178      using (new PerformanceLogger("GetLightweightJobTasksWithoutStateLog")) {
179        var taskDao = pm.TaskDao;
180        return pm.UseTransaction(() => {
181          return taskDao.GetByJobId(jobId)
182            .ToList()
183            .Select(x => new DT.LightweightTask {
184              Id = x.TaskId,
185              ExecutionTime = TimeSpan.FromMilliseconds(x.ExecutionTimeMs),
186              ParentTaskId = x.ParentTaskId,
187              StateLog = new List<DT.StateLog>(),
188              State = x.State.ToDto(),
189              Command = x.Command.ToDto(),
190              LastTaskDataUpdate = x.JobData.LastUpdate
191            })
192            .ToList();
193        }, false, true);
194      }
195    }
196
197    public DT.TaskData GetTaskData(Guid taskId) {
198      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
199      AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
200      var pm = PersistenceManager;
201      using (new PerformanceLogger("GetTaskData")) {
202        var taskDataDao = pm.TaskDataDao;
203        return pm.UseTransaction(() => taskDataDao.GetById(taskId).ToDto());
204      }
205    }
206
207    public void UpdateTask(DT.Task taskDto) {
208      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
209      AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
210      var pm = PersistenceManager;
211      using (new PerformanceLogger("UpdateTask")) {
212        var taskDao = pm.TaskDao;
213        pm.UseTransaction(() => {
214          var task = taskDao.GetById(taskDto.Id);
215          taskDto.CopyToEntity(task);
216          pm.SubmitChanges();
217        });
218      }
219    }
220
221    public void UpdateTaskData(DT.Task taskDto, DT.TaskData taskDataDto) {
222      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
223      AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
224      var pm = PersistenceManager;
225      using (new PerformanceLogger("UpdateTaskData")) {
226        var taskDao = pm.TaskDao;
227        var taskDataDao = pm.TaskDataDao;
228        pm.UseTransaction(() => {
229          var task = taskDao.GetById(taskDto.Id);
230          var taskData = taskDataDao.GetById(taskDataDto.TaskId);
231          taskDto.CopyToEntity(task);
232          taskDataDto.CopyToEntity(taskData);
233          taskData.LastUpdate = DateTime.Now;
234          pm.SubmitChanges();
235        });
236      }
237    }
238
239    public DT.Task UpdateTaskState(Guid taskId, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
240      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
241      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
242      var pm = PersistenceManager;
243      using (new PerformanceLogger("UpdateTaskState")) {
244        var taskDao = pm.TaskDao;
245        return pm.UseTransaction(() => {
246          var task = taskDao.GetById(taskId);
247          UpdateTaskState(pm, task, taskState, slaveId, userId, exception);
248          pm.SubmitChanges();
249          return task.ToDto();
250        });
251      }
252    }
253    #endregion
254
255    #region Task Control Methods
256    public void StopTask(Guid taskId) {
257      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
258      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
259      var pm = PersistenceManager;
260      using (new PerformanceLogger("StopTask")) {
261        var taskDao = pm.TaskDao;
262        pm.UseTransaction(() => {
263          var task = taskDao.GetById(taskId);
264          if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
265            task.Command = DA.Command.Stop;
266          } else if (task.State != DA.TaskState.Aborted
267                     && task.State != DA.TaskState.Finished
268                     && task.State != DA.TaskState.Failed) {
269            UpdateTaskState(pm, task, DT.TaskState.Aborted, null, null, string.Empty);
270          }
271          pm.SubmitChanges();
272        });
273      }
274    }
275
276    public void PauseTask(Guid taskId) {
277      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
278      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
279      var pm = PersistenceManager;
280      using (new PerformanceLogger("PauseTask")) {
281        var taskDao = pm.TaskDao;
282        pm.UseTransaction(() => {
283          var task = taskDao.GetById(taskId);
284          if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
285            task.Command = DA.Command.Pause;
286          } else if (task.State != DA.TaskState.Paused
287                     && task.State != DA.TaskState.Aborted
288                     && task.State != DA.TaskState.Finished
289                     && task.State != DA.TaskState.Failed) {
290            UpdateTaskState(pm, task, DT.TaskState.Paused, null, null, string.Empty);
291          }
292          pm.SubmitChanges();
293        });
294      }
295    }
296
297    public void RestartTask(Guid taskId) {
298      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
299      AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
300      var pm = PersistenceManager;
301      using (new PerformanceLogger("RestartTask")) {
302        var taskDao = pm.TaskDao;
303        pm.UseTransaction(() => {
304          var task = taskDao.GetById(taskId);
305          task.Command = null;
306          UpdateTaskState(pm, task, DT.TaskState.Waiting, null, UserManager.CurrentUserId, string.Empty);
307          pm.SubmitChanges();
308        });
309      }
310    }
311    #endregion
312
313    #region Job Methods
314    public DT.Job GetJob(Guid id) {
315      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
316      AuthorizationManager.AuthorizeForJob(id, DT.Permission.Read);
317      var pm = PersistenceManager;
318      using (new PerformanceLogger("GetJob")) {
319        var jobDao = pm.JobDao;
320        var jobPermissionDao = pm.JobPermissionDao;
321        var taskDao = pm.TaskDao;
322        var currentUserId = UserManager.CurrentUserId;
323        return pm.UseTransaction(() => {
324          var job = jobDao.GetById(id).ToDto();
325          if (job != null) {
326            var statistics = taskDao.GetByJobId(job.Id)
327              .GroupBy(x => x.JobId)
328              .Select(x => new {
329                TotalCount = x.Count(),
330                CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
331                FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
332              }).FirstOrDefault();
333            if (statistics != null) {
334              job.JobCount = statistics.TotalCount;
335              job.CalculatingCount = statistics.CalculatingCount;
336              job.FinishedCount = statistics.FinishedCount;
337            }
338            job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
339            if (currentUserId == job.OwnerUserId) {
340              job.Permission = Permission.Full;
341            } else {
342              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
343              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
344            }
345          }
346          return job;
347        });
348      }
349    }
350
351    public IEnumerable<DT.Job> GetJobs() {
352      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
353      var pm = PersistenceManager;
354      using (new PerformanceLogger("GetJobs")) {
355        var jobDao = pm.JobDao;
356        var jobPermissionDao = pm.JobPermissionDao;
357        var taskDao = pm.TaskDao;
358        var currentUserId = UserManager.CurrentUserId;
359        return pm.UseTransaction(() => {
360          var jobs = jobDao.GetAll()
361            .Where(x => x.OwnerUserId == currentUserId
362                     || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
363                                                 && y.GrantedUserId == currentUserId) > 0)
364            .Select(x => x.ToDto())
365            .ToList();
366          var statistics = taskDao.GetAll()
367              .GroupBy(x => x.JobId)
368              .Select(x => new {
369                x.Key,
370                TotalCount = x.Count(),
371                CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
372                FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
373              })
374              .ToList();
375          foreach (var job in jobs) {
376            var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
377            if (statistic != null) {
378              job.JobCount = statistic.TotalCount;
379              job.CalculatingCount = statistic.CalculatingCount;
380              job.FinishedCount = statistic.FinishedCount;
381            }
382            job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
383            if (currentUserId == job.OwnerUserId) {
384              job.Permission = Permission.Full;
385            } else {
386              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
387              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
388            }
389          }
390          return jobs;
391        });
392      }
393    }
394
395    public Guid AddJob(DT.Job jobDto) {
396      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
397      var pm = PersistenceManager;
398      using (new PerformanceLogger("AddJob")) {
399        var jobDao = pm.JobDao;
400        var userPriorityDao = pm.UserPriorityDao;
401        return pm.UseTransaction(() => {
402          jobDto.OwnerUserId = UserManager.CurrentUserId;
403          jobDto.DateCreated = DateTime.Now;
404          var job = jobDao.Save(jobDto.ToEntity());
405          if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
406            userPriorityDao.Save(new DA.UserPriority {
407              UserId = jobDto.OwnerUserId,
408              DateEnqueued = jobDto.DateCreated
409            });
410          }
411          pm.SubmitChanges();
412          return job.JobId;
413        });
414      }
415    }
416
417    public Guid AddJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
418      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
419      // check user - project
420      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
421      // check project - resources
422      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
423      var pm = PersistenceManager;
424      using (new PerformanceLogger("AddJob")) {
425        var jobDao = pm.JobDao;
426        var userPriorityDao = pm.UserPriorityDao;
427
428        return pm.UseTransaction(() => {
429          var newJob = jobDto.ToEntity();
430          newJob.OwnerUserId = UserManager.CurrentUserId;
431          newJob.DateCreated = DateTime.Now;
432
433          // add resource assignments
434          newJob.AssignedJobResources.AddRange(resourceIds.Select(
435            x => new DA.AssignedJobResource {
436              ResourceId = x
437          }));
438 
439          var job = jobDao.Save(newJob);
440          if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
441            userPriorityDao.Save(new DA.UserPriority {
442              UserId = jobDto.OwnerUserId,
443              DateEnqueued = jobDto.DateCreated
444            });
445          }
446          pm.SubmitChanges();
447          return job.JobId;
448        });
449      }
450    }
451
452    public void UpdateJob(DT.Job jobDto) {
453      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
454      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
455      var pm = PersistenceManager;
456      using (new PerformanceLogger("UpdateJob")) {
457        bool exists = true;
458        var jobDao = pm.JobDao;
459        pm.UseTransaction(() => {
460          var job = jobDao.GetById(jobDto.Id);
461          if (job == null) {
462            exists = false;
463            job = new DA.Job();
464          }
465          jobDto.CopyToEntity(job);
466          if (!exists) {
467            jobDao.Save(job);
468          }
469          pm.SubmitChanges();
470        });
471      }
472    }
473
474    public void UpdateJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
475      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
476      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
477      // check user - project permission
478      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
479      // check project - resources permission
480      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
481
482      var pm = PersistenceManager;
483      using (new PerformanceLogger("UpdateJob")) {
484        bool exists = true;
485        var jobDao = pm.JobDao;
486        pm.UseTransaction(() => {
487          var job = jobDao.GetById(jobDto.Id);
488          if (job == null) {
489            exists = false;
490            job = new DA.Job();
491          }
492          jobDto.CopyToEntity(job);
493
494          // remove former resource assignments
495          job.AssignedJobResources.Clear();
496          // add resource assignments
497          job.AssignedJobResources.AddRange(resourceIds.Select(
498            x => new DA.AssignedJobResource {
499              ResourceId = x
500          }));
501
502          if (!exists) {
503            jobDao.Save(job);
504          }
505          pm.SubmitChanges();
506        });
507      }
508    }
509
510    public void DeleteJob(Guid jobId) {
511      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
512      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
513      var pm = PersistenceManager;
514      using (new PerformanceLogger("DeleteJob")) {
515        var jobDao = pm.JobDao;
516        pm.UseTransaction(() => {
517          // child task will be deleted by db-trigger
518          jobDao.Delete(jobId);
519          pm.SubmitChanges();
520        });
521      }
522    }
523    #endregion
524
525    #region JobPermission Methods
526    public void GrantPermission(Guid jobId, Guid grantedUserId, DT.Permission permission) {
527      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
528      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
529      var pm = PersistenceManager;
530      using (new PerformanceLogger("GrantPermission")) {
531        var jobPermissionDao = pm.JobPermissionDao;
532        var currentUserId = UserManager.CurrentUserId;
533        pm.UseTransaction(() => {
534          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, permission.ToEntity());
535          pm.SubmitChanges();
536        });
537      }
538    }
539
540    public void RevokePermission(Guid jobId, Guid grantedUserId) {
541      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
542      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
543      var pm = PersistenceManager;
544      using (new PerformanceLogger("RevokePermission")) {
545        var jobPermissionDao = pm.JobPermissionDao;
546        var currentUserId = UserManager.CurrentUserId;
547        pm.UseTransaction(() => {
548          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, DA.Permission.NotAllowed);
549          pm.SubmitChanges();
550        });
551      }
552    }
553
554    public IEnumerable<JobPermission> GetJobPermissions(Guid jobId) {
555      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
556      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
557      var pm = PersistenceManager;
558      using (new PerformanceLogger("GetJobPermissions")) {
559        var jobPermissionDao = pm.JobPermissionDao;
560        return pm.UseTransaction(() => jobPermissionDao.GetByJobId(jobId)
561          .Select(x => x.ToDto())
562          .ToList()
563        );
564      }
565    }
566
567    // BackwardsCompatibility3.3
568    #region Backwards compatible code, remove with 3.4
569    public bool IsAllowedPrivileged() {
570      return true;
571    }
572    #endregion
573    #endregion
574
575    #region Login Methods
576    public void Hello(DT.Slave slaveInfo) {
577      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
578      if (UserManager.CurrentUser.UserName != "hiveslave") {
579        slaveInfo.OwnerUserId = UserManager.CurrentUserId;
580      }
581      var pm = PersistenceManager;
582      using (new PerformanceLogger("Hello")) {
583        var slaveDao = pm.SlaveDao;
584        pm.UseTransaction(() => {
585          var slave = slaveDao.GetById(slaveInfo.Id);
586          if (slave == null) {
587            slaveDao.Save(slaveInfo.ToEntity());
588          } else {
589            bool oldIsAllowedToCalculate = slave.IsAllowedToCalculate;
590            Guid? oldParentResourceId = slave.ParentResourceId;
591            slaveInfo.CopyToEntity(slave);
592            slave.IsAllowedToCalculate = oldIsAllowedToCalculate;
593            slave.ParentResourceId = oldParentResourceId;
594            slave.LastHeartbeat = DateTime.Now;
595            slave.SlaveState = DA.SlaveState.Idle;
596          }
597          pm.SubmitChanges();
598        });
599      }
600    }
601
602    public void GoodBye(Guid slaveId) {
603      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
604      var pm = PersistenceManager;
605      using (new PerformanceLogger("GoodBye")) {
606        var slaveDao = pm.SlaveDao;
607        pm.UseTransaction(() => {
608          var slave = slaveDao.GetById(slaveId);
609          if (slave != null) {
610            slave.SlaveState = DA.SlaveState.Offline;
611            pm.SubmitChanges();
612          }
613        });
614      }
615    }
616    #endregion
617
618    #region Heartbeat Methods
619    public List<MessageContainer> Heartbeat(DT.Heartbeat heartbeat) {
620      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
621      List<MessageContainer> result = new List<MessageContainer>();
622      try {
623        using (new PerformanceLogger("ProcessHeartbeat")) {
624          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
625        }
626      } catch (Exception ex) {
627        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
628      }
629      if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
630        TriggerEventManager(false);
631      }
632      return result;
633    }
634    #endregion
635
636    #region Plugin Methods
637    public DT.Plugin GetPlugin(Guid pluginId) {
638      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
639      var pm = PersistenceManager;
640      using (new PerformanceLogger("GetPlugin")) {
641        var pluginDao = pm.PluginDao;
642        return pm.UseTransaction(() => pluginDao.GetById(pluginId).ToDto());
643      }
644    }
645
646    public Guid AddPlugin(DT.Plugin plugin, List<DT.PluginData> pluginData) {
647      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
648      var pm = PersistenceManager;
649      using (new PerformanceLogger("AddPlugin")) {
650        var pluginDao = pm.PluginDao;
651        plugin.UserId = UserManager.CurrentUserId;
652        plugin.DateCreated = DateTime.Now;
653        return pm.UseTransaction(() => {
654          var pluginEntity = pluginDao.GetByHash(plugin.Hash).SingleOrDefault();
655          if (pluginEntity != null) {
656            throw new FaultException<PluginAlreadyExistsFault>(new PluginAlreadyExistsFault(pluginEntity.PluginId));
657          }
658          pluginEntity = plugin.ToEntity();
659          foreach (var data in pluginData) {
660            data.PluginId = default(Guid); // real id will be assigned from linq2sql
661            pluginEntity.PluginData.Add(data.ToEntity());
662          }
663          pluginDao.Save(pluginEntity);
664          pm.SubmitChanges();
665          return pluginEntity.PluginId;
666        });
667      }
668    }
669
670    public IEnumerable<DT.Plugin> GetPlugins() {
671      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
672      var pm = PersistenceManager;
673      using (new PerformanceLogger("GetPlugins")) {
674        var pluginDao = pm.PluginDao;
675        return pm.UseTransaction(() => pluginDao.GetAll()
676          .Where(x => x.Hash != null)
677          .Select(x => x.ToDto())
678          .ToList()
679        );
680      }
681    }
682
683    public IEnumerable<DT.PluginData> GetPluginDatas(List<Guid> pluginIds) {
684      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
685      var pm = PersistenceManager;
686      using (new PerformanceLogger("GetPluginDatas")) {
687        var pluginDataDao = pm.PluginDataDao;
688        return pm.UseTransaction(() => pluginDataDao.GetAll()
689            .Where(x => pluginIds.Contains(x.PluginId))
690            .Select(x => x.ToDto())
691            .ToList()
692        );
693      }
694    }
695    #endregion
696
697    #region Project Methods
698    public Guid AddProject(DT.Project projectDto) {
699      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
700      var pm = PersistenceManager;
701      using (new PerformanceLogger("AddProject")) {
702        var projectDao = pm.ProjectDao;
703        return pm.UseTransaction(() => {
704          var project = projectDao.Save(projectDto.ToEntity());
705          pm.SubmitChanges();
706          return project.ProjectId;
707        });
708      }
709    }
710
711    public void UpdateProject(DT.Project projectDto) {
712      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
713      var pm = PersistenceManager;
714      using (new PerformanceLogger("UpdateProject")) {
715        var projectDao = pm.ProjectDao;
716        pm.UseTransaction(() => {
717          var project = projectDao.GetById(projectDto.Id);
718          if (project != null) {
719            projectDto.CopyToEntity(project);
720          } else {
721            projectDao.Save(projectDto.ToEntity());
722          }
723          pm.SubmitChanges();
724        });
725      }
726    }
727
728    public void DeleteProject(Guid projectId) {
729      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
730      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
731      var pm = PersistenceManager;
732      using (new PerformanceLogger("DeleteProject")) {
733        var projectDao = pm.ProjectDao;
734        pm.UseTransaction(() => {
735          projectDao.Delete(projectId);
736          pm.SubmitChanges();
737        });
738      }
739    }
740
741    public DT.Project GetProject(Guid projectId) {
742      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
743      var pm = PersistenceManager;
744      using (new PerformanceLogger("GetProject")) {
745        var projectDao = pm.ProjectDao;
746        return pm.UseTransaction(() => projectDao.GetById(projectId).ToDto());
747      }
748    }
749
750    public IEnumerable<DT.Project> GetProjects() {
751      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
752      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
753      var pm = PersistenceManager;
754      using (new PerformanceLogger("GetProjects")) {
755        var projectDao = pm.ProjectDao;
756        var projectPermissionDao = pm.ProjectPermissionDao;
757        var currentUserId = UserManager.CurrentUserId;
758        return pm.UseTransaction(() => {
759          var projectPermissions = projectPermissionDao.GetAll();
760          return projectDao.GetAll().ToList()
761            .Where(x => isAdministrator
762              || x.OwnerUserId == currentUserId
763              || UserManager.VerifyUser(currentUserId, projectPermissions
764                  .Where(y => y.ProjectId == x.ProjectId)
765                  .Select(z => z.GrantedUserId)
766                  .ToList())
767              )
768            .Select(x => x.ToDto())
769            .ToList();
770        });
771      }
772    }
773    #endregion
774
775    #region ProjectPermission Methods
776    public void GrantProjectPermissions(Guid projectId, Guid[] grantedUserIds, bool cascading) {
777      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
778      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
779      var pm = PersistenceManager;
780      using (new PerformanceLogger("GrantProjectPermissions")) {
781        var projectDao = pm.ProjectDao;
782       
783        pm.UseTransaction(() => {
784          var project = projectDao.GetById(projectId);
785          var projectPermissions = project.ProjectPermissions.ToList();
786          foreach (var id in grantedUserIds) {
787            if (projectPermissions.All(x => x.GrantedUserId != id)) {
788              project.ProjectPermissions.Add(new DA.ProjectPermission {
789                GrantedUserId = id,
790                GrantedByUserId = UserManager.CurrentUserId
791              });
792            }
793          }
794          if(cascading) {
795            var childProjects = projectDao.GetChildProjectsById(projectId);
796            foreach (var p in childProjects) {
797              p.ProjectPermissions.Clear();
798              foreach (var id in grantedUserIds) {
799                p.ProjectPermissions.Add(new DA.ProjectPermission {
800                  GrantedUserId = id,
801                  GrantedByUserId = UserManager.CurrentUserId
802                });
803              }
804            }
805          }
806          pm.SubmitChanges();
807        });
808      }
809    }
810
811    public void RevokeProjectPermissions(Guid projectId, Guid[] grantedUserIds, bool cascading) {
812      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
813      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
814      var pm = PersistenceManager;
815      using (new PerformanceLogger("RevokeProjectPermissions")) {
816        var projectPermissionDao = pm.ProjectPermissionDao;
817        var projectDao = pm.ProjectDao;
818        pm.UseTransaction(() => {
819          if(cascading) {
820            var childProjectIds = projectDao.GetChildProjectIdsById(projectId);
821            projectPermissionDao.DeleteByProjectIdsAndGrantedUserIds(childProjectIds, grantedUserIds);
822          }
823          projectPermissionDao.DeleteByProjectIdAndGrantedUserIds(projectId, grantedUserIds);
824          pm.SubmitChanges();
825        });
826      }
827    }
828
829    public IEnumerable<DT.ProjectPermission> GetProjectPermissions(Guid projectId) {
830      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
831      var pm = PersistenceManager;
832      using (new PerformanceLogger("GetProjectPermissions")) {
833        var projectPermissionDao = pm.ProjectPermissionDao;
834        return pm.UseTransaction(() => projectPermissionDao.GetByProjectId(projectId)
835          .Select(x => x.ToDto())
836          .ToList()
837        );
838      }
839    }
840    #endregion
841
842    #region AssignedProjectResource Methods
843    public void AssignProjectResources(Guid projectId, Guid[] resourceIds) {
844      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
845      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
846      var pm = PersistenceManager;
847      using (new PerformanceLogger("AssignProjectResources")) {
848        var projectDao = pm.ProjectDao;
849        pm.UseTransaction(() => {
850          var project = projectDao.GetById(projectId);
851          var assignedProjectResources = project.AssignedProjectResources.ToList();
852
853          // TODO-JAN
854          if (!RoleVerifier.IsInRole(HiveRoles.Administrator))
855            AuthorizeForResources(pm, project, resourceIds);
856
857          foreach (var id in resourceIds) {
858            if (assignedProjectResources.All(x => x.ResourceId != id)) {
859              project.AssignedProjectResources.Add(new DA.AssignedProjectResource {
860                ResourceId = id
861              });
862            }
863          }
864          pm.SubmitChanges();
865        });
866      }
867    }
868
869    public void UnassignProjectResources(Guid projectId, Guid[] resourceIds) {
870      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
871      AuthorizationManager.AuthorizeForProjectAdministration(projectId);
872      // TODO-JAN: adjust Authorization Method
873      // only users who are owners of a parent project of projectId are allowed to manage resources
874      // these users can only those resources which are already assigned to
875      // (1) the nearest parent they own
876      // (2) to any of the parent they own
877      var pm = PersistenceManager;
878      using (new PerformanceLogger("UnassignProjectResources")) {
879        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
880        pm.UseTransaction(() => {
881          assignedProjectResourceDao.DeleteByProjectAndGrantedUserId(projectId, resourceIds);
882          pm.SubmitChanges();
883        });
884      }
885    }
886
887    public IEnumerable<AssignedProjectResource> GetAssignedResourcesForProject(Guid projectId) {
888      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
889      var pm = PersistenceManager;
890      using (new PerformanceLogger("GetAssignedResourcesForProject")) {
891        var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
892        return pm.UseTransaction(() => assignedProjectResourceDao.GetByProjectId(projectId)
893          .Select(x => x.ToDto())
894          .ToList()
895        );
896      }
897    }
898    #endregion
899
900    #region Slave Methods
901    public Guid AddSlave(DT.Slave slaveDto) {
902      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
903      var pm = PersistenceManager;
904      using (new PerformanceLogger("AddSlave")) {
905        var slaveDao = pm.SlaveDao;
906        return pm.UseTransaction(() => {
907          var slave = slaveDao.Save(slaveDto.ToEntity());
908          pm.SubmitChanges();
909          return slave.ResourceId;
910        });
911      }
912    }
913
914    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
915      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
916      var pm = PersistenceManager;
917      using (new PerformanceLogger("AddSlaveGroup")) {
918        var slaveGroupDao = pm.SlaveGroupDao;
919        return pm.UseTransaction(() => {
920          if (slaveGroupDto.Id == Guid.Empty) {
921            slaveGroupDto.Id = Guid.NewGuid();
922          }
923          var slaveGroup = slaveGroupDao.Save(slaveGroupDto.ToEntity());
924          pm.SubmitChanges();
925          return slaveGroup.ResourceId;
926        });
927      }
928    }
929
930    public DT.Slave GetSlave(Guid slaveId) {
931      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
932      var pm = PersistenceManager;
933      using (new PerformanceLogger("GetSlave")) {
934        var slaveDao = pm.SlaveDao;
935        return pm.UseTransaction(() => slaveDao.GetById(slaveId).ToDto());
936      }
937    }
938
939    public IEnumerable<DT.Slave> GetSlaves() {
940      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
941      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
942      var pm = PersistenceManager;
943      using (new PerformanceLogger("GetSlaves")) {
944        var slaveDao = pm.SlaveDao;
945        var resourcePermissionDao = pm.ProjectPermissionDao;
946        var currentUserId = UserManager.CurrentUserId;
947        return pm.UseTransaction(() => {
948          var resourcePermissions = resourcePermissionDao.GetAll();
949          return slaveDao.GetAll().ToList()
950            .Where(x => isAdministrator
951              || x.OwnerUserId == null
952              || x.OwnerUserId == currentUserId
953              || UserManager.VerifyUser(currentUserId, resourcePermissions
954                  //.Where(y => y.ResourceId == x.ResourceId)
955                  .Select(z => z.GrantedUserId)
956                  .ToList())
957              )
958            .Select(x => x.ToDto())
959            .ToList();
960        });
961      }
962    }
963
964    public IEnumerable<DT.SlaveGroup> GetSlaveGroups() {
965      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
966      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
967      var pm = PersistenceManager;
968      using (new PerformanceLogger("GetSlaveGroups")) {
969        var slaveGroupDao = pm.SlaveGroupDao;
970        var resourcePermissionDao = pm.ProjectPermissionDao;
971        var currentUserId = UserManager.CurrentUserId;
972        return pm.UseTransaction(() => {
973          var resourcePermissions = resourcePermissionDao.GetAll();
974          return slaveGroupDao.GetAll().ToList()
975            .Where(x => isAdministrator
976              || x.OwnerUserId == null
977              || x.OwnerUserId == currentUserId
978              || UserManager.VerifyUser(currentUserId, resourcePermissions
979                  //.Where(y => y.ResourceId == x.ResourceId)
980                  .Select(z => z.GrantedUserId)
981                  .ToList())
982              )
983            .Select(x => x.ToDto())
984            .ToList();
985        });
986      }
987    }
988
989    public void UpdateSlave(DT.Slave slaveDto) {
990      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
991      var pm = PersistenceManager;
992      using (new PerformanceLogger("UpdateSlave")) {
993        var slaveDao = pm.SlaveDao;
994        pm.UseTransaction(() => {
995          var slave = slaveDao.GetById(slaveDto.Id);
996          if (slave != null) {
997            slaveDto.CopyToEntity(slave);
998          } else {
999            slaveDao.Save(slaveDto.ToEntity());
1000          }
1001          pm.SubmitChanges();
1002        });
1003      }
1004    }
1005
1006    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
1007      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1008      var pm = PersistenceManager;
1009      using (new PerformanceLogger("UpdateSlaveGroup")) {
1010        var slaveGroupDao = pm.SlaveGroupDao;
1011        pm.UseTransaction(() => {
1012          var slaveGroup = slaveGroupDao.GetById(slaveGroupDto.Id);
1013          if (slaveGroup != null) {
1014            slaveGroupDto.CopyToEntity(slaveGroup);
1015          } else {
1016            slaveGroupDao.Save(slaveGroupDto.ToEntity());
1017          }
1018          pm.SubmitChanges();
1019        });
1020      }
1021    }
1022
1023    public void DeleteSlave(Guid slaveId) {
1024      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1025      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
1026      var pm = PersistenceManager;
1027      using (new PerformanceLogger("DeleteSlave")) {
1028        var slaveDao = pm.SlaveDao;
1029        pm.UseTransaction(() => {
1030          slaveDao.Delete(slaveId);
1031          pm.SubmitChanges();
1032        });
1033      }
1034    }
1035
1036    public void DeleteSlaveGroup(Guid slaveGroupId) {
1037      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1038      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
1039      var pm = PersistenceManager;
1040      using (new PerformanceLogger("DeleteSlaveGroup")) {
1041        var slaveGroupDao = pm.SlaveGroupDao;
1042        pm.UseTransaction(() => {
1043          slaveGroupDao.Delete(slaveGroupId);
1044          pm.SubmitChanges();
1045        });
1046      }
1047    }
1048
1049    public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
1050      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1051      var pm = PersistenceManager;
1052      using (new PerformanceLogger("AddResourceToGroup")) {
1053        var resourceDao = pm.ResourceDao;
1054        pm.UseTransaction(() => {
1055          var resource = resourceDao.GetById(resourceId);
1056          resource.ParentResourceId = slaveGroupId;
1057          pm.SubmitChanges();
1058        });
1059      }
1060    }
1061
1062    public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
1063      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1064      var pm = PersistenceManager;
1065      using (new PerformanceLogger("RemoveResourceFromGroup")) {
1066        var resourceDao = pm.ResourceDao;
1067        pm.UseTransaction(() => {
1068          var resource = resourceDao.GetById(resourceId);
1069          resource.ParentResourceId = null;
1070          pm.SubmitChanges();
1071        });
1072      }
1073    }
1074
1075    public Guid GetResourceId(string resourceName) {
1076      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1077      var pm = PersistenceManager;
1078      using (new PerformanceLogger("GetResourceId")) {
1079        var resourceDao = pm.ResourceDao;
1080        return pm.UseTransaction(() => {
1081          var resource = resourceDao.GetByName(resourceName);
1082          return resource != null ? resource.ResourceId : Guid.Empty;
1083        });
1084      }
1085    }
1086
1087    public void TriggerEventManager(bool force) {
1088      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
1089      // use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
1090      bool cleanup;
1091      var pm = PersistenceManager;
1092      using (new PerformanceLogger("TriggerEventManager")) {
1093        cleanup = false;
1094        var lifecycleDao = pm.LifecycleDao;
1095        pm.UseTransaction(() => {
1096          var lastLifecycle = lifecycleDao.GetLastLifecycle();
1097          DateTime lastCleanup = lastLifecycle != null ? lastLifecycle.LastCleanup : DateTime.MinValue;
1098          if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
1099            lifecycleDao.UpdateLifecycle();
1100            cleanup = true;
1101            pm.SubmitChanges();
1102          }
1103        }, true);
1104      }
1105      if (cleanup) {
1106        EventManager.Cleanup();
1107      }
1108    }
1109
1110    public int GetNewHeartbeatInterval(Guid slaveId) {
1111      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
1112      var pm = PersistenceManager;
1113      using (new PerformanceLogger("GetNewHeartbeatInterval")) {
1114        var slaveDao = pm.SlaveDao;
1115        return pm.UseTransaction(() => {
1116          var slave = slaveDao.GetById(slaveId);
1117          if (slave != null) {
1118            return slave.HbInterval;
1119          }
1120          return -1;
1121        });
1122      }
1123    }
1124    #endregion
1125
1126    #region Downtime Methods
1127    public Guid AddDowntime(DT.Downtime downtimeDto) {
1128      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1129      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
1130      var pm = PersistenceManager;
1131      using (new PerformanceLogger("AddDowntime")) {
1132        var downtimeDao = pm.DowntimeDao;
1133        return pm.UseTransaction(() => {
1134          var downtime = downtimeDao.Save(downtimeDto.ToEntity());
1135          pm.SubmitChanges();
1136          return downtime.ResourceId;
1137        });
1138      }
1139    }
1140
1141    public void DeleteDowntime(Guid downtimeId) {
1142      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1143      var pm = PersistenceManager;
1144      using (new PerformanceLogger("DeleteDowntime")) {
1145        var downtimeDao = pm.DowntimeDao;
1146        pm.UseTransaction(() => {
1147          downtimeDao.Delete(downtimeId);
1148          pm.SubmitChanges();
1149        });
1150      }
1151    }
1152
1153    public void UpdateDowntime(DT.Downtime downtimeDto) {
1154      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1155      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
1156      var pm = PersistenceManager;
1157      using (new PerformanceLogger("UpdateDowntime")) {
1158        var downtimeDao = pm.DowntimeDao;
1159        pm.UseTransaction(() => {
1160          var downtime = downtimeDao.GetById(downtimeDto.Id);
1161          if (downtime != null) {
1162            downtimeDto.CopyToEntity(downtime);
1163          } else {
1164            downtimeDao.Save(downtimeDto.ToEntity());
1165          }
1166          pm.SubmitChanges();
1167        });
1168      }
1169    }
1170
1171    public IEnumerable<DT.Downtime> GetDowntimesForResource(Guid resourceId) {
1172      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1173      var pm = PersistenceManager;
1174      using (new PerformanceLogger("GetDowntimesForResource")) {
1175        var downtimeDao = pm.DowntimeDao;
1176        return pm.UseTransaction(() => downtimeDao.GetByResourceId(resourceId)
1177          .Select(x => x.ToDto())
1178          .ToList()
1179        );
1180      }
1181    }
1182    #endregion
1183
1184    #region User Methods
1185    public string GetUsernameByUserId(Guid userId) {
1186      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1187      var user = UserManager.GetUserById(userId);
1188      return user != null ? user.UserName : null;
1189    }
1190
1191    public Guid GetUserIdByUsername(string username) {
1192      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
1193      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
1194      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
1195    }
1196    #endregion
1197
1198    #region UserPriorities Methods
1199    public IEnumerable<DT.UserPriority> GetUserPriorities() {
1200      var pm = PersistenceManager;
1201      using (new PerformanceLogger("GetUserPriorities")) {
1202        var userPriorityDao = pm.UserPriorityDao;
1203        return pm.UseTransaction(() => userPriorityDao.GetAll()
1204          .Select(x => x.ToDto())
1205          .ToList()
1206        );
1207      }
1208    }
1209    #endregion
1210
1211    #region Private Helper Methods
1212    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
1213      var stateLogDao = pm.StateLogDao;
1214      var taskStateEntity = taskState.ToEntity();
1215
1216      if (task.State == DA.TaskState.Transferring && taskStateEntity == DA.TaskState.Paused && task.Command == null) {
1217        // slave paused and uploaded the task (no user-command) -> set waiting.
1218        taskStateEntity = DA.TaskState.Waiting;
1219      }
1220
1221      stateLogDao.Save(new DA.StateLog {
1222        State = taskStateEntity,
1223        DateTime = DateTime.Now,
1224        TaskId = task.TaskId,
1225        UserId = userId,
1226        SlaveId = slaveId,
1227        Exception = exception
1228      });
1229
1230      task.State = taskStateEntity;
1231
1232      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
1233          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
1234          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
1235        task.Command = null;
1236      }
1237    }
1238
1239    // Check if the current user is authorized to administer resourceIds
1240    private void AuthorizeForResource(IPersistenceManager pm, DA.Project project, Guid[] resourceIds) {
1241      var projectDao = pm.ProjectDao;
1242      var resourceDao = pm.ResourceDao;
1243
1244      var projectBranch = new List<DA.Project> { project };
1245      projectBranch.AddRange(projectDao.GetParentProjectsById(project.ProjectId));
1246      var ownedProjects = projectBranch.Where(x => x.OwnerUserId == UserManager.CurrentUserId).ToList();
1247
1248      // get all assigned resourceIds (including children) of owned projects in this branch
1249      var assignedResourceIds = ownedProjects.SelectMany(x => x.AssignedProjectResources).Select(x => x.ResourceId).ToList();
1250      var assignedChildResourceIds = assignedResourceIds.SelectMany(x => resourceDao.GetParentResourceIdsById(x));
1251      assignedResourceIds.AddRange(assignedChildResourceIds);
1252
1253      // look up if all resourceIds are among the assigned ones
1254      if (resourceIds.Except(assignedResourceIds).Any()) {
1255        throw new SecurityException(NOT_AUTHORIZED_RESOURCE);
1256      }
1257    }
1258
1259    // Check if the current user is authorized (i.e. is owner of the (sub)project) to set permissions
1260    // for a certain resource (resourceId) in the context of a certain project (projectId)
1261    private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId, Guid projectId) {
1262      var projectDao = pm.ProjectDao;
1263      var project = projectDao.GetById(projectId);
1264      if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT); // if project does not exist
1265
1266      var resourceDao = pm.ResourceDao;
1267      var resource = resourceDao.GetById(resourceId);
1268      if (resource == null) throw new SecurityException(NOT_AUTHORIZED_RESOURCE); // if resource does not exist
1269
1270
1271      // check if user is administrator, owner of the project or any parent project
1272      var projectTree = new List<DA.Project> { project };
1273      projectTree.AddRange(projectDao.GetParentProjectsById(projectId));
1274      if (!projectTree.Select(x => x.OwnerUserId).Contains(UserManager.CurrentUserId)
1275        && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
1276        throw new SecurityException(NOT_AUTHORIZED_PROJECT);
1277      }
1278
1279      // look up if resourceId is amongst the assigned ones
1280      var assignedResources = project.AssignedProjectResources.ToList();
1281      if (assignedResources.Select(x => x.ResourceId).Contains(resourceId)) {
1282        return resource;
1283      }
1284
1285      // look up if one of the parent resourceIds is amongst the assigned ones
1286      // note: this should be faster than checking all children of the assigned
1287      // resource(-groups) for the certain resourceId
1288      var parentResourceIds = resourceDao.GetParentResourceIdsById(resourceId);
1289      if (assignedResources.Select(x => x.ResourceId)
1290        .Intersect(parentResourceIds).Count() > 0) {
1291        return resource;
1292      }
1293
1294      throw new SecurityException(NOT_AUTHORIZED_PROJECT);
1295    }
1296    #endregion
1297  }
1298}
Note: See TracBrowser for help on using the repository browser.