1 %# {{{ BEGIN BPS TAGGED BLOCK
5 %# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC
6 %# <jesse@bestpractical.com>
8 %# (Except where explicitly superseded by other copyright notices)
13 %# This work is made available to you under the terms of Version 2 of
14 %# the GNU General Public License. A copy of that license should have
15 %# been provided with this software, but in any event can be snarfed
18 %# This work is distributed in the hope that it will be useful, but
19 %# WITHOUT ANY WARRANTY; without even the implied warranty of
20 %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 %# General Public License for more details.
23 %# You should have received a copy of the GNU General Public License
24 %# along with this program; if not, write to the Free Software
25 %# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 %# CONTRIBUTION SUBMISSION POLICY:
30 %# (The following paragraph is not intended to limit the rights granted
31 %# to you to modify and distribute this software under the terms of
32 %# the GNU General Public License and is only of importance to you if
33 %# you choose to contribute your changes and enhancements to the
34 %# community by submitting them to Best Practical Solutions, LLC.)
36 %# By intentionally submitting any modifications, corrections or
37 %# derivatives to this work, or any other work intended for use with
38 %# Request Tracker, to Best Practical Solutions, LLC, you confirm that
39 %# you are the copyright holder for those contributions and you grant
40 %# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
41 %# royalty-free, perpetual, license to use, copy, create derivative
42 %# works based on those contributions, and sublicense and distribute
43 %# those contributions and any derivatives thereof.
45 %# }}} END BPS TAGGED BLOCK
48 # Roll back any dangling transactions from a previous failed connection
49 $RT::Handle->ForceRollback() if $RT::Handle->TransactionDepth;
52 local *session unless $m->is_subrequest; # avoid reentrancy, as suggested by masonbook
54 # Disable AutoFlush using an attribute
55 if ($m->request_comp->attr_exists('AutoFlush')) {
56 $m->autoflush($m->request_comp->attr('AutoFlush'));
60 # if they've passed multiple values, they'll be an array. if they've
61 # passed just one, a scalar whatever they are, mark them as utf8
64 ? Encode::decode(utf8 => $_, Encode::FB_PERLQQ) :
66 ? [ map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } @$_ ] :
68 ? { map { ref($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } %$_ } : $_
73 $m->{'rt_base_time'} = [Time::HiRes::gettimeofday()];
77 $m->{'rt_base_time'} = time;
79 $m->comp('/Elements/SetupSessionCookie', %ARGS);
81 unless ($session{'CurrentUser'} && $session{'CurrentUser'}->Id) {
82 $session{'CurrentUser'} = RT::CurrentUser->new();
85 # Set the proper encoding for the current language handle
86 $r->content_type("text/html; charset=utf-8");
88 # If it's a noauth file, don't ask for auth.
89 if ($m->base_comp->path =~ $RT::WebNoAuthRegex )
95 # If RT is configured for external auth, let's go through and get REMOTE_USER
96 elsif ( $RT::WebExternalAuth ) {
98 # do we actually have a REMOTE_USER equivlent?
99 if ( RT::Interface::Web::WebCanonicalizeInfo() ) {
101 my $orig_user = $user;
103 $user = RT::Interface::Web::WebCanonicalizeInfo();
104 $session{'CurrentUser'} = RT::CurrentUser->new();
105 my $load_method = $RT::WebExternalGecos ? 'LoadByGecos' : 'Load';
107 if ($^O eq 'MSWin32' and $RT::WebExternalGecos) {
108 my $NodeName = Win32::NodeName();
109 $user =~ s/^\Q$NodeName\E\\//i;
112 $session{'CurrentUser'}->$load_method($user);
114 if ($RT::WebExternalAuto and !$session{'CurrentUser'}->Id() ) {
115 # Create users on-the-fly
117 my $UserObj = RT::User->new(RT::CurrentUser->new('RT_System'));
119 my ($val, $msg) = $UserObj->Create(
120 %{ref($RT::AutoCreate) ? $RT::AutoCreate : {}},
127 # now get user specific information, to better create our user.
128 my $new_user_info = RT::Interface::Web::WebExternalAutoInfo($user);
130 # set the attributes that have been defined.
131 # FIXME: this is a horrible kludge. I'm sure there's something cleaner
132 foreach my $attribute ('Name', 'Comments', 'Signature', 'EmailAddress',
133 'PagerEmailAddress', 'FreeformContactInfo',
134 'Organization', 'Disabled', 'Privileged',
135 'RealName', 'NickName', 'Lang', 'EmailEncoding',
136 'WebEncoding', 'ExternalContactInfoId',
137 'ContactInfoSystem', 'ExternalAuthId', 'Gecos',
138 'HomePhone', 'WorkPhone', 'MobilePhone',
139 'PagerPhone', 'Address1', 'Address2', 'City',
140 'State', 'Zip', 'Country') {
141 $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'NewUser');
143 my $method = "Set$attribute";
144 $UserObj->$method($new_user_info->{$attribute})
145 if( defined $new_user_info->{$attribute} );
147 $session{'CurrentUser'}->Load($user);
150 # we failed to successfully create the user. abort abort abort.
151 delete $session{'CurrentUser'};
152 $m->abort() unless $RT::WebFallbackToInternalAuth;
153 $m->comp('/Elements/Login', %ARGS,
154 Error=> loc('Cannot create user: [_1]', $msg));
158 unless ( $session{'CurrentUser'}->Id() ) {
159 delete $session{'CurrentUser'};
162 if ( $RT::WebExternalOnly ) {
163 $m->comp('/Elements/Login', %ARGS,
164 Error=> loc('You are not an authorized user'));
169 elsif ($RT::WebFallbackToInternalAuth) {
170 unless (defined($session{'CurrentUser'})) {
171 $m->comp('/Elements/Login', %ARGS,
172 Error=> loc('XXX CHANGEME You are not an authorized user'));
176 # WebExternalAuth is set, but we don't have a REMOTE_USER. abort
177 delete $session{'CurrentUser'} if defined $session{'CurrentUser'};
181 delete $session{'CurrentUser'}
182 unless $session{'CurrentUser'} and defined $session{'CurrentUser'}->Id;
185 # Process per-page authentication callbacks
186 $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'Auth');
188 # If the user is logging in, let's authenticate
189 if (!$session{'CurrentUser'} && defined ($user) && defined ($pass) ){
190 $session{'CurrentUser'} = RT::CurrentUser->new();
191 $session{'CurrentUser'}->Load($user);
193 if (!$session{'CurrentUser'}->id() ||
194 !$session{'CurrentUser'}->IsPassword($pass))
196 $RT::Logger->error("FAILED LOGIN for $user from $ENV{'REMOTE_ADDR'}");
197 delete $session{'CurrentUser'};
198 $m->comp('/Elements/Login', %ARGS,
199 Error => loc('Your username or password is incorrect'));
203 $RT::Logger->info("Successful login for $user from $ENV{'REMOTE_ADDR'}");
207 # If we've got credentials, let's serve the file up.
208 if ( (defined $session{'CurrentUser'}) and
209 ( $session{'CurrentUser'}->Id) ) {
211 # Process per-page global callbacks
212 $m->comp('/Elements/Callback', %ARGS);
214 # If the user isn't privileged, they can only see SelfService
215 if ((! $session{'CurrentUser'}->Privileged) and
216 ($m->base_comp->path !~ '^(/+)SelfService/') ) {
217 $m->comp('/SelfService/index.html');
221 $m->call_next(%ARGS);
225 # If we have no credentials
227 $m->comp('/Elements/Login', %ARGS);
231 <& /Elements/Footer, %ARGS &>