The Attribute Framework

For information about the Attribute Framework UI, see this page.

The attribute framework is used for attaching metadata to various objects in the registry.

attributeDefs.create.grant.all.attrRead          = true|false
attributeDefs.create.grant.all.attrUpdate        = true|false

Object types

Attribute definition (attributeDef):

An attribute definition holds the type of attribute (attribute, permission, limit, etc), privileges (who can assign or see assignments), restrictions about where it can be assigned (e.g. which folder), which owner types it can be assigned to (e.g. group, folder, etc), which type of value (e.g. text, numeric, etc), if it is multi-valued, if it can be assigned to the same owner object more than once at a time, etc.  For permissions, this also holds which actions (in the triple) are available for this permission (e.g. READ, WRITE, ADMIN, etc).  The attributeDef and attributeDefName live in a folder (stem) for namespace reasons.  If you can CREATE in the stem, you can create attribute objects.  It is up to you if you keep those centrally in a top level folder in Grouper or closer to the leaf where the application lives.

Attribute definition name (attributeDefName):

An attribute definition name has a many-to-one relationship to attributeDef.  This is the thing that is assigned to the owner.  It is similar to a list-of-values for the attribute.  You cannot assign an attribute without having an attributeDefName.  This allows you to share common settings among multiple attributes without having to reconfigure each value.  You might have only one attributeDefName for an attributeDef, but generally you will have more than 1.

Attribute assignment:

This is the relationship between the owner (e.g. Group, Folder), and the attributeDefName.  This might have a start/end timestamp, and other metadata (e.g. for permissions if it is delegatable, if it is allowed or forbidden, etc)

Attribute assignment value:

If an attributeDef is not of value type 'marker', then it can have a value, or multiple values (of the same type) if the attributeDef is labeled as multi-valued.  The attribute assign value is a many to one on the attribute assignment.  The value can have a type (e.g. text, integer, floating, timestamp, etc), and at some point it would be nice if it had the capability to have validations (e.g. a regex).

GSH commands

Create an attribute definition

addRootStem("school","school");
addStem("school", "attr", "attr");
addStem("school:attr", "students", "students");
grouperSession = GrouperSession.startRootSession();
attrStudentsStem = StemFinder.findByName(grouperSession, "school:attr:students");
studentsAttrDef = attrStudentsStem.addChildAttributeDef("students", AttributeDefType.attr);
studentsAttrDef.setAssignToGroup(true);
studentsAttrDef.store();
Create an attribute name
attrArtsAndSciences = attrStudentsStem.addChildAttributeDefName(studentsAttrDef, "artsAndSciences", "artsAndSciences");
Assign an attribute name to an object:
addStem("school", "math", "math");
groupBrainProject = addGroup("school:math", "brainProject", "brainProject");
groupBrainProject.getAttributeDelegate().assignAttribute(attrArtsAndSciences);
Set the security of an attribute definition

groupStudents = addGroup("school", "students", "students");
studentsAttrDef.getPrivilegeDelegate().grantPriv(groupStudents.toSubject(), AttributeDefPrivilege.ATTR_READ, false);

Here is how to assign the same attribute multiple times (v1.6+) \[note, needed to restart GSH to clear cache)

studentsAttrDef.setMultiAssignable(true);
studentsAttrDef.store();
-- RESTART GSH --
grouperSession = GrouperSession.startRootSession();
groupBrainProject = GroupFinder.findByName(grouperSession, "school:math:brainProject", true);
attrArtsAndSciences = AttributeDefNameFinder.findByName("school:attr:students:artsAndSciences", true);
groupBrainProject.getAttributeDelegate().addAttribute(attrAtrsAndSciences);
groupBrainProject.getAttributeDelegate().addAttribute(attrAtrsAndSciences);
groupBrainProject.getAttributeDelegate().addAttribute(attrAtrsAndSciences);
groupBrainProject.getAttributeDelegate().retrieveAssignments(attrArtsAndSciences);

Here is how to assign a value (v1.6+) \[note, needed to restart GSH to clear cache)

studentsAttrDef.setValueType(AttributeDefValueType.string);
studentsAttrDef.store();
groupBrainProject.getAttributeDelegate().retrieveAssignments(attrArtsAndSciences).iterator().next().getValueDelegate().assignValue("hey");

//or, assign directly from group based on name of attributeDefName

//note, you get a result that has the assignment object, and whether this was a new assignment, or already existed
//this is true for the value delegate, or the delegate on the assignment above
groupBrainProject.getAttributeValueDelegate().assignValue("school:attr:students:artsAndSciences", "hey");

Here is how to assign multiple values to an assignment  (v1.6+) \[note, needed to restart GSH to clear cache).

studentsAttrDef.setMultiValued(true);
studentsAttrDef.store();

//again, this returns a result object that has the object
groupBrainProject.getAttributeDelegate().retrieveAssignments(attrArtsAndSciences).iterator().next().getValueDelegate().addValue("there");
groupBrainProject.getAttributeDelegate().retrieveAssignments(attrArtsAndSciences).iterator().next().getValueDelegate().retrieveValuesString();
java.util.ArrayList: [there, hey]

//you could also do this directly with the value delegate
groupBrainProject.getAttributeValueDelegate().addValue("school:attr:students:artsAndSciences", "there");
groupBrainProject.getAttributeValueDelegate().retrieveValuesString("school:attr:students:artsAndSciences");
java.util.ArrayList: [there, there]

Example

Add a multi-valued attribute to a group, say mailAlternateAddress with two values "foo@memphis.edu" and "bar@memphis.edu".  Here is the API code:

AttributeDef attributeDef = stem.addChildAttributeDef("someName", AttributeDefType.attr); attributeDef.setAssignToGroup(true);
attributeDef.setMultiValued(true);
attributeDef.setValueType(AttributeDefValueType.string);
attributeDef.store();

AttributeDefName attributeDefName = stem.addChildAttributeDefName(attributeDef, "mailAlternateAddress", "mailAlternateAddress");

group.getAttributeValueDelegate().assignValuesString(
	attributeDefName.getName(), GrouperUtil.toSet("foo@memphis.edu", "bar@memphis.edu"), true);

Example 2

Put an attribute on a membership

gsh 0%
gsh 1% grouperSession = GrouperSession.startRootSession();
edu.internet2.middleware.grouper.GrouperSession: 3c50fffcfb104b39adbd55d05d47355 7,'GrouperSystem','application'
gsh 2% folder = StemFinder.findByName(grouperSession, "Communities:LVC:LSC:MOU:UWM:UWMGroupAttributes",true)
stem: name='Communities:LVC:LSC:MOU:UWM:UWMGroupAttributes' displayName='Communi ties:LVC:LSC:MOU:UWM:UWMGroupAttributes' uuid='97f4c134149941fbad8906d3a1ed2340'
gsh 3% attributeDef = folder.addChildAttributeDef("attr01", AttributeDefType.attr);
edu.internet2.middleware.grouper.attr.AttributeDef: AttributeDef[name=Communities:LVC:LSC:MOU:UWM:UWMGroupAttributes:attr01,uuid=f8756aac777947ff9ae386786de4a287]
gsh 4% attributeDef.setAssignToImmMembership(true);
gsh 5% attributeDef.store();
gsh 6% myAttributeName = folder.addChildAttributeDefName(attributeDef,"myAttributeName","myAttributeName");
edu.internet2.middleware.grouper.attr.AttributeDefName: AttributeDefName[name=Communities:LVC:LSC:MOU:UWM:UWMGroupAttributes:myAttributeName ,uuid=db8d3c93b30e4e2f96d3cdd9ae1af737]
gsh 7% subject = SubjectFinder.findById("scott.koranda@LIGO.ORG", true);
subject: id='scott.koranda@LIGO.ORG' type='person' source='ligo' name='Scott Koranda'
gsh 8% member = MemberFinder.findBySubject(grouperSession, subject, true);
member: id='scott.koranda@LIGO.ORG' type='person' source='ligo' uuid='56246fe035bd4266bc92abb617430033'
gsh 9% group = GroupFinder.findByName(grouperSession, "Communities:LVC:LSC:MOU:UWM:UWMGroupMembers");
group: name='Communities:LVC:LSC:MOU:UWM:UWMGroupMembers' displayName='Communities:LVC:LSC:MOU:UWM:UWMGroupMembers' uuid='00918b49-ad44-49aa-8b13-49d8a1aa459c'
gsh 10% membership = MembershipFinder.findImmediateMembership(grouperSession, group,subject,Group.getDefaultList(), true)
edu.internet2.middleware.grouper.Membership: Membership[createTime=1270587726584,creatorUuid=e00f1b26f1c340db8845e1dfe297f01b,depth=0,listName=members,listType=list,memberUuid=56246fe035bd4266bc92abb617430033,groupId=00918b49-ad44-49aa-8b13-49d8a1aa459c,type=immediate,uuid=faefbff7e2ce4561b86c7e070fcd0ac9:a5b12a759438462a996842dca313ccfc]
gsh 11% membership.getAttributeDelegate().assignAttribute(myAttributeName);
edu.internet2.middleware.grouper.attr.assign.AttributeAssignResult: edu.internet2.middleware.grouper.attr.assign.AttributeAssignResult@488e753c
gsh 12% membership.getAttributeDelegate().retrieveAssignments(myAttributeName);
edu.internet2.middleware.grouper.attr.assign.AttributeAssign: AttributeAssign[id=350594e5dc39431ea56c17635eab253f,action=assign,attributeDefName=Communities:LVC:LSC:MOU:UWM:UWMGroupAttributes:evil,membershipId=faefbff7e2ce4561b86c7e070fcd0ac9]
gsh 13%