Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/AssignedJobResourceDao.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/AssignedJobResourceDao.cs	(revision 15529)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/AssignedJobResourceDao.cs	(revision 15530)
@@ -22,6 +22,11 @@
     }
 
-    public bool CheckJobGrantedForResources(Guid jobId, Guid[] resourceIds) {
-      return DataContext.ExecuteQuery<int>(CheckJobGrantedForResourcesQueryString).Count() > 0;
+    public bool CheckJobGrantedForResources(Guid jobId, IEnumerable<Guid> resourceIds) {
+      string paramResourceIds = string.Join(",", resourceIds.Select(x => string.Format("'{0}'", x)));
+      if (!string.IsNullOrWhiteSpace(paramResourceIds)) {
+        string queryString = string.Format(CheckJobGrantedForResourcesQueryString, jobId, paramResourceIds);
+        return DataContext.ExecuteQuery<int>(queryString).Count() == 0;
+      }
+      return false;
     }
 
@@ -43,5 +48,5 @@
         SELECT ResourceId, ParentResourceId
         FROM [Resource]
-        WHERE ResourceId = {0}
+        WHERE ResourceId = {1}
         UNION ALL
         SELECT r.ResourceId, r.ParentResourceId
@@ -52,5 +57,5 @@
       FROM rbranch, AssignedJobResource ajr
       WHERE rbranch.ResourceId = ajr.ResourceId
-      AND ajr.JobId = {1}
+      AND ajr.JobId = {0}
     ";
     private const string CheckTaskGrantedForResourceQueryString = @"
@@ -58,5 +63,5 @@
         SELECT ResourceId, ParentResourceId
         FROM [Resource]
-        WHERE ResourceId = {0}
+        WHERE ResourceId = {1}
         UNION ALL
         SELECT r.ResourceId, r.ParentResourceId
@@ -68,5 +73,5 @@
       WHERE rbranch.ResourceId = ajr.ResourceId
       AND ajr.JobId = t.JobId
-      AND t.JobId = {1}
+      AND t.JobId = {0}
     ";
     private const string CheckJobGrantedForResourcesQueryString = @"
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/AssignedProjectResourceDao.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/AssignedProjectResourceDao.cs	(revision 15529)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/AssignedProjectResourceDao.cs	(revision 15530)
@@ -45,4 +45,21 @@
     }
 
+    public bool CheckProjectGrantedForResources(Guid projectId, IEnumerable<Guid> resourceIds) {
+      string paramResourceIds = string.Join(",", resourceIds.Select(x => string.Format("'{0}'", x)));
+      if (!string.IsNullOrWhiteSpace(paramResourceIds)) {
+        string queryString = string.Format(CheckProjectGrantedForResourcesQueryString, projectId, paramResourceIds);
+        return DataContext.ExecuteQuery<int>(queryString).Count() == 0;
+      }
+      return false;
+    }
+
+    public IEnumerable<Resource> GetAllGrantedResourcesByProjectId(Guid projectId) {
+      return DataContext.ExecuteQuery<Resource>(GetAllGrantedResourcesByProjectIdQueryString, projectId);
+    }
+
+    public IEnumerable<Guid> GetAllGrantedResourceIdsByProjectId(Guid projectId) {
+      return DataContext.ExecuteQuery<Guid>(GetAllGrantedResourceIdsByProjectIdQueryString, projectId);
+    }
+
     #region Compiled queries
     private static readonly Func<DataContext, Guid, IEnumerable<AssignedProjectResource>> GetByProjectIdGetByIdQuery =
@@ -58,4 +75,69 @@
          WHERE ProjectId = '{0}'
            AND ResourceId IN ({1});";
+    private const string CheckProjectGrantedForResourcesQueryString = @"
+    WITH rtree AS
+    (
+	    SELECT ResourceId, ParentResourceId
+	    FROM [Resource]
+	    UNION ALL
+	    SELECT rt.ResourceId, r.ParentResourceId
+	    FROM [Resource] r
+	    JOIN rtree rt ON rt.ParentResourceId = r.ResourceId
+    )
+    SELECT r.ResourceId
+    FROM [Resource] r
+    WHERE r.ResourceId IN ({1})
+    EXCEPT
+    (
+	    SELECT rtree.ResourceId
+	    FROM rtree, [AssignedProjectResource] apr
+	    WHERE rtree.ParentResourceId = apr.ResourceId
+	    AND apr.ProjectId = {0}
+	    UNION
+	    SELECT apr.ResourceId
+	    FROM [AssignedProjectResource] apr
+	    WHERE apr.ProjectId = {0}
+    )
+    ";
+    private const string GetAllGrantedResourcesByProjectIdQueryString = @"
+      WITH rtree AS
+      (
+	      SELECT ResourceId, ParentResourceId
+	      FROM [Resource]
+	      UNION ALL
+	      SELECT rt.ResourceId, r.ParentResourceId
+	      FROM [Resource] r
+	      JOIN rtree rt ON rt.ParentResourceId = r.ResourceId
+      )
+      SELECT res.*
+      FROM rtree, [AssignedProjectResource] apr, [Resource] res
+      WHERE rtree.ParentResourceId = apr.ResourceId
+      AND rtree.ResourceId = res.ResourceId
+      AND apr.ProjectId = {0}
+      UNION
+      SELECT res.*
+      FROM [AssignedProjectResource] apr, [Resource] res
+      WHERE apr.ResourceId = res.ResourceId
+      AND apr.ProjectId = {0}
+    ";
+    private const string GetAllGrantedResourceIdsByProjectIdQueryString = @"
+    WITH rtree AS
+    (
+	    SELECT ResourceId, ParentResourceId
+	    FROM [Resource]
+	    UNION ALL
+	    SELECT rt.ResourceId, r.ParentResourceId
+	    FROM [Resource] r
+	    JOIN rtree rt ON rt.ParentResourceId = r.ResourceId
+    )
+    SELECT rtree.ResourceId
+    FROM rtree, [AssignedProjectResource] apr
+    WHERE rtree.ParentResourceId = apr.ResourceId
+    AND apr.ProjectId = {0}
+    UNION
+    SELECT apr.ResourceId
+    FROM [AssignedProjectResource] apr
+    WHERE apr.ProjectId = {0}
+    ";
     #endregion
   }
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectPermissionDao.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectPermissionDao.cs	(revision 15529)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectPermissionDao.cs	(revision 15530)
@@ -37,8 +37,26 @@
     }
 
-    public void DeleteByProjectAndGrantedUserId(Guid projectId, IEnumerable<Guid> grantedUserId) {
-      string paramIds = string.Join(",", grantedUserId.Select(x => string.Format("'{0}'", x)));
+    public bool CheckUserGrantedForProject(Guid projectId, IEnumerable<Guid> userAndGroupIds) {
+      string paramUserAndGroupIds = string.Join(",", userAndGroupIds.Select(x => string.Format("'{0}'", x)));
+      if(!string.IsNullOrWhiteSpace(paramUserAndGroupIds)) {
+        string queryString = string.Format(CheckUserGrantedForProjectQueryString, projectId, paramUserAndGroupIds);
+        return DataContext.ExecuteQuery<int>(queryString).First() > 0;
+      }
+      return false;
+    }
+
+    public void DeleteByProjectIdAndGrantedUserIds(Guid projectId, IEnumerable<Guid> grantedUserIds) {
+      string paramIds = string.Join(",", grantedUserIds.Select(x => string.Format("'{0}'", x)));
       if (!string.IsNullOrWhiteSpace(paramIds)) {
-        string query = string.Format(DeleteByGrantedUserQuery, projectId, paramIds);
+        string query = string.Format(DeleteByProjectIdAndGrantedUserIdsQueryString, projectId, paramIds);
+        DataContext.ExecuteCommand(query);
+      }
+    }
+
+    public void DeleteByProjectIdsAndGrantedUserIds(IEnumerable<Guid> projectIds, IEnumerable<Guid> grantedUserIds) {
+      string paramProjectIds = string.Join(",", projectIds.Select(x => string.Format("'{0}'", x)));
+      string paramUserIds = string.Join(",", grantedUserIds.Select(x => string.Format("'{0}'", x)));
+      if (!string.IsNullOrWhiteSpace(paramProjectIds) && !string.IsNullOrWhiteSpace(paramUserIds)) {
+        string query = string.Format(DeleteByProjectIdsAndGrantedUserIdsQueryString, paramProjectIds, paramUserIds);
         DataContext.ExecuteCommand(query);
       }
@@ -54,8 +72,20 @@
 
     #region String queries
-    private const string DeleteByGrantedUserQuery =
-      @"DELETE FROM [ProjectPermission]
-         WHERE ProjectId = '{0}'
-           AND GrantedUserId IN ({1});";
+    private const string DeleteByProjectIdAndGrantedUserIdsQueryString = @"
+      DELETE FROM [ProjectPermission]
+      WHERE ProjectId = '{0}'
+      AND GrantedUserId IN ({1});
+    ";
+    private const string DeleteByProjectIdsAndGrantedUserIdsQueryString = @"
+      DELETE FROM [ProjectPermission]
+      WHERE ProjectId IN '({0})'
+      AND GrantedUserId IN ({1});
+    ";
+    private const string CheckUserGrantedForProjectQueryString = @"
+      SELECT COUNT(pp.ProjectId)
+      FROM [ProjectPermission] pp
+      WHERE pp.ProjectId = {0}
+      AND pp.GrantedUserId IN ({1})
+    ";
     #endregion
   }
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15529)
+++ /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;
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Interfaces/IAuthorizationManager.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Interfaces/IAuthorizationManager.cs	(revision 15529)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Interfaces/IAuthorizationManager.cs	(revision 15530)
@@ -22,4 +22,5 @@
 using System;
 using HeuristicLab.Services.Hive.DataTransfer;
+using System.Collections.Generic;
 
 namespace HeuristicLab.Services.Hive {
@@ -37,4 +38,8 @@
 
     void AuthorizeForProjectAdministration(Guid projectId);
+
+    void AuthorizeProjectForResourcesUse(Guid projectId, IEnumerable<Guid> resourceIds);
+
+    void AuthorizeUserForProjectUse(Guid userId, Guid projectId);
   }
 }
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs	(revision 15529)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs	(revision 15530)
@@ -33,5 +33,8 @@
   public class AuthorizationManager : IAuthorizationManager {
 
-    private const string NOT_AUTHORIZED = "Current user is not authorized to access the requested resource";
+    private const string NOT_AUTHORIZED_USERRESOURCE = "Current user is not authorized to access the requested resource";
+    private const string NOT_AUTHORIZED_USERPROJECT = "Current user is not authorized to access the requested project";
+    private const string NOT_AUTHORIZED_PROJECTRESOURCE = "Selected project is not authorized to access the requested resource";
+
     private IPersistenceManager PersistenceManager {
       get { return ServiceLocator.Instance.PersistenceManager; }
@@ -48,5 +51,5 @@
     public void Authorize(Guid userId) {
       if (userId != ServiceLocator.Instance.UserManager.CurrentUserId)
-        throw new SecurityException(NOT_AUTHORIZED);
+        throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
     }
 
@@ -57,5 +60,5 @@
       pm.UseTransaction(() => {
         var task = taskDao.GetById(taskId);
-        if (task == null) throw new SecurityException(NOT_AUTHORIZED);
+        if (task == null) throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
         AuthorizeJob(pm, task.JobId, requiredPermission);
       });
@@ -74,8 +77,8 @@
       pm.UseTransaction(() => {
         var resource = resourceDao.GetById(resourceId);
-        if (resource == null) throw new SecurityException(NOT_AUTHORIZED);
+        if (resource == null) throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
         if (resource.OwnerUserId != UserManager.CurrentUserId
             && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
-          throw new SecurityException(NOT_AUTHORIZED);
+          throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
         }
       });
@@ -87,13 +90,34 @@
       pm.UseTransaction(() => {
         var project = projectDao.GetById(projectId);
-        if (project == null) throw new SecurityException(NOT_AUTHORIZED);
+        if (project == null) throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
 
-        var projectTree = new List<Project>() { project };
-        projectTree.AddRange(projectDao.GetProjectsByChildId(projectId));
+        var projectTree = projectDao.GetCurrentAndParentProjectsById(projectId);
         if(!projectTree.Select(x => x.OwnerUserId).Contains(UserManager.CurrentUserId)
             && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
-          throw new SecurityException(NOT_AUTHORIZED);
+          throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
         }
       });
+    }
+
+    // Check if a project is authorized to use a list of resources
+    public void AuthorizeProjectForResourcesUse(Guid projectId, IEnumerable<Guid> resourceIds) {
+      var pm = PersistenceManager;
+      var assignedProjectResourceDao = pm.AssignedProjectResourceDao;
+      if (!assignedProjectResourceDao.CheckProjectGrantedForResources(projectId, resourceIds))
+        throw new SecurityException(NOT_AUTHORIZED_PROJECTRESOURCE);
+    }
+
+    // Check if current user is authorized to use an explicit project (e.g. in order to add a job)
+    // note: administrators and project owner are NOT automatically granted
+    public void AuthorizeUserForProjectUse(Guid userId, Guid projectId) {
+      var pm = PersistenceManager;
+      // collect current and group membership Ids
+      var userAndGroupIds = new List<Guid>() { userId };
+      userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(userId));
+      // perform the actual check
+      var projectPermissionDao = pm.ProjectPermissionDao;
+      if (!projectPermissionDao.CheckUserGrantedForProject(projectId, userAndGroupIds)) {
+        throw new SecurityException(NOT_AUTHORIZED_USERPROJECT);
+      }
     }
 
@@ -114,5 +138,5 @@
       if (permission == Permission.NotAllowed
           || ((permission != requiredPermissionEntity) && requiredPermissionEntity == Permission.Full)) {
-        throw new SecurityException(NOT_AUTHORIZED);
+        throw new SecurityException(NOT_AUTHORIZED_USERRESOURCE);
       }
     }
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/ServiceContracts/IHiveService.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/ServiceContracts/IHiveService.cs	(revision 15529)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/ServiceContracts/IHiveService.cs	(revision 15530)
@@ -151,8 +151,8 @@
     #region ProjectPermission Methods
     [OperationContract]
-    void GrantProjectPermissions(Guid projectId, Guid[] grantedUserIds);
-
-    [OperationContract]
-    void RevokeProjectPermissions(Guid projectId, Guid[] grantedUserIds);
+    void GrantProjectPermissions(Guid projectId, Guid[] grantedUserIds, bool cascading);
+
+    [OperationContract]
+    void RevokeProjectPermissions(Guid projectId, Guid[] grantedUserIds, bool cascading);
 
     [OperationContract]
