← Index
NYTProf Performance Profile   « block view • line view • sub view »
For /usr/local/src/github.com/foswiki/core/bin/view
  Run on Sun Dec 4 17:17:59 2011
Reported on Sun Dec 4 17:27:11 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/LoginManager/TemplateLogin.pm
StatementsExecuted 16 statements in 1.92ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11145µs275µsFoswiki::LoginManager::TemplateLogin::::newFoswiki::LoginManager::TemplateLogin::new
11130µs39µsFoswiki::LoginManager::TemplateLogin::::BEGIN@19Foswiki::LoginManager::TemplateLogin::BEGIN@19
11123µs72µsFoswiki::LoginManager::TemplateLogin::::BEGIN@21Foswiki::LoginManager::TemplateLogin::BEGIN@21
11122µs48µsFoswiki::LoginManager::TemplateLogin::::BEGIN@20Foswiki::LoginManager::TemplateLogin::BEGIN@20
11110µs10µsFoswiki::LoginManager::TemplateLogin::::BEGIN@23Foswiki::LoginManager::TemplateLogin::BEGIN@23
0000s0sFoswiki::LoginManager::TemplateLogin::::_packRequestFoswiki::LoginManager::TemplateLogin::_packRequest
0000s0sFoswiki::LoginManager::TemplateLogin::::_unpackRequestFoswiki::LoginManager::TemplateLogin::_unpackRequest
0000s0sFoswiki::LoginManager::TemplateLogin::::forceAuthenticationFoswiki::LoginManager::TemplateLogin::forceAuthentication
0000s0sFoswiki::LoginManager::TemplateLogin::::loginFoswiki::LoginManager::TemplateLogin::login
0000s0sFoswiki::LoginManager::TemplateLogin::::loginUrlFoswiki::LoginManager::TemplateLogin::loginUrl
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2
3=begin TML
4
5---+ package Foswiki::LoginManager::TemplateLogin
6
7This is a login manager that you can specify in the security setup section of
8[[%SCRIPTURL{"configure"}%][configure]]. It provides users with a
9template-based form to enter usernames and passwords, and works with the
10PasswordManager that you specify to verify those passwords.
11
12Subclass of Foswiki::LoginManager; see that class for documentation of the
13methods of this class.
14
15=cut
16
17package Foswiki::LoginManager::TemplateLogin;
18
19255µs249µs
# spent 39µs (30+9) within Foswiki::LoginManager::TemplateLogin::BEGIN@19 which was called: # once (30µs+9µs) by Foswiki::LoginManager::makeLoginManager at line 19
use strict;
# spent 39µs making 1 call to Foswiki::LoginManager::TemplateLogin::BEGIN@19 # spent 9µs making 1 call to strict::import
20252µs274µs
# spent 48µs (22+26) within Foswiki::LoginManager::TemplateLogin::BEGIN@20 which was called: # once (22µs+26µs) by Foswiki::LoginManager::makeLoginManager at line 20
use warnings;
# spent 48µs making 1 call to Foswiki::LoginManager::TemplateLogin::BEGIN@20 # spent 26µs making 1 call to warnings::import
21256µs2121µs
# spent 72µs (23+49) within Foswiki::LoginManager::TemplateLogin::BEGIN@21 which was called: # once (23µs+49µs) by Foswiki::LoginManager::makeLoginManager at line 21
use Assert;
# spent 72µs making 1 call to Foswiki::LoginManager::TemplateLogin::BEGIN@21 # spent 49µs making 1 call to Assert::import
22
2321.70ms110µs
# spent 10µs within Foswiki::LoginManager::TemplateLogin::BEGIN@23 which was called: # once (10µs+0s) by Foswiki::LoginManager::makeLoginManager at line 23
use Foswiki::LoginManager ();
# spent 10µs making 1 call to Foswiki::LoginManager::TemplateLogin::BEGIN@23
24110µsour @ISA = ('Foswiki::LoginManager');
25
26=begin TML
27
28---++ ClassMethod new ($session, $impl)
29
30Construct the TemplateLogin object
31
32=cut
33
34
# spent 275µs (45+230) within Foswiki::LoginManager::TemplateLogin::new which was called: # once (45µs+230µs) by Foswiki::LoginManager::makeLoginManager at line 127 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/LoginManager.pm
sub new {
3512µs my ( $class, $session ) = @_;
36122µs1221µs my $this = $class->SUPER::new($session);
# spent 221µs making 1 call to Foswiki::LoginManager::new
3716µs19µs $session->enterContext('can_login');
# spent 9µs making 1 call to Foswiki::enterContext
3812µs if ( $Foswiki::cfg{Sessions}{ExpireCookiesAfter} ) {
39 $session->enterContext('can_remember_login');
40 }
4112µs if ( $Foswiki::cfg{TemplateLogin}{PreventBrowserRememberingPassword} ) {
42 $session->enterContext('no_auto_complete_login');
43 }
4419µs return $this;
45}
46
47# Pack key request parameters into a single value
48# Used for passing meta-information about the request
49# through a URL (without requiring passthrough)
50sub _packRequest {
51 my ( $uri, $method, $action ) = @_;
52 return '' unless $uri;
53 if ( ref($uri) ) { # first parameter is a $session
54 my $r = $uri->{request};
55 $uri = $r->uri();
56 $method = $r->method() || 'UNDEFINED';
57 $action = $r->action();
58 }
59 return "$method,$action,$uri";
60}
61
62# Unpack single value to key request parameters
63sub _unpackRequest {
64 my $packed = shift || '';
65 my ( $method, $action, $uri ) = split( ',', $packed, 3 );
66 return ( $uri, $method, $action );
67}
68
69=begin TML
70
71---++ ObjectMethod forceAuthentication () -> $boolean
72
73method called when authentication is required - redirects to (...|view)auth
74Triggered on auth fail
75
76=cut
77
78sub forceAuthentication {
79 my $this = shift;
80 my $session = $this->{session};
81
82 unless ( $session->inContext('authenticated') ) {
83 my $query = $session->{request};
84
85 # Redirect with passthrough so we don't lose the original query params
86
87 my $url = $session->getScriptUrl( 0, 'login' );
88
89 # We use the query here to ensure the original path_info
90 # from the request gets through to the login form. See also
91 # PATH_INFO below.
92 $url .= Foswiki::urlEncode( $query->path_info() );
93
94 $query->param(
95 -name => 'foswiki_origin',
96 -value => _packRequest($session)
97 );
98 $session->redirect( $url, 1 ); # with passthrough
99 return 1;
100 }
101 return 0;
102}
103
104=begin TML
105
106---++ ObjectMethod loginUrl () -> $loginUrl
107
108Overrides LoginManager. Content of a login link.
109
110=cut
111
112sub loginUrl {
113 my $this = shift;
114 my $session = $this->{session};
115 my $topic = $session->{topicName};
116 my $web = $session->{webName};
117 return $session->getScriptUrl( 0, 'login', $web, $topic,
118 foswiki_origin => _packRequest($session) );
119}
120
121=begin TML
122
123---++ ObjectMethod login( $query, $session )
124
125If a login name and password have been passed in the query, it
126validates these and if authentic, redirects to the original
127script. If there is no username in the query or the username/password is
128invalid (validate returns non-zero) then it prompts again.
129
130If a flag to remember the login has been passed in the query, then the
131corresponding session variable will be set. This will result in the
132login cookie being preserved across browser sessions.
133
134The password handler is expected to return a perl true value if the password
135is valid. This return value is stored in a session variable called
136VALIDATION. This is so that password handlers can return extra information
137about the user, such as a list of Wiki groups stored in a separate
138database, that can then be displayed by referring to
139%<nop>SESSION_VARIABLE{"VALIDATION"}%
140
141=cut
142
143sub login {
144 my ( $this, $query, $session ) = @_;
145 my $users = $session->{users};
146
147 my $origin = $query->param('foswiki_origin');
148 my ( $origurl, $origmethod, $origaction ) = _unpackRequest($origin);
149 my $loginName = $query->param('username');
150 my $loginPass = $query->param('password');
151 my $remember = $query->param('remember');
152
153 # Eat these so there's no risk of accidental passthrough
154 $query->delete( 'foswiki_origin', 'username', 'password' );
155
156 # UserMappings can over-ride where the login template is defined
157 my $loginTemplate = $users->loginTemplateName(); #defaults to login.tmpl
158 my $tmpl = $session->templates->readTemplate($loginTemplate);
159
160 my $banner = $session->templates->expandTemplate('LOG_IN_BANNER');
161 my $note = '';
162 my $topic = $session->{topicName};
163 my $web = $session->{webName};
164
165 my $cgisession = $this->{_cgisession};
166
167 $cgisession->param( 'REMEMBER', $remember ) if $cgisession;
168 if ( $cgisession
169 && $cgisession->param('AUTHUSER')
170 && $loginName
171 && $loginName ne $cgisession->param('AUTHUSER') )
172 {
173 $banner = $session->templates->expandTemplate('LOGGED_IN_BANNER');
174 $note = $session->templates->expandTemplate('NEW_USER_NOTE');
175 }
176
177 my $error = '';
178
179 if ($loginName) {
180 my $validation = $users->checkPassword( $loginName, $loginPass );
181 $error = $users->passwordError();
182
183 if ($validation) {
184
185 # SUCCESS our user is authenticated. Note that we may already
186 # have been logged in by the userLoggedIn call in loadSession,
187 # because the username-password URL params are the same as
188 # the params passed to this script, and they will be used
189 # in loadSession if no other user info is available.
190 $this->userLoggedIn($loginName);
191 $session->logEvent(
192 'login',
193 $web . '.' . $topic,
194 "AUTHENTICATION SUCCESS - $loginName - "
195 );
196
197 # remove the sudo param - its only to tell TemplateLogin
198 # that we're using BaseMapper..
199 $query->delete('sudo');
200
201 $cgisession->param( 'VALIDATION', $validation ) if $cgisession;
202 if ( !$origurl || $origurl eq $query->url() ) {
203 $origurl = $session->getScriptUrl( 0, 'view', $web, $topic );
204 }
205 else {
206
207 # Unpack params encoded in the origurl and restore them
208 # to the query. If they were left in the query string they
209 # would be lost if we redirect with passthrough.
210 # First extract the params, ignoring any trailing fragment.
211 if ( $origurl =~ s/\?([^#]*)// ) {
212 foreach my $pair ( split( /[&;]/, $1 ) ) {
213 if ( $pair =~ /(.*?)=(.*)/ ) {
214 $query->param( $1, TAINT($2) );
215 }
216 }
217 }
218
219 # Restore the action too
220 $query->action($origaction) if $origaction;
221 }
222
223 # Restore the method used on origUrl so if it was a GET, we
224 # get another GET.
225 $query->method($origmethod);
226 $session->redirect( $origurl, 1 );
227 return;
228 }
229 else {
230
231 # Tasks:Item1029 After much discussion, the 403 code is not
232 # used for authentication failures. RFC states: "Authorization
233 # will not help and the request SHOULD NOT be repeated" which
234 # is not the situation here.
235 $session->{response}->status(200);
236 $session->logEvent(
237 'login',
238 $web . '.' . $topic,
239 "AUTHENTICATION FAILURE - $loginName - "
240 );
241 $banner = $session->templates->expandTemplate('UNRECOGNISED_USER');
242 }
243 }
244 else {
245
246 # If the loginName is unset, then the request was likely a perfectly
247 # valid GET call to http://foswiki/bin/login
248 # 4xx cannot be a correct status, as we want the user to retry the
249 # same URL with a different login/password
250 $session->{response}->status(200);
251 }
252
253 # Remove the validation_key from the *passed through* params. It isn't
254 # required, because the form will have a new validation key, and
255 # giving the parameter twice will confuse the strikeone Javascript.
256 $session->{request}->delete('validation_key');
257
258 # set the usernamestep value so it can be re-displayed if we are here due
259 # to a failed authentication attempt.
260 $query->param( -name => 'usernamestep', -value => $loginName );
261
262 # TODO: add JavaScript password encryption in the template
263 $origurl ||= '';
264
265 # Set session preferences that will be expanded when the login
266 # template is instantiated
267 $session->{prefs}->setSessionPreferences(
268 FOSWIKI_ORIGIN => Foswiki::entityEncode(
269 _packRequest( $origurl, $origmethod, $origaction )
270 ),
271
272 # Path to be used in the login form action.
273 # Could have used %ENV{PATH_INFO} (after extending {AccessibleENV})
274 # but decided against it as the path_info might have been rewritten
275 # from the original env var.
276 PATH_INFO => $query->path_info(),
277 BANNER => $banner,
278 NOTE => $note,
279 ERROR => $error
280 );
281
282 my $topicObject = Foswiki::Meta->new( $session, $web, $topic );
283 $tmpl = $topicObject->expandMacros($tmpl);
284 $tmpl = $topicObject->renderTML($tmpl);
285 $tmpl =~ s/<nop>//g;
286 $session->writeCompletePage($tmpl);
287}
288
28916µs1;
290__END__