3 %# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
5 %# (Except where explictly superceded by other copyright notices)
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
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.
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.
26 # Roll back any dangling transactions from a previous failed connection
27 $RT::Handle->ForceRollback() if $RT::Handle->TransactionDepth;
30 local *session unless $m->is_subrequest; # avoid reentrancy, as suggested by masonbook
32 # Disable AutoFlush using an attribute
33 if ($m->request_comp->attr_exists('AutoFlush')) {
34 $m->autoflush($m->request_comp->attr('AutoFlush'));
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
42 ? Encode::decode(utf8 => $_, Encode::FB_PERLQQ) :
44 ? [ map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } @$_ ] :
46 ? { map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } %$_ } : $_
51 $m->{'rt_base_time'} = [Time::HiRes::gettimeofday()];
55 $m->{'rt_base_time'} = time;
57 $m->comp('/Elements/SetupSessionCookie', %ARGS);
59 unless ($session{'CurrentUser'} && $session{'CurrentUser'}->Id) {
60 $session{'CurrentUser'} = RT::CurrentUser->new();
63 # Set the proper encoding for the current language handle
64 $r->content_type("text/html; charset=utf-8");
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/')
74 # If RT is configured for external auth, let's go through and get REMOTE_USER
75 elsif ( $RT::WebExternalAuth ) {
77 # do we actually have a REMOTE_USER equivlent?
78 if ( RT::Interface::Web::WebCanonicalizeInfo() ) {
80 my $orig_user = $user;
82 $user = RT::Interface::Web::WebCanonicalizeInfo();
83 $session{'CurrentUser'} = RT::CurrentUser->new();
84 my $load_method = $RT::WebExternalGecos ? 'LoadByGecos' : 'Load';
86 if ($^O eq 'MSWin32' and $RT::WebExternalGecos) {
87 my $NodeName = Win32::NodeName();
88 $user =~ s/^\Q$NodeName\E\\//i;
91 $session{'CurrentUser'}->$load_method($user);
93 if ($RT::WebExternalAuto and !$session{'CurrentUser'}->Id() ) {
94 # Create users on-the-fly
96 my $UserObj = RT::User->new(RT::CurrentUser->new('root'));
98 my ($val, $msg) = $UserObj->Create(
99 %{ref($RT::AutoCreate) ? $RT::AutoCreate : {}},
106 # now get user specific information, to better create our user.
107 my $new_user_info = RT::Interface::Web::WebExternalAutoInfo($user);
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') {
121 my $method = "Set$attribute";
122 $UserObj->$method($new_user_info->{$attribute})
123 if( defined $new_user_info->{$attribute} );
125 $session{'CurrentUser'}->Load($user);
128 # we failed to successfully create the user. abort abort abort.
129 delete $session{'CurrentUser'};
130 $m->abort() unless $RT::WebFallbackToInternalAuth;
131 $m->comp('/Elements/Login', %ARGS,
132 Error=> loc('Cannot create user: [_1]', $msg));
136 unless ( $session{'CurrentUser'}->Id() ) {
137 delete $session{'CurrentUser'};
140 if ( $RT::WebExternalOnly ) {
141 $m->comp('/Elements/Login', %ARGS,
142 Error=> loc('You are not an authorized user'));
147 elsif ($RT::WebFallbackToInternalAuth) {
148 unless (defined($session{'CurrentUser'})) {
149 $m->comp('/Elements/Login', %ARGS,
150 Error=> loc('XXX CHANGEME You are not an authorized user'));
154 # WebExternalAuth is set, but we don't have a REMOTE_USER. abort
155 delete $session{'CurrentUser'} if defined $session{'CurrentUser'};
159 delete $session{'CurrentUser'}
160 unless $session{'CurrentUser'} and defined $session{'CurrentUser'}->Id;
163 # Process per-page authentication callbacks
164 $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'Auth');
166 # If the user is logging in, let's authenticate
167 if (!$session{'CurrentUser'} && defined ($user) && defined ($pass) ){
168 $session{'CurrentUser'} = RT::CurrentUser->new();
169 $session{'CurrentUser'}->Load($user);
171 if (!$session{'CurrentUser'}->id() ||
172 !$session{'CurrentUser'}->IsPassword($pass))
174 delete $session{'CurrentUser'};
175 $m->comp('/Elements/Login', %ARGS,
176 Error => loc('Your username or password is incorrect'));
181 # If we've got credentials, let's serve the file up.
182 if ( (defined $session{'CurrentUser'}) and
183 ( $session{'CurrentUser'}->Id) ) {
185 # Process per-page global callbacks
186 $m->comp('/Elements/Callback', %ARGS);
188 # If the user isn't privileged, they can only see SelfService
189 if ((! $session{'CurrentUser'}->Privileged) and
190 ($m->base_comp->path !~ '^(/+)SelfService/') ) {
191 $m->comp('/SelfService/index.html');
195 $m->call_next(%ARGS);
199 # If we have no credentials
201 $m->comp('/Elements/Login', %ARGS);
205 <& /Elements/Footer, %ARGS &>