# # User.pm Local Overlay. # Drop @cam.ac.uk from email address to create CRSID as username # use strict; no warnings qw(redefine); package RT::User; =head2 LoadOrCreateByEmal ADDRESS Attempts to find a user who has the provided email address. If that fails, creates an unpriviledged user with the provided email address and loads them. Address can be provided either as L object or string which is parsed using the module. Returns a tuple of the user's id and a status message. 0 will be returned in place of the user's id in case of failure. If an @cam.ac.uk email address is found, parse out the CRSID and use that as the username, this enables the user to login to the Selfservice portal using Raven web authentication. =cut sub LoadOrCreateByEmail { my $self = shift; my $email = shift; $RT::Logger->debug("LoadOrCreateByEmail called from User local overlay"); my ($message, $name); if ( UNIVERSAL::isa( $email => 'Email::Address' ) ) { ($email, $name) = ($email->address, $email->phrase); } else { ($email, $name) = RT::Interface::Email::ParseAddressFromHeader( $email ); } $self->LoadByEmail( $email ); $self->Load( $email ) unless $self->Id; $message = $self->loc('User loaded'); unless( $self->Id ) { my $name; #check for @cam.ac.uk email if ($email =~ /([a-zA-Z]+[0-9]+)(?:--.+)?@(?:hermes\.)?cam\.ac\.uk/ ) { $name = $1; } else { $name = $email; } $RT::Logger->debug("LoadOrCreateByEmail: Username set to".$name); my $val; ($val, $message) = $self->Create( Name => $name, EmailAddress => $email, RealName => $name, Privileged => 0, Comments => 'Autocreated when added as a watcher (User Local Overlay)', ); unless ( $val ) { # Deal with the race condition of two account creations at once $self->LoadByEmail( $email ); unless ( $self->Id ) { sleep 5; $self->LoadByEmail( $email ); } if ( $self->Id ) { $RT::Logger->error("Recovered from creation failure due to race condition"); $message = $self->loc("User loaded"); } else { $RT::Logger->crit("Failed to create user ". $email .": " .$message); } } } return (0, $message) unless $self->id; return ($self->Id, $message); } 1;