The Filesystem Group Service

The Filesystem Group Store

The filesystem group store lets you create a group service from lists of user ids in file system files. The files and directories in the filesystem model the groups and their members in the group system.  The filesystem adaptor is meant to help get you up and running quickly and to encourage experimentation.  You can use it to bridge the gap between portal start-up and the time when your users are correctly affiliated in LDAP, and it can supplement other membership sources with quirky data that doesn't fit anywhere else. 

The store class, org.jasig.portal.groups.filesystem.FileSystemGroupStore, implements IEntityGroupStore, IEntityStore and a no-op IEntitySearcher. You can substitute a functional entity searcher by adding it to the group service element for this component in the configuration document, compositeGroupServices.xml.
The directories and files look something like this:

-- groups root (perhaps "/apps/portal/groups")
  |-- org.jasig.portal.ChannelDefinition (directory)
  |-- channel definition file1
 |-- channel definition file2
 [ other channel definition files ]
 |-- org.jasig.portal.security.IPerson (directory)
  |-- person directory1
  |-- person file1
 |-- person file2
 [ other person files ]
 |-- person directory2
 etc.

The groups root is a file system directory declared in the group service configuration document, as an attribute of the filesystem group service element. This directory has sub-directories, each named for the underlying entity type contained by groups in that sub-directory. If a service only contains groups of IPersons, the groups root would have 1 sub-directory named org.jasig.portal.security.IPerson.

A directory named for a type may contain both sub-directories and files. The sub-directories represent groups that can contain other groups. The files represent groups that can contain entity as well as group members. The files contain keys, one to a line, and look like this:

---- # this is a comment
# another comment

Moe  this is ignored
Larry
group:org.jasig.portal.security.IPerson/someDirectory/someFile
Curly
 # comment

Blank lines and lines starting with FileSystemGroupStore.COMMENT (here "#") are ignored. The first token on a non-ignored line is assumed to be a group member key. If the key starts with  FileSystemGroupStore.GROUP_PREFIX (here ":group"), it is treated as a local group key. Otherwise, it is assumed to be an entity key. The rest of the tokens on the line are ignored.

The example above contains 3 entity keys, Moe, Larry, and Curly, and 1 group key, org.jasig.portal.security.IPerson/someDirectory/someFile. It represents a group with 3 entity members and 1 group member. The local key of a group is its file path starting at the type name.  If the nodeSeparator for the composite configuration is ".", the FileSystemGroupStore.SUBSTITUTE_PERIOD ("$") is substituted for the real period character in a group key, so the group entry in this example would be

org$jasig$portal$security$IPerson/someDirectory/someFile.

To demonstrate how this actually works, try the following short Filesystem Group Service Tutorial (estimated time 15 minutes) on the base distribution.

Although they're easy to create, filesystem groups work like other groups: they can be associated with Permissions, they can become group members, you can browse and select (though not update) them in Groups Manager.  However, since they are not internally-managed, they cannot contain foreign memberships (groups from other services) and membership changes are not guaranteed to show up in real time. 

Note also that the store class is not a singleton, so you can have multiple filesystem services pointing to different "root" directories.

Possible Enhancements

We could use something like Commons VFS to put a layer between the Filesystem store and the underlying store. This could make it possible to use a wide range of sources, including zip files, ftp and webdav.