colas@0
|
1 |
# Module of TWiki Enterprise Collaboration Platform, http://TWiki.org/
|
colas@0
|
2 |
#
|
colas@0
|
3 |
# Copyright (C) 2005-2006 TWiki Contributors.
|
colas@0
|
4 |
# All Rights Reserved. TWiki Contributors
|
colas@0
|
5 |
# are listed in the AUTHORS file in the root of this distribution.
|
colas@0
|
6 |
# NOTE: Please extend that file, not this notice.
|
colas@0
|
7 |
#
|
colas@0
|
8 |
# Additional copyrights apply to some or all of the code in this
|
colas@0
|
9 |
# file as follows:
|
colas@0
|
10 |
# Copyright (C) 2005 Greg Abbas, twiki@abbas.org
|
colas@0
|
11 |
#
|
colas@0
|
12 |
# This program is free software; you can redistribute it and/or
|
colas@0
|
13 |
# modify it under the terms of the GNU General Public License
|
colas@0
|
14 |
# as published by the Free Software Foundation; either version 2
|
colas@0
|
15 |
# of the License, or (at your option) any later version. For
|
colas@0
|
16 |
# more details read LICENSE in the root of this distribution.
|
colas@0
|
17 |
#
|
colas@0
|
18 |
# This program is distributed in the hope that it will be useful,
|
colas@0
|
19 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
colas@0
|
20 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
colas@0
|
21 |
#
|
colas@0
|
22 |
# As per the GPL, removal of this notice is prohibited.
|
colas@0
|
23 |
|
colas@0
|
24 |
=pod
|
colas@0
|
25 |
|
colas@0
|
26 |
---+ package TWiki::LoginManager::TemplateLogin
|
colas@0
|
27 |
|
colas@0
|
28 |
This is a login manager that you can specify in the security setup section of
|
colas@0
|
29 |
[[%SCRIPTURL{"configure"}%][configure]]. It provides users with a
|
colas@0
|
30 |
template-based form to enter usernames and passwords, and works with the
|
colas@0
|
31 |
PasswordManager that you specify to verify those passwords.
|
colas@0
|
32 |
|
colas@0
|
33 |
Subclass of TWiki::LoginManager; see that class for documentation of the
|
colas@0
|
34 |
methods of this class.
|
colas@0
|
35 |
|
colas@0
|
36 |
=cut
|
colas@0
|
37 |
|
colas@0
|
38 |
package TWiki::LoginManager::TemplateLogin;
|
colas@0
|
39 |
use base 'TWiki::LoginManager';
|
colas@0
|
40 |
|
colas@0
|
41 |
use strict;
|
colas@0
|
42 |
use Assert;
|
colas@0
|
43 |
|
colas@0
|
44 |
|
colas@0
|
45 |
=pod
|
colas@0
|
46 |
|
colas@0
|
47 |
---++ ClassMethod new ($session, $impl)
|
colas@0
|
48 |
|
colas@0
|
49 |
Construct the TemplateLogin object
|
colas@0
|
50 |
|
colas@0
|
51 |
=cut
|
colas@0
|
52 |
|
colas@0
|
53 |
sub new {
|
colas@0
|
54 |
my( $class, $session ) = @_;
|
colas@0
|
55 |
my $this = $class->SUPER::new($session);
|
colas@0
|
56 |
$session->enterContext( 'can_login' );
|
colas@0
|
57 |
if ($TWiki::cfg{Sessions}{ExpireCookiesAfter}) {
|
colas@0
|
58 |
$session->enterContext( 'can_remember_login' );
|
colas@0
|
59 |
}
|
colas@0
|
60 |
return $this;
|
colas@0
|
61 |
}
|
colas@0
|
62 |
|
colas@0
|
63 |
=pod
|
colas@0
|
64 |
|
colas@0
|
65 |
---++ ObjectMethod forceAuthentication () -> boolean
|
colas@0
|
66 |
|
colas@0
|
67 |
method called when authentication is required - redirects to (...|view)auth
|
colas@0
|
68 |
Triggered on auth fail
|
colas@0
|
69 |
|
colas@0
|
70 |
=cut
|
colas@0
|
71 |
|
colas@0
|
72 |
sub forceAuthentication {
|
colas@0
|
73 |
my $this = shift;
|
colas@0
|
74 |
my $twiki = $this->{twiki};
|
colas@0
|
75 |
|
colas@0
|
76 |
unless( $twiki->inContext( 'authenticated' )) {
|
colas@0
|
77 |
my $query = $twiki->{cgiQuery};
|
colas@0
|
78 |
# Redirect with passthrough so we don't lose the original query params
|
colas@0
|
79 |
my $twiki = $this->{twiki};
|
colas@0
|
80 |
my $topic = $twiki->{topicName};
|
colas@0
|
81 |
my $web = $twiki->{webName};
|
colas@0
|
82 |
my $url = $twiki->getScriptUrl( 0, 'login', $web, $topic);
|
colas@0
|
83 |
$query->param( -name=>'origurl', -value=>$ENV{REQUEST_URI} );
|
colas@0
|
84 |
$twiki->redirect( $url, 1 );
|
colas@0
|
85 |
return 1;
|
colas@0
|
86 |
}
|
colas@0
|
87 |
return undef;
|
colas@0
|
88 |
}
|
colas@0
|
89 |
|
colas@0
|
90 |
|
colas@0
|
91 |
=pod
|
colas@0
|
92 |
|
colas@0
|
93 |
---++ ObjectMethod loginUrl () -> $loginUrl
|
colas@0
|
94 |
|
colas@0
|
95 |
TODO: why is this not used internally? When is it called, and why
|
colas@0
|
96 |
Content of a login link
|
colas@0
|
97 |
|
colas@0
|
98 |
=cut
|
colas@0
|
99 |
|
colas@0
|
100 |
sub loginUrl {
|
colas@0
|
101 |
my $this = shift;
|
colas@0
|
102 |
my $twiki = $this->{twiki};
|
colas@0
|
103 |
my $topic = $twiki->{topicName};
|
colas@0
|
104 |
my $web = $twiki->{webName};
|
colas@0
|
105 |
return $twiki->getScriptUrl( 0, 'login', $web, $topic,
|
colas@0
|
106 |
origurl => $ENV{REQUEST_URI} );
|
colas@0
|
107 |
}
|
colas@0
|
108 |
|
colas@0
|
109 |
=pod
|
colas@0
|
110 |
|
colas@0
|
111 |
---++ ObjectMethod login( $query, $twiki )
|
colas@0
|
112 |
|
colas@0
|
113 |
If a login name and password have been passed in the query, it
|
colas@0
|
114 |
validates these and if authentic, redirects to the original
|
colas@0
|
115 |
script. If there is no username in the query or the username/password is
|
colas@0
|
116 |
invalid (validate returns non-zero) then it prompts again.
|
colas@0
|
117 |
|
colas@0
|
118 |
If a flag to remember the login has been passed in the query, then the
|
colas@0
|
119 |
corresponding session variable will be set. This will result in the
|
colas@0
|
120 |
login cookie being preserved across browser sessions.
|
colas@0
|
121 |
|
colas@0
|
122 |
The password handler is expected to return a perl true value if the password
|
colas@0
|
123 |
is valid. This return value is stored in a session variable called
|
colas@0
|
124 |
VALIDATION. This is so that password handlers can return extra information
|
colas@0
|
125 |
about the user, such as a list of TWiki groups stored in a separate
|
colas@0
|
126 |
database, that can then be displayed by referring to
|
colas@0
|
127 |
%<nop>SESSION_VARIABLE{"VALIDATION"}%
|
colas@0
|
128 |
|
colas@0
|
129 |
=cut
|
colas@0
|
130 |
|
colas@0
|
131 |
sub login {
|
colas@0
|
132 |
my( $this, $query, $twikiSession ) = @_;
|
colas@0
|
133 |
my $twiki = $this->{twiki};
|
colas@0
|
134 |
my $users = $twiki->{users};
|
colas@0
|
135 |
|
colas@0
|
136 |
my $origurl = $query->param( 'origurl' );
|
colas@0
|
137 |
my $loginName = $query->param( 'username' );
|
colas@0
|
138 |
my $loginPass = $query->param( 'password' );
|
colas@0
|
139 |
my $remember = $query->param( 'remember' );
|
colas@0
|
140 |
|
colas@0
|
141 |
# Eat these so there's no risk of accidental passthrough
|
colas@0
|
142 |
$query->delete('origurl', 'username', 'password');
|
colas@0
|
143 |
|
colas@0
|
144 |
# UserMappings can over-ride where the login template is defined
|
colas@0
|
145 |
my $loginTemplate = $users->loginTemplateName(); #defaults to login.tmpl
|
colas@0
|
146 |
my $tmpl = $twiki->templates->readTemplate(
|
colas@0
|
147 |
$loginTemplate, $twiki->getSkin() );
|
colas@0
|
148 |
|
colas@0
|
149 |
my $banner = $twiki->templates->expandTemplate( 'LOG_IN_BANNER' );
|
colas@0
|
150 |
my $note = '';
|
colas@0
|
151 |
my $topic = $twiki->{topicName};
|
colas@0
|
152 |
my $web = $twiki->{webName};
|
colas@0
|
153 |
|
colas@0
|
154 |
my $cgisession = $this->{_cgisession};
|
colas@0
|
155 |
|
colas@0
|
156 |
$cgisession->param( 'REMEMBER', $remember ) if $cgisession;
|
colas@0
|
157 |
if( $cgisession && $cgisession->param( 'AUTHUSER' ) &&
|
colas@0
|
158 |
$loginName && $loginName ne $cgisession->param( 'AUTHUSER' )) {
|
colas@0
|
159 |
$banner = $twiki->templates->expandTemplate( 'LOGGED_IN_BANNER' );
|
colas@0
|
160 |
$note = $twiki->templates->expandTemplate( 'NEW_USER_NOTE' );
|
colas@0
|
161 |
}
|
colas@0
|
162 |
|
colas@0
|
163 |
my $error = '';
|
colas@0
|
164 |
|
colas@0
|
165 |
if( $loginName ) {
|
colas@0
|
166 |
my $validation = $users->checkPassword( $loginName, $loginPass );
|
colas@0
|
167 |
$error = $users->passwordError();
|
colas@0
|
168 |
|
colas@0
|
169 |
if( $validation ) {
|
colas@0
|
170 |
$this->userLoggedIn( $loginName );
|
colas@0
|
171 |
$cgisession->param( 'VALIDATION', $validation ) if $cgisession;
|
colas@0
|
172 |
if( !$origurl || $origurl eq $query->url() ) {
|
colas@0
|
173 |
$origurl = $twiki->getScriptUrl( 0, 'view', $web, $topic );
|
colas@0
|
174 |
}
|
colas@0
|
175 |
#SUCCESS our user is authenticated..
|
colas@0
|
176 |
$query->delete('sudo'); #remove the sudo param - its only to tell TemplateLogin that we're using BaseMapper..
|
colas@0
|
177 |
# Redirect with passthrough
|
colas@0
|
178 |
$twikiSession->redirect($origurl, 1 );
|
colas@0
|
179 |
return;
|
colas@0
|
180 |
} else {
|
colas@0
|
181 |
$banner = $twiki->templates->expandTemplate('UNRECOGNISED_USER');
|
colas@0
|
182 |
}
|
colas@0
|
183 |
}
|
colas@0
|
184 |
|
colas@0
|
185 |
# TODO: add JavaScript password encryption in the template
|
colas@0
|
186 |
# to use a template)
|
colas@0
|
187 |
$origurl ||= '';
|
colas@0
|
188 |
$twiki->{prefs}->pushPreferenceValues('SESSION', {ORIGURL=>$origurl, BANNER=>$banner, NOTE=>$note, ERROR=>$error});
|
colas@0
|
189 |
|
colas@0
|
190 |
$tmpl = $twiki->handleCommonTags( $tmpl, $web, $topic );
|
colas@0
|
191 |
$tmpl = $twiki->renderer->getRenderedVersion( $tmpl, '' );
|
colas@0
|
192 |
$tmpl =~ s/<nop>//g;
|
colas@0
|
193 |
print $twiki->generateHTTPHeaders( $query );
|
colas@0
|
194 |
print $tmpl;
|
colas@0
|
195 |
}
|
colas@0
|
196 |
|
colas@0
|
197 |
1;
|