Proposal: A Strategy for Managing User Attributes from Multiple Sources
Problem
A user's attributes typically come primarily from a single source, which is usually an LDAP directory. Local portal users, by contrast, normally have a similar set of attributes which come from the uPortalAccountUserSource (LocalAccountPersonAttributeDao). It would be a useful feature if it were possible for users to have attributes from both of these sources, as well as other similar sources. But what happens when multiple sources define the same attribute? In point of fact, the PersonDirectory API can manage this case in a deterministic and admin-configurable manner, but the resulting behavior isn't well communicated to the user in the UI. How do we establish which attributes may be managed for which data sources using which tools, and how do we communicate that to users in the portal?
Summary
This proposal describes a service that describes which attributes are mutable for which groups and provides an API for making those changes.
IRC Discussion
For some background on this proposal, check out this IRC discussion: uPortal IRC Logs-2012-08-20
Configuration
The configuration should enable statements like "Persist user attribute 'a' via persistence implmenetation 's' for users in group g". These declarations should be structured in a list, with the order determining well-defined behavior for overlapping user attributes.
Example use case:
For users in group "Students", store attributes first name, last name, and email in the student LDAP store
For users in group "Faculty", store attributes first name, last name, and email in the faculty LDAP store
For users in group "Local Test Users", store attributes first name, last name, and email in the local account store
For all users, store attribute birthday in the local account store
Configuration might take one of the following forms, which include PreferenceInput objects that describe how the attribute can be rendered on a form:
Map<groupName, Map<attributeName, Descriptor(daoImpl, input)>>
List<GroupMappingThing(groupName, Map<attributeName, Descriptor(daoImpl, input)>)>
Proposed Persistence API
interface IPersistingPersonAttributeDAO
public void updateAttributes(String username, Map<String, List<Object>> attributes);
class LDAPPersistingPersonAttributeDaoImpl implements IPersistingPersonAttributeDao
class LocalAccountPersistingPersonAttributeDaoImpl implements IPersistingPersonAttributeDao
Implementations may need to:
Create new users in order to persist attributes
Require configuration to handle particular attributes (e.g. passwords) specially
Interact with uPortal caches to refresh person attribute data
Implementation Notes
Should be done in the spirit of PersonDirectory, but NOT within it. NOTE: this choice is in large part because that API is so badly in need of update; this use case should be considered as we plan a major overhaul to the PD APIs.
I'm reviewing this outline, and I'm wondering if this vision is more complex or just _more_ than we actually need. I fear it gets us back into sticky questions like "what happens of the user is both a Student and a Faculty?" I guess I don't see a reason, from where I'm standing, that the rules for attributes need to be tied to groups.
Wouldn't it be enough to say...
- A local attribute MAY declare and/or override office phone
- A local attribute MAY declare (but not override) the mail attribute
- A local attribute MAY NOT declare eduPersonPrimaryAffiliation