[Rt-devel] User AutoCreation in RT

Jim Meyer purp at acm.org
Mon Apr 3 21:03:16 EDT 2006


Hello!

This is bound to be a bit long. I apologize and will strive to be
concise as well as informative

Here's all the places I've found which create users and how they go
about it; rather than quote 10-30 lines of code per instance, I've
boiled each down to a shorthand indicating how the RT::User object is
created and how Create() is called.

RT::Interface::Email::CreateUser
================================
  # grep -r show no usage in ${RTHOME}/lib or ${RTHOME}/share/html
  RT::User->new($RT::SystemUser)->Create(Name => ($Username || $Address),
                       EmailAddress => $Address,
                       RealName => $Name,
                       Password => undef,
                       Privileged => 0,
                       Comments => 'Autocreated on ticket submission')

RT::Ticket::Create
==================
  # $watcher is an email address of a Requestor, Cc, or AdminCc
  RT::User->new($RT::SystemUser)->LoadOrCreateByEmail($watcher)

  # This is the sole caller of LoadOrCreateByEmail. Expanded to include
  # that function and noting that we pass nothing but email address,
  # this is really:
  RT::User->new($RT::SystemUser)->Create(
    Name => $watcher,
    EmailAddress => $watcher,
    RealName     => $watcher,
    Privileged   => 0,
    Comments     => 'Autocreated when added as a watcher');

RT::Queue::_AddWatcher
======================
  my ( $Address, $Name ) =
    RT::Interface::Email::ParseAddressFromHeader($args{'Email'});
  RT::User->new($RT::SystemUser)->Create(
                Name => $Address,
                EmailAddress => $Address,
                RealName     => $Name,
                Privileged   => 0,
                Comments     => 'Autocreated when added as a watcher');

share/html/autohandler
======================
  # Called only if you're using the WebExternal*
  RT::User->new(RT::CurrentUser->new('RT_System'))->Create(
    %{ref($RT::AutoCreate) ? $RT::AutoCreate : {}},
    Name   => $user,
    Gecos  => $user,
  );
  # ...then call Set<Attr> methods (e.g. SetName, SetComments, etc.)
  # to add info from OS via RT::Interface::Web::WebExternalAutoInfo

share/html/Admin/Users/Modify.html and
share/html/REST/1.0/Forms/user/default also create users, but they're
in response to explicit requests rather than autocreation.

Some observations:
* All instances of user creation are invoked by the RT System user
* All except the autohandler could call LoadOrCreateByEmail()
* All except the autohandler contain hard-coded defaults;
  these defaults are mostly consistent but vary slightly.

I'd like to propose a generalized RT::User->LoadOrCreate() function
which can be passed a pile of user info and told which piece to
attempt to load by; it would honor $RT::AutoCreateUserInfo to set any
user info which wasn't passed in by the caller. The interface might
look like either of these:

  $UserObj->LoadOrCreate('Name', $user_info_hashref);

  $UserObj->LoadOrCreate(LoadBy => 'Name',
                         Name   => 'purp',
                         EmailAddress => 'purp at acm.org',
                         ...);

(I like the latter for readability)

LoadOrCreateByEmail() would then be a thin wrapper to LoadOrCreate();
LoadOrCreateByName() could also be such. Failure modes would be
essentially the same: if you attempt to create a username which
already exists, you fail; otherwise, there are no guaranteed unique
attributes. It seems like it should require either an email address or
username, but I supposed it's possible to create a user who doesn't
get email, so...???

Sound reasonable? I'd love to hear comments. Meanwhile, I'll be
finishing an autocreation implementation/overlay/patch tomorrow; if we
can nail these details down quickly, it'll be something worthy of
sharing.

Thanks!

--j
--
Jim Meyer, Geek at Large                                    purp at acm.org


More information about the Rt-devel mailing list