[Rt-devel] Proposed Contrib: External (LDAP) user info attr mapping

Ruslan Zakirov ruslan.zakirov at gmail.com
Thu Dec 1 16:51:03 EST 2005

On 11/30/05, Jim Meyer <purp at acm.org> wrote:
> Hello!
> I apologize in advance for the length of this. I hate long email but I
> value the advice of this list when approaching something as complex as
> I'm describing below ... and if I can't adequately explain it here, I
> feel like I shouldn't do it at all. So you get to read a long email.
> Sorry. =\
> I want to implement the mapping of LDAP attr -> RT field mentioned in
> Philip Cole's code comments at
> http://wiki.bestpractical.com/index.cgi?AutoCreateAndCanonicalizeUserInfo and, in order to avoid synchronization issues, I want information which is gotten from LDAP to be immutable in all RT interfaces (web and CLI). I have the additional challenge of five valid FQDNs by which you can reach folks here using some various combos of unix login, first-initial-last-name, and first.last left of the @ ... but there's no one LHS which is universal to all five RHS.
> I should mention that I have no control of, and little influence in, how
> this all works, so cleaning it up isn't an option for me. I'm also in a
> hurry (I need to finish this by Friday), so waiting for the coming
> cleanup isn't an option, either.
> Fun, eh?
> I'm considering doing this like so:
Ok. I never tried external auth systems to use with RT, but try to comment this.

> * Add %RT::LdapAttrMap as Philip Cole suggests, with some way of
>   indicating user-based custom fields as well. Perhaps:
>   %RT::LdapAttrMap = ( Name=> 'uid',
>                        RealName=> 'cn',
>                        EmailAdress=> 'mail',
>                        CF::ExternalObjectID=> 'dn'
>                        ...);
There is also other auth systems and really is better to implement
into the RT core code that would allow you to define name of the
module (for example RT::Auth::LDAP). This would allow you to subclass
module and implement own mapping or something like this.

> * Add $RT::LdapUserInfoEnable and $RT::LdapUserInfoTTL (in minutes)
>   to control whether user info is acquired from LDAP and, if so, how
>   long it's considered valid before rechecking LDAP.
1) $RT::LdapUserInfoEnable should be named ExternalUserInfo or
something like this and RT should just call method in the module of
the chosen auth system.
2) $RT::LdapUserInfoTTL - I think external script should check it, RT
can fetch data on the first request, but then external script can be
ran from cron to check if some records require update.

> * Add user-based CFs for:
>   * preferred email (Freeform single, set when receiving user email)
>   * valid email addrs (Freeform multiple, cached from LDAP)
Don't know if it should be CF, but anyway "multiple emails" is good feature.

>   * ExternalObjectId (Freeform single, cached from LDAP)
It should be Attribute of the user's object.

>   * last LDAP update (Freeform single, set while getting LDAP info);
>     alternately, this could just use the existing "LastUpdate"
>     RT::User attr ... though I was thinking that forcing a cache
>     refresh could be as easy as blanking this CF and clicking
>     "Save Preferences".
Again attribute instead of CF.

> * Refactor Philip Cole's RT::User::LookupExternalUserInfo() to accept
>   ExternalObjectId or ExternalUserName (for use with the LDAP auth
>   params), as well as the current key/value scheme.
> * Add a method, RT::User->RefreshFromExternalUserInfo(), which calls
>   LookupExternalUserInfo() then uses the mapping defined in
>   %RT::LdapAttrMap to set the current objects attrs appropriately.
As said before, move to plugable solution, refactor it a bit. I'm not
good in genrating names, but there is could be something like
RT::User::External::LDAP, RT::User::External::NTLM, PAM or
MyCompanyDBWithUsers that has all that methods: LookupUser,
UpdateUserInfo and so on.

> * Any time user info is loaded RT::User->Load(), check that the cached
>   data hasn't outlived its expiration and, if it has, call
>   RefreshFromExternalInfo(). Failure of this refresh generates a
>   warning (info? crit?) but is not fatal.
I really don't like it, do this updates in external script.

> So where are the holes I've missed?
> Thanks for reading this far!
> --j
> p.s. if ever you want to be sure to understand what you intend, compose
> your plans in an email to people smarter than yourself and in front of
> whom you'd like not to make a fool of yourself. It's worked for me. =]
> p.p.s. A minor digression: if I were implementing directly in RT rather
> than as a contrib, I'd extend the Users table with ExternalObjectId and
> LastExternalUpdate columns, both of which would only be seen on the
> /Admin/Users/Modify page. I'd also add an EmailAddresses table with id,
> ObjectId (users or groups, right?), EmailAddress, and Preferred
> (boolean) columns.
Now we have Attributes table that allows us to stick info to any
record in the DB, but if this feature will slowdown things a lot then
it could be splitted into own tables and fields.

> I'd also work to better integrate the external autho/info methods
> (RT::ExternalInfo.pm? $RT::ExternalAuthMethod? Dunno =). It might be fun
> to leverage this to groups, too (manage RT group membership in LDAP;
> give groups a distinct email address and leave off emailing individuals;
> etc.)
manage groups membership from external source is good idea, but I
think it's hard to implement as also group's email addresses.

> If someone cares to comment on this approach, I'd enjoy the benefit of
> their knowledge.
> --
> Jim Meyer, Geek at Large                                    purp at acm.org
> _______________________________________________
> Rt-devel mailing list
> Rt-devel at lists.bestpractical.com
> http://lists.bestpractical.com/cgi-bin/mailman/listinfo/rt-devel

Best regards, Ruslan.

More information about the Rt-devel mailing list