← 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:26:33 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/LoginManager.pm
StatementsExecuted 227 statements in 9.02ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1112.17ms10.7msFoswiki::LoginManager::::makeLoginManagerFoswiki::LoginManager::makeLoginManager
111383µs137msFoswiki::LoginManager::::loadSessionFoswiki::LoginManager::loadSession
511173µs291µsFoswiki::LoginManager::::endRenderingHandlerFoswiki::LoginManager::endRenderingHandler
111159µs159µsFoswiki::LoginManager::::CORE:readdirFoswiki::LoginManager::CORE:readdir (opcode)
111154µs221µsFoswiki::LoginManager::::newFoswiki::LoginManager::new
211139µs10.1msFoswiki::LoginManager::::_LOGOUTFoswiki::LoginManager::_LOGOUT
111136µs1.75msFoswiki::LoginManager::::finishFoswiki::LoginManager::finish
111115µs21.7msFoswiki::LoginManager::::userLoggedInFoswiki::LoginManager::userLoggedIn
111114µs317µsFoswiki::LoginManager::::expireDeadSessionsFoswiki::LoginManager::expireDeadSessions
113182µs82µsFoswiki::LoginManager::::CORE:substFoswiki::LoginManager::CORE:subst (opcode)
21172µs616µsFoswiki::LoginManager::::_LOGOUTURLFoswiki::LoginManager::_LOGOUTURL
11154µs522µsFoswiki::LoginManager::::_addSessionCookieToResponseFoswiki::LoginManager::_addSessionCookieToResponse
11142µs1.56msFoswiki::LoginManager::::completeFoswiki::LoginManager::complete
21138µs80µsFoswiki::LoginManager::::_LOGINFoswiki::LoginManager::_LOGIN
95138µs38µsFoswiki::LoginManager::::__ANON__[:208]Foswiki::LoginManager::__ANON__[:208]
11135µs54µsFoswiki::LoginManager::::checkAccessFoswiki::LoginManager::checkAccess
11125µs33µsFoswiki::LoginManager::::BEGIN@51Foswiki::LoginManager::BEGIN@51
11120µs368µsFoswiki::LoginManager::::BEGIN@54Foswiki::LoginManager::BEGIN@54
11116µs35µsFoswiki::LoginManager::::BEGIN@52Foswiki::LoginManager::BEGIN@52
11116µs16µsFoswiki::LoginManager::::CORE:open_dirFoswiki::LoginManager::CORE:open_dir (opcode)
11116µs52µsFoswiki::LoginManager::::BEGIN@53Foswiki::LoginManager::BEGIN@53
41115µs15µsFoswiki::LoginManager::::CORE:matchFoswiki::LoginManager::CORE:match (opcode)
11110µs10µsFoswiki::LoginManager::::getCGISessionFoswiki::LoginManager::getCGISession
1119µs9µsFoswiki::LoginManager::::BEGIN@56Foswiki::LoginManager::BEGIN@56
1118µs8µsFoswiki::LoginManager::::CORE:statFoswiki::LoginManager::CORE:stat (opcode)
1114µs4µsFoswiki::LoginManager::::getUserFoswiki::LoginManager::getUser
1114µs4µsFoswiki::LoginManager::::CORE:closedirFoswiki::LoginManager::CORE:closedir (opcode)
0000s0sFoswiki::LoginManager::::_AUTHENTICATEDFoswiki::LoginManager::_AUTHENTICATED
0000s0sFoswiki::LoginManager::::_CANLOGINFoswiki::LoginManager::_CANLOGIN
0000s0sFoswiki::LoginManager::::_IP2SIDFoswiki::LoginManager::_IP2SID
0000s0sFoswiki::LoginManager::::_LOGINURLFoswiki::LoginManager::_LOGINURL
0000s0sFoswiki::LoginManager::::_SESSION_VARIABLEFoswiki::LoginManager::_SESSION_VARIABLE
0000s0sFoswiki::LoginManager::::_dispLogonFoswiki::LoginManager::_dispLogon
0000s0sFoswiki::LoginManager::::_myScriptURLREFoswiki::LoginManager::_myScriptURLRE
0000s0sFoswiki::LoginManager::::_real_traceFoswiki::LoginManager::_real_trace
0000s0sFoswiki::LoginManager::::_rewriteFORMFoswiki::LoginManager::_rewriteFORM
0000s0sFoswiki::LoginManager::::_rewriteURLFoswiki::LoginManager::_rewriteURL
0000s0sFoswiki::LoginManager::::_skinSelectFoswiki::LoginManager::_skinSelect
0000s0sFoswiki::LoginManager::::clearSessionValueFoswiki::LoginManager::clearSessionValue
0000s0sFoswiki::LoginManager::::forceAuthenticationFoswiki::LoginManager::forceAuthentication
0000s0sFoswiki::LoginManager::::getSessionValueFoswiki::LoginManager::getSessionValue
0000s0sFoswiki::LoginManager::::getSessionValuesFoswiki::LoginManager::getSessionValues
0000s0sFoswiki::LoginManager::::isValidLoginNameFoswiki::LoginManager::isValidLoginName
0000s0sFoswiki::LoginManager::::loginUrlFoswiki::LoginManager::loginUrl
0000s0sFoswiki::LoginManager::::rewriteRedirectUrlFoswiki::LoginManager::rewriteRedirectUrl
0000s0sFoswiki::LoginManager::::setSessionValueFoswiki::LoginManager::setSessionValue
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
6
7The package is also a Factory for login managers and also the base class
8for all login managers.
9
10On it's own, an object of this class is used when you specify 'none' in
11the security setup section of
12[[%SCRIPTURL{"configure"}%][configure]]. When it is used,
13logins are not supported. If you want to authenticate users then you should
14consider TemplateLogin or ApacheLogin, which are subclasses of this class.
15
16If you are building a new login manager, then you should write a new subclass
17of this class, implementing the methods marked as *VIRTUAL*. There are already
18examples in the =lib/Foswiki/LoginManager= directory.
19
20The class has extensive tracing, which is enabled by
21$Foswiki::cfg{Trace}{LoginManager}. The tracing is done in such a way as to
22let the perl optimiser optimise out the trace function as a no-op if tracing
23is disabled.
24
25Here's an overview of how it works:
26
27Early in Foswiki::new, the login manager is created. The creation of the login manager does two things:
28 1 If sessions are in use, it loads CGI::Session but doesn't initialise the session yet.
29 1 Creates the login manager object
30Slightly later in Foswiki::new, loginManager->loadSession is called.
31 1 Calls loginManager->getUser to get the username *before* the session is created
32 * Foswiki::LoginManager::ApacheLogin looks at REMOTE_USER (only for authenticated scripts)
33 * Foswiki::LoginManager::TemplateLogin just returns undef
34 1 If the NO_FOSWIKI_SESSION environment variable is defined, then no session is created and the username is returned. This might be defined for search engine bots, depending on how the web server is configured
35 1 Reads the FOSWIKISID cookie to get the SID (or the FOSWIKISID parameters in the CGI query if cookies aren't available, or IP2SID mapping if that's enabled).
36 1 Creates the CGI::Session object, and the session is thereby read.
37 1 If the username still isn't known, reads it from the cookie. Thus Foswiki::LoginManager::ApacheLogin overrides the cookie using REMOTE_USER, and Foswiki::LoginManager::TemplateLogin *always* uses the session.
38
39Later again in Foswiki::new, plugins are given a chance to *override* the username found from the loginManager.
40
41The last step in Foswiki::new is to find the user, using whatever user mapping manager is in place.
42
43---++ ObjectData =twiki=
44
45The Foswiki object this login manager is attached to.
46
47=cut
48
49package Foswiki::LoginManager;
50
51246µs240µs
# spent 33µs (25+8) within Foswiki::LoginManager::BEGIN@51 which was called: # once (25µs+8µs) by Foswiki::Users::BEGIN@64 at line 51
use strict;
# spent 33µs making 1 call to Foswiki::LoginManager::BEGIN@51 # spent 8µs making 1 call to strict::import
52244µs253µs
# spent 35µs (16+18) within Foswiki::LoginManager::BEGIN@52 which was called: # once (16µs+18µs) by Foswiki::Users::BEGIN@64 at line 52
use warnings;
# spent 35µs making 1 call to Foswiki::LoginManager::BEGIN@52 # spent 18µs making 1 call to warnings::import
53250µs288µs
# spent 52µs (16+36) within Foswiki::LoginManager::BEGIN@53 which was called: # once (16µs+36µs) by Foswiki::Users::BEGIN@64 at line 53
use Assert;
# spent 52µs making 1 call to Foswiki::LoginManager::BEGIN@53 # spent 36µs making 1 call to Assert::import
54247µs2716µs
# spent 368µs (20+348) within Foswiki::LoginManager::BEGIN@54 which was called: # once (20µs+348µs) by Foswiki::Users::BEGIN@64 at line 54
use Error qw( :try );
# spent 368µs making 1 call to Foswiki::LoginManager::BEGIN@54 # spent 348µs making 1 call to Error::import
55
5626.96ms19µs
# spent 9µs within Foswiki::LoginManager::BEGIN@56 which was called: # once (9µs+0s) by Foswiki::Users::BEGIN@64 at line 56
use Foswiki::Sandbox ();
# spent 9µs making 1 call to Foswiki::LoginManager::BEGIN@56
57
58# Marker chars
5912µsour $M1 = chr(5);
6011µsour $M2 = chr(6);
6112µsour $M3 = chr(7);
62
63# Some session keys are secret (not to be given to the browser) and
64# others read only (not to be changed from the browser)
6515µsour %secretSK = ( STRIKEONESECRET => 1, VALID_ACTIONS => 1 );
6615µsour %readOnlySK = ( %secretSK, AUTHUSER => 1, SUDOFROMAUTHUSER => 1 );
67
68=begin TML
69
70---++ StaticMethod makeLoginManager( $session ) -> $Foswiki::LoginManager
71
72Factory method, used to generate a new Foswiki::LoginManager object
73for the given session.
74
75=cut
76
77
# spent 10.7ms (2.17+8.57) within Foswiki::LoginManager::makeLoginManager which was called: # once (2.17ms+8.57ms) by Foswiki::Users::new at line 107 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Users.pm
sub makeLoginManager {
7820184µs my $session = shift;
79
8014µs ASSERT( $session->isa('Foswiki') ) if DEBUG;
# spent 4µs making 1 call to Assert::ASSERTS_OFF
81
82 #user is trying to sudo login - use BaseUserMapping
83162µs if ( $session->{request}->param('sudo') ) {
# spent 62µs making 1 call to Foswiki::Request::param
84
85 #promote / login to internal wiki admin
86 $session->enterContext('sudo_login');
87 }
88
8918µs if ( $Foswiki::cfg{UseClientSessions}
# spent 8µs making 1 call to Foswiki::inContext
90 && !$session->inContext('command_line') )
91 {
92
93 my $use = 'use Foswiki::LoginManager::Session';
94 if ( $Foswiki::cfg{Sessions}{UseIPMatching} ) {
95 $use .= ' qw(-ip_match)';
96 }
97 $use .= '; use CGI::Cookie ()';
98 eval $use;
# spent 183µs executing statements in string eval
# includes 496µs spent executing 2 calls to 2 subs defined therein.
99 throw Error::Simple($@) if $@;
100 if ( $Foswiki::LoginManager::Session::VERSION eq '4.10' ) {
101
102 # 4.10 is broken; see Item1989
103 $Foswiki::LoginManager::Session::NAME = 'FOSWIKISID';
104 }
105 else {
106110µs Foswiki::LoginManager::Session->name('FOSWIKISID');
# spent 10µs making 1 call to CGI::Session::name
107 }
108 }
109
110 my $mgr;
111 if ( $Foswiki::cfg{LoginManager} eq 'none' ) {
112
113 # No login manager; just use default behaviours
114 $mgr = new Foswiki::LoginManager($session);
115 }
116 else {
117
118 # Rename from old "Client" to new "LoginManager" - see TWikibug:Item3375
11914µs $Foswiki::cfg{LoginManager} =~ s/::Client::/::LoginManager::/;
# spent 4µs making 1 call to Foswiki::LoginManager::CORE:subst
120 my $loginManager = $Foswiki::cfg{LoginManager};
12118µs if ( $session->inContext('sudo_login') )
# spent 8µs making 1 call to Foswiki::inContext
122 { #TODO: move selection into BaseUserMapper
123 $loginManager = 'Foswiki::LoginManager::TemplateLogin';
124 }
125 eval "require $loginManager";
# spent 127µs executing statements in string eval
126 die $@ if $@;
1271275µs $mgr = $loginManager->new($session);
# spent 275µs making 1 call to Foswiki::LoginManager::TemplateLogin::new
128 }
129 return $mgr;
130}
131
132=begin TML
133
134---++ ClassMethod new ($session, $impl)
135
136Construct the user management object
137
138=cut
139
140# protected: Construct new client object.
141
# spent 221µs (154+67) within Foswiki::LoginManager::new which was called: # once (154µs+67µs) by Foswiki::LoginManager::TemplateLogin::new at line 36 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/LoginManager/TemplateLogin.pm
sub new {
14226135µs my ( $class, $session ) = @_;
143 my $this = bless(
144 {
145 session => $session,
146 twiki => $session, # backwards compatibility
147 _haveCookie => 0,
148 },
149 $class
150 );
151
152112µs $session->leaveContext('can_login');
# spent 12µs making 1 call to Foswiki::leaveContext
153 map { $this->{_authScripts}{$_} = 1; }
154 split( /[\s,]+/, $Foswiki::cfg{AuthScripts} );
155
156 # register tag handlers and values
157111µs Foswiki::registerTagHandler( 'LOGINURL', \&_LOGINURL );
# spent 11µs making 1 call to Foswiki::registerTagHandler
15818µs Foswiki::registerTagHandler( 'LOGIN', \&_LOGIN );
# spent 8µs making 1 call to Foswiki::registerTagHandler
15918µs Foswiki::registerTagHandler( 'LOGOUT', \&_LOGOUT );
# spent 8µs making 1 call to Foswiki::registerTagHandler
16017µs Foswiki::registerTagHandler( 'LOGOUTURL', \&_LOGOUTURL );
# spent 7µs making 1 call to Foswiki::registerTagHandler
16117µs Foswiki::registerTagHandler( 'SESSION_VARIABLE', \&_SESSION_VARIABLE );
# spent 7µs making 1 call to Foswiki::registerTagHandler
16217µs Foswiki::registerTagHandler( 'AUTHENTICATED', \&_AUTHENTICATED );
# spent 7µs making 1 call to Foswiki::registerTagHandler
16317µs Foswiki::registerTagHandler( 'CANLOGIN', \&_CANLOGIN );
# spent 7µs making 1 call to Foswiki::registerTagHandler
164
165 return $this;
166}
167
168=begin TML
169
170---++ ObjectMethod finish()
171Break circular references.
172
173=cut
174
175# Note to developers; please undef *all* fields in the object explicitly,
176# whether they are references or not. That way this method is "golden
177# documentation" of the live fields in the object.
178
# spent 1.75ms (136µs+1.61) within Foswiki::LoginManager::finish which was called: # once (136µs+1.61ms) by Foswiki::Users::finish at line 162 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Users.pm
sub finish {
179766µs my $this = shift;
18011.56ms $this->complete(); # call to flush the session if not already done
# spent 1.56ms making 1 call to Foswiki::LoginManager::complete
181 undef $this->{_authScripts};
182 undef $this->{_cgisession};
183160µs254µs undef $this->{_haveCookie};
# spent 48µs making 1 call to CGI::Session::DESTROY # spent 7µs making 1 call to CGI::Session::Driver::file::DESTROY
184 undef $this->{_MYSCRIPTURL};
185 undef $this->{session};
186}
187
188=begin TML
189
190---++ ClassMethod _real_trace ($session, $impl)
191
192Construct the user management object
193
194=cut
195
196sub _real_trace {
197 my ( $this, $mess ) = @_;
198 my $id =
199 'SESSION ' . ( $this->{_cgisession} ? $this->{_cgisession}->id() : '?' );
200 $id .= '(c)' if $this->{_haveCookie};
201 print STDERR "$id: $mess\n";
202}
203
20415µsif ( $Foswiki::cfg{Trace}{LoginManager} ) {
205 *_trace = \&_real_trace;
206}
207else {
2081064µs
# spent 38µs within Foswiki::LoginManager::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/LoginManager.pm:208] which was called 9 times, avg 4µs/call: # 5 times (18µs+0s) by Foswiki::LoginManager::loadSession at line 466, avg 4µs/call # once (6µs+0s) by Foswiki::LoginManager::userLoggedIn at line 622 # once (5µs+0s) by Foswiki::LoginManager::loadSession at line 355 # once (5µs+0s) by Foswiki::LoginManager::loadSession at line 271 # once (4µs+0s) by Foswiki::LoginManager::loadSession at line 294
*_trace = sub { undef };
209}
210
211=begin TML
212
213---++ ClassMethod _IP2SID ($session, $impl)
214
215 read/write IP to SID map, return SID
216
217=cut
218
219sub _IP2SID {
220 my ( $this, $sid ) = @_;
221
222 my $ip = $this->{session}->{request}->address;
223
224 return unless $ip; # no IP address, can't map
225
226 my %ips;
227 my $IPMAP;
228 if ( open( $IPMAP, '<', $Foswiki::cfg{WorkingDir} . '/tmp/ip2sid' ) ) {
229 local $/ = undef;
230 %ips = map { split( /:/, $_ ) } split( /\r?\n/, <$IPMAP> );
231 close($IPMAP);
232 }
233 if ($sid) {
234
235 # known SID, map the IP addr to it
236 $ips{$ip} = $sid;
237 open( $IPMAP, '>', $Foswiki::cfg{WorkingDir} . '/tmp/ip2sid' )
238 || die
239"Failed to open ip2sid map for write. Ask your administrator to make sure that the {Sessions}{Dir} is writable by the webserver user.";
240 print $IPMAP map { "$_:$ips{$_}\n" } keys %ips;
241 close($IPMAP);
242 }
243 else {
244
245 # Return the SID for this IP address
246 $sid = $ips{$ip};
247 }
248 return $sid;
249}
250
251=begin TML
252
253---++ ObjectMethod loadSession($defaultUser, $pwchecker) -> $login
254
255Get the client session data, using the cookie and/or the request URL.
256Set up appropriate session variables in the twiki object and return
257the login name.
258
259$pwchecker is a pointer to an object that implements checkPassword
260
261$defaultUser is a username to use if one is not available from other
262sources. The username passed when you create a Foswiki instance is
263passed in here.
264
265=cut
266
267
# spent 137ms (383µs+136) within Foswiki::LoginManager::loadSession which was called: # once (383µs+136ms) by Foswiki::Users::loadSession at line 144 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Users.pm
sub loadSession {
26842319µs my ( $this, $defaultUser, $pwchecker ) = @_;
269 my $session = $this->{session};
270
27115µs _trace( $this, "LOAD SESSION\n" );
272
273 $defaultUser = $Foswiki::cfg{DefaultUserLogin}
274 unless ( defined($defaultUser) );
275
276 # Try and get the user from the webserver. This is referred to as
277 # the "webserver user". the webserver user is authenticated by some
278 # means beyond foswiki e.g. Basic Auth
27914µs my $authUser = $this->getUser($this);
# spent 4µs making 1 call to Foswiki::LoginManager::getUser
280 _trace( $this, "Webserver says user is $authUser" ) if ($authUser);
281
282 # If the NO_FOSWIKI_SESSION environment varaible is defined, then
283 # do not create the session. This might be defined if the request
284 # is made by a search engine bot, depending on how the web server
285 # is configured
286 return $authUser if $ENV{NO_FOSWIKI_SESSION};
287
28818µs if ( $Foswiki::cfg{UseClientSessions}
# spent 8µs making 1 call to Foswiki::inContext
289 && !$session->inContext('command_line') )
290 {
291
292152µs $this->{_haveCookie} = $session->{request}->header('Cookie');
# spent 52µs making 1 call to Foswiki::Request::header
293
29414µs _trace( $this,
295 $this->{_haveCookie}
296 ? "Cookie $this->{_haveCookie}"
297 : "No cookie " );
298
299 # Item3568: CGI::Session from 4.0 already does the -d and creates the
300 # sessions directory if it does not exist. For performance reasons we
301 # only test for and create session file directory for older
302 # CGI::Session
303 my $sessionDir = "$Foswiki::cfg{WorkingDir}/tmp";
304 if ( $Foswiki::LoginManager::Session::VERSION < 4.0 ) {
305 unless (
306 -d $sessionDir
307 || ( mkdir( $Foswiki::cfg{WorkingDir} )
308 && mkdir($sessionDir) )
309 )
310 {
311 die "Could not create $sessionDir for storing sessions";
312 }
313 }
314
315 # First, see if there is a cookied session, creating a new session
316 # if necessary.
317 if ( $Foswiki::cfg{Sessions}{MapIP2SID} ) {
318
319 # map the end user IP address to a session ID
320
321 my $sid = $this->_IP2SID();
322 if ($sid) {
323 $this->{_cgisession} =
324 Foswiki::LoginManager::Session->new( undef, $sid,
325 { Directory => $sessionDir } );
326 }
327 else {
328
329 # The IP address was not mapped; create a new session
330
331 $this->{_cgisession} =
332 Foswiki::LoginManager::Session->new( undef, undef,
333 { Directory => $sessionDir } );
334 _trace( $this, "New IP2SID session" );
335 $this->_IP2SID( $this->{_cgisession}->id() );
336 }
337 }
338 else {
339
340 # IP mapping is off; use the request cookie
341
3421114ms $this->{_cgisession} =
# spent 114ms making 1 call to CGI::Session::new
343 Foswiki::LoginManager::Session->new( undef, $session->{request},
344 { Directory => $sessionDir } );
345 }
346
347 die Foswiki::LoginManager::Session->errstr()
348 unless $this->{_cgisession};
349
350 # Get the authorised user stored in the session
351
352254µs my $sessionUser = Foswiki::Sandbox::untaintUnchecked(
# spent 29µs making 1 call to CGI::Session::param # spent 25µs making 1 call to Foswiki::Sandbox::untaintUnchecked
353 $this->{_cgisession}->param('AUTHUSER') );
354
35515µs _trace( $this, "AUTHUSER is $sessionUser" ) if defined $sessionUser;
356
357 # An admin user stored in the session can override the webserver
358 # user; handy for sudo
359
360 $authUser = $sessionUser
361 if ( !defined($authUser)
362 || $sessionUser && $sessionUser eq $Foswiki::cfg{AdminUserLogin} );
363 }
364
365 if ( !$authUser ) {
366
367 # if we couldn't get the login manager or the http session to tell
368 # us who the user is, check the username and password URI params.
369
370 my $login = $session->{request}->param('username');
371 my $pass = $session->{request}->param('password');
372 if ( $login && defined $pass && $pwchecker ) {
373 my $validation = $pwchecker->checkPassword( $login, $pass );
374 unless ($validation) {
375 my $res = $session->{response};
376 my $err = "ERROR: (401) Can't login as $login";
377
378 # Item1953: You might think that this is needed:
379 # $res->header( -type => 'text/html', -status => '401' );
380 # throw Foswiki::EngineException( 401, $err, $res );
381 # but it would be wrong, because it would require the
382 # exception to be handled before the session object is
383 # properly initialised, which would cause an error.
384 # Instead, we do this, and let the caller handle the error.
385 undef $login;
386 }
387 $authUser = $login || $defaultUser;
388 _trace( $this, "URI params say user is $authUser" );
389 }
390 else {
391
392 # Last ditch attempt; if a user was passed in to this function,
393 # then use it (it is normally {remoteUser} from the session
394 # object)
395 $authUser = $defaultUser;
396 _trace( $this, "Falling back to $authUser" ) if $authUser;
397
398 }
399 }
400
401 # We should have a user at this point; or $defaultUser if there
402 # was no better information available.
403
404 # is this a logout?
405154µs if ( ( $authUser && $authUser ne $Foswiki::cfg{DefaultUserLogin} )
# spent 54µs making 1 call to Foswiki::Request::param
406 && ( $session->{request} && $session->{request}->param('logout') ) )
407 {
408
409 # SMELL: is there any way to get evil data into the CGI session such
410 # that this untaint is less than safe?
411 my $sudoUser = Foswiki::Sandbox::untaintUnchecked(
412 $this->{_cgisession}->param('SUDOFROMAUTHUSER') );
413
414 if ($sudoUser) {
415 _trace( $this, "User is logging out to $sudoUser" );
416 $session->logEvent( 'sudo logout', '',
417 'from ' . ( $authUser || '' ), $sudoUser );
418 $this->{_cgisession}->clear('SUDOFROMAUTHUSER');
419 $authUser = $sudoUser;
420 }
421 else {
422 _trace( $this, "User is logging out" );
423 $session->logEvent( 'logout', ' ',
424 "AUTHENTICATION LOGOUT - $authUser - " );
425
426 #TODO: consider if we should risk passing on the urlparams on logout
427 my $path_info = $session->{request}->path_info();
428 if ( my $topic = $session->{request}->param('topic') )
429 { #we should at least respect the ?topic= request
430 my $topicRequest = Foswiki::Sandbox::untaintUnchecked(
431 $session->{request}->param('topic') );
432 my ( $web, $topic ) =
433 $this->{session}
434 ->normalizeWebTopicName( undef, $topicRequest );
435 $path_info = '/' . $web . '/' . $topic;
436 }
437
438 my $redirectUrl;
439 if ($path_info) {
440 $redirectUrl = $session->{request}->url() . $path_info;
441 }
442 else {
443 $redirectUrl = $session->{request}->referer();
444 }
445
446 #lets avoid infinite loops
447 $session->{request}->delete('logout');
448 $authUser = $defaultUser;
449 $session->redirect( $redirectUrl, 0 );
450 }
451 }
452112µs $session->{request}->delete('logout');
# spent 12µs making 1 call to Foswiki::Request::delete
453
454121.7ms $this->userLoggedIn($authUser);
# spent 21.7ms making 1 call to Foswiki::LoginManager::userLoggedIn
455
456 if ( $this->{_cgisession} ) {
457252µs $session->{prefs}->setInternalPreferences(
# spent 29µs making 1 call to Foswiki::Prefs::setInternalPreferences # spent 23µs making 1 call to CGI::Session::id
458 SESSIONID => $this->{_cgisession}->id(),
459 SESSIONVAR => $CGI::Session::NAME
460 );
461
462 # Restore CGI Session parameters
4631103µs for ( $this->{_cgisession}->param ) {
# spent 103µs making 1 call to CGI::Session::param
464594µs my $value = $this->{_cgisession}->param($_);
# spent 94µs making 5 calls to CGI::Session::param, avg 19µs/call
465575µs $session->{prefs}->setInternalPreferences( $_ => $value );
# spent 75µs making 5 calls to Foswiki::Prefs::setInternalPreferences, avg 15µs/call
466518µs $this->_trace( "Setting internal preference $_ to "
467 . ( $value ? $value : 'null' ) );
468 }
469
470 # May end up doing this several times; but this is the only place
471 # if should really need to be done, unless someone allocates a
472 # new response object.
4731522µs $this->_addSessionCookieToResponse();
474 }
475
476 return $authUser;
477}
478
479=begin TML
480
481---++ ObjectMethod checkAccess()
482
483Check if the script being run in this session is authorised for execution.
484If not, throw an access control exception.
485
486=cut
487
488
# spent 54µs (35+19) within Foswiki::LoginManager::checkAccess which was called: # once (35µs+19µs) by Foswiki::UI::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/UI.pm:318] at line 315 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/UI.pm
sub checkAccess {
489
490528µs return unless ( $Foswiki::cfg{UseClientSessions} );
491
492 my $this = shift;
493 my $session = $this->{session};
494
495113µs return if $session->inContext('command_line');
# spent 13µs making 1 call to Foswiki::inContext
496
49717µs unless ( $session->inContext('authenticated')
# spent 7µs making 1 call to Foswiki::inContext
498 || $Foswiki::cfg{LoginManager} eq 'none' )
499 {
500
501 # This checks the *base_action* which is the action in the
502 # request *before* any request cache was restored. Otherwise
503 # you can end up with an infinite loop - see
504 # Foswiki:Development.FoswikiRedirectCache
505 my $action = $session->{request}->base_action();
506
507 if ( defined $action && $this->{_authScripts}{$action} ) {
508 my $topic = $session->{topicName};
509 my $web = $session->{webName};
510 require Foswiki::AccessControlException;
511 throw Foswiki::AccessControlException( $action, $session->{user},
512 $web, $topic, $action . ' requires authentication' );
513 }
514 }
515}
516
517=begin TML
518
519---++ ObjectMethod complete()
520
521Complete processing after the client's HTTP request has been responded
522to. Flush the user's session (if any) to disk.
523
524=cut
525
526
# spent 1.56ms (42µs+1.52) within Foswiki::LoginManager::complete which was called: # once (42µs+1.52ms) by Foswiki::LoginManager::finish at line 180
sub complete {
527646µs my $this = shift;
528
529 if ( $this->{_cgisession} ) {
53011.17ms $this->{_cgisession}->flush();
# spent 1.17ms making 1 call to CGI::Session::flush
531125µs die $this->{_cgisession}->errstr()
# spent 25µs making 1 call to CGI::Session::ErrorHandler::errstr
532 if $this->{_cgisession}->errstr();
533 }
534
535 return unless ( $Foswiki::cfg{Sessions}{ExpireAfter} > 0 );
536
5371317µs expireDeadSessions();
# spent 317µs making 1 call to Foswiki::LoginManager::expireDeadSessions
538}
539
540=begin TML
541
542---++ StaticMethod expireDeadSessions()
543
544Delete sessions and passthrough files that are sitting around but are really expired.
545This *assumes* that the sessions are stored as files.
546
547This is a static method, but requires Foswiki::cfg. It is designed to be
548run from a session or from a cron job.
549
550=cut
551
552
# spent 317µs (114+202) within Foswiki::LoginManager::expireDeadSessions which was called: # once (114µs+202µs) by Foswiki::LoginManager::complete at line 537
sub expireDeadSessions {
55315316µs my $time = time() || 0;
554 my $exp = $Foswiki::cfg{Sessions}{ExpireAfter} || 36000; # 10 hours
555 $exp = -$exp if $exp < 0;
556
557116µs opendir( D, "$Foswiki::cfg{WorkingDir}/tmp" ) || return;
# spent 16µs making 1 call to Foswiki::LoginManager::CORE:open_dir
5581159µs foreach my $file ( readdir(D) ) {
# spent 159µs making 1 call to Foswiki::LoginManager::CORE:readdir
559
560 # Validate
561415µs next unless $file =~ /^((passthru|cgisess)_[0-9a-f]{32})$/;
# spent 15µs making 4 calls to Foswiki::LoginManager::CORE:match, avg 4µs/call
562 $file = $1; # untaint validated file name
563
56418µs my @stat = stat("$Foswiki::cfg{WorkingDir}/tmp/$file");
# spent 8µs making 1 call to Foswiki::LoginManager::CORE:stat
565
566 # CGI::Session updates the session file each time a browser views a
567 # topic setting the access and expiry time as values in the file. This
568 # also sets the mtime (modification time) for the file which is all
569 # we need. We know that the expiry time is mtime +
570 # $Foswiki::cfg{Sessions}{ExpireAfter} so we do not need to waste
571 # execution time opening and reading the file. We just check the
572 # mtime. As a fallback we also check ctime. Files are deleted when
573 # they expire.
574 my $lat = $stat[9] || $stat[10] || 0;
575 unlink "$Foswiki::cfg{WorkingDir}/tmp/$file"
576 if ( $time - $lat >= $exp );
577 next;
578 }
57914µs closedir D;
# spent 4µs making 1 call to Foswiki::LoginManager::CORE:closedir
580}
581
582=begin TML
583
584---++ ObjectMethod userLoggedIn( $login, $wikiname)
585
586Called when the user is known. It's invoked from Foswiki::UI::Register::finish
587for instance,
588 1 when the user follows the link in their verification email message
589 2 or when the session store is read
590 3 when the user authenticates (via templatelogin / sudo)
591
592 * =$login= - string login name
593 * =$wikiname= - string wikiname
594
595=cut
596
597
# spent 21.7ms (115µs+21.6) within Foswiki::LoginManager::userLoggedIn which was called: # once (115µs+21.6ms) by Foswiki::LoginManager::loadSession at line 454
sub userLoggedIn {
5981698µs my ( $this, $authUser, $wikiName ) = @_;
599
600 my $session = $this->{session};
601 if ( $session->{users} ) {
602120.3ms $session->{user} = $session->{users}->getCanonicalUserID($authUser);
# spent 20.3ms making 1 call to Foswiki::Users::getCanonicalUserID
603 }
604 return
60519µs if $session->inContext('command_line')
# spent 9µs making 1 call to Foswiki::inContext
606 || $session->{remoteUser}
607 && $authUser
608 && $authUser eq $session->{remoteUser}; # same user
609
610 if ( $Foswiki::cfg{UseClientSessions} ) {
611
612 # create new session if necessary
613 unless ( $this->{_cgisession} ) {
614 $this->{_cgisession} =
615 Foswiki::LoginManager::Session->new( undef, $session->{request},
616 { Directory => "$Foswiki::cfg{WorkingDir}/tmp" } );
617 die Foswiki::LoginManager::Session->errstr()
618 unless $this->{_cgisession};
619 }
620 }
621 if ( $authUser && $authUser ne $Foswiki::cfg{DefaultUserLogin} ) {
62216µs _trace( $this,
623 'Authenticated; converting from '
624 . ( $session->{remoteUser} || 'undef' ) . ' to '
625 . $authUser );
626
627 # SMELL: right now anyone that makes a template login url can log
628 # in multiple times - should i forbid it
629 if ( $Foswiki::cfg{UseClientSessions} ) {
630 if ( defined( $session->{remoteUser} )
631 && $session->inContext('sudo_login') )
632 {
633 $session->logEvent( 'sudo login', '',
634 'from ' . ( $session->{remoteUser} || '' ), $authUser );
635 $this->{_cgisession}
636 ->param( 'SUDOFROMAUTHUSER', $session->{remoteUser} );
637 }
638
639 # SMELL: these are bare logins, so if and when there are
640 # multiple usermappings, this would need to include cUID..
641196µs $this->{_cgisession}->param( 'AUTHUSER', $authUser );
# spent 96µs making 1 call to CGI::Session::param
642 }
643111µs $session->enterContext('authenticated');
# spent 11µs making 1 call to Foswiki::enterContext
644 }
645 else {
646 _trace( $this, "Session is NOT authenticated" );
647
648 # if we are not authenticated, expire any existing session
649 $this->{_cgisession}->clear( ['AUTHUSER'] )
650 if ( $Foswiki::cfg{UseClientSessions} );
651 $session->leaveContext('authenticated');
652 }
653 if ( $Foswiki::cfg{UseClientSessions} ) {
654
655 # flush the session, to try to fix Item1820 and Item2234
65611.17ms $this->{_cgisession}->flush();
# spent 1.17ms making 1 call to CGI::Session::flush
657116µs die $this->{_cgisession}->errstr() if $this->{_cgisession}->errstr();
# spent 16µs making 1 call to CGI::Session::ErrorHandler::errstr
658 }
659}
660
661=begin TML
662
663---++ ObjectMethod _myScriptURLRE ($thisl)
664
- -
667=cut
668
669# get an RE that matches a local script URL
670sub _myScriptURLRE {
671 my $this = shift;
672
673 my $s = $this->{_MYSCRIPTURL};
674 unless ($s) {
675 $s = quotemeta( $this->{session}->getScriptUrl( 1, $M1, $M2, $M3 ) );
676 $s =~ s@\\$M1@[^/]*?@go;
677 $s =~ s@\\$M2@[^/]*?@go;
678 $s =~ s@\\$M3@[^#\?/]*@go;
679
680 # now add alternates for the various script-specific overrides
681 foreach my $v ( values %{ $Foswiki::cfg{ScriptUrlPaths} } ) {
682 my $over = $v;
683
684 # escape non-alphabetics
685 $over =~ s/(\W)/\\$1/g;
686 $s .= '|' . $over;
687 }
688 $this->{_MYSCRIPTURL} = "($s)";
689 }
690 return $s;
691}
692
693=begin TML
694
695---++ ObjectMethod _rewriteURL ($this, $url) -> $url
696
697=cut
698
699# Rewrite a URL inserting the session id
700sub _rewriteURL {
701 my ( $this, $url ) = @_;
702
703 return $url unless $url;
704
705 my $sessionId = $this->{_cgisession}->id();
706 return $url unless $sessionId;
707 return $url if $url =~ m/\?$Foswiki::LoginManager::Session::NAME=/;
708
709 my $s = _myScriptURLRE($this);
710
711 # If the URL has no colon in it, or it matches the local script
712 # URL, it must be an internal URL and therefore needs the session.
713 if ( $url !~ /:/ || $url =~ /^$s/ ) {
714
715 # strip off the anchor
716 my $anchor = '';
717 if ( $url =~ s/(#.*)// ) {
718 $anchor = $1;
719 }
720
721 # strip off existing params
722 my $params = "?$Foswiki::LoginManager::Session::NAME=$sessionId";
723
724 # implicit untaint is OK because recombined with url later
725 if ( $url =~ s/\?(.*)$// ) {
726 $params .= ';' . $1;
727 }
728
729 # rebuild the URL
730 $url .= $params . $anchor;
731 } # otherwise leave it untouched
732
733 return $url;
734}
735
736=begin TML
737
738---++ ObjectMethod _rewriteFORM ($thisl)
739
740
741=cut
742
743# Catch all FORMs and add a hidden Session ID variable.
744# Only do this if the form is pointing to an internal link.
745# This occurs if there are no colons in its target, if it has
746# no target, or if its target matches a getScriptUrl URL.
747# '$rest' is the bit of the initial form tag up to the closing >
748sub _rewriteFORM {
749 my ( $this, $url, $rest ) = @_;
750
751 return $url . $rest unless $this->{_cgisession};
752
753 my $s = _myScriptURLRE($this);
754
755 if ( $url !~ /:/ || $url =~ /^($s)/ ) {
756 $rest .= CGI::hidden(
757 -name => $Foswiki::LoginManager::Session::NAME,
758 -value => $this->{_cgisession}->id()
759 );
760 }
761 return $url . $rest;
762}
763
764=begin TML
765
766---++ ObjectMethod endRenderingHandler()
767
768This handler is called by getRenderedVersion just before the plugins
769postRenderingHandler. So it is passed all HTML text just before it is
770printed.
771
772*DEPRECATED* Use postRenderingHandler instead.
773
774=cut
775
776
# spent 291µs (173+118) within Foswiki::LoginManager::endRenderingHandler which was called 5 times, avg 58µs/call: # 5 times (173µs+118µs) by Foswiki::Render::getRenderedVersion at line 1443 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Render.pm, avg 58µs/call
sub endRenderingHandler {
77730230µs return unless ( $Foswiki::cfg{UseClientSessions} );
778
779 my $this = shift;
780539µs return if $this->{session}->inContext('command_line');
# spent 39µs making 5 calls to Foswiki::inContext, avg 8µs/call
781
782 # If cookies are not turned on and transparent CGI session IDs are,
783 # grab every URL that is an internal link and pass a CGI variable
784 # with the session ID
785 unless ( $this->{_haveCookie} || !$Foswiki::cfg{Sessions}{IDsInURLs} ) {
786
787 # rewrite internal links to include the transparent session ID
788 # Doesn't catch Javascript, because there are just so many ways
789 # to generate links from JS.
790 # SMELL: this would probably be done better using javascript
791 # that handles navigation away from this page, and uses the
792 # rules to rewrite any relative URLs at that time.
793
794 # a href= rewriting
795 $_[0] =~
796s/(<a[^>]*(?<=\s)href=(["']))(.*?)(\2)/$1.$this->_rewriteURL($3).$4/geoi;
797
798 # form action= rewriting
799 # SMELL: Forms that have no target are also implicit internal
800 # links, but are not handled. Does this matter>
801 $_[0] =~
802s/(<form[^>]*(?<=\s)(?:action)=(["']))(.*?)(\2[^>]*>)/$1._rewriteFORM( $this,$3, $4)/geoi;
803 }
804
805 # And, finally, the logon stuff
806557µs $_[0] =~ s/%SESSIONLOGON%/_dispLogon( $this )/geo;
# spent 57µs making 5 calls to Foswiki::LoginManager::CORE:subst, avg 11µs/call
807522µs $_[0] =~ s/%SKINSELECT%/_skinSelect( $this )/geo;
# spent 22µs making 5 calls to Foswiki::LoginManager::CORE:subst, avg 4µs/call
808}
809
810
# spent 522µs (54+468) within Foswiki::LoginManager::_addSessionCookieToResponse which was called: # once (54µs+468µs) by Foswiki::LoginManager::loadSession at line 473
sub _addSessionCookieToResponse {
811449µs my $this = shift;
812
8133458µs my $cookie = CGI::Cookie->new(
# spent 431µs making 1 call to CGI::Cookie::new # spent 21µs making 1 call to CGI::Session::id # spent 6µs making 1 call to Foswiki::Request::secure
814 -name => $Foswiki::LoginManager::Session::NAME,
815 -value => $this->{_cgisession}->id(),
816 -path => '/',
817 -domain => $Foswiki::cfg{Sessions}{CookieRealm} || '',
818 -httponly => 1,
819 -secure => $this->{session}->{request}->secure,
820 );
821
822 # An expiry time is only set if the session has the REMEMBER variable
823 # in it. This is to prevent accidentally remembering cookies with
824 # login managers where the authority is cached in the browser and
825 # *not* in the session. Otherwise another user might be able to login
826 # on the same machine and inherit the authorities of a prior user.
827 if ( $Foswiki::cfg{Sessions}{ExpireCookiesAfter}
828 && $this->getSessionValue('REMEMBER') )
829 {
830 require Foswiki::Time;
831 my $exp = Foswiki::Time::formatTime(
832 time() + $Foswiki::cfg{Sessions}{ExpireCookiesAfter},
833 '$wday, $day-$month-$ye $hours:$minutes:$seconds GMT'
834 );
835
836 $cookie->expires($exp);
837 }
838
839110µs $this->{session}->{response}->cookies( [$cookie] );
# spent 10µs making 1 call to Foswiki::Response::cookies
840}
841
842=begin TML
843
844---++ ObjectMethod rewriteRedirectUrl( $url ) ->$url
845
846Rewrite the URL used in a redirect if necessary to include any session
847identification.
848 * =$url= - target of the redirection.
849
850=cut
851
852sub rewriteRedirectUrl {
853
854 my ( $this, $url ) = @_;
855
856 return $url unless $this->{_cgisession};
857
858 if ( $Foswiki::cfg{Sessions}{IDsInURLs} && !$this->{_haveCookie} ) {
859 $url = _rewriteURL( $this, $url );
860 }
861
862 # This usually won't be important, but just in case they haven't
863 # yet received the cookie and happen to be redirecting, be sure
864 # they do have the cookie.
865 $this->_addSessionCookieToResponse();
866
867 return $url;
868}
869
870=begin TML
871
872---++ ObjectMethod getSessionValues() -> \%values
873
874Get a name->value hash of all the defined session variables
875
876=cut
877
878sub getSessionValues {
879 my ($this) = @_;
880
881 return unless $this->{_cgisession};
882
883 return $this->{_cgisession}->param_hashref();
884}
885
886=begin TML
887
888---++ ObjectMethod getCGISession()
889Get the currect CGI session object
890
891=cut
892
893
# spent 10µs within Foswiki::LoginManager::getCGISession which was called: # once (10µs+0s) by Foswiki::Users::getCGISession at line 403 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Users.pm
sub getCGISession {
894218µs my $this = shift;
895 return $this->{_cgisession};
896}
897
898=begin TML
899
900---++ ObjectMethod getSessionValue( $name ) -> $value
901
902Get the value of a session variable.
903
904=cut
905
906sub getSessionValue {
907 my ( $this, $key ) = @_;
908 return unless $this->{_cgisession};
909
910 return $this->{_cgisession}->param($key);
911}
912
913=begin TML
914
915---++ ObjectMethod setSessionValue( $name, $value )
916
917Set the value of a session variable.
918
919=cut
920
921sub setSessionValue {
922 my ( $this, $key, $value ) = @_;
923
924 if ( $this->{_cgisession}
925 && defined( $this->{_cgisession}->param( $key, $value ) ) )
926 {
927 return 1;
928 }
929
930 return;
931}
932
933=begin TML
934
935---++ ObjectMethod clearSessionValue( $name ) -> $boolean
936
937Clear the value of a session variable.
938We do not allow setting of AUTHUSER.
939
940=cut
941
942sub clearSessionValue {
943 my ( $this, $key ) = @_;
944
945 # We do not allow clearing of AUTHUSER.
946 if ( $this->{_cgisession}
947 && $key ne 'AUTHUSER'
948 && defined( $this->{_cgisession}->param($key) ) )
949 {
950 $this->{_cgisession}->clear( [ $_[1] ] );
951
952 return 1;
953 }
954
955 return;
956}
957
958=begin TML
959
960---++ ObjectMethod forceAuthentication() -> boolean
961
962*VIRTUAL METHOD* implemented by subclasses
963
964Triggered by an access control violation, this method tests
965to see if the current session is authenticated or not. If not,
966it does whatever is needed so that the user can log in, and returns 1.
967
968If the user has an existing authenticated session, the function simply drops
969though and returns 0.
970
971=cut
972
973sub forceAuthentication {
974 return 0;
975}
976
977=begin TML
978
979---++ ObjectMethod loginUrl( ... ) -> $url
980
981*VIRTUAL METHOD* implemented by subclasses
982
983Return a full URL suitable for logging in.
984 * =...= - url parameters to be added to the URL, in the format required by Foswiki::getScriptUrl()
985
986=cut
987
988sub loginUrl {
989 return '';
990}
991
992=begin TML
993
994---++ ObjectMethod getUser()
995
996Should be implemented by subclasses
997
998If there is some other means of getting a username - for example,
999Apache has remote_user() - then return it. Otherwise, return undef and
1000the username stored in the session will be used.
1001
1002This method of getting the user *assumes* that the identified user
1003has been authenticated in some way (for example, by the web server)
1004
1005=cut
1006
1007
# spent 4µs within Foswiki::LoginManager::getUser which was called: # once (4µs+0s) by Foswiki::LoginManager::loadSession at line 279
sub getUser {
100817µs return;
1009}
1010
1011=begin TML
1012
1013---++ ObjectMethod isValidLoginName( $name ) -> $boolean
1014
1015Check for a valid login name (not an existance check, just syntax).
1016Default behaviour is to check the login name against
1017$Foswiki::cfg{LoginNameFilterIn}
1018
1019=cut
1020
1021sub isValidLoginName {
1022 my ( $this, $name ) = @_;
1023
1024 # this function was erroneously marked as static
1025 ASSERT( !ref($name) ) if DEBUG;
1026 return $name =~ /$Foswiki::cfg{LoginNameFilterIn}/;
1027}
1028
1029=begin TML
1030
1031---++ ObjectMethod _LOGIN ($thisl)
1032
1033
1034=cut
1035
1036
# spent 80µs (38+42) within Foswiki::LoginManager::_LOGIN which was called 2 times, avg 40µs/call: # 2 times (38µs+42µs) by Foswiki::_expandMacroOnTopicRendering at line 3066 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 40µs/call
sub _LOGIN {
1037
1038 #my( $session, $params, $topic, $web ) = @_;
1039633µs my $session = shift;
1040229µs my $this = $session->getLoginManager();
# spent 29µs making 2 calls to Foswiki::getLoginManager, avg 14µs/call
1041
1042213µs return '' if $session->inContext('authenticated');
# spent 13µs making 2 calls to Foswiki::inContext, avg 7µs/call
1043
1044 my $url = $this->loginUrl();
1045 if ($url) {
1046 my $text = $session->templates->expandTemplate('LOG_IN');
1047 return CGI::a( { href => $url }, $text );
1048 }
1049 return '';
1050}
1051
1052=begin TML
1053
1054---++ ObjectMethod _LOGOUTURL ($thisl)
1055
1056
1057=cut
1058
1059
# spent 616µs (72+544) within Foswiki::LoginManager::_LOGOUTURL which was called 2 times, avg 308µs/call: # 2 times (72µs+544µs) by Foswiki::LoginManager::_LOGOUT at line 1084, avg 308µs/call
sub _LOGOUTURL {
1060663µs my ( $session, $params, $topic, $web ) = @_;
1061228µs my $this = $session->getLoginManager();
# spent 28µs making 2 calls to Foswiki::getLoginManager, avg 14µs/call
1062
10636516µs return $session->getScriptUrl(
# spent 480µs making 2 calls to Foswiki::getScriptUrl, avg 240µs/call # spent 35µs making 4 calls to Foswiki::Prefs::getPreference, avg 9µs/call
1064 0, 'view',
1065 $session->{prefs}->getPreference('BASEWEB'),
1066 $session->{prefs}->getPreference('BASETOPIC'),
1067 'logout' => 1
1068 );
1069}
1070
1071=begin TML
1072
1073---++ ObjectMethod _LOGOUT ($thisl)
1074
1075
1076=cut
1077
1078
# spent 10.1ms (139µs+9.92) within Foswiki::LoginManager::_LOGOUT which was called 2 times, avg 5.03ms/call: # 2 times (139µs+9.92ms) by Foswiki::_expandMacroOnTopicRendering at line 3066 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 5.03ms/call
sub _LOGOUT {
107914133µs my ( $session, $params, $topic, $web ) = @_;
1080255µs my $this = $session->getLoginManager();
# spent 55µs making 2 calls to Foswiki::getLoginManager, avg 28µs/call
1081
1082216µs return '' unless $session->inContext('authenticated');
# spent 16µs making 2 calls to Foswiki::inContext, avg 8µs/call
1083
10842616µs my $url = _LOGOUTURL(@_);
# spent 616µs making 2 calls to Foswiki::LoginManager::_LOGOUTURL, avg 308µs/call
1085 if ($url) {
10864628µs my $text = $session->templates->expandTemplate('LOG_OUT');
# spent 607µs making 2 calls to Foswiki::Templates::expandTemplate, avg 304µs/call # spent 21µs making 2 calls to Foswiki::templates, avg 10µs/call
108727.48ms return CGI::a( { href => $url }, $text );
# spent 7.34ms making 1 call to CGI::AUTOLOAD # spent 131µs making 1 call to CGI::a
1088 }
1089 return '';
1090}
1091
1092=begin TML
1093
1094---++ ObjectMethod _AUTHENTICATED ($thisl)
1095
1096
1097=cut
1098
1099sub _AUTHENTICATED {
1100 my ( $session, $params ) = @_;
1101 my $this = $session->getLoginManager();
1102
1103 if ( $session->inContext('authenticated') ) {
1104 return $params->{then} || 1;
1105 }
1106 else {
1107 return $params->{else} || 0;
1108 }
1109}
1110
1111=begin TML
1112
1113---++ ObjectMethod _CANLOGIN ($thisl)
1114
1115=cut
1116
1117sub _CANLOGIN {
1118 my ( $session, $params ) = @_;
1119 my $this = $session->getLoginManager();
1120 if ( $session->inContext('can_login') ) {
1121 return $params->{then} || 1;
1122 }
1123 else {
1124 return $params->{else} || 0;
1125 }
1126}
1127
1128=begin TML
1129
1130---++ ObjectMethod _SESSION_VARIABLE ($thisl)
1131
1132=cut
1133
1134sub _SESSION_VARIABLE {
1135 my ( $session, $params ) = @_;
1136 my $this = $session->getLoginManager();
1137 my $name = $params->{_DEFAULT};
1138
1139 if ( defined $name ) {
1140 if ( defined( $params->{set} ) ) {
1141 unless ( $readOnlySK{$name} ) {
1142 $this->setSessionValue( $name, $params->{set} );
1143 }
1144 }
1145 elsif ( defined( $params->{clear} ) ) {
1146 unless ( $readOnlySK{$name} ) {
1147 $this->clearSessionValue($name);
1148 }
1149 }
1150 elsif ( !$secretSK{$name} ) {
1151 my $val = $this->getSessionValue($name);
1152 $val = '' unless defined $val;
1153 return $val;
1154 }
1155 }
1156 return '';
1157}
1158
1159=begin TML
1160
1161---++ ObjectMethod _LOGINURL ($thisl)
1162
1163
1164=cut
1165
1166sub _LOGINURL {
1167 my ( $session, $params ) = @_;
1168 my $this = $session->{users}->getLoginManager();
1169 return $this->loginUrl();
1170}
1171
1172=begin TML
1173
1174---++ ObjectMethod _dispLogon ($thisl)
1175
1176=cut
1177
1178sub _dispLogon {
1179 my $this = shift;
1180
1181 return '' unless $this->{_cgisession};
1182
1183 my $session = $this->{session};
1184 my $topic = $session->{topicName};
1185 my $web = $session->{webName};
1186 my $sessionId = $this->{_cgisession}->id();
1187
1188 my $urlToUse = $this->loginUrl();
1189
1190 unless ( $this->{_haveCookie} || !$Foswiki::cfg{Sessions}{IDsInURLs} ) {
1191 $urlToUse = _rewriteURL( $this, $urlToUse );
1192 }
1193
1194 my $text = $session->templates->expandTemplate('LOG_IN');
1195 return CGI::a( { class => 'foswikiAlert', href => $urlToUse }, $text );
1196}
1197
1198=begin TML
1199
1200---++ PrivateMethod _skinSelect ()
1201
1202Internal use only
1203TODO: what does it do?
1204
1205=cut
1206
1207sub _skinSelect {
1208 my $this = shift;
1209 my $session = $this->{session};
1210 my $skins = $session->{prefs}->getPreference('SKINS');
1211 my $skin = $session->getSkin();
1212 my @skins = split( /,/, $skins );
1213 unshift( @skins, 'default' );
1214 my $options = '';
1215 foreach my $askin (@skins) {
1216 $askin =~ s/\s//go;
1217 if ( $askin eq $skin ) {
1218 $options .=
1219 CGI::option( { selected => 'selected', name => $askin }, $askin );
1220 }
1221 else {
1222 $options .= CGI::option( { name => $askin }, $askin );
1223 }
1224 }
1225 return CGI::Select( { name => 'stickskin' }, $options );
1226}
1227
1228112µs1;
1229__END__
 
# spent 4µs within Foswiki::LoginManager::CORE:closedir which was called: # once (4µs+0s) by Foswiki::LoginManager::expireDeadSessions at line 579
sub Foswiki::LoginManager::CORE:closedir; # opcode
# spent 15µs within Foswiki::LoginManager::CORE:match which was called 4 times, avg 4µs/call: # 4 times (15µs+0s) by Foswiki::LoginManager::expireDeadSessions at line 561, avg 4µs/call
sub Foswiki::LoginManager::CORE:match; # opcode
# spent 16µs within Foswiki::LoginManager::CORE:open_dir which was called: # once (16µs+0s) by Foswiki::LoginManager::expireDeadSessions at line 557
sub Foswiki::LoginManager::CORE:open_dir; # opcode
# spent 159µs within Foswiki::LoginManager::CORE:readdir which was called: # once (159µs+0s) by Foswiki::LoginManager::expireDeadSessions at line 558
sub Foswiki::LoginManager::CORE:readdir; # opcode
# spent 8µs within Foswiki::LoginManager::CORE:stat which was called: # once (8µs+0s) by Foswiki::LoginManager::expireDeadSessions at line 564
sub Foswiki::LoginManager::CORE:stat; # opcode
# spent 82µs within Foswiki::LoginManager::CORE:subst which was called 11 times, avg 7µs/call: # 5 times (57µs+0s) by Foswiki::LoginManager::endRenderingHandler at line 806, avg 11µs/call # 5 times (22µs+0s) by Foswiki::LoginManager::endRenderingHandler at line 807, avg 4µs/call # once (4µs+0s) by Foswiki::LoginManager::makeLoginManager at line 119
sub Foswiki::LoginManager::CORE:subst; # opcode