Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectDao.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectDao.cs	(revision 15507)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ProjectDao.cs	(revision 15508)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Data.Linq;
 using System.Linq;
@@ -32,4 +33,12 @@
     }
 
+    public IEnumerable<Project> GetProjectsByChildId(Guid id) {
+      return DataContext.ExecuteQuery<Project>(GetProjectsByChildIdQuery, id);
+    }
+
+    public IEnumerable<Guid> GetProjectIdsByChildId(Guid id) {
+      return DataContext.ExecuteQuery<Guid>(GetProjectIdsByChildIdQuery, id);
+    }
+
     #region Compiled queries
     private static readonly Func<DataContext, Guid, Project> GetByIdQuery =
@@ -39,4 +48,36 @@
          select project).SingleOrDefault());
     #endregion
+
+    #region String queries
+    private const string GetProjectsByChildIdQuery = @"
+      WITH ptree AS
+      (
+	      SELECT ProjectId, ParentProjectId
+        FROM [Project]
+	      UNION ALL
+	      SELECT pt.ProjectId, p.ParentProjectId
+	      FROM [Project] p
+	      JOIN ptree pt ON pt.ParentProjectId = p.ProjectId AND p.ParentProjectId <> p.ProjectId AND pt.ParentProjectId <> pt.ProjectId
+      )
+      SELECT DISTINCT pro.*
+      FROM ptree, [Project] pro
+      WHERE ptree.ProjectId = {0}
+      AND ptree.ParentProjectId = pro.ProjectId
+    ";
+    private const string GetProjectIdsByChildIdQuery = @"
+      WITH ptree AS
+      (
+	      SELECT ProjectId, ParentProjectId
+        FROM [Project]
+	      UNION ALL
+	      SELECT pt.ProjectId, p.ParentProjectId
+	      FROM [Project] p
+	      JOIN ptree pt ON pt.ParentProjectId = p.ProjectId AND p.ParentProjectId <> p.ProjectId AND pt.ParentProjectId <> pt.ProjectId
+      )
+      SELECT DISTINCT ptree.ParentProjectId
+      FROM ptree
+      WHERE ptree.ProjectId = {0}
+    ";
+    #endregion
   }
 }
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj	(revision 15507)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj	(revision 15508)
@@ -123,4 +123,5 @@
     <Compile Include="Daos\RequiredPluginDao.cs" />
     <Compile Include="Daos\ResourceDao.cs" />
+    <Compile Include="Daos\ResourcePermissionDao.cs" />
     <Compile Include="Daos\SlaveDao.cs" />
     <Compile Include="Daos\SlaveGroupDao.cs" />
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 15507)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 15508)
@@ -151,5 +151,7 @@
     <Compile Include="Scheduler\JobInfoForScheduler.cs" />
     <Compile Include="Scheduler\RoundRobinTaskScheduler.cs" />
-    <None Include="app.config" />
+    <None Include="app.config">
+      <SubType>Designer</SubType>
+    </None>
     <None Include="Plugin.cs.frame" />
     <None Include="Properties\AssemblyInfo.cs.frame" />
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15507)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15508)
@@ -76,56 +76,12 @@
         var stateLogDao = pm.StateLogDao;
 
-        var resourceDao = pm.ResourceDao;
-        var resourcePermissionDao = pm.ResourcePermissionDao;
-        var currentUserId = UserManager.CurrentUserId;
-
-        //// V1 user grant check
-        //// get granted (parent) resources
-        //var allGrantedResourceIds = pm.UseTransaction(() => {
-        //  return resourcePermissionDao.GetAll().ToList()
-        //    .Where(x => x.GrantedUserId == currentUserId
-        //      || UserManager.VerifyUser(currentUserId, new List<Guid> { x.GrantedUserId }))
-        //    .Select(y => y.ResourceId)
-        //    .ToList();
-        //});
-
-        //// get children of granted parent resources
-        //var userGrantedChildResourceIds = pm.UseTransaction(() => {
-        //  return allGrantedResourceIds
-        //  .SelectMany(x => resourceDao.GetResourcesByParentId(x))
-        //  .Select(y => y.ResourceId);
-        //});
-
-        //// join list of parent and child resources
-        //allGrantedResourceIds.AddRange(userGrantedChildResourceIds);
-
-        // V2 user grant check
-        var allGrantedResourceIds = pm.UseTransaction(() => {
-          var groupAndGroupIds = new List<Guid> { currentUserId };
-          groupAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
-          return resourcePermissionDao.GetByUserAndGroupIds(groupAndGroupIds).ToList();
-        });
-
-        // get all owned resourceIds
-        var ownedResourceIds = resourceDao.GetAll()
-          .Where(x => x.OwnerUserId == currentUserId)
-          .Select(x => x.ResourceId).ToList();
-
-        // join list of owned and granted resourceIds
-        allGrantedResourceIds.AddRange(ownedResourceIds);
-
-        // filter initial resourceId list with the list of the granted ones
-        var filteredResourceIds = resourceIds
-          .Where(x => allGrantedResourceIds.Contains(x))
-          .Distinct().ToList();
-
-        // TODO-JAN: Additional Filtering:
-        // TODO-JAN: user - project check; project - resource check
-
+        pm.UseTransaction(() => {
+          CheckTaskPermissions(pm, task, resourceIds);
+        });
 
         var newTask = task.ToEntity();
         newTask.JobData = taskData.ToEntity();
         newTask.JobData.LastUpdate = DateTime.Now;
-        newTask.AssignedTaskResources.AddRange(filteredResourceIds.Select(
+        newTask.AssignedTaskResources.AddRange(resourceIds.Select(
           x => new DA.AssignedTaskResource {
             ResourceId = x
@@ -739,6 +695,7 @@
       var pm = PersistenceManager;
       using (new PerformanceLogger("GrantProjectPermissions")) {
-        pm.UseTransaction(() => {
-          var project = AuthorizeForProject(pm, projectId);
+        var projectDao = pm.ProjectDao;
+        pm.UseTransaction(() => {
+          var project = projectDao.GetById(projectId);
           var projectPermissions = project.ProjectPermissions.ToList();
           foreach (var id in grantedUserIds) {
@@ -787,7 +744,12 @@
       var pm = PersistenceManager;
       using (new PerformanceLogger("AssignProjectResources")) {
-        pm.UseTransaction(() => {
-          var project = AuthorizeForProject(pm, projectId);
+        var projectDao = pm.ProjectDao;
+        pm.UseTransaction(() => {
+          var project = projectDao.GetById(projectId);
           var assignedProjectResources = project.AssignedProjectResources.ToList();
+
+          if (!RoleVerifier.IsInRole(HiveRoles.Administrator))
+            AuthorizeForResources(pm, project, resourceIds);
+
           foreach (var id in resourceIds) {
             if (assignedProjectResources.All(x => x.ResourceId != id)) {
@@ -1078,20 +1040,4 @@
     }
 
-    // only for authorized Administrator/ResourceOwner/(Sub)ProjectOwner to which the Resource (i.e. resourceId) is assigned
-    public void GrantResourcePermissions(Guid resourceId, Guid projectId, Guid[] grantedUserIds) {
-      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      AuthorizationManager.AuthorizeForResourceAdministration(resourceId);
-      var pm = PersistenceManager;
-      using (new PerformanceLogger("GrantResourcePermissions")) {
-        pm.UseTransaction(() => {
-
-
-          // TODO-JAN
-
-
-          pm.SubmitChanges();
-        });
-      }
-    }
 
     // only for authorized Administrator/ResourceOwner
@@ -1109,6 +1055,22 @@
     }
 
+
+    // OBSOLETE (change to public if...)
     // only for authorized Administrator/ResourceOwner/(Sub)ProjectOwner to which the Resource (i.e. resourceId) is assigned
-    public void RevokeResourcePermissions(Guid resourceId, Guid projectId, Guid[] grantedUserIds) {
+    private void GrantResourcePermissions(Guid resourceId, Guid projectId, Guid[] grantedUserIds) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      //AuthorizationManager.AuthorizeForResourceAdministration(resourceId);
+      var pm = PersistenceManager;
+      using (new PerformanceLogger("GrantResourcePermissions")) {
+        pm.UseTransaction(() => {
+          // TODO-JAN
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    // OBSOLETE (change to public if...)
+    // only for authorized Administrator/ResourceOwner/(Sub)ProjectOwner to which the Resource (i.e. resourceId) is assigned
+    private void RevokeResourcePermissions(Guid resourceId, Guid projectId, Guid[] grantedUserIds) {
       // TODO-JAN
     }
@@ -1229,13 +1191,133 @@
     }
 
-    private DA.Project AuthorizeForProject(IPersistenceManager pm, Guid projectId) {
+    // 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 project = projectDao.GetById(projectId);
-      if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT);
-      if (project.OwnerUserId != UserManager.CurrentUserId
-          && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
+      var resourceDao = pm.ResourceDao;
+      var resourcePermissionDao = pm.ResourcePermissionDao;
+      var projectPermissionDao = pm.ProjectPermissionDao;
+      var currentUserId = UserManager.CurrentUserId;
+
+      //// PART 1: user-resource permission check (V1)
+      //// get granted (parent) resources
+      //var allGrantedResourceIds = pm.UseTransaction(() => {
+      //  return resourcePermissionDao.GetAll().ToList()
+      //    .Where(x => x.GrantedUserId == currentUserId
+      //      || UserManager.VerifyUser(currentUserId, new List<Guid> { x.GrantedUserId }))
+      //    .Select(y => y.ResourceId)
+      //    .ToList();
+      //});
+
+      //// get children of granted parent resources
+      //var userGrantedChildResourceIds = pm.UseTransaction(() => {
+      //  return allGrantedResourceIds
+      //  .SelectMany(x => resourceDao.GetResourcesByParentId(x))
+      //  .Select(y => y.ResourceId);
+      //});
+
+      //// join list of parent and child resources
+      //allGrantedResourceIds.AddRange(userGrantedChildResourceIds);
+
+      // PART 1: user-resource permission check (V2)
+      // collect the current currentUserId and all Ids of affiliated groups
+      var userAndGroupIds = new List<Guid> { currentUserId };
+      userAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
+
+      // get all granted resourceIds
+      var allGrantedResourceIds = resourcePermissionDao.GetByUserAndGroupIds(userAndGroupIds).ToList();
+
+      // get all owned resourceIds (including child resourceIds)
+      var ownedResourceIds = resourceDao.GetAll()
+        .Where(x => x.OwnerUserId == currentUserId)
+        .Select(x => x.ResourceId).ToList();
+      var ownedChildResourceIds = ownedResourceIds.SelectMany(x => resourceDao.GetResourceIdsByParentId(x));
+      ownedResourceIds.AddRange(ownedChildResourceIds);
+
+      // join list of owned into the list with granted resourceIds
+      allGrantedResourceIds.AddRange(ownedResourceIds);
+
+      // check the argument resourceIds against the list of granted (and owned) ones
+      if (resourceIds.Except(allGrantedResourceIds).Any()) {
+        throw new SecurityException(NOT_AUTHORIZED_RESOURCE);
+      }
+
+      // 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.GetResourceIdsByParentId(x));
+      assignedResourceIds.AddRange(assignedChildResourceIds);
+      if (resourceIds.Except(assignedResourceIds).Any()) {
         throw new SecurityException(NOT_AUTHORIZED_PROJECT);
       }
-      return 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.GetProjectsByChildId(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) {
+      var projectDao = pm.ProjectDao;
+      var resourceDao = pm.ResourceDao;
+
+      var projectBranch = new List<DA.Project> { project };
+      projectBranch.AddRange(projectDao.GetProjectsByChildId(project.ProjectId));
+      var ownedProjects = projectBranch.Where(x => x.OwnerUserId == UserManager.CurrentUserId).ToList();
+
+      // get all assigned resourceIds (including children) of owned projects in this branch
+      var assignedResourceIds = ownedProjects.SelectMany(x => x.AssignedProjectResources).Select(x => x.ResourceId).ToList();
+      var assignedChildResourceIds = assignedResourceIds.SelectMany(x => resourceDao.GetResourceIdsByChildId(x));
+      assignedResourceIds.AddRange(assignedChildResourceIds);
+
+      // look up if all resourceIds are among the assigned ones
+      if(resourceIds.Except(assignedResourceIds).Any()) {
+        throw new SecurityException(NOT_AUTHORIZED_RESOURCE);
+      }
     }
 
@@ -1245,12 +1327,15 @@
       var projectDao = pm.ProjectDao;
       var project = projectDao.GetById(projectId);
-      if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT);
+      if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT); // if project does not exist
 
       var resourceDao = pm.ResourceDao;
       var resource = resourceDao.GetById(resourceId);
-      if (resource == null) throw new SecurityException(NOT_AUTHORIZED_RESOURCE);
-
-
-      if (project.OwnerUserId != UserManager.CurrentUserId
+      if (resource == null) throw new SecurityException(NOT_AUTHORIZED_RESOURCE); // if resource does not exist
+
+
+      // check if user is administrator, owner of the project or any parent project
+      var projectTree = new List<DA.Project> { project };
+      projectTree.AddRange(projectDao.GetProjectsByChildId(projectId));
+      if(!projectTree.Select(x => x.OwnerUserId).Contains(UserManager.CurrentUserId)
         && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
         throw new SecurityException(NOT_AUTHORIZED_PROJECT);
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs	(revision 15507)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs	(revision 15508)
@@ -27,5 +27,6 @@
 using DA = HeuristicLab.Services.Hive.DataAccess;
 using DT = HeuristicLab.Services.Hive.DataTransfer;
-
+using System.Collections.Generic;
+using System.Linq;
 
 namespace HeuristicLab.Services.Hive {
@@ -87,5 +88,8 @@
         var project = projectDao.GetById(projectId);
         if (project == null) throw new SecurityException(NOT_AUTHORIZED);
-        if (project.OwnerUserId != UserManager.CurrentUserId
+
+        var projectTree = new List<Project>() { project };
+        projectTree.AddRange(projectDao.GetProjectsByChildId(projectId));
+        if(!projectTree.Select(x => x.OwnerUserId).Contains(UserManager.CurrentUserId)
             && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
           throw new SecurityException(NOT_AUTHORIZED);
