X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=rt%2Fhtml%2Fautohandler;h=b21d26145b70bb47975176642b339f9b5e5a5791;hp=ce8b7569e1ffffdbd8972bd7727e8e59a3a99952;hb=f7fd2a3e34da751cbc02bbf215e99c6dc89adc15;hpb=0ebeec96313dd7edfca340f01f8fbbbac1f4aa1d diff --git a/rt/html/autohandler b/rt/html/autohandler index ce8b7569e..b21d26145 100644 --- a/rt/html/autohandler +++ b/rt/html/autohandler @@ -1,8 +1,14 @@ -%# BEGIN LICENSE BLOCK +%# {{{ BEGIN BPS TAGGED BLOCK %# -%# Copyright (c) 1996-2003 Jesse Vincent +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC +%# %# -%# (Except where explictly superceded by other copyright notices) +%# (Except where explicitly superseded by other copyright notices) +%# +%# +%# LICENSE: %# %# 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 @@ -14,31 +20,53 @@ %# 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. +%# You should have received a copy of the GNU General Public License +%# along with this program; if not, write to the Free Software +%# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +%# +%# +%# CONTRIBUTION SUBMISSION POLICY: %# +%# (The following paragraph is not intended to limit the rights granted +%# to you to modify and distribute this software under the terms of +%# the GNU General Public License and is only of importance to you if +%# you choose to contribute your changes and enhancements to the +%# community by submitting them to Best Practical Solutions, LLC.) %# -%# END LICENSE BLOCK +%# By intentionally submitting any modifications, corrections or +%# derivatives to this work, or any other work intended for use with +%# Request Tracker, to Best Practical Solutions, LLC, you confirm that +%# you are the copyright holder for those contributions and you grant +%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +%# royalty-free, perpetual, license to use, copy, create derivative +%# works based on those contributions, and sublicense and distribute +%# those contributions and any derivatives thereof. +%# +%# }}} END BPS TAGGED BLOCK <%INIT> # Roll back any dangling transactions from a previous failed connection $RT::Handle->ForceRollback() if $RT::Handle->TransactionDepth; -local *session; +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 + # 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') + ($type eq 'ARRAY') ? [ map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } @$_ ] : - ($type eq 'HASH') + ($type eq 'HASH') ? { map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } %$_ } : $_ -} %ARGS; + } %ARGS; if ($ARGS{'Debug'}) { require Time::HiRes; @@ -58,76 +86,102 @@ unless ($session{'CurrentUser'} && $session{'CurrentUser'}->Id) { $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/') +if ($m->base_comp->path =~ $RT::WebNoAuthRegex ) { $m->call_next(%ARGS); $m->abort(); } -# If RT is configured for external auth, let's get REMOTE_USER -elsif ($RT::WebExternalAuth and length($ENV{'REMOTE_USER'})) { - my $orig_user = $user; - - $user = $ENV{'REMOTE_USER'}; - $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 with default attributes - - 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) { - $UserObj->SetPrivileged(1); - - if ($^O !~ /^(?:riscos|MacOS|MSWin32|dos|os2)$/) { - # Populate fields with information from Unix /etc/passwd - - my ($comments, $realname) = (getpwnam($user))[5, 6]; - $UserObj->SetComments($comments) if defined $comments; - $UserObj->SetRealName($realname) if defined $realname; +# 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('RT_System')); + + 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') { + $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'NewUser'); + + my $method = "Set$attribute"; + $UserObj->$method($new_user_info->{$attribute}) + if( defined $new_user_info->{$attribute} ); + } + $session{'CurrentUser'}->Load($user); } - elsif ($^O eq 'MSWin32' and eval 'use Net::AdminMisc; 1') { - # Populate fields with information from NT domain controller + 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)); } - - $session{'CurrentUser'}->Load($user); } - else { + + unless ( $session{'CurrentUser'}->Id() ) { delete $session{'CurrentUser'}; - $m->abort() unless $RT::WebFallbackToInternalAuth; - $m->comp('/Elements/Login', %ARGS, Error=> loc('Cannot create user: [_1]', $msg)); + $user = $orig_user; + + if ( $RT::WebExternalOnly ) { + $m->comp('/Elements/Login', %ARGS, + Error=> loc('You are not an authorized user')); + $m->abort(); + } } } - - 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'); @@ -139,11 +193,15 @@ if (!$session{'CurrentUser'} && defined ($user) && defined ($pass) ){ if (!$session{'CurrentUser'}->id() || !$session{'CurrentUser'}->IsPassword($pass)) { + $RT::Logger->error("FAILED LOGIN for $user from $ENV{'REMOTE_ADDR'}"); delete $session{'CurrentUser'}; $m->comp('/Elements/Login', %ARGS, Error => loc('Your username or password is incorrect')); $m->abort(); } + else { + $RT::Logger->info("Successful login for $user from $ENV{'REMOTE_ADDR'}"); + } } # If we've got credentials, let's serve the file up.