import rt 3.0.12
[freeside.git] / rt / html / autohandler
1 %# BEGIN LICENSE BLOCK
2 %# 
3 %# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
4 %# 
5 %# (Except where explictly superceded by other copyright notices)
6 %# 
7 %# This work is made available to you under the terms of Version 2 of
8 %# the GNU General Public License. A copy of that license should have
9 %# been provided with this software, but in any event can be snarfed
10 %# from www.gnu.org.
11 %# 
12 %# This work is distributed in the hope that it will be useful, but
13 %# WITHOUT ANY WARRANTY; without even the implied warranty of
14 %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 %# General Public License for more details.
16 %# 
17 %# Unless otherwise specified, all modifications, corrections or
18 %# extensions to this work which alter its source code become the
19 %# property of Best Practical Solutions, LLC when submitted for
20 %# inclusion in the work.
21 %# 
22 %# 
23 %# END LICENSE BLOCK
24 <%INIT>
25
26 # Roll back any dangling transactions from a previous failed connection
27 $RT::Handle->ForceRollback() if $RT::Handle->TransactionDepth;
28
29
30 local *session unless $m->is_subrequest; # avoid reentrancy, as suggested by masonbook
31
32 # Disable AutoFlush using an attribute
33 if ($m->request_comp->attr_exists('AutoFlush')) {
34     $m->autoflush($m->request_comp->attr('AutoFlush'));
35 }
36
37 %ARGS = map {
38     # if they've passed multiple values, they'll be an array. if they've 
39     # passed just one, a scalar whatever they are, mark them as utf8
40     my $type = ref($_);
41     (!$type)
42         ? Encode::decode(utf8 => $_, Encode::FB_PERLQQ) :
43         ($type eq 'ARRAY')
44         ? [ map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } @$_ ] :
45         ($type eq 'HASH')
46         ? { map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } %$_ } : $_
47     } %ARGS;
48
49 if ($ARGS{'Debug'}) {
50         require Time::HiRes;
51         $m->{'rt_base_time'} = [Time::HiRes::gettimeofday()];
52         
53 }
54 else {
55         $m->{'rt_base_time'} = time;
56 }
57 $m->comp('/Elements/SetupSessionCookie', %ARGS);
58
59 unless ($session{'CurrentUser'} && $session{'CurrentUser'}->Id) {
60     $session{'CurrentUser'} = RT::CurrentUser->new();
61 }
62
63 # Set the proper encoding for the current language handle
64 $r->content_type("text/html; charset=utf-8");
65
66 # If it's a noauth file, don't ask for auth.
67 if ($m->base_comp->path =~ '^/+NoAuth/' ||
68     $m->base_comp->path =~ '^/+REST/\d+\.\d+/NoAuth/')
69 {
70     $m->call_next(%ARGS);
71     $m->abort();
72 }
73
74 # If RT is configured for external auth, let's go through and get REMOTE_USER
75 elsif ( $RT::WebExternalAuth ) {
76
77     # do we actually have a REMOTE_USER equivlent?
78     if ( RT::Interface::Web::WebCanonicalizeInfo() ) {
79
80         my $orig_user = $user;
81         
82         $user = RT::Interface::Web::WebCanonicalizeInfo();
83         $session{'CurrentUser'} = RT::CurrentUser->new();
84         my $load_method = $RT::WebExternalGecos ? 'LoadByGecos' : 'Load';
85         
86         if ($^O eq 'MSWin32' and $RT::WebExternalGecos) {
87             my $NodeName = Win32::NodeName();
88             $user =~ s/^\Q$NodeName\E\\//i;
89         }
90         
91         $session{'CurrentUser'}->$load_method($user);
92         
93         if ($RT::WebExternalAuto and !$session{'CurrentUser'}->Id() ) {
94             # Create users on-the-fly
95             
96             my $UserObj = RT::User->new(RT::CurrentUser->new('root'));
97             
98             my ($val, $msg) = $UserObj->Create(
99                                                %{ref($RT::AutoCreate) ? $RT::AutoCreate : {}},
100                                                Name   => $user,
101                                                Gecos  => $user,
102                                                );
103             
104             if ($val) {
105                 
106                 # now get user specific information, to better create our user.
107                 my $new_user_info = RT::Interface::Web::WebExternalAutoInfo($user);
108                 
109                 # set the attributes that have been defined.
110                 # FIXME: this is a horrible kludge. I'm sure there's something cleaner
111                 foreach my $attribute ('Name', 'Comments', 'Signature', 'EmailAddress',
112                                        'PagerEmailAddress', 'FreeformContactInfo',
113                                        'Organization', 'Disabled', 'Privileged',
114                                        'RealName', 'NickName', 'Lang', 'EmailEncoding',
115                                        'WebEncoding', 'ExternalContactInfoId',
116                                        'ContactInfoSystem', 'ExternalAuthId', 'Gecos',
117                                        'HomePhone', 'WorkPhone', 'MobilePhone',
118                                        'PagerPhone', 'Address1', 'Address2', 'City',
119                                        'State', 'Zip', 'Country') {
120                $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'NewUser');
121                     
122                     my $method = "Set$attribute";
123                     $UserObj->$method($new_user_info->{$attribute}) 
124                         if( defined $new_user_info->{$attribute} );
125                 }           
126                 $session{'CurrentUser'}->Load($user);
127             }
128             else {
129                 # we failed to successfully create the user. abort abort abort.
130                 delete $session{'CurrentUser'};
131                 $m->abort() unless $RT::WebFallbackToInternalAuth;
132                 $m->comp('/Elements/Login', %ARGS, 
133                          Error=> loc('Cannot create user: [_1]', $msg));
134             }
135         }
136         
137         unless ( $session{'CurrentUser'}->Id() ) {
138             delete $session{'CurrentUser'};
139             $user = $orig_user;
140             
141             if ( $RT::WebExternalOnly ) {               
142                 $m->comp('/Elements/Login', %ARGS, 
143                          Error=> loc('You are not an authorized user'));
144                 $m->abort();
145             }
146         }
147     }
148     elsif ($RT::WebFallbackToInternalAuth) {
149         unless (defined($session{'CurrentUser'})) {
150                 $m->comp('/Elements/Login', %ARGS,
151                          Error=> loc('XXX CHANGEME You are not an authorized user'));
152                 $m->abort();
153         }
154     } else {
155         # WebExternalAuth is set, but we don't have a REMOTE_USER. abort
156         delete $session{'CurrentUser'} if defined $session{'CurrentUser'};
157     }
158 }
159
160 delete $session{'CurrentUser'}
161     unless $session{'CurrentUser'} and defined $session{'CurrentUser'}->Id;
162
163
164 # Process per-page authentication callbacks
165 $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'Auth');
166
167 # If the user is logging in, let's authenticate
168 if (!$session{'CurrentUser'} && defined ($user) && defined ($pass) ){
169     $session{'CurrentUser'} = RT::CurrentUser->new();
170     $session{'CurrentUser'}->Load($user);
171
172     if (!$session{'CurrentUser'}->id() ||
173         !$session{'CurrentUser'}->IsPassword($pass))
174     {
175         $RT::Logger->error("FAILED LOGIN for $user from $ENV{'REMOTE_ADDR'}");
176         delete $session{'CurrentUser'};
177         $m->comp('/Elements/Login', %ARGS,
178                  Error => loc('Your username or password is incorrect'));
179         $m->abort();
180     }
181     else {
182         $RT::Logger->info("Successful login for $user from $ENV{'REMOTE_ADDR'}");
183     }
184 }
185   
186 # If we've got credentials, let's serve the file up.
187 if ( (defined $session{'CurrentUser'}) and 
188      ( $session{'CurrentUser'}->Id) ) {
189     
190     # Process per-page global callbacks
191     $m->comp('/Elements/Callback', %ARGS);
192
193     # If the user isn't privileged, they can only see SelfService
194     if ((! $session{'CurrentUser'}->Privileged) and
195         ($m->base_comp->path !~ '^(/+)SelfService/') ) {
196         $m->comp('/SelfService/index.html');
197         $m->abort();
198     }
199     else {
200         $m->call_next(%ARGS);
201     }
202 }
203
204 # If we have no credentials
205 else {
206     $m->comp('/Elements/Login', %ARGS);
207     $m->abort();
208 }
209 </%INIT>
210 <& /Elements/Footer, %ARGS &>
211 <%ARGS>
212 $user => undef
213 $pass => undef
214 $menu => undef
215 </%ARGS>