%# BEGIN LICENSE BLOCK %# %# Copyright (c) 1996-2003 Jesse Vincent %# %# (Except where explictly superceded by other copyright notices) %# %# This work is made available to you under the terms of Version 2 of %# the GNU General Public License. A copy of that license should have %# been provided with this software, but in any event can be snarfed %# from www.gnu.org. %# %# This work is distributed in the hope that it will be useful, but %# WITHOUT ANY WARRANTY; without even the implied warranty of %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU %# General Public License for more details. %# %# Unless otherwise specified, all modifications, corrections or %# extensions to this work which alter its source code become the %# property of Best Practical Solutions, LLC when submitted for %# inclusion in the work. %# %# %# END LICENSE BLOCK <%INIT> # Roll back any dangling transactions from a previous failed connection $RT::Handle->ForceRollback() if $RT::Handle->TransactionDepth; local *session unless $m->is_subrequest; # avoid reentrancy, as suggested by masonbook # Disable AutoFlush using an attribute if ($m->request_comp->attr_exists('AutoFlush')) { $m->autoflush($m->request_comp->attr('AutoFlush')); } %ARGS = map { # if they've passed multiple values, they'll be an array. if they've # passed just one, a scalar whatever they are, mark them as utf8 my $type = ref($_); (!$type) ? Encode::decode(utf8 => $_, Encode::FB_PERLQQ) : ($type eq 'ARRAY') ? [ map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } @$_ ] : ($type eq 'HASH') ? { map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } %$_ } : $_ } %ARGS; if ($ARGS{'Debug'}) { require Time::HiRes; $m->{'rt_base_time'} = [Time::HiRes::gettimeofday()]; } else { $m->{'rt_base_time'} = time; } $m->comp('/Elements/SetupSessionCookie', %ARGS); unless ($session{'CurrentUser'} && $session{'CurrentUser'}->Id) { $session{'CurrentUser'} = RT::CurrentUser->new(); } # Set the proper encoding for the current language handle $r->content_type("text/html; charset=utf-8"); # If it's a noauth file, don't ask for auth. if ($m->base_comp->path =~ '^/+NoAuth/' || $m->base_comp->path =~ '^/+REST/\d+\.\d+/NoAuth/') { $m->call_next(%ARGS); $m->abort(); } # If RT is configured for external auth, let's go through and get REMOTE_USER elsif ( $RT::WebExternalAuth ) { # do we actually have a REMOTE_USER equivlent? if ( RT::Interface::Web::WebCanonicalizeInfo() ) { my $orig_user = $user; $user = RT::Interface::Web::WebCanonicalizeInfo(); $session{'CurrentUser'} = RT::CurrentUser->new(); my $load_method = $RT::WebExternalGecos ? 'LoadByGecos' : 'Load'; if ($^O eq 'MSWin32' and $RT::WebExternalGecos) { my $NodeName = Win32::NodeName(); $user =~ s/^\Q$NodeName\E\\//i; } $session{'CurrentUser'}->$load_method($user); if ($RT::WebExternalAuto and !$session{'CurrentUser'}->Id() ) { # Create users on-the-fly my $UserObj = RT::User->new(RT::CurrentUser->new('root')); my ($val, $msg) = $UserObj->Create( %{ref($RT::AutoCreate) ? $RT::AutoCreate : {}}, Name => $user, Gecos => $user, ); if ($val) { # now get user specific information, to better create our user. my $new_user_info = RT::Interface::Web::WebExternalAutoInfo($user); # set the attributes that have been defined. # FIXME: this is a horrible kludge. I'm sure there's something cleaner foreach my $attribute ('Name', 'Comments', 'Signature', 'EmailAddress', 'PagerEmailAddress', 'FreeformContactInfo', 'Organization', 'Disabled', 'Privileged', 'RealName', 'NickName', 'Lang', 'EmailEncoding', 'WebEncoding', 'ExternalContactInfoId', 'ContactInfoSystem', 'ExternalAuthId', 'Gecos', 'HomePhone', 'WorkPhone', 'MobilePhone', 'PagerPhone', 'Address1', 'Address2', 'City', 'State', 'Zip', 'Country') { my $method = "Set$attribute"; $UserObj->$method($new_user_info->{$attribute}) if( defined $new_user_info->{$attribute} ); } $session{'CurrentUser'}->Load($user); } else { # we failed to successfully create the user. abort abort abort. delete $session{'CurrentUser'}; $m->abort() unless $RT::WebFallbackToInternalAuth; $m->comp('/Elements/Login', %ARGS, Error=> loc('Cannot create user: [_1]', $msg)); } } unless ( $session{'CurrentUser'}->Id() ) { delete $session{'CurrentUser'}; $user = $orig_user; if ( $RT::WebExternalOnly ) { $m->comp('/Elements/Login', %ARGS, Error=> loc('You are not an authorized user')); $m->abort(); } } } elsif ($RT::WebFallbackToInternalAuth) { unless (defined($session{'CurrentUser'})) { $m->comp('/Elements/Login', %ARGS, Error=> loc('XXX CHANGEME You are not an authorized user')); $m->abort(); } } else { # WebExternalAuth is set, but we don't have a REMOTE_USER. abort delete $session{'CurrentUser'} if defined $session{'CurrentUser'}; } } delete $session{'CurrentUser'} unless $session{'CurrentUser'} and defined $session{'CurrentUser'}->Id; # Process per-page authentication callbacks $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'Auth'); # If the user is logging in, let's authenticate if (!$session{'CurrentUser'} && defined ($user) && defined ($pass) ){ $session{'CurrentUser'} = RT::CurrentUser->new(); $session{'CurrentUser'}->Load($user); if (!$session{'CurrentUser'}->id() || !$session{'CurrentUser'}->IsPassword($pass)) { delete $session{'CurrentUser'}; $m->comp('/Elements/Login', %ARGS, Error => loc('Your username or password is incorrect')); $m->abort(); } } # If we've got credentials, let's serve the file up. if ( (defined $session{'CurrentUser'}) and ( $session{'CurrentUser'}->Id) ) { # Process per-page global callbacks $m->comp('/Elements/Callback', %ARGS); # If the user isn't privileged, they can only see SelfService if ((! $session{'CurrentUser'}->Privileged) and ($m->base_comp->path !~ '^(/+)SelfService/') ) { $m->comp('/SelfService/index.html'); $m->abort(); } else { $m->call_next(%ARGS); } } # If we have no credentials else { $m->comp('/Elements/Login', %ARGS); $m->abort(); } <& /Elements/Footer, %ARGS &> <%ARGS> $user => undef $pass => undef $menu => undef