Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourceDao.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourceDao.cs	(revision 15502)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourceDao.cs	(revision 15503)
@@ -41,10 +41,18 @@
     }
 
+    public IEnumerable<Resource> GetResourcesByParentId(Guid id) {
+      return DataContext.ExecuteQuery<Resource>(GetResourcesByParentIdQuery, id);
+    }
+
     public IEnumerable<Guid> GetResourceIdsByParentId(Guid id) {
       return DataContext.ExecuteQuery<Guid>(GetResourceIdsByParentIdQuery, id);
     }
 
-    public IEnumerable<Resource> GetResourcesByParentId(Guid id) {
-      return DataContext.ExecuteQuery<Resource>(GetResourcesByParentIdQuery, id);
+    public IEnumerable<Resource> GetResourcesByChildId(Guid id) {
+      return DataContext.ExecuteQuery<Resource>(GetResourcesByChildIdQuery, id);
+    }
+
+    public IEnumerable<Guid> GetResourceIdsByChildId(Guid id) {
+      return DataContext.ExecuteQuery<Guid>(GetResourceIdsByChildIdQuery, id);
     }
 
@@ -65,18 +73,4 @@
     #region String queries
     private const string GetResourcesByParentIdQuery = @"
-      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 AND r.ParentResourceId <> r.ResourceId AND rt.ParentResourceId <> rt.ResourceId
-      )
-      SELECT DISTINCT rtree.ResourceId
-      FROM rtree
-      WHERE rtree.ParentResourceId = ({0})
-    ";
-    private const string GetResourceIdsByParentIdQuery = @"
     	WITH rtree AS
       (
@@ -93,4 +87,47 @@
 	    AND rtree.ResourceId = res.ResourceId
     ";
+    private const string GetResourceIdsByParentIdQuery = @"
+      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 AND r.ParentResourceId <> r.ResourceId AND rt.ParentResourceId <> rt.ResourceId
+      )
+      SELECT DISTINCT rtree.ResourceId
+      FROM rtree
+      WHERE rtree.ParentResourceId = ({0})
+    ";
+    private const string GetResourcesByChildIdQuery = @"
+      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 AND r.ParentResourceId <> r.ResourceId AND rt.ParentResourceId <> rt.ResourceId
+      )
+      SELECT DISTINCT res.*
+      FROM rtree, [Resource] res
+      WHERE rtree.ResourceId = ({0})
+      AND rtree.ParentResourceId = res.ResourceId
+    ";
+    private const string GetResourceIdsByChildIdQuery = @"
+      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 AND r.ParentResourceId <> r.ResourceId AND rt.ParentResourceId <> rt.ResourceId
+      )
+      SELECT DISTINCT rtree.ParentResourceId
+      FROM rtree
+      WHERE rtree.ResourceId = ({0})
+    ";
     #endregion
   }
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourcePermissionDao.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourcePermissionDao.cs	(revision 15502)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourcePermissionDao.cs	(revision 15503)
@@ -43,4 +43,12 @@
     }
 
+    public void DeleteByResourceIdAndGrantedUserId(Guid resourceId, IEnumerable<Guid> grantedUserId) {
+      string paramIds = string.Join(",", grantedUserId.Select(x => string.Format("'{0}'", x)));
+      if (!string.IsNullOrWhiteSpace(paramIds)) {
+        string query = string.Format(DeleteByGrantedUserQuery, resourceId, paramIds);
+        DataContext.ExecuteCommand(query);
+      }
+    }
+
     #region Compiled queries
     private static readonly Func<DataContext, Guid, IEnumerable<ResourcePermission>> GetByResourceIdQuery =
@@ -71,4 +79,9 @@
       ;";
 
+    private const string DeleteByGrantedUserQuery = @"
+      DELETE FROM [ResourcePermission]
+        WHERE ResourceId = '{0}'
+        AND GrantedUserId IN ({1})
+    ;";
     #endregion
   }
Index: /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15502)
+++ /branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15503)
@@ -41,4 +41,7 @@
   [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 static readonly DA.TaskState[] CompletedStates = { DA.TaskState.Finished, DA.TaskState.Aborted, DA.TaskState.Failed };
 
@@ -79,5 +82,5 @@
         //// V1 user grant check
         //// get granted (parent) resources
-        //var userGrantedResourceIds = pm.UseTransaction(() => {
+        //var allGrantedResourceIds = pm.UseTransaction(() => {
         //  return resourcePermissionDao.GetAll().ToList()
         //    .Where(x => x.GrantedUserId == currentUserId
@@ -89,5 +92,5 @@
         //// get children of granted parent resources
         //var userGrantedChildResourceIds = pm.UseTransaction(() => {
-        //  return userGrantedResourceIds
+        //  return allGrantedResourceIds
         //  .SelectMany(x => resourceDao.GetResourcesByParentId(x))
         //  .Select(y => y.ResourceId);
@@ -95,22 +98,34 @@
 
         //// join list of parent and child resources
-        //userGrantedResourceIds.AddRange(userGrantedChildResourceIds);
-
-        //// filter initial resourceId list with the list of the granted ones
-        //var allUserGrantedResourceIds = resourceIds
-        //  .Where(x => userGrantedResourceIds.Contains(x))
-        //  .Distinct().ToList();
+        //allGrantedResourceIds.AddRange(userGrantedChildResourceIds);
 
         // V2 user grant check
-        var allUserGrantedResourceIds = pm.UseTransaction(() => {
+        var allGrantedResourceIds = pm.UseTransaction(() => {
           var groupAndGroupIds = new List<Guid> { currentUserId };
           groupAndGroupIds.AddRange(UserManager.GetUserGroupIdsOfUser(currentUserId));
-          return resourcePermissionDao.GetByUserAndGroupIds(groupAndGroupIds);
-        });
+          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
+
 
         var newTask = task.ToEntity();
         newTask.JobData = taskData.ToEntity();
         newTask.JobData.LastUpdate = DateTime.Now;
-        newTask.AssignedTaskResources.AddRange(allUserGrantedResourceIds.Select(
+        newTask.AssignedTaskResources.AddRange(filteredResourceIds.Select(
           x => new DA.AssignedTaskResource {
             ResourceId = x
@@ -1039,4 +1054,66 @@
     #endregion
 
+    #region ResourcePermission Methods
+    // only for authorized Administrator/ResourceOwner
+    public void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForResourceAdministration(resourceId);
+      var pm = PersistenceManager;
+      using(new PerformanceLogger("GrantResourcePermissions")) {
+        pm.UseTransaction(() => {
+          var resourceDao = pm.ResourceDao;
+          var resource = resourceDao.GetById(resourceId);
+          var resourcePermissions = resource.ResourcePermissions.ToList();
+          foreach(var id in grantedUserIds) {
+            if(resourcePermissions.All(x => x.GrantedUserId != id)) {
+              resource.ResourcePermissions.Add(new DA.ResourcePermission {
+                GrantedUserId = id,
+                GrantedByUserId = UserManager.CurrentUserId
+              });
+            }
+          }
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    // 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
+    public void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForResourceAdministration(resourceId);
+      var pm = PersistenceManager;
+      using(new PerformanceLogger("RevokeResourcePermission")) {
+        pm.UseTransaction(() => {
+          var resourcePermissionDao = pm.ResourcePermissionDao;
+          resourcePermissionDao.DeleteByResourceIdAndGrantedUserId(resourceId, grantedUserIds);
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    // 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) {
+      // TODO-JAN
+    }
+
+    #endregion
+
     #region Downtime Methods
     public Guid AddDowntime(DT.Downtime downtimeDto) {
@@ -1155,10 +1232,45 @@
       var projectDao = pm.ProjectDao;
       var project = projectDao.GetById(projectId);
-      if (project == null) throw new SecurityException("Not authorized");
+      if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT);
       if (project.OwnerUserId != UserManager.CurrentUserId
           && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
-        throw new SecurityException("Not authorized");
+        throw new SecurityException(NOT_AUTHORIZED_PROJECT);
       }
       return project;
+    }
+
+    // Check if the current user is authorized (i.e. is owner of the (sub)project) to set permissions 
+    // for a certain resource (resourceId) in the context of a certain project (projectId)
+    private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId, Guid projectId) {
+      var projectDao = pm.ProjectDao;
+      var project = projectDao.GetById(projectId);
+      if (project == null) throw new SecurityException(NOT_AUTHORIZED_PROJECT);
+
+      var resourceDao = pm.ResourceDao;
+      var resource = resourceDao.GetById(resourceId);
+      if (resource == null) throw new SecurityException(NOT_AUTHORIZED_RESOURCE);
+
+
+      if (project.OwnerUserId != UserManager.CurrentUserId
+        && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
+        throw new SecurityException(NOT_AUTHORIZED_PROJECT);
+      }
+
+      // look up if resourceId is amongst the assigned ones
+      var assignedResources = project.AssignedProjectResources.ToList();
+      if (assignedResources.Select(x => x.ResourceId).Contains(resourceId)) {
+        return resource;
+      }
+
+      // look up if one of the parent resourceIds is amongst the assigned ones
+      // note: this should be faster than checking all children of the assigned 
+      // resource(-groups) for the certain resourceId
+      var parentResourceIds = resourceDao.GetResourceIdsByChildId(resourceId);
+      if(assignedResources.Select(x => x.ResourceId)
+        .Intersect(parentResourceIds).Count() > 0) {
+        return resource;
+      }
+
+      throw new SecurityException(NOT_AUTHORIZED_PROJECT);
     }
     #endregion
