1 %# BEGIN BPS TAGGED BLOCK {{{
5 %# This software is Copyright (c) 1996-2005 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::is_utf8($_) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) :
66 ? [ map { (ref($_) or Encode::is_utf8($_)) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } @$_ ] :
68 ? { map { (ref($_) or Encode::is_utf8($_)) ? $_ : Encode::decode(utf8 => $_, Encode::FB_PERLQQ) } %$_ } : $_
71 $m->{'rt_base_time'} = [Time::HiRes::gettimeofday()];
73 $m->comp('/Elements/SetupSessionCookie', %ARGS);
75 unless ($session{'CurrentUser'} && $session{'CurrentUser'}->Id) {
76 $session{'CurrentUser'} = RT::CurrentUser->new();
79 # Set the proper encoding for the current language handle
80 $r->content_type("text/html; charset=utf-8");
82 # If it's a noauth file, don't ask for auth.
83 if ($m->base_comp->path =~ $RT::WebNoAuthRegex )
89 # If RT is configured for external auth, let's go through and get REMOTE_USER
90 elsif ( $RT::WebExternalAuth ) {
92 # do we actually have a REMOTE_USER equivlent?
93 if ( RT::Interface::Web::WebCanonicalizeInfo() ) {
95 my $orig_user = $user;
97 $user = RT::Interface::Web::WebCanonicalizeInfo();
98 $session{'CurrentUser'} = RT::CurrentUser->new();
99 my $load_method = $RT::WebExternalGecos ? 'LoadByGecos' : 'Load';
101 if ($^O eq 'MSWin32' and $RT::WebExternalGecos) {
102 my $NodeName = Win32::NodeName();
103 $user =~ s/^\Q$NodeName\E\\//i;
106 $session{'CurrentUser'}->$load_method($user);
108 if ($RT::WebExternalAuto and !$session{'CurrentUser'}->Id() ) {
109 # Create users on-the-fly
111 my $UserObj = RT::User->new(RT::CurrentUser->new('RT_System'));
113 my ($val, $msg) = $UserObj->Create(
114 %{ref($RT::AutoCreate) ? $RT::AutoCreate : {}},
121 # now get user specific information, to better create our user.
122 my $new_user_info = RT::Interface::Web::WebExternalAutoInfo($user);
124 # set the attributes that have been defined.
125 # FIXME: this is a horrible kludge. I'm sure there's something cleaner
126 foreach my $attribute ('Name', 'Comments', 'Signature', 'EmailAddress',
127 'PagerEmailAddress', 'FreeformContactInfo',
128 'Organization', 'Disabled', 'Privileged',
129 'RealName', 'NickName', 'Lang', 'EmailEncoding',
130 'WebEncoding', 'ExternalContactInfoId',
131 'ContactInfoSystem', 'ExternalAuthId', 'Gecos',
132 'HomePhone', 'WorkPhone', 'MobilePhone',
133 'PagerPhone', 'Address1', 'Address2', 'City',
134 'State', 'Zip', 'Country') {
135 $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'NewUser');
137 my $method = "Set$attribute";
138 $UserObj->$method($new_user_info->{$attribute})
139 if( defined $new_user_info->{$attribute} );
141 $session{'CurrentUser'}->Load($user);
144 # we failed to successfully create the user. abort abort abort.
145 delete $session{'CurrentUser'};
146 $m->abort() unless $RT::WebFallbackToInternalAuth;
147 $m->comp('/Elements/Login', %ARGS,
148 Error=> loc('Cannot create user: [_1]', $msg));
152 unless ( $session{'CurrentUser'}->Id() ) {
153 delete $session{'CurrentUser'};
156 if ( $RT::WebExternalOnly ) {
157 $m->comp('/Elements/Login', %ARGS,
158 Error=> loc('You are not an authorized user'));
163 elsif ($RT::WebFallbackToInternalAuth) {
164 unless (defined($session{'CurrentUser'})) {
165 $m->comp('/Elements/Login', %ARGS,
166 Error=> loc('You are not an authorized user'));
170 # WebExternalAuth is set, but we don't have a REMOTE_USER. abort
171 delete $session{'CurrentUser'} if defined $session{'CurrentUser'};
175 delete $session{'CurrentUser'}
176 unless $session{'CurrentUser'} and defined $session{'CurrentUser'}->Id;
179 # Process per-page authentication callbacks
180 $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'Auth');
182 # If the user is logging in, let's authenticate
183 if (!$session{'CurrentUser'} && defined ($user) && defined ($pass) ){
184 $session{'CurrentUser'} = RT::CurrentUser->new();
185 $session{'CurrentUser'}->Load($user);
187 if (!$session{'CurrentUser'}->id() ||
188 !$session{'CurrentUser'}->IsPassword($pass))
190 delete $session{'CurrentUser'};
191 $RT::Logger->error("FAILED LOGIN for $user from $ENV{'REMOTE_ADDR'}");
192 $m->comp('/Elements/Login', %ARGS,
193 Error => loc('Your username or password is incorrect'));
197 $RT::Logger->info("Successful login for $user from $ENV{'REMOTE_ADDR'}");
201 # If we've got credentials, let's serve the file up.
202 if ( (defined $session{'CurrentUser'}) and
203 ( $session{'CurrentUser'}->Id) ) {
205 # Process per-page global callbacks
206 $m->comp('/Elements/Callback', %ARGS);
208 # If the user isn't privileged, they can only see SelfService
209 if ((! $session{'CurrentUser'}->Privileged) and
210 ($m->base_comp->path !~ '^(/+)SelfService/') ) {
211 $m->comp('/SelfService/index.html');
215 $m->call_next(%ARGS);
219 # If we have no credentials
221 $m->comp('/Elements/Login', %ARGS);
225 <& /Elements/Footer, %ARGS &>