You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

Overview: For Grouper 2.2 the plan is to migrate from legacy attributes to the new attribute framework in a transparent way.  The old API and WS and UI should still work correctly.  Plan to migrate lists and hooks as well 

Current functionality

Group types:

 - Grouper allows administrators to create group types (typically using GSH or the API)
 - There are several internal/built-in group types -- base, naming, attributeDef.  There's also requireInGroups, addIncludeExclude, and grouperLoader.
 - Group types can have one more more attributes and one or more custom lists.
 - There are change log events when group types are created, updated, or deleted.  The change log processor doesn't do anything with them.
 - Special group type called grouperGroupMembershipSettings that's used to help users skin the lite membership UI.
 - Hooks
 - User audit

Group type assignments (GroupTypeTuple):

 - In general, all users can assign a group type to groups that they admin.
 - There are built-in hooks to limit who can assign a specific group type or edit attributes of a group associated with that group type.
 - When assigning a group type to a group, a bundle of attributes and lists become available for that group.  For example with the gruopLoader type.
 - There are change log events when group types are assigned or unassigned.  The change log processor does look at these events.
 - Hooks
 - User audit

Fields:

 - Attributes and custom lists are fields.  (Just like the fields used for group memberships and group/stem/attributeDef privileges.)
 - Fields are associated with a group type.
 - Fields have properties for read and write privilege.
   - e.g. You must have read (or opt-in or update or admin, etc) privilege on a group to read an attribute value on a group.
   - e.g. You must have update (or read or opt-in or admin, etc) privilege on a group to update/delete an attribute value on a group.
   - Same with addMember, deleteMember, and getMembers on custom lists.  You can have crazy settings like requiring opt-out privilege on a group to be able to add member to a custom list.
 - Fields have a nullable property.  This prevents deleting an attribute from a group if failOnRequiredAttribute is true in the API call and the nullable property is true on the field.
 - Change log
 - Hooks
 - PIT audit

Attributes:

 - Stored in the grouper_attributes table.  Has a reference to the group and field.
 - Single valued only.
 - Can be copied when copying groups.
 - Hooks
 - User audit

Custom lists:

 - Stored in the grouper_memberships table like regular memberships and privileges.  Again has a reference to the group and field.
 - Can be copied when copying groups.
 - Change log
 - Hooks
 - User audit
 - PIT audit

Requirements

 - Prevent use of legacy attributes.
 - Create old style attributes in the new attribute framework within a configurable folder (e.g. etc:attribute:legacy).  By default, everybody can read and assign the attribute.
 - Preserve the API methods that allow setting and getting an attribute from a group.
 - Web services and UI should continue to work when dealing with getting and setting attributes.
 - Hooks should continue to fire when setting and deleting attributes.
 - Preserve existing views as much as possible.

Design and API Changes

GroupType

- Get rid of grouper_types table.  The default, base, naming, and attributeDef types will no longer be represented in the API.

GroupType.createType(session, name)
 - deprecated
GroupType.createType(session, name, exceptionIfExists)
 - deprecated
GroupType.internal_createType(session, name, isAssignable, isInternal, exceptionIfExists, changed, uuid)
 - rewrite
 - Remove isAssignable and isInternal?
 - Create new 2 attributeDefs and attributeDefName in etc:attribute:legacy
   - One attributeDef assignable to groups.  Maybe call it legacyGroupTypeDef_<name>.  The other assignable to assignments on groups.  Maybe call it legacyAttributeDef_<name>.
   - attributeDefName as marker attribute for group type.  Maybe call it legacyGroupType_<name>.
   - Add scope:
     - legacyAttributeDef_<name>.getAttributeDefScopeDelegate().assignScope(AttributeDefScopeType.idEquals, legacyGroupType_<name>.getId(), null);
 - Maybe the groupType uuid should become the uuid of the attributeDefName legacyGroupType_<name>.
GroupType.addAttribute(session, name, read, write, required)
 - deprecate
GroupType.addAttribute(session, name, read, write, required, exceptionIfExists)
 - deprecate
 - rewrite - the current code creates a field for this, but we're not doing that.
 - Ignore required?
 - Ignore read and write privileges? Should users be forced to set up privileges using the new API when creating new attributes?
 - Create attribute in new framework.  Maybe call it legacyAttribute_<name>.
GroupType.addOrUpdateAttribute(session, name, read, write, required)
 - same as above
GroupType.addList(session, name, read, write)
 - We're still supporting custom lists.  Still deprecate in favor of separate groups.
 - Going forward, expecting a properties file config to link up the groupType with the field.
 - Maybe the admin needs to add the config first, then run this to add the field?
GroupType.delete(session)
 - deprecate
 - Delete the two attribute definitions.
GroupType.deleteField(session, name)
 - deprecate
 - Continue to delete the field as before if this is a field for a list.  Admin needs to remove config.
 - If the field is for an attribute, if there aren't any assignments, delete the legacyAttribute_<name>.
GroupType.getFields()
 - deprecate
 - Note that attributes are no longer fields.

GroupTypeFinder

GroupTypeFinder.find(name, exceptionIfNotFound)
 - deprecate
 - Create GroupType objects based on attributeDefNames in etc:attribute:legacy that start with legacyGroupType_.
 - The GroupType name and uuid would be accurate.  But other fields would be left null. Hmm
GroupTypeFinder.findByUuid(uuid, exceptionIfNotFound)
 - deprecate
 - Same as above
GroupTypeFinder.findAll()
 - deprecate
 - Just return all
GroupTypeFinder.findAllAssignable()
 - deprecate
 - Just return all

GroupTypeTuple

 - Get rid of the grouper_group_types table.
 - Everything is essentially deprecated.
 - Should the uuid of a GroupTypeTuple be the uuid of the attribute assignment of legacyGroupType_<name>?

Field

 - In general, I'm assuming that we're not going to try to treat legacy attributes as fields anymore or try to support current 2.1 API that does.
 - Getting rid of the columns grouptype_uuid and is_nullable.

 - Field.isAttributeName()
   - deprecate
   - Would always return false since legacy attributes are no longer fields.

FieldFinder

 - FieldFinder.findFieldIdForAttribute(attributeName, exceptionIfNull)
   - deprecate
   - This won't work anymore since attributes aren't fields.

FieldType

 - "attribute" is no longer a valid field type.

Group

 - Group.initGroupAttributes(groups)
   - Seems like this was set up to address a performance issue with getting legacy attributes.
   - Maybe deprecate and allow it to continue to work.  That is, efficiently query for legacy attributes in etc:attribute:legacy.
 - Group.deleteAttribute(attributeName)
   - deprecate
 - Group.deleteAttribute(attributeName, failOnRequiredAttribute)
   - deprecate
   - Ignore failOnRequiredAttribute?
   - rewrite to delete from new attribute framework.
 - Group.getAttributeValue(attributeName, checkSecurity, exceptionIfNotFound)
   - deprecate
   - exceptionIfNotFound is currently based on a field check.  Since legacy attributes won't be fields, this needs to change to instead check all the attributeDefNames starting with legacyAttribute_ under etc:attribute:legacy that are applicable for this group.
   - checkSecurity needs to check security based on new attribute framework.
 - Group.getAttribute(attributeName)
   - already deprecated.  why doesn't this just call getAttributeValue???
 - Group.getAttributes()
   - already deprecated.  why doesn't this just call getAttributesMap???
 - Group.setAttribute(attributeName, value)
   - deprecate
 - Group.setAttribute(attributeName, value, checkPrivileges)
   - deprecate
 - Group.setAttribute(attributeName, value, checkPrivileges, uuid)
   - deprecate
   - Change to use new framework.  Should the uuid be used as the uuid of the attribute assignment?
 - Group.getAttributesMap(checkSecurity)
   - deprecate
   - Change to use new framework.
 - Group.getAttributesDb()
   - already deprecated.  why doesn't this just call getAttributesMap???
 - Group.internal_setAttributes(attributes)
   - deprecate
 - Group.setAttributes(attributes)
   - deprecate
 - Group.internal_copy()
   - Perhaps assume that this continues to only work with legacy attributes for now.
   - Privilege checks on attributes need to use new framework.
 - Group.addType(type)
   - deprecate
 - Group.addType(type, exceptionIfAlreadyHasType)
   - deprecate
   - Assign legacyGroupType_<typeName> to group.
 - Group.canReadField(subj, field) and various other similar methods
   - Okay to make this no longer work for legacy attributes?
 - Group.deleteType(type)
   - deprecate
   - Change to use new framework (including privilege checks).
 - Group.getRemovableTypes()
   - deprecate
   - assume all types are removable.
 - Group.getTypes()
   - deprecate
   - Assume no types are "internal"
 - Group.getTypesDb()
   - deprecate
   - Return all assignments within etc:legacy:attribute.
 - Group.hasType(type)
   - deprecate
 - Group.setTypes(types)
   - deprecate

Attribute

- Basically deprecate everything.
- Get rid of grouper_attributes table.
- Perhaps the attribute id should be the uuid of the attribute assignment.
- field id is no longer applicable therefore always null.

Migration

- Assume that the isAssignable and isInternal flags on group types can be ignored?

- Assume that the required flag on legacy attributes can be ignored?

- Create attributeDefs and attributeDefNames in the new attribute framework based on the adjusted API above.

- Note that if custom lists are used, the migration will involve config additions as well.

Privileges

One of the challenges with the migration is going to be dealing with privileges.  The old and new attribute frameworks have different ways of dealing with read and write privileges on attributes. 

With the old attribute framework, read access to an attribute assigned to a group is based on a specified level of access on that group.  For instance, in order to read an attribute assigned to a group, you may need read or update or admin privilege on the group.  The same applies to write access in the old attribute framework.

With the new attribute framework, read access on an attribute assigned to a group requires view privilege on the group and attr_read privilege on the attribute definition.  And update access requires admin privilege on the group and attr_update privilege on the attribute definition.

Steps to migrate read privileges
  1. For each group type that contains legacy attributes, get the list of groups that have been assigned that group type.
    1. For the list of groups, determine the effective read privilege for each group.
    2. If the effective read privilege is everybody, give GrouperAll attr_read privilege to the attribute definition in the new attribute framework.
    3. Excluding GrouperSystem, if the effective read privilege for all groups is based on the same list of groups, then give that list of groups attr_read privilege to the attribute definition in the new attribute framework.  If the effective read privilege for all groups is based on a list of groups, but not the same for each group, then migrate in the same manner (using a union of all groups) but only if for each group the attribute readers (in the old framework) is a super set of the group viewers.
    4. Excluding GrouperSystem, if the effective read privilege for all groups is based on the same list of subjects, then give that list of subjects attr_read privilege to the attribute definition in the new attribute framework.  If the effective read privilege for all groups is not based on the same subjects, then migrate in the same manner (using a union of all subjects) but only if for each group the attribute readers (in the old framework) is a super set of the group viewers.  Also in either case, during the migration, output a warning message to indicate that read privileges have been migrated but would need to be handled differently by the users going forward.
    5. Otherwise, do not migrate privileges and output a warning message.
  2. Repeat for next group type.
Steps to migrate update privileges
  1. For each group type that contains legacy attributes, get the list of groups that have been assigned that group type.
    1. For the list of groups, determine the effective update privilege for each group.
    2. Excluding GrouperSystem, if the effective update privilege for all groups is based on a list of groups (not necessarily the same list for each group), then give that list of groups (a union of all) attr_update privilege to the attribute definition in the new attribute framework.
    3. Excluding GrouperSystem, if the effective update privilege for all groups is based on a list of subjects, then give that list of subjects (a union of all) attr_update privilege to the attribute definition in the new attribute framework.  Also, during the migration, output a warning message to indicate that update privileges have been migrated but would need to be handled differently by the users going forward.  The output can contain the groups that were problematic (i.e. the ones that contain update privileges that were not solely based on a list of groups).
    4. In either case, if a subject had update privileges in the old attribute framework but no longer does in the new attribute framework because the subject does not have admin privileges to the group, then output a warning message for each subject/group.
  2. Repeat for next group type.
  • No labels