phpDocumentor pond
[ class tree: pond ] [ index: pond ] [ all elements ]

Source for file login.php

Documentation is available at login.php

  1. <?php
  2. /**
  3.  * This is the login screen. It also handles actions related to loggin in and registering.
  4.  *
  5.  * This file is part of Quam Plures - {@link http://quamplures.net/}
  6.  * See also {@link https://launchpad.net/quam-plures}.
  7.  *
  8.  * @copyright (c) 2009 - 2011 by the Quam Plures developers - {@link http://quamplures.net/}
  9.  * @copyright (c)2003-2009 by Francois PLANQUE - {@link http://fplanque.net/}
  10.  *  Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
  11.  *
  12.  *  {@internal License choice
  13.  *  - If you have received this file as part of a package, please find the license.txt file in
  14.  *    the same folder or the closest folder above for complete license terms.
  15.  *  - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
  16.  *    then you must choose one of the following licenses before using the file:
  17.  *    - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
  18.  *    - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
  19.  *  }}}
  20.  *
  21.  *  {@internal Open Source relicensing agreement:
  22.  *  Daniel HAHLER grants Francois PLANQUE the right to license
  23.  *  Daniel HAHLER's contributions to this file and the b2evolution project
  24.  *  under any OSI approved OSS license (http://www.opensource.org/licenses/).
  25.  *
  26.  *  Matt FOLLETT grants Francois PLANQUE the right to license
  27.  *  Matt FOLLETT's contributions to this file and the b2evolution project
  28.  *  under any OSI approved OSS license (http://www.opensource.org/licenses/).
  29.  *  }}}
  30.  *
  31.  *  {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  32.  * @author blueyed: Daniel HAHLER
  33.  * @author fplanque: Francois PLANQUE
  34.  * @author mfollett: Matt FOLLETT.
  35.  *
  36.  * @package pond
  37.  */
  38.  
  39. /**
  40.  * Includes:
  41.  */
  42. require_once dirname(__FILE__).'/../qp_config/_config.php';
  43. require_once $inc_path.'_main.inc.php';
  44.  
  45. param'action''string''req_login' );
  46. param'mode''string''' );
  47. param'login''string''' );
  48.  
  49. // gets used by header_redirect();
  50. // TODO: dh> problem here is that $ReqURI won't include the e.g. "ctrl" param in a POSTed form and therefor the user lands on the default admin page after logging in (again)
  51. // fp> I think this will fix itself when we do another improvement: 303 redirect after each POST so that we never have an issue with people trying to reload a post
  52. param'redirect_to''string'$ReqURI );
  53.  
  54. switch$action )
  55. {
  56.     case 'logout':
  57.         logout();          // logout $Session and set $current_User = NULL
  58.  
  59.         // TODO: to give the user feedback through Messages, we would need to start a new $Session here and append $Messages to it.
  60.  
  61.         header_nocache();
  62.         header_redirect()// defaults to redirect_to param and exits
  63.         /* exited */
  64.         break;
  65.  
  66.  
  67.     case 'retrievepassword'// Send passwort change request by mail
  68.         $login_required true// Do not display "Without login.." link on the form
  69.  
  70.         $UserCache get_Cache'UserCache' );
  71.         $ForgetfulUser $UserCache->get_by_login$login );
  72.  
  73.         if$ForgetfulUser )
  74.         // User does not exist
  75.             // pretend that the email is sent for avoiding guessing user_login
  76.             $Messages->addT_('If you correctly typed in your login, a link to change your password has been sent to your registered email address.' )'success' );
  77.             $action 'req_login';
  78.             break;
  79.         }
  80.  
  81.         if$demo_mode && ($ForgetfulUser->ID == 1
  82.             || $ForgetfulUser->login == 'demouser'
  83.             || $ForgetfulUser->login == 'demoblogger'
  84.             || $ForgetfulUser->login == 'demospecial') )
  85.         {
  86.             $Messages->addT_('You cannot reset this account in demo mode.')'error' );
  87.             $action 'req_login';
  88.             break;
  89.         }
  90.  
  91.         locale_temp_switch$ForgetfulUser->locale );
  92.  
  93.         // DEBUG!
  94.         ifempty$ForgetfulUser->email ) )
  95.         {
  96.             $Messages->addT_('You have no email address with your profile, therefore we cannot reset your password.')
  97.                 .' '.T_('Please try contacting the admin.')'error' );
  98.         }
  99.         else
  100.         {
  101.             $request_id generate_random_key(22)// 22 to make it not too long for URL but unique/safe enough
  102.  
  103.             $message T_'Somebody (presumably you) has requested a password change for your account.' )
  104.                 ."\n\n"
  105.                 .T_('Login:')." $login\n"
  106.                 .T_('Link to change your password:')
  107.                 ."\n"
  108.                 .$srvc_url_sensitive.'login.php?action=changepwd'
  109.                     .'&login='.rawurlencode$ForgetfulUser->login )
  110.                     .'&reqID='.$request_id
  111.                     .'&sessID='.$Session->ID  // used to detect cookie problems
  112.                 ."\n\n"
  113.                 .T_('Please note:')
  114.                 .' '.T_('For security reasons the link is only valid for your current session (by means of your session cookie).')
  115.                 ."\n\n"
  116.                 .T_('If it was not you that requested this password change, simply ignore this mail.');
  117.  
  118.             ifsend_mail$ForgetfulUser->emailNULLsprintfT_('Password change request for %s')$ForgetfulUser->login )$message$notify_from ) )
  119.             {
  120.                 $Messages->addT_('Sorry, the email with the link to reset your password could not be sent.')
  121.                     .'<br />'.T_('Possible reason: the PHP mail() function may have been disabled on the server.')'error' );
  122.             }
  123.             else
  124.             {
  125.                 $Session->set'core.changepwd.request_id'$request_id86400 )// expires in two days (or when clicked)
  126.                 $Session->dbsave()// save immediately
  127.  
  128.                 $Messages->addT_('If you correctly typed in your login, a link to change your password has been sent to your registered email address.' )'success' );
  129.             }
  130.         }
  131.  
  132.         locale_restore_previous()// restores previous locale
  133.  
  134.         $action 'req_login';
  135.         break;
  136.  
  137.  
  138.     case 'changepwd'// Clicked "Change password request" link from a mail
  139.         param'reqID''string''' );
  140.         param'sessID''integer''' );
  141.  
  142.         $UserCache get_Cache'UserCache' );
  143.         $ForgetfulUser $UserCache->get_by_login($login);
  144.  
  145.         if$ForgetfulUser || empty($reqID) )
  146.         // This was not requested
  147.             $Messages->addT_('Invalid password change request! Please try again...')'error' );
  148.             $action 'lostpassword';
  149.             $login_required true// Do not display "Without login.." link on the form
  150.             break;
  151.         }
  152.  
  153.         if$sessID != $Session->ID )
  154.         // Another session ID than for requesting password change link used!
  155.             $Messages->addT_('You have to use the same session (by means of your session cookie) as when you have requested the action. Please try again...')'error' );
  156.             $action 'lostpassword';
  157.             $login_required true// Do not display "Without login.." link on the form
  158.             break;
  159.         }
  160.  
  161.         // Validate provided reqID against the one stored in the user's session
  162.         if$Session->get'core.changepwd.request_id' != $reqID )
  163.         {
  164.             $Messages->addT_('Invalid password change request! Please try again...')'error' );
  165.             $action 'lostpassword';
  166.             $login_required true// Do not display "Without login.." link on the form
  167.             break;
  168.         }
  169.  
  170.         // Link User to Session:
  171.         $Session->set_user_ID$ForgetfulUser->ID );
  172.  
  173.         // Add Message to change the password:
  174.         $Messages->addT_'Please change your password to something you remember now.' )'success' );
  175.  
  176.         // Note: the 'core.changepwd.request_id' Session setting gets removed in b2users.php
  177.  
  178.         // Redirect to the user's profile in the "users" controller:
  179.         // TODO: This will probably fail if the user has no admin-access permission! Redirect to profile page in blog instead!?
  180.         header_nocache();
  181.         // redirect Will save $Messages into Session:
  182.         header_redirecturl_add_param$admin_url'ctrl=users&user_ID='.$ForgetfulUser->ID'&' ) )// display user's profile
  183.         /* exited */
  184.         break;
  185.  
  186.  
  187.     case 'validatemail'// Clicked "Validate email" link from a mail
  188.         param'reqID''string''' );
  189.         param'sessID''integer''' );
  190.  
  191.         ifis_logged_in(&& $current_User->validated )
  192.         // Already validated, e.g. clicked on an obsolete email link:
  193.             $Messages->addT_('Your account has already been validated.')'note' );
  194.             // no break: cleanup & redirect below
  195.         }
  196.         else
  197.         {
  198.             // Check valid format:
  199.             ifempty($reqID) )
  200.             // This was not requested
  201.                 $Messages->addT_('Invalid email address validation request!')'error' );
  202.                 $action 'req_validatemail';
  203.                 break;
  204.             }
  205.  
  206.             // Check valid session (format only, meant as help for the user):
  207.             if$sessID != $Session->ID )
  208.             // Another session ID than for requesting account validation link used!
  209.                 $Messages->addT_('You have to use the same session (by means of your session cookie) as when you have requested the action. Please try again...')'error' );
  210.                 $action 'req_validatemail';
  211.                 break;
  212.             }
  213.  
  214.             // Validate provided reqID against the one stored in the user's session
  215.             $request_ids $Session->get'core.validatemail.request_ids' );
  216.             if( ( is_array($request_ids|| in_array$reqID$request_ids ) )
  217.                 && isset($current_User&& $current_User->group_ID == && $reqID == /* admin users can validate themselves by a button click */ ) )
  218.             {
  219.                 $Messages->addT_('Invalid email address validation request!')'error' );
  220.                 $action 'req_validatemail';
  221.                 $login_required true// Do not display "Without login.." link on the form
  222.                 break;
  223.             }
  224.  
  225.             ifis_logged_in() )
  226.             // this can happen, if a new user registers and clicks on the "validate by email" link, without logging in first
  227.                 // Note: we reuse $reqID and $sessID in the form to come back here.
  228.  
  229.                 $Messages->addT_('Please login to validate your account.')'error' );
  230.                 break;
  231.             }
  232.  
  233.             // Validate user:
  234.  
  235.             $current_User->set'validated');
  236.             $current_User->dbupdate();
  237.  
  238.             $Messages->addT_'Your email address has been validated.' )'success' );
  239.         }
  240.  
  241.         $redirect_to $Session->get'core.validatemail.redirect_to' );
  242.  
  243.         ifempty($redirect_to&& $current_User->check_perm('admin') )
  244.         // User can access backoffice
  245.             $redirect_to $admin_url;
  246.         }
  247.  
  248.         // Cleanup:
  249.         $Session->delete('core.validatemail.request_ids');
  250.         $Session->delete('core.validatemail.redirect_to');
  251.  
  252.         header_nocache();
  253.         // redirect Will save $Messages into Session:
  254.         header_redirect();
  255.         /* exited */
  256.         break;
  257.  
  258. // switch( $action ) (1st)
  259.  
  260.  
  261.  
  262. /* For actions that other delegate to from the switch above: */
  263. switch$action )
  264. {
  265.     case 'req_validatemail'// Send email validation link by mail (initial form and action)
  266.         ifis_logged_in() )
  267.         {
  268.             $Messages->addT_('You have to be logged in to request an account validation link.')'error' );
  269.             $action '';
  270.             break;
  271.         }
  272.  
  273.         if$current_User->validated || $Settings->get('newusers_mustvalidate') )
  274.         // validating emails is not activated/necessary (check this after login, so it gets not "announced")
  275.             $action '';
  276.             break;
  277.         }
  278.  
  279.         param'req_validatemail_submit''integer')// has the form been submitted
  280.         param'email''string'$current_User->email )// the email address is editable
  281.  
  282.         if$req_validatemail_submit )
  283.         // Form has been submitted
  284.             param_check_email'email'true );
  285.  
  286.             // Call plugin event to allow catching input in general and validating own things from DisplayRegisterFormFieldset event
  287.             $Plugins->trigger_event'ValidateAccountFormSent' );
  288.  
  289.             if$Messages->count('error') )
  290.             {
  291.                 break;
  292.             }
  293.  
  294.             // Update user's email:
  295.             $current_User->set_email$email );
  296.             if$current_User->dbupdate() )
  297.             {
  298.                 $Messages->addT_('Your profile has been updated.')'note' );
  299.             }
  300.  
  301.             if$current_User->send_validate_email($redirect_to) )
  302.             {
  303.                 $Messages->addsprintf/* TRANS: %s gets replaced by the user's email address */ T_('An email has been sent to your email address (%s). Please click on the link therein to validate your account.')$current_User->dget('email') )'success' );
  304.             }
  305.             else
  306.             {
  307.                 $Messages->addT_('Sorry, the email with the link to validate and activate your password could not be sent.')
  308.                             .'<br />'.T_('Possible reason: the PHP mail() function may have been disabled on the server.')'error' );
  309.             }
  310.         }
  311.         else
  312.         // Form not yet submitted:
  313.             // Add a note, if we have already sent validation links:
  314.             $request_ids $Session->get'core.validatemail.request_ids' );
  315.             ifis_array($request_ids&& count($request_ids) )
  316.             {
  317.                 $Messages->addsprintfT_('We have already sent you %d email(s) with a validation link.')count($request_ids) )'note' );
  318.             }
  319.  
  320.             ifempty($current_User->email) )
  321.             // add (error) note to be displayed in the form
  322.                 $Messages->addT_('You have no email address with your profile, therefore we cannot validate it. Please give your email address below.')'error' );
  323.             }
  324.         }
  325.         break;
  326. }
  327.  
  328.  
  329. ifdefined'QP_MAIN_INIT' ) )
  330. {    // Do not check this if the form was included inside of _main.inc
  331.     if$ReqHost.$ReqPath != $srvc_url_sensitive.'login.php' )
  332.     {
  333.         $Messages->addsprintfT_('WARNING: you are trying to log in on <strong>%s</strong> but we expect you to log in on <strong>%s</strong>. If this is due to an automatic redirect, this will prevent you from successfully loging in. You must either fix your webserver configuration, or your %s configuration in order for these two URLs to match.')$ReqHost.$ReqPath$srvc_url_sensitive.'login.php'$app_name )'error' );
  334.     }
  335. }
  336.  
  337.  
  338. // Test if cookie_domain matches the URL where we want to redirect to:
  339. ifstrlen($redirect_to) )
  340. {
  341.     // Make it relative to the form's target, in case it has been set absolute (and can be made relative).
  342.     // Just in case it gets sent absolute. This should not trigger this warning then..!
  343.     $redirect_to url_rel_to_same_host($redirect_to$srvc_url_sensitive);
  344.  
  345.     $cookie_domain_match false;
  346.     if$redirect_to[0== '/' )
  347.     // relative => ok
  348.         $cookie_domain_match true;
  349.     }
  350.     else
  351.     {
  352.         $parsed_redirect_to @parse_url($redirect_to);
  353.         ifisset($parsed_redirect_to['host']) )
  354.         {
  355.             if$cookie_domain == $parsed_redirect_to['host')
  356.             {
  357.                 $cookie_domain_match true;
  358.             }
  359.             elseif$cookie_domain[0== '.'
  360.                 && substr($cookie_domain,1== substr($parsed_redirect_to['host']1-strlen($cookie_domain)) )
  361.             // cookie domain includes subdomains and matches the last part of where we want to redirect to
  362.                 $cookie_domain_match true;
  363.             }
  364.         }
  365.         else
  366.         {
  367.             $cookie_domain_match preg_match'#^https?://[a-z\-.]*'.str_replace'.''\.'$cookie_domain ).'#i'$redirect_to );
  368.         }
  369.     }
  370.     if$cookie_domain_match )
  371.     {
  372.         $Messages->addsprintfT_('WARNING: you are trying to log in to <strong>%s</strong> but your cookie domain is <strong>%s</strong>. You will not be able to successfully log in to the requested domain until you fix your cookie domain in your %s configuration.')$redirect_to$cookie_domain$app_name )'error' );
  373.     }
  374. }
  375.  
  376.  
  377. ifpreg_match'#/login.php([&?].*)?$#'$redirect_to ) )
  378. // avoid "endless loops"
  379.     $redirect_to $admin_url;
  380. }
  381.  
  382. // Remove login and pwd parameters from URL, so that they do not trigger the login screen again:
  383. $redirect_to preg_replace'~(?<=\?|&) (login|pwd) = [^&]+ ~x'''$redirect_to );
  384. $Debuglog->add'redirect_to: '.$redirect_to );
  385.  
  386.  
  387. /**
  388.  * Display:
  389.  */
  390. switch$action )
  391. {
  392.     case 'lostpassword':
  393.         // Lost password:
  394.         // Display retrieval form:
  395.         require $admintemplates_path.'login/_lostpass_form.main.php';
  396.         break;
  397.  
  398.     case 'req_validatemail':
  399.         // Send email validation link by mail (initial form and action)
  400.         // Display validation form:
  401.         require $admintemplates_path.'login/_validate_form.main.php';
  402.         break;
  403.  
  404.     default:
  405.         // Display login form
  406.         require $admintemplates_path.'login/_login_form.main.php';
  407. }
  408.  
  409. exit(0);
  410.  
  411.  
  412. ?>