airavata-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From scnakand...@apache.org
Subject [16/57] airavata git commit: adding more files
Date Thu, 28 Jul 2016 17:45:30 GMT
http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/edu/internet2/middleware/grouper/permissions/PermissionFinder.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/edu/internet2/middleware/grouper/permissions/PermissionFinder.java b/modules/group-manager/src/main/java/edu/internet2/middleware/grouper/permissions/PermissionFinder.java
new file mode 100755
index 0000000..390fe31
--- /dev/null
+++ b/modules/group-manager/src/main/java/edu/internet2/middleware/grouper/permissions/PermissionFinder.java
@@ -0,0 +1,770 @@
+/**
+ * Copyright 2014 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author mchyzer
+ * $Id$
+ */
+package edu.internet2.middleware.grouper.permissions;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+
+import edu.internet2.middleware.grouper.GroupFinder;
+import edu.internet2.middleware.grouper.GrouperSession;
+import edu.internet2.middleware.grouper.Member;
+import edu.internet2.middleware.grouper.MemberFinder;
+import edu.internet2.middleware.grouper.Stem;
+import edu.internet2.middleware.grouper.Stem.Scope;
+import edu.internet2.middleware.grouper.attr.AttributeDef;
+import edu.internet2.middleware.grouper.attr.AttributeDefName;
+import edu.internet2.middleware.grouper.attr.finder.AttributeDefFinder;
+import edu.internet2.middleware.grouper.attr.finder.AttributeDefNameFinder;
+import edu.internet2.middleware.grouper.internal.dao.QueryOptions;
+import edu.internet2.middleware.grouper.misc.GrouperDAOFactory;
+import edu.internet2.middleware.grouper.permissions.PermissionEntry.PermissionType;
+import edu.internet2.middleware.grouper.permissions.limits.PermissionLimitBean;
+import edu.internet2.middleware.grouper.permissions.role.Role;
+import edu.internet2.middleware.grouper.util.GrouperUtil;
+import edu.internet2.middleware.subject.Subject;
+
+
+/**
+ *
+ */
+public class PermissionFinder {
+
+  /**
+   * limitEnvVars if processing limits, pass in a map of limits.  The name is the
+   * name of the variable, and the value is the value.  Note, you can typecast the
+   * values by putting a valid type in parens in front of the param name.  e.g.
+   * name: (int)amount, value: 50
+   */
+  private Map<String, Object> limitEnvVars = null;
+  
+  /**
+   * limitEnvVars if processing limits with PermissionProcessor, pass in a map of limits.  The name is the
+   * name of the variable, and the value is the value.  Note, you can typecast the
+   * values by putting a valid type in parens in front of the param name.  e.g.
+   * name: (int)amount, value: 50
+   * @param key
+   * @param value
+   * @return this for chaining
+   */
+  public PermissionFinder addLimitEnvVar(String key, Object value) {
+    if (this.limitEnvVars == null) {
+      this.limitEnvVars = new LinkedHashMap<String, Object>();
+    }
+    this.limitEnvVars.put(key, value);
+    return this;
+  }
+
+  /**
+   * limitEnvVars if processing limits, pass in a map of limits.  The name is the
+   * name of the variable, and the value is the value.  Note, you can typecast the
+   * values by putting a valid type in parens in front of the param name.  e.g.
+   * name: (int)amount, value: 50
+   * @param theEnvVars the map to replace
+   * @return this for chaining
+   */
+  public PermissionFinder assignLimitEnvVars(Map<String, Object> theEnvVars) {
+    this.limitEnvVars = theEnvVars;
+    return this;
+  }
+  
+  /**
+   * 
+   */
+  private Collection<String> memberIds = null;
+  
+  /**
+   * add a member id to the search criteria
+   * @param memberId
+   * @return this for chaining
+   */
+  public PermissionFinder addMemberId(String memberId) {
+    if (this.memberIds == null) {
+      this.memberIds = new ArrayList<String>();
+    }
+    //no need to look for dupes
+    if (!this.memberIds.contains(memberId)) {
+      this.memberIds.add(memberId);
+    }
+    return this;
+  }
+
+  /**
+   * add a collection of member ids to look for
+   * @param theMemberIds
+   * @return this for chaining
+   */
+  public PermissionFinder assignMemberIds(Collection<String> theMemberIds) {
+    this.memberIds = theMemberIds;
+    return this;
+  }
+  
+  /**
+   * add a subject to look for.
+   * @param subject
+   * @return this for chaining
+   */
+  public PermissionFinder addSubject(Subject subject) {
+    
+    //note, since we are chaining, we need to add if not found, since if we dont, it will find for
+    //all subjects if no more are added
+    Member member = MemberFinder.findBySubject(GrouperSession.staticGrouperSession(), subject, true);
+    return this.addMemberId(member.getUuid());
+  }
+  
+  /**
+   * 
+   */
+  private Collection<String> roleIds = null;
+  
+  /**
+   * add a role id to the search criteria
+   * @param roleId
+   * @return this for chaining
+   */
+  public PermissionFinder addRoleId(String roleId) {
+    if (!StringUtils.isBlank(roleId)) {
+      if (this.roleIds == null) {
+        this.roleIds = new ArrayList<String>();
+      }
+      //no need to look for dupes
+      if (!this.roleIds.contains(roleId)) {
+        this.roleIds.add(roleId);
+      }
+    }
+    return this;
+  }
+
+  /**
+   * assign a collection of role ids to look for
+   * @param theRoleIds
+   * @return this for chaining
+   */
+  public PermissionFinder assignRoleIds(Collection<String> theRoleIds) {
+    this.roleIds = theRoleIds;
+    return this;
+  }
+  
+  /**
+   * add a role to look for.
+   * @param role
+   * @return this for chaining
+   */
+  public PermissionFinder addRole(Role role) {
+    
+    return this.addRoleId(role.getId());
+  }
+  
+  /**
+   * add a role to look for by name.
+   * @param name
+   * @return this for chaining
+   */
+  public PermissionFinder addRole(String name) {
+    
+    Role role = GroupFinder.findByName(GrouperSession.staticGrouperSession(), name, true);
+    
+    return this.addRoleId(role.getId());
+  }
+  
+  
+  /**
+   * 
+   */
+  private Collection<String> permissionDefIds = null;
+  
+  /**
+   * add a attribute def id to the search criteria
+   * @param attributeDefId
+   * @return this for chaining
+   */
+  public PermissionFinder addPermissionDefId(String attributeDefId) {
+    if (!StringUtils.isBlank(attributeDefId)) {
+      if (this.permissionDefIds == null) {
+        this.permissionDefIds = new ArrayList<String>();
+      }
+      //no need to look for dupes
+      if (!this.permissionDefIds.contains(attributeDefId)) {
+        this.permissionDefIds.add(attributeDefId);
+      }
+    }
+    return this;
+  }
+
+  /**
+   * assign a collection of attribute def ids to look for
+   * @param theAttributeDefIds
+   * @return this for chaining
+   */
+  public PermissionFinder assignPermissionDefIds(Collection<String> theAttributeDefIds) {
+    this.permissionDefIds = theAttributeDefIds;
+    return this;
+  }
+  
+  /**
+   * if narrowing search for permissions in a certain folder only
+   * @param permissionNameFolder1
+   * @return this for chaining
+   */
+  public PermissionFinder assignPermissionNameFolder(Stem permissionNameFolder1) {
+    this.permissionNameFolder = permissionNameFolder1;
+    return this;
+  }
+  
+  /**
+   * if searching in a folder, this is the scope: only in this folder, or also in subfolders
+   * @param scope
+   * @return this for chaining
+   */
+  public PermissionFinder assignPermissionNameFolderScope(Scope scope) {
+    this.permissionNameFolderScope = scope;
+    return this;
+  }
+  
+  /**
+   * add a attribute def to look for.
+   * @param attributeDef
+   * @return this for chaining
+   */
+  public PermissionFinder addPermissionDef(AttributeDef attributeDef) {
+    
+    return this.addPermissionDefId(attributeDef.getId());
+  }
+  
+  /**
+   * add a attribute def to look for by name.
+   * @param attributeDefName
+   * @return this for chaining
+   */
+  public PermissionFinder addPermissionDef(String attributeDefName) {
+    
+    AttributeDef attributeDef = AttributeDefFinder.findByName(attributeDefName, true);
+    
+    return this.addPermissionDefId(attributeDef.getId());
+  }
+  
+  
+  /**
+   * 
+   */
+  private Collection<String> permissionNameIds = null;
+  
+  /**
+   * if looking for permissions in a certain folder
+   */
+  private Stem permissionNameFolder = null;
+
+  /**
+   * if looking for permissions in any subfolder, or just in this folder directly
+   */
+  private Scope permissionNameFolderScope = null;
+  
+  /**
+   * add an attribute def name id to the search criteria
+   * @param attributeDefNameId
+   * @return this for chaining
+   */
+  public PermissionFinder addPermissionNameId(String attributeDefNameId) {
+    if (!StringUtils.isBlank(attributeDefNameId)) {
+      if (this.permissionNameIds == null) {
+        this.permissionNameIds = new ArrayList<String>();
+      }
+      //no need to look for dupes
+      if (!this.permissionNameIds.contains(attributeDefNameId)) {
+        this.permissionNameIds.add(attributeDefNameId);
+      }
+    }
+    return this;
+  }
+
+  /**
+   * assign a collection of attribute def name ids to look for
+   * @param theAttributeDefNameIds
+   * @return this for chaining
+   */
+  public PermissionFinder assignPermissionNameIds(Collection<String> theAttributeDefNameIds) {
+    this.permissionNameIds = theAttributeDefNameIds;
+    return this;
+  }
+  
+  /**
+   * add a attribute def name to look for.
+   * @param attributeDefName
+   * @return this for chaining
+   */
+  public PermissionFinder addPermissionName(AttributeDefName attributeDefName) {
+    
+    return this.addPermissionNameId(attributeDefName.getId());
+  }
+  
+  /**
+   * add a attribute def name to look for by name.
+   * @param name
+   * @return this for chaining
+   */
+  public PermissionFinder addPermissionName(String name) {
+    
+    AttributeDefName attributeDefName = AttributeDefNameFinder.findByName(name, true);
+    
+    return this.addPermissionNameId(attributeDefName.getId());
+  }
+  
+
+  /**
+   * 
+   */
+  private Collection<String> actions = null;
+  
+  /**
+   * add a action to the search criteria
+   * @param action
+   * @return this for chaining
+   */
+  public PermissionFinder addAction(String action) {
+    if (!StringUtils.isBlank(action)) {
+      if (this.actions == null) {
+        this.actions = new ArrayList<String>();
+      }
+      //no need to look for dupes
+      if (!this.actions.contains(action)) {
+        this.actions.add(action);
+      }
+    }
+    return this;
+  }
+
+  /**
+   * if sorting or paging
+   */
+  private QueryOptions queryOptions;
+  
+  /**
+   * if sorting, paging, caching, etc
+   * @param theQueryOptions
+   * @return this for chaining
+   */
+  public PermissionFinder assignQueryOptions(QueryOptions theQueryOptions) {
+    this.queryOptions = theQueryOptions;
+    return this;
+  }
+  
+  /**
+   * assign actions to search for, return this for chaining
+   * @param theActions
+   * @return this for chaining
+   */
+  public PermissionFinder assignActions(Collection<String> theActions) {
+    this.actions = theActions;
+    return this;
+  }
+  
+  /** if we should look for all, or enabled only.  default is all */
+  private Boolean enabled;
+  
+  /**
+   * true means enabled only, false, means disabled only, and null means all
+   * @param theEnabled
+   * @return this for chaining
+   */
+  public PermissionFinder assignEnabled(Boolean theEnabled) {
+    this.enabled = theEnabled;
+    return this;
+  }
+  
+  /**
+   * if we should find the best answer, or process limits, etc
+   */
+  private PermissionProcessor permissionProcessor;
+
+  /**
+   * if we should find the best answer, or process limits, etc
+   * @param thePermissionProcessor
+   * @return this for chaining
+   */
+  public PermissionFinder assignPermissionProcessor(PermissionProcessor thePermissionProcessor) {
+    this.permissionProcessor = thePermissionProcessor;
+    return this;
+  }
+  
+  /** if we should filter out non immediate permissions */
+  private boolean immediateOnly = false;
+
+  /**
+   * if we should filter out non immediate permissions
+   * @param theImmediate
+   * @return this for chaining
+   */
+  public PermissionFinder assignImmediateOnly(boolean theImmediate) {
+    this.immediateOnly = theImmediate;
+    return this;
+  }
+  
+  /** are we looking for role permissions or subject permissions?  cant be null */
+  private PermissionType permissionType = PermissionType.role_subject;
+  
+  /**
+   * are we looking for role permissions or subject permissions?  cant be null
+   * @param thePermissionType 
+   * @return this for chaining
+   */
+  public PermissionFinder assignPermissionType(PermissionType thePermissionType) {
+    this.permissionType = thePermissionType;
+    return this;
+  }
+  
+  
+  /**
+   * based on what you are querying for, see if has permission.
+   * Note, you should be looking for one subject, 
+   * one action, one resource, one role or multiple roles, etc
+   * If you are looking for multiple, it will see if anyone has that permission
+   * @return true if has permission, false if not
+   */
+  public boolean hasPermission() {
+    
+    //there needs to be a subject if looking by subject
+    if (this.permissionType == PermissionType.role_subject) {
+      if (GrouperUtil.length(this.memberIds) != 1) {
+        throw new RuntimeException("You need to search for 1 and only 1 subject when using hasPermission for subject permissions: " + this);
+      }
+    } else if (this.permissionType == PermissionType.role) {
+      if (GrouperUtil.length(this.roleIds) != 1) {
+        throw new RuntimeException("You need to search for 1 and only 1 role when using hasPermission for role permissions: " + this);
+      }
+    }
+    
+    if (this.permissionProcessor == null) {
+      //get all the permissions for this user in these roles
+      this.permissionProcessor = limitEnvVars == null ? PermissionProcessor.FILTER_REDUNDANT_PERMISSIONS_AND_ROLES
+          : PermissionProcessor.FILTER_REDUNDANT_PERMISSIONS_AND_ROLES_AND_PROCESS_LIMITS ;
+    } else if (this.permissionProcessor != PermissionProcessor.FILTER_REDUNDANT_PERMISSIONS_AND_ROLES 
+        && this.permissionProcessor != PermissionProcessor.FILTER_REDUNDANT_PERMISSIONS_AND_ROLES_AND_PROCESS_LIMITS){
+      throw new RuntimeException("permissionProcessor must be FILTER_REDUNDANT_PERMISSIONS_AND_ROLES " +
+          "or FILTER_REDUNDANT_PERMISSIONS_AND_ROLES_AND_PROCESS_LIMITS");
+    }
+    
+    Set<PermissionEntry> permissionEntriesSet = findPermissions();
+
+    if (GrouperUtil.length(permissionEntriesSet) > 1) {
+      throw new RuntimeException("Why is there more than one permission entry? " + GrouperUtil.stringValue(permissionEntriesSet));
+    }
+    
+    if (GrouperUtil.length(permissionEntriesSet) == 0) {
+      return false;
+    }
+    
+    if (pointInTimeTo != null || pointInTimeFrom != null) {
+      // we're not taking into consideration limits here...
+      return !permissionEntriesSet.iterator().next().isDisallowed();
+    }
+
+    return permissionEntriesSet.iterator().next().isAllowedOverall();
+  }
+  
+  /**
+   * get the permissions, and the limits, so the caller (e.g. the UI/WS) doesnt have to get them again
+   * @return the map of entry to the limits and values
+   */
+  public Map<PermissionEntry, Set<PermissionLimitBean>> findPermissionsAndLimits() {
+    
+    PermissionProcessor originalProcessor = this.permissionProcessor;
+    
+    this.validateProcessor();
+    
+    PermissionProcessor nonLimitProcessor = originalProcessor;
+    boolean getLimits = false;
+
+    if (originalProcessor != null && this.permissionProcessor.isLimitProcessor()) {
+      nonLimitProcessor = this.permissionProcessor.nonLimitPermissionProcesssor();
+      getLimits = true;
+    }
+    
+    //do this without limits
+    this.assignPermissionProcessor(nonLimitProcessor);
+    
+    Set<PermissionEntry> permissionEntrySet = this.findPermissions();
+    
+    //List<PermissionEntry> permissionEntryList = new ArrayList<PermissionEntry>(permissionEntrySet);
+    //for (PermissionEntry permissionEntry : permissionEntryList) {
+    //  System.out.println(permissionEntry.getRole().getDisplayExtension() + " - " 
+    //      + permissionEntry.getSubjectId() + " - " + permissionEntry.getAction() + " - " 
+    //      + permissionEntry.getAttributeDefName().getDisplayExtension() + " - " 
+    //      + permissionEntry.getAttributeAssignId());
+    //}
+    //System.out.println("\n");
+      
+    //assign back original
+    this.assignPermissionProcessor(originalProcessor);
+    
+    //get limits from permissions
+    //CH 20111005: pass PIT to this method, to get limit attribute assignments at a certain point in time
+    Map<PermissionEntry, Set<PermissionLimitBean>> permissionLimitBeanMap = GrouperUtil.nonNull(PermissionLimitBean.findPermissionLimits(permissionEntrySet));
+    
+    //if (GrouperUtil.length(permissionLimitBeanMap) > 0) {
+    //  for (PermissionEntry permissionEntry : permissionLimitBeanMap.keySet()) {
+    //    System.out.println(permissionEntry.getRole().getDisplayExtension() + " - " 
+    //        + permissionEntry.getSubjectId() + " - " + permissionEntry.getAction() + " - " 
+    //        + permissionEntry.getAttributeDefName().getDisplayExtension() + " - " 
+    //        + permissionEntry.getAttributeAssignId() + ":");
+    //    Set<PermissionLimitBean> permissionLimitBeans = permissionLimitBeanMap.get(permissionEntry);
+    //    for (PermissionLimitBean permissionLimitBean : GrouperUtil.nonNull(permissionLimitBeans)) {
+    //      System.out.println("  -> " + permissionLimitBean.getLimitAssign().getId() + " - " 
+    //          + permissionLimitBean.getLimitAssign().getAttributeDefName().getDisplayExtension());
+    //    }
+    //  }
+    //}
+    
+    if (getLimits) {
+      PermissionProcessor.processLimits(permissionEntrySet, this.limitEnvVars, permissionLimitBeanMap);
+    }
+    
+    return permissionLimitBeanMap;
+  }
+
+  /**
+   * permission result gives helper methods in processing the results
+   * @return the permission result
+   */
+  public PermissionResult findPermissionResult() {
+    
+    Set<PermissionEntry> permissionEntries = this.findPermissions();
+    
+    return new PermissionResult(permissionEntries);
+  }
+  
+  /**
+   * find a list of permissions
+   * @return the set of permissions never null
+   */
+  public Set<PermissionEntry> findPermissions() {
+
+    validateProcessor();
+
+    Set<PermissionEntry> permissionEntries = null;
+    
+    if (pointInTimeFrom == null && pointInTimeTo == null) {
+      if (this.permissionType == PermissionType.role_subject) {
+        permissionEntries = GrouperDAOFactory.getFactory().getPermissionEntry().findPermissions(
+            this.permissionDefIds, this.permissionNameIds, this.roleIds, this.actions, this.enabled, 
+            this.memberIds, false, this.permissionNameFolder, this.permissionNameFolderScope, this.queryOptions);
+      } else if (this.permissionType == PermissionType.role) {
+        permissionEntries = GrouperDAOFactory.getFactory().getPermissionEntry().findRolePermissions(
+            this.permissionDefIds, this.permissionNameIds, this.roleIds, this.actions, 
+            this.enabled, false, this.permissionNameFolder, this.permissionNameFolderScope);
+      } else {
+        throw new RuntimeException("Not expecting permission type: " + this.permissionType);
+      }
+    } else {
+      if (this.permissionType == PermissionType.role_subject) {
+        if (this.permissionNameFolder != null) {
+          throw new RuntimeException("Not implemented looking for permissions by folder and point in time");
+        }
+        permissionEntries = GrouperDAOFactory.getFactory().getPITPermissionAllView().findPermissions(
+            permissionDefIds, permissionNameIds, roleIds, actions, memberIds, pointInTimeFrom, pointInTimeTo);
+      } else {
+        throw new RuntimeException("Not expecting permission type: " + this.permissionType);
+      }
+    }
+    
+    //if size is one, there arent redundancies to process
+    if (this.permissionProcessor != null) {
+      this.permissionProcessor.processPermissions(permissionEntries, this.limitEnvVars);
+    }
+    
+    //if immediate only, do this after processing since it might affect the best decision
+    if (this.immediateOnly) {
+      //see if we are doing immediate only
+      Iterator<PermissionEntry> iterator = GrouperUtil.nonNull(permissionEntries).iterator();
+      while (iterator.hasNext()) {
+        PermissionEntry permissionEntry = iterator.next();
+        if (!permissionEntry.isImmediate(this.permissionType)) {
+          iterator.remove();
+        }
+      }
+    }
+    
+    return permissionEntries;
+    
+  }
+
+  /**
+   * validate that the processor dosent conflict with anything...
+   */
+  private void validateProcessor() {
+    if (this.permissionProcessor != null && (this.enabled != null && !this.enabled)) {      
+      throw new RuntimeException("You cannot process the permissions " +
+          "(FILTER_REDUNDANT_PERMISSIONS || FILTER_REUNDANT_PERMISSIONS_AND_ROLES) " +
+          "without looking for enabled permissions only");
+    }
+    
+    //if processing permissions, just look at enabled
+    if (this.permissionProcessor != null && this.enabled == null) {
+      this.enabled = true;
+    }
+    
+    // verify options for point in time queries
+    if (pointInTimeFrom != null || pointInTimeTo != null) {
+      if (limitEnvVars != null && limitEnvVars.size() > 0) {
+        throw new RuntimeException("Cannot use limits for point in time queries.");
+      }
+      
+      if (immediateOnly) {
+        throw new RuntimeException("immediateOnly is not supported for point in time queries.");
+      }
+      
+      if (enabled == null || !enabled) {
+        throw new RuntimeException("Cannot search for disabled permissions for point in time queries.");
+      }
+      
+      if (permissionType == PermissionType.role) {
+        throw new RuntimeException("Permission type " + PermissionType.role.getName() + " is not supported for point in time queries.");
+      }
+      
+      if (permissionProcessor != null) {
+        if (permissionProcessor.isLimitProcessor()) {
+          throw new RuntimeException("limit processors are not supported for point in time queries.");
+        }
+        
+        if (pointInTimeFrom == null || pointInTimeTo == null || pointInTimeFrom.getTime() != pointInTimeTo.getTime()) {
+          throw new RuntimeException("When using permission processors with point in time queries, queries have to be at a single point in time.");
+        }
+      }
+    }
+  }
+
+  /**
+   * find a permission
+   * @param exceptionIfNotFound true if exception should be thrown if permission not found
+   * @return the permission or null
+   */
+  public PermissionEntry findPermission(boolean exceptionIfNotFound) {
+
+    Set<PermissionEntry> permissions = findPermissions();
+    
+    //this should find one if it is there...
+    PermissionEntry permissionEntry = null;
+    
+    if (GrouperUtil.length(permissions) > 1) {
+      throw new RuntimeException("Why is there more than one permission found? " + this);
+    }
+    
+    if (GrouperUtil.length(permissions) == 1) {
+      permissionEntry = permissions.iterator().next();
+    }
+    
+    if (permissionEntry == null && exceptionIfNotFound) {
+      throw new RuntimeException("could not find permission: " 
+          + this);
+    }
+    return permissionEntry;
+    
+  }
+
+  /**
+   * @see Object#toString()
+   */
+  @Override
+  public String toString() {
+    StringBuilder result = new StringBuilder();
+    if (GrouperUtil.length(this.actions) > 0) {
+      result.append("actions: ").append(GrouperUtil.toStringForLog(this.actions, 100));
+    }
+    if (GrouperUtil.length(this.permissionDefIds) > 0) {
+      result.append("attributeDefIds: ").append(GrouperUtil.toStringForLog(this.permissionDefIds, 100));
+    }
+    if (GrouperUtil.length(this.permissionNameIds) > 0) {
+      result.append("attributeDefNameIds: ").append(GrouperUtil.toStringForLog(this.permissionNameIds, 100));
+    }
+    if (enabled != null) {
+      result.append("enabled: ").append(this.enabled);
+    }
+    if (this.immediateOnly) {
+      result.append("immediateOnly: ").append(this.immediateOnly);
+    }
+    if (GrouperUtil.length(this.limitEnvVars) > 0) {
+      result.append("limitEnvVars: ").append(GrouperUtil.toStringForLog(this.limitEnvVars, 100));
+    }
+    if (GrouperUtil.length(this.memberIds) > 0) {
+      result.append("memberIds: ").append(GrouperUtil.toStringForLog(this.memberIds, 100));
+    }
+    if (this.permissionProcessor != null) {
+      result.append("permissionProcessor: ").append(this.permissionProcessor);
+    }
+    if (this.permissionType != null) {
+      result.append("permissionType: ").append(this.permissionType);
+    }
+    if (GrouperUtil.length(this.roleIds) > 0) {
+      result.append("roleIds: ").append(GrouperUtil.toStringForLog(this.roleIds, 100));
+    }
+    return result.toString();
+  }
+
+  /**
+   * To query permissions at a certain point in time or time range in the past, set this value
+   * and/or the value of pointInTimeTo.  This parameter specifies the start of the range
+   * of the point in time query.  If this is specified but pointInTimeTo is not specified,
+   * then the point in time query range will be from the time specified to now.
+   */
+  private Timestamp pointInTimeFrom = null;
+  
+  /**
+   * To query permissions at a certain point in time or time range in the past, set this value
+   * and/or the value of pointInTimeFrom.  This parameter specifies the end of the range
+   * of the point in time query.  If this is the same as pointInTimeFrom, then the query
+   * will be done at a single point in time rather than a range.  If this is specified but
+   * pointInTimeFrom is not specified, then the point in time query range will be from the
+   * minimum point in time to the time specified.
+   */
+  private Timestamp pointInTimeTo = null;
+  
+  /**
+   * To query permissions at a certain point in time or time range in the past, set this value
+   * and/or the value of pointInTimeTo.  This parameter specifies the start of the range
+   * of the point in time query.  If this is specified but pointInTimeTo is not specified,
+   * then the point in time query range will be from the time specified to now.
+   * @param pointInTimeFrom 
+   * @return this for changing
+   */
+  public PermissionFinder assignPointInTimeFrom(Timestamp pointInTimeFrom) {
+    this.pointInTimeFrom = pointInTimeFrom;
+    return this;
+  }
+  
+  /**
+   * To query permissions at a certain point in time or time range in the past, set this value
+   * and/or the value of pointInTimeFrom.  This parameter specifies the end of the range
+   * of the point in time query.  If this is the same as pointInTimeFrom, then the query
+   * will be done at a single point in time rather than a range.  If this is specified but
+   * pointInTimeFrom is not specified, then the point in time query range will be from the
+   * minimum point in time to the time specified.
+   * @param pointInTimeTo 
+   * @return this for changing
+   */
+  public PermissionFinder assignPointInTimeTo(Timestamp pointInTimeTo) {
+    this.pointInTimeTo = pointInTimeTo;
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/AiravataGrouperUtil.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/AiravataGrouperUtil.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/AiravataGrouperUtil.java
new file mode 100755
index 0000000..3dc164c
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/AiravataGrouperUtil.java
@@ -0,0 +1,35 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper;
+
+
+/**
+ * @author vsachdeva
+ *
+ */
+public class AiravataGrouperUtil {
+  
+  public static final String COLON = ":";
+  
+  public static final String ROOT_STEM_NAME = "airavata";
+  
+  public static final String ROLES_STEM_NAME = ROOT_STEM_NAME + COLON + "roles";
+  
+  public static final String GROUPS_STEM_NAME = ROOT_STEM_NAME + COLON +"groups";
+  
+  public static final String PROJECT_STEM_NAME = ROOT_STEM_NAME + COLON + "projects";
+
+  public static final String EXPERIMENT_STEM_NAME = ROOT_STEM_NAME + COLON + "experiments";
+  
+  public static final String DATA_STEM_NAME = ROOT_STEM_NAME + COLON + "data";
+  
+  public static final String OTHER_STEM_NAME = ROOT_STEM_NAME + COLON + "other";
+  
+  public static final String PERMISSIONS_ATTRIBUTE_DEF = ROOT_STEM_NAME +  COLON + "permissions" + COLON + "airavataAttributeDef";
+  
+  public static final String SUBJECT_SOURCE = "AIRAVATA_SUBJECT_SOURCE";
+  
+  
+  
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerCPI.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerCPI.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerCPI.java
new file mode 100644
index 0000000..70ef6a2
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerCPI.java
@@ -0,0 +1,24 @@
+package org.apache.airavata.grouper;
+
+import org.apache.airavata.grouper.permission.PermissionAction;
+import org.apache.airavata.grouper.resource.Resource;
+import org.apache.airavata.grouper.resource.ResourceType;
+
+import java.util.List;
+import java.util.Set;
+
+public interface GroupManagerCPI {
+    void createResource(Resource projectResource);
+
+    boolean isResourceRegistered(String resourceId, org.apache.airavata.grouper.resource.ResourceType resourceType);
+
+    void grantPermission(String userId, SubjectType subjectType, String resourceId, ResourceType resourceType,
+                         PermissionAction permissionAction);
+
+    void revokePermission(String userId, SubjectType subjectType, String resourceId, ResourceType resourceType,
+                          PermissionAction action);
+
+    Set<String> getAllAccessibleUsers(String resourceId, ResourceType resourceType, PermissionAction permissionType);
+
+    List<String> getAccessibleResourcesForUser(String userId, ResourceType resourceType, PermissionAction permissionAction);
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerException.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerException.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerException.java
new file mode 100644
index 0000000..4f8951e
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerException.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+package org.apache.airavata.grouper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupManagerException extends Exception {
+    private final static Logger logger = LoggerFactory.getLogger(GroupManagerException.class);
+
+    public GroupManagerException(Exception e) {
+        super(e);
+    }
+
+    public GroupManagerException(String s) {
+        super(s);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerFactory.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerFactory.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerFactory.java
new file mode 100644
index 0000000..5c6a447
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerFactory.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+package org.apache.airavata.grouper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupManagerFactory {
+    private final static Logger logger = LoggerFactory.getLogger(GroupManagerFactory.class);
+
+    private static GroupManagerCPI groupManager;
+
+    public static GroupManagerCPI getGroupManager() throws GroupManagerException {
+        try {
+            if (groupManager == null) {
+                 groupManager = new GroupManagerImpl();
+            }
+        } catch (Exception e) {
+            logger.error("Unable to create Group Manager client", e);
+            throw new GroupManagerException(e);
+        }
+        return groupManager;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerImpl.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerImpl.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerImpl.java
new file mode 100644
index 0000000..db5993d
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/GroupManagerImpl.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+package org.apache.airavata.grouper;
+
+import org.apache.airavata.grouper.permission.PermissionAction;
+import org.apache.airavata.grouper.permission.PermissionServiceImpl;
+import org.apache.airavata.grouper.resource.Resource;
+import org.apache.airavata.grouper.resource.ResourceServiceImpl;
+import org.apache.airavata.grouper.resource.ResourceType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+public class GroupManagerImpl implements GroupManagerCPI {
+    private final static Logger logger = LoggerFactory.getLogger(GroupManagerImpl.class);
+
+    private ResourceServiceImpl resourceService;
+    private PermissionServiceImpl permissionService;
+
+    public GroupManagerImpl(){
+        this.resourceService = new ResourceServiceImpl();
+        this.permissionService = new PermissionServiceImpl();
+    }
+
+    @Override
+    public void createResource(Resource projectResource) {
+        resourceService.createResource(projectResource);
+    }
+
+    @Override
+    public boolean isResourceRegistered(String resourceId, ResourceType resourceType) {
+        return resourceService.getResource(resourceId, resourceType) != null;
+    }
+
+    @Override
+    public void grantPermission(String userId, SubjectType subjectType, String resourceId, ResourceType resourceType,
+                                PermissionAction permissionAction) {
+        permissionService.grantPermission(userId, subjectType, resourceId, resourceType, permissionAction);
+    }
+
+    @Override
+    public void revokePermission(String userId, SubjectType subjectType, String resourceId, ResourceType resourceType,
+                                 PermissionAction action) {
+        permissionService.revokePermission(userId, subjectType, resourceId, resourceType, action);
+    }
+
+    @Override
+    public Set<String> getAllAccessibleUsers(String resourceId, ResourceType resourceType, PermissionAction permissionType) {
+        return resourceService.getAllAccessibleUsers(resourceId, resourceType, permissionType);
+    }
+
+    @Override
+    public List<String> getAccessibleResourcesForUser(String userId, ResourceType resourceType, PermissionAction permissionAction) {
+        Set<Resource> allResources = resourceService.getAccessibleResourcesForUser(userId, resourceType, permissionAction, false, 0, -1);
+        List<String> ids = new ArrayList<>(allResources.size());
+        allResources.stream().forEach(r->ids.add(r.getId()));
+        return ids;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/SubjectType.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/SubjectType.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/SubjectType.java
new file mode 100755
index 0000000..81e3f27
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/SubjectType.java
@@ -0,0 +1,14 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper;
+
+
+/**
+ * @author vsachdeva
+ *
+ */
+public enum SubjectType {
+  PERSON,
+  GROUP
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/Group.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/Group.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/Group.java
new file mode 100755
index 0000000..fdb64b4
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/Group.java
@@ -0,0 +1,94 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper.group;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author vsachdeva
+ *
+ */
+public class Group {
+  
+  private String id;
+  
+  private String name;
+  
+  private String description;
+  
+  private List<String> users = new ArrayList<String>();
+  
+  /**
+   * @return the id
+   */
+  public String getId() {
+    return id;
+  }
+
+  
+  /**
+   * @param id the id to set
+   */
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  
+  /**
+   * @return the name
+   */
+  public String getName() {
+    return name;
+  }
+
+  
+  /**
+   * @param name the name to set
+   */
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  
+  /**
+   * @return the description
+   */
+  public String getDescription() {
+    return description;
+  }
+
+  
+  /**
+   * @param description the description to set
+   */
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+  
+  /**
+   * @return the users
+   */
+  public List<String> getUsers() {
+    return users;
+  }
+
+  /**
+   * @param users the users to set
+   */
+  public void setUsers(List<String> users) {
+    this.users = users;
+  }
+
+
+  /**
+   * @see Object#toString()
+   */
+  @Override
+  public String toString() {
+    return "Group [id=" + id + ", name=" + name + ", description=" + description + "]";
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupMembership.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupMembership.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupMembership.java
new file mode 100755
index 0000000..1348aa3
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupMembership.java
@@ -0,0 +1,88 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper.group;
+
+import org.apache.airavata.grouper.SubjectType;
+
+/**
+ * @author vsachdeva
+ *
+ */
+public class GroupMembership {
+  
+  private String groupId;
+  
+  private String memberId;
+  
+  private SubjectType memberType;
+  
+  private GroupMembershipType groupMembershipType;
+  
+  /**
+   * @return the groupId
+   */
+  public String getGroupId() {
+    return groupId;
+  }
+  
+  /**
+   * @param groupId the groupId to set
+   */
+  public void setGroupId(String groupId) {
+    this.groupId = groupId;
+  }
+  
+  /**
+   * @return the memberId
+   */
+  public String getMemberId() {
+    return memberId;
+  }
+  
+  /**
+   * @param memberId the memberId to set
+   */
+  public void setMemberId(String memberId) {
+    this.memberId = memberId;
+  }
+  
+  /**
+   * @return the memberType
+   */
+  public SubjectType getMemberType() {
+    return memberType;
+  }
+  
+  /**
+   * @param memberType the memberType to set
+   */
+  public void setMemberType(SubjectType memberType) {
+    this.memberType = memberType;
+  }
+  
+  /**
+   * @return the groupMembershipType
+   */
+  public GroupMembershipType getGroupMembershipType() {
+    return groupMembershipType;
+  }
+  
+  /**
+   * @param groupMembershipType the groupMembershipType to set
+   */
+  public void setGroupMembershipType(GroupMembershipType groupMembershipType) {
+    this.groupMembershipType = groupMembershipType;
+  }
+
+  /**
+   * @see Object#toString()
+   */
+  @Override
+  public String toString() {
+    return "GroupMembership [groupId=" + groupId + ", memberId=" + memberId
+        + ", memberType=" + memberType + ", groupMembershipType=" + groupMembershipType
+        + "]";
+  }
+    
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupMembershipType.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupMembershipType.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupMembershipType.java
new file mode 100755
index 0000000..f5bbdaa
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupMembershipType.java
@@ -0,0 +1,12 @@
+package org.apache.airavata.grouper.group;
+
+/**
+ * 
+ * @author vsachdeva
+ *
+ */
+public enum GroupMembershipType {
+
+  DIRECT,
+  INDIRECT
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupService.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupService.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupService.java
new file mode 100755
index 0000000..b80b1a1
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupService.java
@@ -0,0 +1,24 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper.group;
+
+import edu.internet2.middleware.grouper.exception.GroupNotFoundException;
+
+/**
+ * @author vsachdeva
+ *
+ */
+public interface GroupService {
+  
+  public void createOrUpdateGroup(Group group);
+  
+  public void deleteGroup(String groupId) throws GroupNotFoundException;
+  
+  public Group getGroup(String groupId) throws GroupNotFoundException;
+  
+  public void addGroupToGroup(String parentGroupId, String childGroupId) throws GroupNotFoundException;
+  
+  public void removeGroupFromGroup(String parentGroupId, String childGroupId) throws GroupNotFoundException;
+
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupServiceImpl.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupServiceImpl.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupServiceImpl.java
new file mode 100755
index 0000000..b63f401
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/group/GroupServiceImpl.java
@@ -0,0 +1,228 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper.group;
+
+import edu.internet2.middleware.grouper.*;
+import edu.internet2.middleware.grouper.exception.GroupNotFoundException;
+import edu.internet2.middleware.grouper.group.TypeOfGroup;
+import edu.internet2.middleware.grouper.internal.dao.QueryOptions;
+import edu.internet2.middleware.grouper.util.GrouperUtil;
+import edu.internet2.middleware.subject.Subject;
+import edu.internet2.middleware.subject.SubjectNotFoundException;
+import org.apache.airavata.grouper.SubjectType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static edu.internet2.middleware.grouper.misc.SaveMode.INSERT_OR_UPDATE;
+import static edu.internet2.middleware.subject.provider.SubjectTypeEnum.PERSON;
+import static org.apache.airavata.grouper.AiravataGrouperUtil.*;
+import static org.apache.airavata.grouper.group.GroupMembershipType.DIRECT;
+import static org.apache.airavata.grouper.group.GroupMembershipType.INDIRECT;
+
+/**
+ * @author vsachdeva
+ *
+ */
+public class GroupServiceImpl implements GroupService {
+  
+  
+  public void createOrUpdateGroup(Group group) {
+    
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      GroupSave groupSave = new GroupSave(grouperSession);
+      groupSave.assignTypeOfGroup(TypeOfGroup.group);
+      groupSave.assignGroupNameToEdit(GROUPS_STEM_NAME+COLON+group.getId());
+      groupSave.assignName(GROUPS_STEM_NAME+COLON+group.getId());
+      groupSave.assignDisplayExtension(group.getName());
+      groupSave.assignDescription(group.getDescription());
+      groupSave.assignSaveMode(INSERT_OR_UPDATE);
+      groupSave.assignCreateParentStemsIfNotExist(true);
+      edu.internet2.middleware.grouper.Group grp = groupSave.save();
+      for (String userId: group.getUsers()) {
+        Subject subject = SubjectFinder.findByIdAndSource(userId, SUBJECT_SOURCE, false);
+        if (subject == null) {
+          throw new SubjectNotFoundException(userId+" airavata internal user id was not found.");
+        }
+        grp.addMember(subject, false);
+      }
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+  }
+  
+  public void deleteGroup(String groupId) throws GroupNotFoundException {
+    
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      edu.internet2.middleware.grouper.Group group = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+groupId, 
+          true, new QueryOptions().secondLevelCache(false));
+      group.delete();
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+  }
+  
+  public Group getGroup(String groupId) throws GroupNotFoundException {
+    
+    GrouperSession grouperSession = null;
+    Group group = new Group();
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      edu.internet2.middleware.grouper.Group grouperGroup = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+groupId, true);
+      group.setId(grouperGroup.getExtension());
+      group.setName(grouperGroup.getDisplayExtension());
+      group.setDescription(grouperGroup.getDescription());
+      List<String> users = new ArrayList<String>();
+      for(Member member: grouperGroup.getMembers()) {
+        if (member.getSubjectType().equals(PERSON)) {
+          users.add(member.getSubjectId());
+        }
+      }
+      group.setUsers(users);
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+    return group;
+  }
+  
+  public void addGroupToGroup(String parentGroupId, String childGroupId) throws GroupNotFoundException {
+    
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      edu.internet2.middleware.grouper.Group grouperParentGroup = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+parentGroupId, true);
+      edu.internet2.middleware.grouper.Group grouperChildGroup = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+childGroupId, true);
+      Subject subject = SubjectFinder.findById(grouperChildGroup.getId(), false);
+      if (subject == null) {
+        throw new GroupNotFoundException(childGroupId+" was not found.");
+      }
+      grouperParentGroup.addMember(subject, false);
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+  }
+  
+  public void removeGroupFromGroup(String parentGroupId, String childGroupId) throws GroupNotFoundException {
+    
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      edu.internet2.middleware.grouper.Group grouperParentGroup = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+parentGroupId, true);
+      edu.internet2.middleware.grouper.Group grouperChildGroup = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+childGroupId, true);
+      Subject subject = SubjectFinder.findById(grouperChildGroup.getId(), false);
+      if (subject == null) {
+        throw new SubjectNotFoundException(childGroupId+" was not found.");
+      }
+      grouperParentGroup.deleteMember(subject, false);
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+  }
+  
+  public void addUserToGroup(String userId, String groupId) throws SubjectNotFoundException, GroupNotFoundException {
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      edu.internet2.middleware.grouper.Group group = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+groupId, true);
+      Subject subject = SubjectFinder.findByIdAndSource(userId, SUBJECT_SOURCE, true);
+      group.addMember(subject, false);
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+  }
+  
+  public void removeUserFromGroup(String userId, String groupId) throws SubjectNotFoundException, GroupNotFoundException {
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      edu.internet2.middleware.grouper.Group group = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+groupId, true);
+      Subject subject = SubjectFinder.findByIdAndSource(userId, SUBJECT_SOURCE, true);
+      group.deleteMember(subject, false);
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+  }
+  
+  public List<GroupMembership> getAllMembersForTheGroup(String groupId) throws GroupNotFoundException {
+    List<GroupMembership> groupMemberships = new ArrayList<GroupMembership>();
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      edu.internet2.middleware.grouper.Group grouperGroup = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+groupId, true);
+      for(Member member: grouperGroup.getImmediateMembers()) {
+        GroupMembership groupMembership = new GroupMembership();
+        groupMembership.setGroupId(groupId);
+        groupMembership.setGroupMembershipType(DIRECT);
+        groupMembership.setMemberId(member.getSubjectType().equals(PERSON) ? member.getSubjectId() : GrouperUtil.substringAfterLast(member.getName(), ":"));
+        groupMembership.setMemberType(member.getSubjectType().equals(PERSON) ? SubjectType.PERSON: SubjectType.GROUP);
+        groupMemberships.add(groupMembership);
+      }
+      for(Member member: grouperGroup.getNonImmediateMembers()) {
+        GroupMembership groupMembership = new GroupMembership();
+        groupMembership.setGroupId(groupId);
+        groupMembership.setGroupMembershipType(INDIRECT);
+        groupMembership.setMemberId(member.getSubjectType().equals(PERSON) ? member.getSubjectId() : GrouperUtil.substringAfterLast(member.getName(), ":"));
+        groupMembership.setMemberType(member.getSubjectType().equals(PERSON) ? SubjectType.PERSON: SubjectType.GROUP);
+        groupMemberships.add(groupMembership);
+      }
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+    return groupMemberships;
+  }
+  
+  public static void main(String[] args) {
+    
+    GroupServiceImpl groupServiceImpl = new GroupServiceImpl();
+    
+    // create a test group
+    Group parentGroup = new Group();
+    parentGroup.setId("airavata parent group id");
+    parentGroup.setName("airavata parent group name");
+    parentGroup.setDescription("airavata parent group description");
+    groupServiceImpl.createOrUpdateGroup(parentGroup);
+    
+    // update the same group
+    Group updateGroup = new Group();
+    updateGroup.setId("airavata parent group id");
+    updateGroup.setName("airavata parent group name updated");
+    updateGroup.setDescription("airavata parent group description updated");
+    groupServiceImpl.createOrUpdateGroup(updateGroup);
+    
+    // create another group
+    Group childGroup = new Group();
+    childGroup.setId("airavata child group id");
+    childGroup.setName("airavata child group name");
+    childGroup.setDescription("airavata child group description");
+    groupServiceImpl.createOrUpdateGroup(childGroup);
+    
+    // add child group to parent group
+    groupServiceImpl.addGroupToGroup("airavata parent group id", "airavata child group id");
+      
+    // add a direct person to the group
+    groupServiceImpl.addUserToGroup("admin@seagrid", "airavata parent group id");
+    
+    // add a person to the child group which will be basically an indirect member of parent group
+    groupServiceImpl.addUserToGroup("scnakandala@seagrid", "airavata child group id");
+    
+    // get the parent group
+    groupServiceImpl.getGroup("airavata parent group id");
+    
+    //get all the members of the group
+    groupServiceImpl.getAllMembersForTheGroup("airavata parent group id");
+    
+    // remove child from parent
+    groupServiceImpl.removeGroupFromGroup("airavata parent group id", "airavata child group id");
+    
+    // delete the same group 
+    groupServiceImpl.deleteGroup("airavata child group id");
+    groupServiceImpl.deleteGroup("airavata parent group id");
+    
+  }
+ 
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/permission/PermissionAction.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/permission/PermissionAction.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/permission/PermissionAction.java
new file mode 100755
index 0000000..d0aed09
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/permission/PermissionAction.java
@@ -0,0 +1,15 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper.permission;
+
+
+/**
+ * @author vsachdeva
+ *
+ */
+public enum PermissionAction {
+  
+  WRITE, READ;
+
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/permission/PermissionServiceImpl.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/permission/PermissionServiceImpl.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/permission/PermissionServiceImpl.java
new file mode 100755
index 0000000..631b09e
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/permission/PermissionServiceImpl.java
@@ -0,0 +1,86 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper.permission;
+
+import static org.apache.airavata.grouper.AiravataGrouperUtil.COLON;
+import static org.apache.airavata.grouper.AiravataGrouperUtil.GROUPS_STEM_NAME;
+import static org.apache.airavata.grouper.AiravataGrouperUtil.SUBJECT_SOURCE;
+import static org.apache.airavata.grouper.SubjectType.PERSON;
+
+import org.apache.airavata.grouper.SubjectType;
+import org.apache.airavata.grouper.resource.ResourceType;
+import org.apache.airavata.grouper.role.RoleServiceImpl;
+
+import edu.internet2.middleware.grouper.GroupFinder;
+import edu.internet2.middleware.grouper.GrouperSession;
+import edu.internet2.middleware.grouper.SubjectFinder;
+import edu.internet2.middleware.subject.Subject;
+
+/**
+ * @author vsachdeva
+ *
+ */
+public class PermissionServiceImpl {
+  
+  
+  public void grantPermission(String userIdOrGroupId, SubjectType subjectType, String resourceId, ResourceType resourceType, PermissionAction action) {
+    
+    if (userIdOrGroupId == null || subjectType == null || resourceId == null || resourceType == null || action == null) {
+      throw new IllegalArgumentException("Invalid input");
+    }
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      Subject subject = null;
+      if (PERSON == subjectType) {
+         subject = SubjectFinder.findByIdAndSource(userIdOrGroupId, SUBJECT_SOURCE, false);
+      } else {
+        edu.internet2.middleware.grouper.Group grouperGroup = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+userIdOrGroupId, false);
+        if (grouperGroup == null) {
+          throw new IllegalArgumentException("group with id/name "+userIdOrGroupId+" could not be found.");
+        }
+        subject = SubjectFinder.findById(grouperGroup.getId(), false);
+      }
+      
+      if (subject == null) {
+        throw new IllegalArgumentException("userIdOrGroupId "+userIdOrGroupId+" could not be found.");
+      }
+      RoleServiceImpl roleService = new RoleServiceImpl();
+      roleService.assignRoleToUser(subject.getId(), resourceId+"_"+action, grouperSession);
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+    
+  }
+  
+  public void revokePermission(String userIdOrGroupId, SubjectType subjectType, String resourceId, ResourceType resourceType, PermissionAction action) {
+    if (userIdOrGroupId == null || subjectType == null || resourceId == null || resourceType == null || action == null) {
+      throw new IllegalArgumentException("Invalid input");
+    }
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      Subject subject = null;
+      if (PERSON == subjectType) {
+        subject = SubjectFinder.findByIdAndSource(userIdOrGroupId, SUBJECT_SOURCE, false);
+      } else {
+        edu.internet2.middleware.grouper.Group grouperGroup = GroupFinder.findByName(grouperSession, GROUPS_STEM_NAME+COLON+userIdOrGroupId, false);
+        if (grouperGroup == null) {
+          throw new IllegalArgumentException("group with id/name "+userIdOrGroupId+" could not be found.");
+        }
+        subject = SubjectFinder.findById(grouperGroup.getId(), false);
+      }
+      
+      if (subject == null) {
+        throw new IllegalArgumentException("userIdOrGroupId "+userIdOrGroupId+" could not be found.");
+      }
+      RoleServiceImpl roleService = new RoleServiceImpl();
+      roleService.removeRoleFromUser(subject.getId(), resourceId+"_"+action, grouperSession);
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+  }
+  
+  
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/Resource.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/Resource.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/Resource.java
new file mode 100755
index 0000000..f599647
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/Resource.java
@@ -0,0 +1,145 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper.resource;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+/**
+ * @author vsachdeva
+ *
+ */
+public class Resource {
+  
+  private String id;
+  
+  private String name;
+  
+  private String description;
+  
+  private String parentResourceId;
+  
+  private ResourceType type;
+  
+  private String ownerId;
+  
+  public Resource(String resourceId, ResourceType resourceType) {
+    if (resourceId == null || resourceType == null) {
+      throw new IllegalArgumentException("Either resourceId or resourceType is null");
+    }
+    this.id = resourceId;
+    this.type = resourceType;
+  }
+  
+  
+  /**
+   * @return the resourceId
+   */
+  public String getId() {
+    return id;
+  }
+
+  
+  /**
+   * @return the resourceName
+   */
+  public String getName() {
+    return name;
+  }
+
+  
+  /**
+   * @param resourceName the resourceName to set
+   */
+  public void setName(String resourceName) {
+    this.name = resourceName;
+  }
+
+  /**
+   * @return the resourceDescription
+   */
+  public String getDescription() {
+    return description;
+  }
+
+  
+  /**
+   * @param resourceDescription the resourceDescription to set
+   */
+  public void setDescription(String resourceDescription) {
+    this.description = resourceDescription;
+  }
+
+
+  /**
+   * @return the parentResourceId
+   */
+  public String getParentResourceId() {
+    return parentResourceId;
+  }
+
+
+  /**
+   * @param parentResourceId the parentResourceId to set
+   */
+  public void setParentResourceId(String parentResourceId) {
+    this.parentResourceId = parentResourceId;
+  }
+  
+  
+  /**
+   * @return the resourceType
+   */
+  public ResourceType getResourceType() {
+    return type;
+  }
+  
+  
+  /**
+   * @return the ownerId
+   */
+  public String getOwnerId() {
+    return ownerId;
+  }
+
+  
+  /**
+   * @param ownerId the ownerId to set
+   */
+  public void setOwnerId(String ownerId) {
+    this.ownerId = ownerId;
+  }
+  
+  
+  @Override
+  public boolean equals(Object other) {
+    if (this == other) {
+      return true;
+    }
+    if (!(other instanceof Resource)) {
+      return false;
+    }
+    return StringUtils.equals(this.getId(), ( (Resource) other ).getId());
+  }
+
+ 
+  @Override
+  public int hashCode() {
+    return new HashCodeBuilder()
+      .append( this.getId() )
+      .toHashCode();
+  }
+
+
+  @Override
+  public String toString() {
+    return "Resource [resourceId=" + id + ", resourceName=" + name
+        + ", resourceDescription=" + description + ", parentResourceId="
+        + parentResourceId + ", resourceType=" + type + "]";
+  }
+  
+  
+
+  
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceNotFoundException.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceNotFoundException.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceNotFoundException.java
new file mode 100755
index 0000000..b5a19c6
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceNotFoundException.java
@@ -0,0 +1,35 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper.resource;
+
+
+/**
+ * @author vsachdeva
+ *
+ */
+public class ResourceNotFoundException extends RuntimeException {
+
+  private static final long serialVersionUID = 1L;
+
+
+  public ResourceNotFoundException() { 
+    super(); 
+  }
+  
+
+  public ResourceNotFoundException(String msg) { 
+    super(msg); 
+  }
+  
+
+  public ResourceNotFoundException(String msg, Throwable cause) { 
+    super(msg, cause); 
+  }
+  
+
+  public ResourceNotFoundException(Throwable cause) { 
+    super(cause); 
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceServiceImpl.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceServiceImpl.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceServiceImpl.java
new file mode 100755
index 0000000..2f7b4c5
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceServiceImpl.java
@@ -0,0 +1,351 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper.resource;
+
+import edu.internet2.middleware.grouper.*;
+import edu.internet2.middleware.grouper.Stem.Scope;
+import edu.internet2.middleware.grouper.attr.*;
+import edu.internet2.middleware.grouper.attr.assign.AttributeAssignAction;
+import edu.internet2.middleware.grouper.attr.finder.AttributeDefFinder;
+import edu.internet2.middleware.grouper.attr.finder.AttributeDefNameFinder;
+import edu.internet2.middleware.grouper.internal.dao.QueryOptions;
+import edu.internet2.middleware.grouper.misc.SaveMode;
+import edu.internet2.middleware.grouper.permissions.PermissionAllowed;
+import edu.internet2.middleware.grouper.permissions.PermissionEntry;
+import edu.internet2.middleware.grouper.permissions.PermissionFinder;
+import edu.internet2.middleware.subject.Subject;
+import edu.internet2.middleware.subject.SubjectNotFoundException;
+import org.apache.airavata.grouper.SubjectType;
+import org.apache.airavata.grouper.group.GroupServiceImpl;
+import org.apache.airavata.grouper.permission.PermissionAction;
+import org.apache.airavata.grouper.permission.PermissionServiceImpl;
+import org.apache.airavata.grouper.role.RoleServiceImpl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.airavata.grouper.AiravataGrouperUtil.*;
+import static org.apache.airavata.grouper.permission.PermissionAction.READ;
+import static org.apache.airavata.grouper.permission.PermissionAction.WRITE;
+import static org.apache.airavata.grouper.resource.ResourceType.*;
+
+/**
+ * @author vsachdeva
+ *
+ */
+public class ResourceServiceImpl {
+  
+  
+  //TODO: break this method into smaller methods
+  public void createResource(Resource resource) throws ResourceNotFoundException {
+    
+    validateResource(resource);
+    
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      AttributeDefName parentAttributeDefName = null;
+      
+      // make sure that the parent resource exists in grouper if it is in the request
+      if (resource.getParentResourceId() != null) {
+        parentAttributeDefName = AttributeDefNameFinder.findByName(resource.getResourceType().getParentResoruceType()
+            .getStemFromResourceType()+COLON+resource.getParentResourceId(), false);
+        if (parentAttributeDefName == null) {
+          throw new ResourceNotFoundException(resource.getParentResourceId() +" was not found.");
+        }
+      }
+      
+      Subject subject = SubjectFinder.findByIdAndSource(resource.getOwnerId(), SUBJECT_SOURCE, false);
+      if (subject == null) {
+        throw new IllegalArgumentException("Resource owner id "+resource.getOwnerId()+" could not be found.");
+      }
+      
+      // create an attribute def if doesn't exist
+      AttributeDef attributeDef = AttributeDefFinder.findByName(PERMISSIONS_ATTRIBUTE_DEF, false);
+      if (attributeDef == null) {
+        AttributeDefSave attributeDefSave = new AttributeDefSave(grouperSession);
+        attributeDef = attributeDefSave.assignAttributeDefType(AttributeDefType.perm).assignToGroup(true)
+          .assignToEffMembership(true).assignName(PERMISSIONS_ATTRIBUTE_DEF).assignCreateParentStemsIfNotExist(true)
+          .assignSaveMode(SaveMode.INSERT_OR_UPDATE).save();
+        AttributeAssignAction read = attributeDef.getAttributeDefActionDelegate().addAction(READ.name());
+        AttributeAssignAction write = attributeDef.getAttributeDefActionDelegate().addAction(WRITE.name());
+        write.getAttributeAssignActionSetDelegate().addToAttributeAssignActionSet(read);
+      }
+      
+      // create attribute def name
+      AttributeDefNameSave attributeDefNameSave = new AttributeDefNameSave(grouperSession, attributeDef);
+      attributeDefNameSave.assignCreateParentStemsIfNotExist(true);
+      attributeDefNameSave.assignSaveMode(SaveMode.INSERT_OR_UPDATE);
+      attributeDefNameSave.assignAttributeDefNameNameToEdit(resource.getResourceType().getStemFromResourceType()+COLON+resource.getId());
+      attributeDefNameSave.assignName(resource.getResourceType().getStemFromResourceType()+COLON+resource.getId());
+      attributeDefNameSave.assignDescription(resource.getDescription());
+      attributeDefNameSave.assignDisplayName(resource.getName());
+      AttributeDefName attributeDefName = attributeDefNameSave.save();
+      
+      // set the inheritance if parent attribute def name is not null
+      if (parentAttributeDefName != null) {
+        parentAttributeDefName.getAttributeDefNameSetDelegate().addToAttributeDefNameSet(attributeDefName);
+      }
+      
+      RoleServiceImpl roleService = new RoleServiceImpl();
+      //TODO remove the session being passed
+      Group readRole = roleService.createRole(resource.getId()+"_"+READ.name(), grouperSession);
+      Group writeRole = roleService.createRole(resource.getId()+"_"+WRITE.name(), grouperSession);
+      
+      readRole.getPermissionRoleDelegate().assignRolePermission(READ.name(), attributeDefName, PermissionAllowed.ALLOWED);
+      writeRole.getPermissionRoleDelegate().assignRolePermission(WRITE.name(), attributeDefName, PermissionAllowed.ALLOWED);
+      writeRole.getRoleInheritanceDelegate().addRoleToInheritFromThis(readRole);
+      
+      // give the write role to ownerId
+      roleService.assignRoleToUser(resource.getOwnerId(), resource.getId()+"_"+WRITE.name(), grouperSession);
+      
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+  }
+  
+  public void deleteResource(String resourceId, ResourceType resourceType) throws ResourceNotFoundException {
+    if (resourceId == null || resourceType == null) {
+      throw new IllegalArgumentException("resouceId "+resourceId+" is null or resourceType"+resourceType+" is null.");
+    }
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      AttributeDefName attributeDefName = AttributeDefNameFinder.findByName(resourceType.getStemFromResourceType()+COLON+resourceId, false);
+      if (attributeDefName == null) {
+        throw new ResourceNotFoundException(resourceId +" was not found.");
+      }
+      RoleServiceImpl roleService = new RoleServiceImpl();
+      // delete all the children resources and roles
+      for (AttributeDefName childAttributeDefName: attributeDefName.getAttributeDefNameSetDelegate().getAttributeDefNamesImpliedByThis()) {
+        childAttributeDefName.delete();
+        // don't change the order since write inherits read
+        roleService.deleteRole(childAttributeDefName.getExtension()+"_"+WRITE.name(), grouperSession);
+        roleService.deleteRole(childAttributeDefName.getExtension()+"_"+READ.name(), grouperSession);
+      }
+      attributeDefName.delete();
+      // don't change the order since write inherits read
+      roleService.deleteRole(resourceId+"_"+WRITE.name(), grouperSession);
+      roleService.deleteRole(resourceId+"_"+READ.name(), grouperSession);
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+  }
+  
+  public Resource getResource(String resourceId, ResourceType resourceType) throws ResourceNotFoundException {
+    if (resourceId == null || resourceType == null) {
+      throw new IllegalArgumentException("resouceId "+resourceId+" is null or resourceType"+resourceType+" is null.");
+    }
+    GrouperSession grouperSession = null;
+    Resource resource = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      AttributeDefName attributeDefName = AttributeDefNameFinder.findByName(resourceType.getStemFromResourceType()+COLON+resourceId, false);
+      if (attributeDefName == null) {
+        throw new ResourceNotFoundException(resourceId +" was not found.");
+      }
+      resource = new Resource(resourceId, resourceType);
+      resource.setDescription(attributeDefName.getDescription());
+      resource.setName(attributeDefName.getDisplayExtension());
+      Set<AttributeDefName> parentAttributeDefNames = attributeDefName.getAttributeDefNameSetDelegate().getAttributeDefNamesThatImplyThisImmediate();
+      if (parentAttributeDefNames != null && parentAttributeDefNames.size() > 0) {
+        resource.setParentResourceId(parentAttributeDefNames.iterator().next().getExtension());
+      }
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+    return resource;
+  }
+  
+  /**
+   * 
+   * @param userId
+   * @param resourceType
+   * @param actions - write or read
+   * @param pageNumber - 1 index based
+   * @param pageSize - items to fetch
+   * @return
+   * @throws SubjectNotFoundException
+   */
+  public Set<Resource> getAccessibleResourcesForUser(String userId, ResourceType resourceType, 
+      PermissionAction action, boolean pagination, Integer pageNumber, Integer pageSize) throws SubjectNotFoundException {
+    
+    if (userId == null || resourceType == null || action == null) {
+      throw new IllegalArgumentException("Invalid input");
+    }
+    if (pagination && (pageNumber < 0 || pageSize < 1)) {
+      throw new IllegalArgumentException("Invalid pagination properties");
+    }
+    
+    GrouperSession grouperSession = null;
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      
+      PermissionFinder permissionFinder = new PermissionFinder();
+      permissionFinder.addPermissionDef(PERMISSIONS_ATTRIBUTE_DEF);
+      permissionFinder.addAction(action.name());
+      Subject subject = SubjectFinder.findByIdAndSource(userId, SUBJECT_SOURCE, false);
+      if (subject == null) {
+        throw new SubjectNotFoundException("userId "+userId+" was not found.");
+      }
+      permissionFinder.addSubject(subject);
+      
+      Stem stem = StemFinder.findByName(grouperSession, resourceType.getStemFromResourceType(), true);
+      permissionFinder.assignPermissionNameFolder(stem);
+      permissionFinder.assignPermissionNameFolderScope(Scope.ONE);
+      if (pagination) {
+        QueryOptions queryOptions = new QueryOptions();
+        queryOptions.paging(pageSize, pageNumber, false);
+        permissionFinder.assignQueryOptions(queryOptions);
+      }
+      Set<PermissionEntry> permissions = permissionFinder.findPermissions();
+      
+      Set<Resource> resources = new HashSet<Resource>();
+      for (PermissionEntry entry: permissions) {
+        Resource resource = new Resource(entry.getAttributeDefNameDispName(), resourceType);
+        resource.setName(entry.getAttributeDefName().getDisplayExtension());
+        
+        //TODO: Discuss it with Suresh and Supun. It might cause some performance issues. We probably should not populate the parent id since caller will already have it.
+//        Set<AttributeDefName> parentAttributeDefNames = entry.getAttributeDefName().getAttributeDefNameSetDelegate().getAttributeDefNamesThatImplyThisImmediate();
+//        if (parentAttributeDefNames != null && parentAttributeDefNames.size() > 0) {
+//          resource.setParentResourceId(parentAttributeDefNames.iterator().next().getExtension());
+//        }
+        
+        resources.add(resource);
+        
+      }
+            
+      return resources;
+      
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+    
+  }
+  
+  // action can be read or write only
+  public Set<String> getAllAccessibleUsers(String resourceId, ResourceType resourceType, PermissionAction action) {
+    
+    if (resourceId == null || resourceType == null || action == null) {
+      throw new IllegalArgumentException("Invalid input");
+    }
+    
+    GrouperSession grouperSession = null;
+    Set<String> userIds = new HashSet<String>();
+    try {
+      grouperSession = GrouperSession.startRootSession();
+      
+      PermissionFinder permissionFinder = new PermissionFinder();
+      permissionFinder.addPermissionDef(PERMISSIONS_ATTRIBUTE_DEF);
+      permissionFinder.addAction(action.name());
+      
+      Stem stem = StemFinder.findByName(grouperSession, resourceType.getStemFromResourceType(), true);
+      permissionFinder.assignPermissionNameFolder(stem);
+      permissionFinder.assignPermissionNameFolderScope(Scope.ONE);
+      Set<PermissionEntry> permissions = permissionFinder.findPermissions();
+      
+      for (PermissionEntry entry: permissions) {
+        if (entry.getSubjectSourceId().equals(SUBJECT_SOURCE)) {
+          userIds.add(entry.getSubjectId());
+        }
+      }
+            
+      return userIds;
+      
+    } finally {
+      GrouperSession.stopQuietly(grouperSession);
+    }
+        
+  }
+  
+  private void validateResource(Resource resource) {
+    if (resource.getResourceType() == null) {
+      throw new IllegalArgumentException("Resource type is a required field");
+    }
+    if ((resource.getResourceType().equals(EXPERIMENT) ||  resource.getResourceType().equals(DATA)) && resource.getParentResourceId() == null) {
+      throw new IllegalArgumentException("Resource type Experiment or Data must provide valid parent resource id");
+    }
+    if (resource.getOwnerId() == null) {
+      throw new IllegalArgumentException("Resource ownerId is a required field.");
+    }
+  }
+  
+  public static void main(String[] args) {
+    ResourceServiceImpl resourceService = new ResourceServiceImpl();
+    
+    // create a Project resource
+    Resource projectResource = new Resource("project resource id", PROJECT);
+    projectResource.setDescription("project resource description");
+    projectResource.setName("project resource name");
+    projectResource.setOwnerId("airavata_id_1");
+    resourceService.createResource(projectResource);
+    
+    // create an Experiment resource
+    Resource experimentResource = new Resource("experiment resource id", EXPERIMENT);
+    experimentResource.setDescription("experiment resource description");
+    experimentResource.setName("experiment resource name");
+    experimentResource.setParentResourceId("project resource id");
+    experimentResource.setOwnerId("airavata_id_1");
+    resourceService.createResource(experimentResource);
+    
+    //create another experiment resource within the same project resource
+    Resource experimentResource1 = new Resource("experiment resource id1", ResourceType.EXPERIMENT);
+    experimentResource1.setDescription("experiment resource description1");
+    experimentResource1.setName("experiment resource name1");
+    experimentResource1.setParentResourceId("project resource id");
+    experimentResource1.setOwnerId("airavata_id_1");
+    resourceService.createResource(experimentResource1);
+    
+    // create a data file resource
+    Resource dataResource = new Resource("data resource id", ResourceType.DATA);
+    dataResource.setDescription("data resource description");
+    dataResource.setName("data resource name");
+    dataResource.setParentResourceId("experiment resource id1");
+    dataResource.setOwnerId("airavata_id_1");
+    resourceService.createResource(dataResource);
+    
+    // get the experiment resource and it should have parent set to project
+    Resource resource = resourceService.getResource("experiment resource id1", EXPERIMENT);
+    System.out.println(resource);
+    
+    Set<Resource> accessibleResourcesForUser = resourceService.getAccessibleResourcesForUser("airavata_id_1", EXPERIMENT, WRITE, true, 1, 2);
+    System.out.println("accessible resources on page 1 are "+accessibleResourcesForUser.size());
+    
+    
+    //share the experiment with airavata_id_2
+    PermissionServiceImpl permissionService = new PermissionServiceImpl();
+    permissionService.grantPermission("airavata_id_2", SubjectType.PERSON, "experiment resource id1", EXPERIMENT, WRITE);
+    
+    // create a group of users
+    GroupServiceImpl groupService = new GroupServiceImpl();
+    org.apache.airavata.grouper.group.Group group = new org.apache.airavata.grouper.group.Group();
+    group.setId("airavata test group id");
+    group.setName("airavata test group name");
+    group.setDescription("airavata test group description");
+    List<String> members = new ArrayList<String>();
+    members.add("airavata_id_3");
+    members.add("airavata_id_4");
+    group.setUsers(members);
+    groupService.createOrUpdateGroup(group);
+    
+    // now share the same experiment with this group as well
+    permissionService.grantPermission("airavata test group id", SubjectType.GROUP, "experiment resource id1", EXPERIMENT, READ);
+    
+    accessibleResourcesForUser = resourceService.getAccessibleResourcesForUser("airavata_id_3", EXPERIMENT, READ, true, 1, 2);
+    System.out.println("accessible resources on page 1 are "+accessibleResourcesForUser.size());
+    
+    // get all resources, or no pagination
+    accessibleResourcesForUser = resourceService.getAccessibleResourcesForUser("airavata_id_1", EXPERIMENT, READ, false, 1, 2);
+    System.out.println("accessible resources without pagination are "+accessibleResourcesForUser.size());
+    
+    Set<String> allAccessibleUsers = resourceService.getAllAccessibleUsers("experiment resource id1", EXPERIMENT, READ);
+    System.out.println("users who have read access on experiment resource id1 are "+allAccessibleUsers);
+
+    //delete the project resource, it will delete all the children/experiment resources and roles as well
+    resourceService.deleteResource("project resource id", PROJECT);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/89e0fdc8/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceType.java
----------------------------------------------------------------------
diff --git a/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceType.java b/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceType.java
new file mode 100755
index 0000000..5b80bfa
--- /dev/null
+++ b/modules/group-manager/src/main/java/org/apache/airavata/grouper/resource/ResourceType.java
@@ -0,0 +1,51 @@
+/**
+ * 
+ */
+package org.apache.airavata.grouper.resource;
+
+import static org.apache.airavata.grouper.AiravataGrouperUtil.DATA_STEM_NAME;
+import static org.apache.airavata.grouper.AiravataGrouperUtil.EXPERIMENT_STEM_NAME;
+import static org.apache.airavata.grouper.AiravataGrouperUtil.OTHER_STEM_NAME;
+import static org.apache.airavata.grouper.AiravataGrouperUtil.PROJECT_STEM_NAME;
+
+/**
+ * @author vsachdeva
+ *
+ */
+public enum ResourceType {
+  
+  PROJECT,
+  EXPERIMENT,
+  DATA,
+  OTHER;
+  
+  public ResourceType getParentResoruceType() {
+    
+    switch (this) {
+      case EXPERIMENT:
+        return PROJECT;
+      case DATA:
+        return EXPERIMENT;
+      default:
+        return null;
+    }
+  }
+  
+  public String getStemFromResourceType() {
+    
+    switch (this) {
+      case PROJECT:
+        return PROJECT_STEM_NAME;
+      case EXPERIMENT:
+        return EXPERIMENT_STEM_NAME;
+      case DATA:
+        return DATA_STEM_NAME;
+      case OTHER:
+        return OTHER_STEM_NAME;
+      default:
+        return null;
+    }
+    
+  }
+
+}


Mime
View raw message