6.0.0-git
2021-10-27

Diff for HordeGroupAPI between 9 and 10

[[toc]]

+ Horde Group API

This document is intended to clarify the Horde Group API, and to provide a solid target for applications to move toward for Horde4.  Motivation for this document was spurred from the conversation between the Bens on IRC regarding the "proper" way to handle groups with LDAP.

----

++ Abstract

In its simplest terms a group consists of an ID and a Name.  The ID is unique to that group and is unchanging.  The name is a human-friendly name that can be changed as desired.  The source and/or format of the group ID should not be of concern to the application using it, and should always be obtained/modified/stored through the group API calls.  The group ID is the **only** acceptable method as to refer to a group, as it is guaranteed to be unique (uniqueness being the job of the driver).  The group name is strictly for interface use.

A group can also have a parent and multiple children.  All references to parents and children are to be made through API calls.  Again, it is of no concern to the application //how//++ Functional Changes
Horde 4 will deviate from Horde 3 in these relationships are maintained, but only that they exist and are free to be used.key ways:

For Horde4, we* The groups collection will move away from the object-oriented method of managing groups in favor of a Horde_Groups class which will act as a group manager.  This should alleviate some of the confusion between the different drivers, and eliminate some of the OO overhead.

Also for Horde4, the way we handle saving groups to the backend will change.  Instead of keeping track of the changes and committing them to storage when updateGroup() is called, all changes should be stored on the fly.  There is a bit of a performance hit for this, but it simplifies the API, and group modifications are rare enough and deliberate enough that this should not be an issue.

++ Open Questions

+++ Flatten Group Structure?

Today the Group subsystem allows for nested groups like this:


  !ParentA
   -> Child1
   -> Child2
  !ParentB
   -> Child3
   -> Child4

This structure can be seen in Horde's administration screens.

However what is not clear is how those groups relate.  This brings up difficult-to-answer questions like:
* Is a member of the group Child1 automatically a member of ParentA?
* If permissions are granted to ParentA, do they automatically apply to Child1 and Child2?

If you answer "yes" to both questions above then an Administrator does not have a convenient way to view all of the group memberships or security settings in effect for a given user.  It also complicates things like sending notification messages to a group (like in the ticketing system or the wiki) because there is no immediate way to view allflat.  Groups cannot be created as children of the users in the group.  The more recursion we allow, the more abstract this becomes and the harder to manage.existing groups.

* Groups can belong to other groups.  In this way complex collections of users can be expressed without duplication.
----

++ Standards

In order to help keep concepts straight, the following standards should be used

* **$gid** -- Group ID
* **$group** -- Group Object
* **$grp_drv** -- Group backend driver
* **$name** -- Group Name
* **$parent** -- ID of Group's Parent

----

++ Group:: (Horde_Groups::Horde_Group_Backend
This is the class that does the work of reading from/saving to the group storage backend.

+++ create($name)

Creates a new group and returns a new Horde_Group object.

* Add handlers for Horde4)$name and $parent parameters from newGroup()

+++ renameGroup($gid, $newName)

Changes the name of a group without affecting its membership list

+++ addGroup(@@--- $group +++ $name, $parent@@)

Adds a group to the groups system. @@--- The group must first be created with                                               
Group::newGroup(), and have any initial users added to it, before this                                                
function is called. @@

* Add handlers for $name and $parent parameters from newGroup()

+++ renameGroup(@@--- $group +++ $gid@@, $newName)

Changes the name of a group without changing its contents or where it                                                 
is in the groups hierarchy.  

+++ removeGroup(@@--- $group +++ $gid@@ @@---, $force = false@@)removeGroup($gid)

Removes a group from the groups system permanently.

+++ getGroupName($gid)getByName($name)

Returns a Horde_Group object based on $name

If the name does not match exactly 1 group (too few or too many) it will raise Horde_Group_Exception with an appropriate error message

+++ getById($gid)

Returns Horde_Group object based on the $gid.

+++ exists($gid)

Retrieves the name ofBoolean: Check if a group.group exists in the system.

+++ getGUID(@@--- $group +++ $gid@@)listGroups()

Returns a globally unique ID for a group.

+++ exists(@@--- $group +++ $gid@@)

Check if a group exists in the system.

+++ getGroupParent($gid@@+++, $deep = false@@)

Returns the single parent ID @@+++ or a list of parent IDs@@ of the given group.

* Add support to take over getGroupParentList()

+++ listGroups($refresh = false)

Returns a listan array of all groups, in the format gid => name.

+++ listUsers($gid@@+++, @alllistUsers($gid, $recurse = false@@)false)

Get a list of every user that is a part of this group ONLY.

If $recurse is true then also check member groups' user list.

* Add support to take over listAllUsers()

+++ getGroupMembership($user, $parentGroups = false)

Get a listReturns an array of every group that $user is in.Horde_Group objects representing the user's membership

+++ userIsInGroup($user, $gid, $subgroups = true)

Say if a user is a member of a group or not.

+++ @@+++ addUser($username, $gid) @@

Add a user to a group.

* Should be able to handle arrays for both parameters.

+++ @@+++ removeUser($username, $gid) @@

Remove a user from a group.

* Should be able to handle arrays for both parameters.


+++ @@--- newGroup($name, $parent = DATATREE_ROOT) @@

deprecated in favor of using addGroup()

+++ @@--- getGroup($gid) @@

deprecated -- no longer using group objects.

+++ @@--- getGroupById($gid) @@

deprecated -- no longer using group objects.

Note: This is used in a (small) number of places, most important among those is probably the Horde base API.  There are a couple methods, (
addGroupPermissions(), removeGroupPermissions()) which use it.  This brings up a greater point: We probably want to have a way to allow external entities to interact with our groups via the API methods.  However this probably necessitates a way to look up group IDs (rather than requiring them to know our internal Group IDs).  I believe this method can be done correctly, but it does need to be better defined.  Today, the DataTree driver allows passing in a Groups object, an array, or a string.  The array is join()ed with ':' to produce a string which is used to look up the Group ID.  Whatever happens, we must be able to design method which does not have an ambiguous return value.

+++ @@--- getGroupShortName($group) @@

deprecated -- no need for short names...they're just confusing (K.I.S.S)

+++ @@--- getGroupId($group) @@

deprecated -- no longer using group objects.

+++ @@--- getGroupParents($gid) @@

deprecated in favor of always using flat lists.

+++ @@--- getGroupParentList($gid) @@

deprecated in favor of getGroupParent()

+++ @@--- listAllUsers($gid) @@

deprecated in favor of listUsers()

+++ @@--- getLevel($gid) @@

deprecated -- This is only used in the group admin UI for the tree.  Horde_Tree automatically determines node depth now, so this is no longer necessary.

+++ @@--- updateGroup($group) @@

deprecated -- All group modifications are saved to the backend on the fly.

+++ @@--- getAuditLog($gid) @@

deprecated -- Only used internally to store group to backend.

+++ @@--- clearAuditLog($gid) @@

deprecated -- Only used internally to store group to backend.


++ @@--- !DatatreeObject_Group @@

All !DatatreeObject_Group functionality has been moved to Group (Horde_Groups) to eliminate OO overhead.

+++ setGroupOb(&$groupOb)

+++ getId()

+++ save()

+++ addUser($username, $update = true)

+++ removeUser($username, $update = true)

+++ listUser()

+++ listAllUsers()

+++ getAuditLog()

+++ clearAuditLog()

----

++ Horde_Groups API

This is a list of the methods that will be available in Horde_Groups to Horde4 applications:

* addGroup($name, $parent)
* removeGroup($gid)
* renameGroup($gid, $newName)
* getGroupname($gid)
* getGUID($gid)
* exists($gid)
* getGroupParent($gid, $deep = false)
* listGroups()
* listUsers($gid, $subgroups = false)
* getGroupMembership($username, $parents = false)
* userIsInGroup($username, $gid, $subgroups = true)
* addUser($username, $gid)
* removeUser($username, $gid)