import of rt 3.0.9
[freeside.git] / rt / html / autohandler
index ce8b756..b2a407a 100644 (file)
 $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;
@@ -65,69 +71,95 @@ if ($m->base_comp->path =~ '^/+NoAuth/' ||
     $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('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);
            }
-           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');