Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15527)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15530)
@@ -41,6 +41,6 @@
   [HiveOperationContextBehavior]
   public class HiveService : IHiveService {
-    private const string NOT_AUTHORIZED_RESOURCE = "Current user is not authorized to access the requested resource";
-    private const string NOT_AUTHORIZED_PROJECT = "Current user is not authorized to access the requested project";
+    private const string NOT_AUTHORIZED_PROJECTRESOURCE = "Selected project is not authorized to access the requested resource";
+    private const string NOT_AUTHORIZED_USERPROJECT = "Current user is not authorized to access the requested project";
 
     private static readonly DA.TaskState[] CompletedStates = { DA.TaskState.Finished, DA.TaskState.Aborted, DA.TaskState.Failed };
@@ -75,8 +75,4 @@
         var taskDao = pm.TaskDao;
         var stateLogDao = pm.StateLogDao;
-
-        pm.UseTransaction(() => {
-          CheckTaskPermissions(pm, task, resourceIds);
-        });
 
         var newTask = task.ToEntity();
@@ -105,18 +101,35 @@
     }
 
+    public Guid AddTask(DT.Task task, DT.TaskData taskData) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("AddTask")) {
+        var taskDao = pm.TaskDao;
+        var stateLogDao = pm.StateLogDao;
+        var newTask = task.ToEntity();
+        newTask.JobData = taskData.ToEntity();
+        newTask.JobData.LastUpdate = DateTime.Now;
+        newTask.State = DA.TaskState.Waiting;
+        return pm.UseTransaction(() => {
+          taskDao.Save(newTask);
+          pm.SubmitChanges();
+          stateLogDao.Save(new DA.StateLog {
+            State = DA.TaskState.Waiting,
+            DateTime = DateTime.Now,
+            TaskId = newTask.TaskId,
+            UserId = UserManager.CurrentUserId,
+            SlaveId = null,
+            Exception = null
+          });
+          pm.SubmitChanges();
+          return newTask.TaskId;
+        }, false, true);
+      }
+    }
+
     public Guid AddChildTask(Guid parentTaskId, DT.Task task, DT.TaskData taskData) {
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      IEnumerable<Guid> resourceIds;
-      var pm = PersistenceManager;
-      using (new PerformanceLogger("AddChildTask")) {
-        var assignedTaskResourceDao = pm.AssignedTaskResourceDao;
-        resourceIds = pm.UseTransaction(() => {
-          return assignedTaskResourceDao.GetByTaskId(parentTaskId)
-            .Select(x => x.ResourceId)
-            .ToList();
-        });
-      }
       task.ParentTaskId = parentTaskId;
-      return AddTask(task, taskData, resourceIds);
+      return AddTask(task, taskData);
     }
 
@@ -402,4 +415,39 @@
     }
 
+    public Guid AddJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      // check user - project
+      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
+      // check project - resources
+      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("AddJob")) {
+        var jobDao = pm.JobDao;
+        var userPriorityDao = pm.UserPriorityDao;
+
+        return pm.UseTransaction(() => {
+          var newJob = jobDto.ToEntity();
+          newJob.OwnerUserId = UserManager.CurrentUserId;
+          newJob.DateCreated = DateTime.Now;
+
+          // add resource assignments
+          newJob.AssignedJobResources.AddRange(resourceIds.Select(
+            x => new DA.AssignedJobResource {
+              ResourceId = x
+          }));
+  
+          var job = jobDao.Save(newJob);
+          if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
+            userPriorityDao.Save(new DA.UserPriority {
+              UserId = jobDto.OwnerUserId,
+              DateEnqueued = jobDto.DateCreated
+            });
+          }
+          pm.SubmitChanges();
+          return job.JobId;
+        });
+      }
+    }
+
     public void UpdateJob(DT.Job jobDto) {
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
@@ -416,4 +464,40 @@
           }
           jobDto.CopyToEntity(job);
+          if (!exists) {
+            jobDao.Save(job);
+          }
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void UpdateJob(DT.Job jobDto, IEnumerable<Guid> resourceIds) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
+      // check user - project permission
+      AuthorizationManager.AuthorizeUserForProjectUse(UserManager.CurrentUserId, jobDto.ProjectId);
+      // check project - resources permission
+      AuthorizationManager.AuthorizeProjectForResourcesUse(jobDto.ProjectId, resourceIds);
+
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("UpdateJob")) {
+        bool exists = true;
+        var jobDao = pm.JobDao;
+        pm.UseTransaction(() => {
+          var job = jobDao.GetById(jobDto.Id);
+          if (job == null) {
+            exists = false;
+            job = new DA.Job();
+          }
+          jobDto.CopyToEntity(job);
+
+          // remove former resource assignments
+          job.AssignedJobResources.Clear();
+          // add resource assignments
+          job.AssignedJobResources.AddRange(resourceIds.Select(
+            x => new DA.AssignedJobResource {
+              ResourceId = x
+          }));
+
           if (!exists) {
             jobDao.Save(job);
@@ -690,5 +774,5 @@
 
     #region ProjectPermission Methods
-    public void GrantProjectPermissions(Guid projectId, Guid[] grantedUserIds) {
+    public void GrantProjectPermissions(Guid projectId, Guid[] grantedUserIds, bool cascading) {
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       AuthorizationManager.AuthorizeForProjectAdministration(projectId);
@@ -696,9 +780,10 @@
       using (new PerformanceLogger("GrantProjectPermissions")) {
         var projectDao = pm.ProjectDao;
+        
         pm.UseTransaction(() => {
           var project = projectDao.GetById(projectId);
           var projectPermissions = project.ProjectPermissions.ToList();
           foreach (var id in grantedUserIds) {
-            if (projectPermissions.All(x => x.GrantedUserId != id)) {
+            if (projectPermissions.All(x => x.GrantedUserId != id)) { 
               project.ProjectPermissions.Add(new DA.ProjectPermission {
                 GrantedUserId = id,
@@ -707,10 +792,22 @@
             }
           }
-          pm.SubmitChanges();
-        });
-      }
-    }
-
-    public void RevokeProjectPermissions(Guid projectId, Guid[] grantedUserIds) {
+          if(cascading) {
+            var childProjects = projectDao.GetChildProjectsById(projectId);
+            foreach (var p in childProjects) {
+              p.ProjectPermissions.Clear();
+              foreach (var id in grantedUserIds) {
+                p.ProjectPermissions.Add(new DA.ProjectPermission {
+                  GrantedUserId = id,
+                  GrantedByUserId = UserManager.CurrentUserId
+                });
+              }
+            }
+          }
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void RevokeProjectPermissions(Guid projectId, Guid[] grantedUserIds, bool cascading) {
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       AuthorizationManager.AuthorizeForProjectAdministration(projectId);
@@ -718,6 +815,11 @@
       using (new PerformanceLogger("RevokeProjectPermissions")) {
         var projectPermissionDao = pm.ProjectPermissionDao;
-        pm.UseTransaction(() => {
-          projectPermissionDao.DeleteByProjectAndGrantedUserId(projectId, grantedUserIds);
+        var projectDao = pm.ProjectDao;
+        pm.UseTransaction(() => {
+          if(cascading) {
+            var childProjectIds = projectDao.GetChildProjectIdsById(projectId);
+            projectPermissionDao.DeleteByProjectIdsAndGrantedUserIds(childProjectIds, grantedUserIds);
+          }
+          projectPermissionDao.DeleteByProjectIdAndGrantedUserIds(projectId, grantedUserIds);
           pm.SubmitChanges();
         });
@@ -749,4 +851,5 @@
           var assignedProjectResources = project.AssignedProjectResources.ToList();
 
+          // TODO-JAN
           if (!RoleVerifier.IsInRole(HiveRoles.Administrator))
             AuthorizeForResources(pm, project, resourceIds);
@@ -767,4 +870,9 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       AuthorizationManager.AuthorizeForProjectAdministration(projectId);
+      // TODO-JAN: adjust Authorization Method
+      // only users who are owners of a parent project of projectId are allowed to manage resources
+      // these users can only those resources which are already assigned to
+      // (1) the nearest parent they own
+      // (2) to any of the parent they own
       var pm = PersistenceManager;
       using (new PerformanceLogger("UnassignProjectResources")) {
@@ -1129,73 +1237,6 @@
     }
 
-    // OBSOLETE
-    // reason: only used for double checking! AuthorizationManager.AuthorizeForProjectAdministration(..) does the same!
-    //private DA.Project AuthorizeForProject(IPersistenceManager pm, Guid projectId) {
-    //  var projectDao = pm.ProjectDao;
-    //  var project = projectDao.GetById(projectId);
-    //  if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT);
-    //  if (project.OwnerUserId != UserManager.CurrentUserId
-    //      && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
-    //    throw new SecurityException(NOT_AUTHORIZED_PROJECT);
-    //  }
-    //  return project;
-    //}
-
-    private void CheckTaskPermissions(IPersistenceManager pm, DT.Task task, IEnumerable<Guid> resourceIds) {
-      var jobDao = pm.JobDao;
-      var projectDao = pm.ProjectDao;
-      var resourceDao = pm.ResourceDao;
-      var projectPermissionDao = pm.ProjectPermissionDao;
-      var currentUserId = UserManager.CurrentUserId;
-
-      // PART 2: user-project permission check
-      var job = jobDao.GetById(task.JobId);
-      var project = projectDao.GetById(job.ProjectId);
-      AuthorizeForProjectTask(pm, project);
-
-      // PART 3: project-resource permission check
-      var assignedResourceIds = project.AssignedProjectResources.Select(x => x.ResourceId).ToList();
-      var assignedChildResourceIds = assignedResourceIds.SelectMany(x => resourceDao.GetChildResourceIdsById(x));
-      assignedResourceIds.AddRange(assignedChildResourceIds);
-      if (resourceIds.Except(assignedResourceIds).Any()) {
-        throw new SecurityException(NOT_AUTHORIZED_PROJECT);
-      }
-    }
-
-    // Check if current user is authorized to add a task on a explicit project
-    // case 1: user is administrator
-    // case 2: user is owner of project or parent project
-    // case 3: user has explicit permission on project or parent project
-    private void AuthorizeForProjectTask(IPersistenceManager pm, DA.Project project) {
-      if (RoleVerifier.IsInRole(HiveRoles.Administrator)) return; // case 1
-
-      // case 2
-      var projectDao = pm.ProjectDao;
-      var projectBranch = new List<DA.Project>() { project };
-      projectBranch.AddRange(projectDao.GetParentProjectsById(project.ProjectId));
-      if (projectBranch
-        .Select(x => x.OwnerUserId)
-        .Contains(UserManager.CurrentUserId)) {
-        return;
-      }
-
-      // case 3
-      if (project.ProjectPermissions
-        .Select(x => x.GrantedUserId)
-        .Contains(UserManager.CurrentUserId)) {
-        return;
-      }
-      if (projectBranch
-        .SelectMany(x => x.ProjectPermissions)
-        .Select(x => x.GrantedUserId)
-        .Contains(UserManager.CurrentUserId)) {
-        return;
-      }
-
-      throw new SecurityException(NOT_AUTHORIZED_PROJECT);
-    }
-
     // Check if the current user is authorized to administer resourceIds
-    private void AuthorizeForResources(IPersistenceManager pm, DA.Project project, Guid[] resourceIds) {
+    private void AuthorizeForResource(IPersistenceManager pm, DA.Project project, Guid[] resourceIds) {
       var projectDao = pm.ProjectDao;
       var resourceDao = pm.ResourceDao;
