Andrew's Web Libraries (AWL)
Loading...
Searching...
No Matches
Session.php
1<?php
26require_once('AWLUtilities.php');
27require_once('AwlQuery.php');
28require_once('EMail.php');
29
30
37function check_temporary_passwords( $they_sent, $user_no ) {
38 $sql = 'SELECT 1 AS ok FROM tmp_password WHERE user_no = ? AND password = text(?) AND valid_until > current_timestamp';
39 $qry = new AwlQuery( $sql, $user_no, $they_sent );
40 if ( $qry->Exec('Session::check_temporary_passwords') ) {
41 dbg_error_log( "Login", " check_temporary_passwords: Rows = ".$qry->rows());
42 if ( $row = $qry->Fetch() ) {
43 dbg_error_log( "Login", " check_temporary_passwords: OK = $row->ok");
44 // Remove all the temporary passwords for that user...
45 $sql = 'DELETE FROM tmp_password WHERE user_no = ? ';
46 $qry = new AwlQuery( $sql, $user_no );
47 $qry->Exec('Login',__LINE__,__FILE__);
48 return true;
49 }
50 }
51 return false;
52}
53
60{
64 var $roles;
65 var $cause = '';
66
68
72
77 var $user_no;
78
83 var $session_id = 0;
84
89 var $username = 'guest';
90
95 var $fullname = 'Guest';
96
101 var $email = '';
102
107 var $logged_in = false;
108
115 var $just_logged_in = false;
116
121 var $active;
122
127 var $email_ok;
128
133 var $joined;
134
139 var $updated;
140
145 var $last_used;
146
151 var $password;
152
158 var $config_data;
159
164 var $date_format_type;
165
170 var $locale;
171
176 var $last_session_start;
177
183 var $last_session_end;
184
189 var $session_start;
190
196 var $session_config;
197
202 var $session_end;
203
208 var $session_key;
209
214 var $login_failed = false;
215
217
234 function __construct( $sid="" )
235 {
236 global $sid, $sysname;
237
238 $this->roles = array();
239 $this->logged_in = false;
240 $this->just_logged_in = false;
241 $this->login_failed = false;
242
243 if ( $sid == "" ) {
244 if ( ! isset($_COOKIE['sid']) ) return;
245 $sid = $_COOKIE['sid'];
246 }
247
248 list( $session_id, $session_key ) = explode( ';', $sid, 2 );
249
259 if ( function_exists('local_session_sql') ) {
260 $sql = local_session_sql();
261 }
262 else {
263 $sql = "SELECT session.*, usr.* FROM session JOIN usr USING ( user_no )";
264 }
265 $sql .= " WHERE session.session_id = ? AND session.session_key = ? ORDER BY session.session_start DESC LIMIT 2";
266
267 $qry = new AwlQuery($sql, $session_id, $session_key);
268 if ( $qry->Exec('Session') && 1 == $qry->rows() ) {
269 $this->AssignSessionDetails( $qry->Fetch() );
270 $qry = new AwlQuery('UPDATE session SET session_end = current_timestamp WHERE session_id=?', $session_id);
271 $qry->Exec('Session');
272 }
273 else {
274 // Kill the existing cookie, which appears to be bogus
275 setcookie('sid', '', 0,'/');
276 $this->cause = 'ERR: Other than one session record matches. ' . $qry->rows();
277 $this->Log( "WARN: Login $this->cause" );
278 }
279 }
280
281
292 function Log( $whatever )
293 {
294 global $c;
295 deprecated('Session::Log');
296
297 $argc = func_num_args();
298 $format = func_get_arg(0);
299 if ( $argc == 1 || ($argc == 2 && func_get_arg(1) == "0" ) ) {
300 error_log( "$c->sysabbr: $format" );
301 }
302 else {
303 $args = array();
304 for( $i=1; $i < $argc; $i++ ) {
305 $args[] = func_get_arg($i);
306 }
307 error_log( sprintf("%s%s: %s", $c->sysabbr, request_id_str(),
308 vsprintf($format, $args) ));
309 }
310 }
311
323 function Dbg( $whatever )
324 {
325 global $debuggroups, $c;
326 deprecated('Session::Dbg');
327
328 $argc = func_num_args();
329 $dgroup = func_get_arg(0);
330
331 if ( ! (isset($debuggroups[$dgroup]) && $debuggroups[$dgroup]) ) return;
332
333 $format = func_get_arg(1);
334 if ( $argc == 2 || ($argc == 3 && func_get_arg(2) == "0" ) ) {
335 error_log( sprintf("%s%s: DBG: %s: %s", $c->sysabbr, request_id_str(),
336 $dgroup, $format ));
337 }
338 else {
339 $args = array();
340 for( $i=2; $i < $argc; $i++ ) {
341 $args[] = func_get_arg($i);
342 }
343
344 error_log( sprintf("%s%s: DBG: %s: %s", $c->sysabbr, request_id_str(),
345 $dgroup, vsprintf($format,$args) ));
346 }
347 }
348
357 function AllowedTo ( $whatever ) {
358 return ( $this->logged_in && isset($this->roles[$whatever]) && $this->roles[$whatever] );
359 }
360
361
365 function GetRoles () {
366 $this->roles = array();
367 $qry = new AwlQuery( 'SELECT role_name FROM role_member m join roles r ON r.role_no = m.role_no WHERE user_no = ? ', $this->user_no );
368 if ( $qry->Exec('Session::GetRoles') && $qry->rows() > 0 ) {
369 while( $role = $qry->Fetch() ) {
370 $this->roles[$role->role_name] = true;
371 }
372 }
373 }
374
375
380 function AssignSessionDetails( $u ) {
381 // Assign each field in the selected record to the object
382 foreach( $u AS $k => $v ) {
383 $this->{$k} = $v;
384 }
385
386 $date_format = ($this->date_format_type == 'E' ? 'European,ISO' : ($this->date_format_type == 'U' ? 'US,ISO' : 'ISO'));
387 $qry = new AwlQuery( 'SET DATESTYLE TO '. $date_format );
388 $qry->Exec();
389
390 $this->GetRoles();
391 $this->logged_in = true;
392 }
393
394
409 function Login( $username, $password, $authenticated = false ) {
410 global $c;
411 $rc = false;
412 dbg_error_log( "Login", " Login: Attempting login for $username" );
413 if ( isset($usr) ) unset($usr);
414
421 if ( !$authenticated && isset($c->authenticate_hook) && isset($c->authenticate_hook['call']) && function_exists($c->authenticate_hook['call']) ) {
432 $usr = call_user_func( $c->authenticate_hook['call'], $username, $password );
433 if ( $usr === false ) unset($usr); else $authenticated = true;
434 }
435
436 $sql = "SELECT * FROM usr WHERE lower(username) = text(?) AND active";
437 $qry = new AwlQuery( $sql, strtolower($username) );
438 if ( isset($usr) || ($qry->Exec('Login',__LINE__,__FILE__) && $qry->rows() == 1 && $usr = $qry->Fetch() ) ) {
439 $user_no = ( method_exists( $usr, 'user_no' ) ? $usr->user_no() : $usr->user_no );
440 if ( $authenticated || session_validate_password( $password, $usr->password ) || check_temporary_passwords( $password, $user_no ) ) {
441 // Now get the next session ID to create one from...
442 $qry = new AwlQuery( "SELECT nextval('session_session_id_seq')" );
443 if ( $qry->Exec('Login') && $qry->rows() == 1 ) {
444 $seq = $qry->Fetch();
445 $session_id = $seq->nextval;
446 $session_key = md5( rand(1010101,1999999999) . microtime() ); // just some random shite
447 dbg_error_log( "Login", " Login: Valid username/password for $username ($user_no)" );
448
449 // Set the last_used timestamp to match the previous login.
450 $qry = new AwlQuery('UPDATE usr SET last_used = (SELECT session_start FROM session WHERE session.user_no = ? ORDER BY session_id DESC LIMIT 1) WHERE user_no = ?;', $usr->user_no, $usr->user_no);
451 $qry->Exec('Session');
452
453 // And create a session
454 $sql = "INSERT INTO session (session_id, user_no, session_key) VALUES( ?, ?, ? )";
455 $qry = new AwlQuery( $sql, $session_id, $user_no, $session_key );
456 if ( $qry->Exec('Login') ) {
457 // Assign our session ID variable
458 $sid = "$session_id;$session_key";
459
460 // Create a cookie for the sesssion
461 setcookie('sid',$sid, 0,'/');
462 // Recognise that we have started a session now too...
463 $this->__construct($sid);
464 dbg_error_log( "Login", " Login: New session $session_id started for $username ($user_no)" );
465 $this->just_logged_in = true;
466
467 // Unset all of the submitted values, so we don't accidentally submit an unexpected form.
468 unset($_POST['username']);
469 unset($_POST['password']);
470 unset($_POST['submit']);
471 unset($_GET['submit']);
472 unset($GLOBALS['submit']);
473
474 if ( function_exists('local_session_sql') ) {
475 $sql = local_session_sql();
476 }
477 else {
478 $sql = "SELECT session.*, usr.* FROM session JOIN usr USING ( user_no )";
479 }
480 $sql .= " WHERE session.session_id = ? AND session.session_key = ? ORDER BY session.session_start DESC LIMIT 2";
481
482 $qry = new AwlQuery($sql, $session_id, $session_key);
483 if ( $qry->Exec('Session') && 1 == $qry->rows() ) {
484 $this->AssignSessionDetails( $qry->Fetch() );
485 }
486
487 $rc = true;
488 return $rc;
489 }
490 // else ...
491 $this->cause = 'ERR: Could not create new session.';
492 }
493 else {
494 $this->cause = 'ERR: Could not increment session sequence.';
495 }
496 }
497 else {
498 $c->messages[] = i18n('Invalid username or password.');
499 if ( isset($c->dbg['Login']) || isset($c->dbg['ALL']) )
500 $this->cause = 'WARN: Invalid password.';
501 else
502 $this->cause = 'WARN: Invalid username or password.';
503 }
504 }
505 else {
506 $c->messages[] = i18n('Invalid username or password.');
507 if ( isset($c->dbg['Login']) || isset($c->dbg['ALL']) )
508 $this->cause = 'WARN: Invalid username.';
509 else
510 $this->cause = 'WARN: Invalid username or password.';
511 }
512
513 $this->Log( "Login failure: $this->cause" );
514 $this->login_failed = true;
515 $rc = false;
516 return $rc;
517 }
518
519
520
526 function RenderLoginPanel() {
527 $action_target = htmlspecialchars(preg_replace('/\?logout.*$/','',$_SERVER['REQUEST_URI']));
528 dbg_error_log( "Login", " RenderLoginPanel: action_target='%s'", $action_target );
529 $userprompt = translate("User Name");
530 $pwprompt = translate("Password");
531 $gobutton = htmlspecialchars(translate("GO!"));
532 $gotitle = htmlspecialchars(translate("Enter your username and password then click here to log in."));
533 $temppwprompt = translate("If you have forgotten your password then");
534 $temppwbutton = htmlspecialchars(translate("Help! I've forgotten my password!"));
535 $temppwtitle = htmlspecialchars(translate("Enter a username, if you know it, and click here, to be e-mailed a temporary password."));
536 $html = <<<EOTEXT
537<div id="logon">
538<form action="$action_target" method="post">
539<table>
540<tr>
541<th class="prompt">$userprompt:</th>
542<td class="entry">
543<input class="text" type="text" name="username" size="12" /></td>
544</tr>
545<tr>
546<th class="prompt">$pwprompt:</th>
547<td class="entry">
548<input class="password" type="password" name="password" size="12" />
549</td>
550</tr>
551<tr>
552<th class="prompt">&nbsp;</th>
553<td class="entry">
554<input type="submit" value="$gobutton" title="$gotitle" name="submit" class="submit" />
555</td>
556</tr>
557</table>
558<p>
559$temppwprompt: <input type="submit" value="$temppwbutton" title="$temppwtitle" name="lostpass" class="submit" />
560</p>
561</form>
562</div>
563
564EOTEXT;
565 return $html;
566 }
567
568
578 function LoginRequired( $groups = "" ) {
579 global $c, $session, $page_elements;
580
581 if ( $this->logged_in && $groups == "" ) return;
582 if ( ! $this->logged_in ) {
583// $c->messages[] = i18n("You must log in to use this system.");
584 if ( function_exists("local_index_not_logged_in") ) {
585 local_index_not_logged_in();
586 }
587 else {
588 $login_html = translate( "<h1>Log On Please</h1><p>For access to the %s you should log on withthe username and password that have been issued to you.</p><p>If you would like to request access, please e-mail %s.</p>");
589 $page_content = sprintf( $login_html, $c->system_name, $c->admin_email );
590 $page_content .= $this->RenderLoginPanel();
591 if ( isset($page_elements) && gettype($page_elements) == 'array' ) {
592 $page_elements[] = $page_content;
593 @include("page-renderer.php");
594 exit(0);
595 }
596 @include("page-header.php");
597 echo $page_content;
598 @include("page-footer.php");
599 }
600 }
601 else {
602 $valid_groups = explode(",", $groups);
603 foreach( $valid_groups AS $k => $v ) {
604 if ( $this->AllowedTo($v) ) return;
605 }
606 $c->messages[] = i18n("You are not authorised to use this function.");
607 if ( isset($page_elements) && gettype($page_elements) == 'array' ) {
608 @include("page-renderer.php");
609 exit(0);
610 }
611 @include("page-header.php");
612 @include("page-footer.php");
613 }
614
615 exit;
616 }
617
618
619
628 function EmailTemporaryPassword( $username, $email_address, $body_template="" ) {
629 global $c;
630
631 $password_sent = false;
632 $where = "";
633 $params = array();
634 if ( isset($username) && $username != "" ) {
635 $where = 'WHERE active AND lower(usr.username) = :lcusername';
636 $params[':lcusername'] = strtolower($username);
637 }
638 else if ( isset($email_address) && $email_address != "" ) {
639 $where = 'WHERE active AND lower(usr.email) = :lcemail';
640 $params[':lcemail'] = strtolower($email_address);
641 }
642
643 if ( $where != '' ) {
644 if ( !isset($body_template) || $body_template == "" ) {
645 $body_template = <<<EOTEXT
646
647@@debugging@@A temporary password has been requested for @@system_name@@.
648
649Temporary Password: @@password@@
650
651This has been applied to the following usernames:
652
653@@usernames@@
654and will be valid for 24 hours.
655
656If you have any problems, please contact the system administrator.
657
658EOTEXT;
659 }
660
661 $qry = new AwlQuery( 'SELECT * FROM usr '.$where, $params );
662 $qry->Exec('Session::EmailTemporaryPassword');
663 if ( $qry->rows() > 0 ) {
664 $q2 = new AwlQuery();
665 $q2->Begin();
666
667 while ( $row = $qry->Fetch() ) {
668 $mail = new EMail( "Access to $c->system_name" );
669 $mail->SetFrom($c->admin_email );
670 $usernames = "";
671 $debug_to = "";
672 if ( isset($c->debug_email) ) {
673 $debug_to = "This e-mail would normally be sent to:\n ";
674 $mail->AddTo( "Tester <$c->debug_email>" );
675 }
676
677 $tmp_passwd = '';
678 for ( $i=0; $i < 8; $i++ ) {
679 $tmp_passwd .= substr( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ+#.-=*%@0123456789abcdefghijklmnopqrstuvwxyz', rand(0,69), 1);
680 }
681
682 $q2->QDo('INSERT INTO tmp_password (user_no, password) VALUES (?, ?)', array($row->user_no, $tmp_passwd));
683 if ( isset($c->debug_email) ) {
684 $debug_to .= "$row->fullname <$row->email> ";
685 }
686 else {
687 $mail->AddTo( "$row->fullname <$row->email>" );
688 }
689 $usernames .= " $row->username\n";
690
691 if ( $mail->To() != "" ) {
692 if ( isset($c->debug_email) ) {
693 $debug_to .= "\n============================================================\n";
694 }
695 $sql .= "COMMIT;";
696 $qry = new AwlQuery( $sql );
697 $qry->Exec("Session::SendTemporaryPassword");
698 $body = str_replace( '@@system_name@@', $c->system_name, $body_template);
699 $body = str_replace( '@@password@@', $tmp_passwd, $body);
700 $body = str_replace( '@@usernames@@', $usernames, $body);
701 $body = str_replace( '@@debugging@@', $debug_to, $body);
702 $mail->SetBody($body);
703 $mail->Send();
704 $password_sent = true;
705 }
706 }
707 }
708 }
709 return $password_sent;
710 }
711
712
721 global $c, $page_elements;
722
723 $password_sent = $this->EmailTemporaryPassword( (isset($_POST['username'])?$_POST['username']:null), (isset($_POST['email_address'])?$_POST['email_address']:null) );
724
725 if ( ! $password_sent && ((isset($_POST['username']) && $_POST['username'] != "" )
726 || (isset($_POST['email_address']) && $_POST['email_address'] != "" )) ) {
727 // Username or EMail were non-null, but we didn't find that user.
728 $page_content = <<<EOTEXT
729<div id="logon">
730<h1>Unable to Reset Password</h1>
731<p>We were unable to reset your password at this time. Please contact
732<a href="mailto:$c->admin_email">$c->admin_email</a>
733to arrange for an administrator to reset your password.</p>
734<p>Thank you.</p>
735</div>
736EOTEXT;
737 }
738 else if ( $password_sent ) {
739 $page_content = <<<EOTEXT
740<div id="logon">
741<h1>Temporary Password Sent</h1>
742<p>A temporary password has been e-mailed to you. This password
743will be valid for 24 hours and you will be required to change
744your password after logging in.</p>
745<p><a href=".">Click here to return to the login page.</a></p>
746</div>
747EOTEXT;
748 }
749 else {
750 $page_content = <<<EOTEXT
751<div id="logon">
752<h1>Temporary Password</h1>
753<form action="$action_target" method="post">
754<table>
755<tr>
756<th class="prompt" style="white-space: nowrap;">Enter your User Name:</th>
757<td class="entry"><input class="text" type="text" name="username" size="12" /></td>
758</tr>
759<tr>
760<th class="prompt" style="white-space: nowrap;">Or your EMail Address:</th>
761<td class="entry"><input class="text" type="text" name="email_address" size="50" /></td>
762</tr>
763<tr>
764<th class="prompt" style="white-space: nowrap;">and click on -></th>
765<td class="entry">
766<input class="submit" type="submit" value="Send me a temporary password" alt="Enter a username, or e-mail address, and click here." name="lostpass" />
767</td>
768</tr>
769</table>
770<p>Note: If you have multiple accounts with the same e-mail address, they will <em>all</em>
771be assigned a new temporary password, but only the one(s) that you use that temporary password
772on will have the existing password invalidated.</p>
773<h2>The temporary password will only be valid for 24 hours.</h2>
774<p>You will need to log on and change your password during this time.</p>
775</form>
776</div>
777EOTEXT;
778 }
779 if ( isset($page_elements) && gettype($page_elements) == 'array' ) {
780 $page_elements[] = $page_content;
781 @include("page-renderer.php");
782 exit(0);
783 }
784 @include("page-header.php");
785 echo $page_content;
786 @include("page-footer.php");
787 exit(0);
788 }
789
790 static function _CheckLogout() {
791 if ( isset($_GET['logout']) ) {
792 dbg_error_log( "Login", ":_CheckLogout: Logging out");
793 if ( isset($_COOKIE['sid']) ) {
794 // clean up our session in the session table
795 list( $session_id, $session_key ) = explode( ';', $_COOKIE['sid'], 2 );
796 $sql = 'DELETE FROM session WHERE session_id = ? AND session_key = ?';
797 $qry = new AwlQuery( $sql, $session_id, $session_key );
798 $qry->Exec('Logout',__LINE__,__FILE__);
799 // expire sessions older than 16 hours
800 $sql = "DELETE FROM session WHERE session_end < current_timestamp - interval '16 hours'";
801 $qry = new AwlQuery( $sql );
802 $qry->Exec('Expire',__LINE__,__FILE__);
803 }
804 setcookie( 'sid', '', 0,'/');
805 unset($_COOKIE['sid']);
806 unset($GLOBALS['sid']);
807 }
808 }
809
810 function _CheckLogin() {
811 global $c;
812 if ( isset($_POST['lostpass']) ) {
813 dbg_error_log( "Login", ":_CheckLogin: User '$_POST[username]' has lost the password." );
814 $this->SendTemporaryPassword();
815 }
816 else if ( isset($_POST['username']) && isset($_POST['password']) ) {
817 $username = $_POST['username'];
818 // Try and log in if we have a username and password
819 $this->Login( $_POST['username'], $_POST['password'] );
820 @dbg_error_log( "Login", ":_CheckLogin: User %s - %s (%d) login status is %d", $username, $this->fullname, $this->user_no, $this->logged_in );
821 }
822 else if ( !isset($_COOKIE['sid']) && isset($c->authenticate_hook['server_auth_type']) ) {
826 if ( ( is_array($c->authenticate_hook['server_auth_type'])
827 && in_array( strtolower($_SERVER['AUTH_TYPE']), array_map('strtolower', $c->authenticate_hook['server_auth_type'])) )
828 ||
829 ( !is_array($c->authenticate_hook['server_auth_type'])
830 && strtolower($c->authenticate_hook['server_auth_type']) == strtolower($_SERVER['AUTH_TYPE']) )
831 ) {
832 if (isset($_SERVER["REMOTE_USER"]))
833 $this->Login($_SERVER['REMOTE_USER'], "", true); // Password will not be checked.
834 else
835 $this->Login($_SERVER['REDIRECT_REMOTE_USER'], "", true); // Password will not be checked.
836 }
837 }
838 }
839
840
847 function FormattedDate( $indate, $type='date' ) {
848 $out = "";
849 if ( preg_match( '#^\s*$#', $indate ) ) {
850 // Looks like it's empty - just return empty
851 return $indate;
852 }
853 if ( preg_match( '#^\d{1,2}[/-]\d{1,2}[/-]\d{2,4}#', $indate ) ) {
854 // Looks like it's nice already - don't screw with it!
855 return $indate;
856 }
857 $yr = substr($indate,0,4);
858 $mo = substr($indate,5,2);
859 $dy = substr($indate,8,2);
860 switch ( $this->date_format_type ) {
861 case 'U':
862 $out = sprintf( "%d/%d/%d", $mo, $dy, $yr );
863 break;
864 case 'E':
865 $out = sprintf( "%d/%d/%d", $dy, $mo, $yr );
866 break;
867 default:
868 $out = sprintf( "%d-%02d-%02d", $yr, $mo, $dy );
869 break;
870 }
871 if ( $type == 'timestamp' ) {
872 $out .= substr($indate,10,6);
873 }
874 return $out;
875 }
876
877
887 function BuildConfirmationHash( $method, $varname ) {
892 $confirmation_hash = session_salted_md5( $this->session_start.$varname.$this->session_key, "" );
893 if ( $method == 'GET' ) {
894 $confirm = $varname .'='. urlencode($confirmation_hash);
895 }
896 else {
897 $confirm = sprintf( '<input type="hidden" name="%s" value="%s">', $varname, htmlspecialchars($confirmation_hash) );
898 }
899 return $confirm;
900 }
901
902
910 function CheckConfirmationHash( $method, $varname ) {
911 if ( $method == 'GET' && isset($_GET[$varname])) {
912 $hashwegot = $_GET[$varname];
913 dbg_error_log('Session',':CheckConfirmationHash: We got "%s" from GET', $hashwegot );
914 }
915 else if ( isset($_POST[$varname]) ) {
916 $hashwegot = $_POST[$varname];
917 dbg_error_log('Session',':CheckConfirmationHash: We got "%s" from POST', $hashwegot );
918 }
919 else {
920 return false;
921 }
922
923 if ( preg_match('{^\*(.+)\*.+$}i', $hashwegot, $regs ) ) {
924 // A nicely salted md5sum like "*<salt>*<salted_md5>"
925 $salt = $regs[1];
926 dbg_error_log('Session',':CheckConfirmationHash: Salt "%s"', $salt );
927 $test_against = session_salted_md5( $this->session_start.$varname.$this->session_key, $salt ) ;
928 dbg_error_log('Session',':CheckConfirmationHash: Testing against "%s"', $test_against );
929
930 return ($hashwegot == $test_against);
931 }
932 return false;
933 }
934
935}
936
937
943
944if ( !isset($session) ) {
945 Session::_CheckLogout();
946 $session = new Session();
947 $session->_CheckLogin();
948}
949
Login( $username, $password, $authenticated=false)
Definition Session.php:409
__construct( $sid="")
Definition Session.php:234
GetRoles()
Definition Session.php:365
SendTemporaryPassword()
Definition Session.php:720
EmailTemporaryPassword( $username, $email_address, $body_template="")
Definition Session.php:628
AllowedTo( $whatever)
Definition Session.php:357
LoginRequired( $groups="")
Definition Session.php:578
Dbg( $whatever)
Definition Session.php:323
_CheckLogin()
Definition Session.php:810
Log( $whatever)
Definition Session.php:292
AssignSessionDetails( $u)
Definition Session.php:380
RenderLoginPanel()
Definition Session.php:526
Definition User.php:34