Overview

Grouper has a hierarchical namespace of folders in which to organize Groups, Roles, and Permissions. For large deployments of Grouper, the namespace can make the UI overwhelming for users to find the objects they want to manage.

In Grouper 2.2, the UI makes it possible to filter the registry by a service. This makes it simpler to navigate the namespace and easier to use the UI. Users can find services in the "services widget" on the main UI screen.

Potential Use Cases

This "My services" feature is not designed for users who simply want to see what they have access to.  One way to see that is to use the link under the search bar (in upper right corner) that has your name in it.   It is also suggested for users to take advantage of the "Favorites"  feature.


Service design

The design for services is based on the attribute framework. There is an attribute definition type reserved for this, called: service. Originally it was called "domain" but never used, and this has been refactored to "service" in Grouper 2.2+, and is automatically migrated on upgrade. A service attribute is assignable to folders. Any user who can create objects in a folder can create a service attribute and attribute name and assign it to their objects.

Creating services

The service attribute definition can be created via GSH or the UI.  Here is an example via the UI as of v2.4


Click on Create new attribute definition


fill out form and save



Click on "Create new attribute name"



fill out the form and save



Assign this attribute to the container folder for the application

Click "Attribute assignments"



assign newly created attribute to folder



Click save.  Now any entities who are members of a group in that folder or subfolder will have that service on the main screen or services screen of the UI.  Any entity who has manage privileges on a group in that folder or subfolder, will be considered an "admin" of the service.  Note with groups as members and with exclude lists, this can not be 100% accurate.
Here is a GSH example of creating a service:

AttributeDef jiraServiceDef = new AttributeDefSave(grouperSession)
      .assignCreateParentStemsIfNotExist(true).assignAttributeDefType(AttributeDefType.service)
      .assignName("apps:jira:jiraServiceDefinition").assignToStem(true).save();

AttributeDefName jiraService = new AttributeDefNameSave(grouperSession, jiraServiceDef)
      .assignCreateParentStemsIfNotExist(true)
      .assignName("apps:jira:jiraService").assignDisplayExtension("Central IT production Jira issue tracker").save();

Here are screenshots on the UI of creating a service definition and name (TODO, IT SHOULD ONLY BE ASSIGNABLE TO FOLDERS!):




Assigning service tags

Service tags can be assigned to folders by GSH, UI, WS, or rule. The service tag applies to the folder, all objects in the folder, and subfolders

Service attribute validation

A Grouper Service attribute definition can not be assigned to objects other than folders. It is a marker attribute (i.e. tag), which has no value. It is single assignable, i.e. you cannot assign the attribute more than once to the same object owner.

Services privileges

Services have the same privileges that attributes have: READ, VIEW, ADMIN, UPDATE. Note, the VIEW privilege is more complicated, generally you dont have to worry about assigning this, since if someone cannot VIEW the service, but can manage groups in the service, then they still CAN see the service in the UI/WS. This makes using services a lot easier.

GSH/API example of service privileges

//the directory is public
directoryServiceDef.getPrivilegeDelegate().grantPriv(SubjectFinder.findAllSubject(), AttributeDefPrivilege.ATTR_VIEW, false);

UI example of service privileges (TODO: NOTE ONLY ASSIGNABLE TO FOLDERS!!!)



Using Grouper services

Services should be exposed by the UI/WS/API. i.e. you should be able to do a GroupFinder filter and restrict the results to a certain service. You should be able to list the services for a user. You could be able to browse the repository and operate comboboxes in the context of a particular service.

API

Find members in a service:

      MembershipResult membershipResult = new MembershipFinder().assignServiceId(confluenceService.getId())
          .assignServiceRole(ServiceRole.admin).findMembershipResult();
      
      List<Member> members = new ArrayList<Member>(membershipResult.members());


Find services for a user:


      Set<AttributeDefName> attributeDefNames = new AttributeDefNameFinder().assignSubject(SubjectTestHelper.SUBJ0)
        .assignServiceRole(ServiceRole.user).findAttributeNames();

WS

Client

c:\temp> java -jar grouperClient.jar --operation=getMembershipsWs --serviceName=school:apps:wiki --serviceRole=admin
Index 0: group: school:apps:wiki:groups:admins, subject: jsmith, list: updaters, type: Immediate, enabled: T
Index 1: group: school:apps:wiki:groups:users, subject: hjohnson, list: admins, type: Immediate, enabled: T
c:\temp> java -jar grouperClient.jar --operation=findAttributeDefNamesWs --scope=% --serviceRole=user --subjectId=jsmith
Index 0: name: school:apps:wiki, displayName: School:Applications:Wiki
Index 1: name: school:apps:pto, displayName: School:Applications:Paid Time Off

Metadata

We should have a requirement that there is one service definition per service name, and there could be some built in metadata on the service definition, like who the owner is, a link if people have problems, contact info, description, etc.

Developing

whereClause.append(" and theAttributeDefName.id = theServiceRoleView.serviceNameId ");
   changedQuery = grouperSession.getAccessResolver().hqlFilterGroupsWhereClause(
     grouperSession.getSubject(), byHqlStatic,
     sql, "theServiceRoleView.groupId", AccessPrivilege.READ_PRIVILEGES);

   //fields for the service role
   HibUtils.convertFieldsToSqlInString(serviceRole.fieldsForGroupQuery(), byHqlStatic, whereClause, "theServiceRoleView.fieldId");
   whereClause.append(" and theServiceRoleView.memberId = :groupMemberId ");
   byHqlStatic.setString("groupMemberId", member.getUuid());

API

In the Grouper API you can get services for a user (note, this is for groups in services where the grouper session can read memberships (or admin)

Set<AttributeDefName> attributeDefNames = new AttributeDefNameFinder().assignSubject(SubjectTestHelper.SUBJ0)
        .assignServiceRole(ServiceRole.user).findAttributeNames();

Here is a web service request:

<WsRestFindAttributeDefNamesRequest>
  <scope>%</scope>
  <serviceRole>user</serviceRole>
  <subjectLookup>
    <subjectId>test.subject.0</subjectId>
  </subjectLookup>
</WsRestFindAttributeDefNamesRequest>

Web service response:

<WsFindAttributeDefNamesResults>
  <attributeDefNameResults>
    <WsAttributeDefName>
      <idIndex>10090</idIndex>
      <extension>jiraService</extension>
      <displayExtension>Central IT production Jira issue tracker
      </displayExtension>
      <displayName>apps:jira:Central IT production Jira issue tracker
      </displayName>
      <name>apps:jira:jiraService</name>
      <uuid>d528f5888e964384be6cc7ed39e3d006</uuid>
      <attributeDefId>05b934189bd342aba0979fafec5e9c07</attributeDefId>
      <attributeDefName>apps:jira:jiraServiceDefinition
      </attributeDefName>
    </WsAttributeDefName>
  </attributeDefNameResults>
  <attributeDefs>
    <WsAttributeDef>
      <idIndex>10022</idIndex>
      <extension>jiraServiceDefinition</extension>
      <name>apps:jira:jiraServiceDefinition</name>
      <uuid>05b934189bd342aba0979fafec5e9c07</uuid>
      <attributeDefType>service</attributeDefType>
      <multiAssignable>F</multiAssignable>
      <multiValued>F</multiValued>
      <valueType>marker</valueType>
    </WsAttributeDef>
  </attributeDefs>
  <resultMetadata>
    <resultCode>SUCCESS</resultCode>
    <resultMessage>Success for: clientVersion: 2.2.0, scope: %,
      splitScope: null, wsAttributeDefLookup: null, attributeAssignType:
      null, attributeDefType: null
      wsAttributeDefNameLookups: null
      wsInheritanceSetRelation: null, pageSize: null, pageNumber: null, sortString: null, ascending:
      null, actAsSubject: null, paramNames:
      , params: null
      , wsSubjectLookup: WsSubjectLookup[subjectId=test.subject.0],
      serviceRole: user
    </resultMessage>
    <success>T</success>
  </resultMetadata>
  <responseMetadata>
    <resultWarnings></resultWarnings>
    <millis>9285</millis>
    <serverVersion>2.2.0</serverVersion>
  </responseMetadata>
</WsFindAttributeDefNamesResults>

Questions

  1. If you are a member of a group in a service, then should you see it in your service drop down? (yes because it would be too hard to maintain if each user of a service has to be assigned to VIEW the service)
  2. Can you see groups you are a member of if you cannot READ that group (My Memberships)? I think that is the current functionality. if it is then it will continue to work