Sessions: Improved inactive account UX; shuffled around a bit of code so that whitelist checks are shared; fixed a bunch of bugs related to ban code and IPv6 addresses
authorDan
Fri, 21 Aug 2009 20:41:38 -0400
changeset 1101 30d8bb88572d
parent 1100 aead4e1ce5df
child 1103 90225c988124
child 1111 8fae8fb3cbb1
Sessions: Improved inactive account UX; shuffled around a bit of code so that whitelist checks are shared; fixed a bunch of bugs related to ban code and IPv6 addresses
includes/constants.php
includes/sessions.php
includes/template.php
plugins/SpecialUserFuncs.php
--- a/includes/constants.php	Fri Aug 21 20:37:55 2009 -0400
+++ b/includes/constants.php	Fri Aug 21 20:41:38 2009 -0400
@@ -118,6 +118,7 @@
 
 define('ED_DATE', 1);
 define('ED_TIME', 2);
+define('ED_DATE_FULL', 4);
 
 // Rendering options!
 
--- a/includes/sessions.php	Fri Aug 21 20:37:55 2009 -0400
+++ b/includes/sessions.php	Fri Aug 21 20:41:38 2009 -0400
@@ -426,6 +426,28 @@
     return $result;
   }
   
+  /**
+   * Returns true if we're currently on a page that shouldn't be blocked even if we have an inactive or banned account
+   * @param bool strict - if true, whitelist of pages is even stricter (Login, Logout and CSS only). if false (default), admin access is allowed, assuming other factors allow it
+   * @return bool
+   */
+  
+  function on_critical_page($strict = false)
+  {
+    global $title;
+    list($page_id, $namespace) = RenderMan::strToPageID($title);
+    list($page_id) = explode('/', $page_id);
+    
+    if ( $strict )
+    {
+      return $namespace == 'Special' && in_array($page_id, array('CSS', 'Login', 'Logout'));
+    }
+    else
+    {
+      return $namespace == 'Admin' || ($namespace == 'Special' && in_array($page_id, array('CSS', 'Login', 'Logout', 'Administration')));
+    }
+  }
+  
   # Session restoration and permissions
   
   /**
@@ -452,13 +474,6 @@
       }
       if ( is_array($userdata) )
       {
-        $data = RenderMan::strToPageID($paths->get_pageid_from_url());
-        
-        if(!$this->compat && $userdata['account_active'] != 1 && $data[1] != 'Special' && $data[1] != 'Admin')
-        {
-          $this->show_inactive_error($userdata);
-        }
-        
         $this->sid = $_COOKIE['sid'];
         $this->user_logged_in = true;
         $this->user_id =       intval($userdata['user_id']);
@@ -566,6 +581,12 @@
     // make sure we aren't banned
     $this->check_banlist();
     
+    // make sure the account is active
+    if ( !$this->compat && $this->user_logged_in && $userdata['account_active'] != 1 && !$this->on_critical_page() )
+    {
+      $this->show_inactive_error($userdata);
+    }
+    
     // Printable page view? Probably the wrong place to control
     // it but $template is pretty dumb, it will just about always
     // do what you ask it to do, which isn't always what we want
@@ -1498,6 +1519,9 @@
     global $db, $session, $paths, $template, $plugins; // Common objects
     global $lang;
     
+    global $title;
+    $paths->init($title);
+    
     $language = intval(getConfig('default_language'));
     $lang = new Language($language);
     @setlocale(LC_ALL, $lang->lang_code);
@@ -1563,7 +1587,10 @@
       }
     }
     
-    die_semicritical($lang->get('user_login_noact_title'), '<p>' . $lang->get('user_login_noact_msg_intro') . ' '.$solution.'</p>' . $form);
+    global $output;
+    $output = new Output_HTML();
+    $output->set_title($lang->get('user_login_noact_title'));
+    die_friendly($lang->get('user_login_noact_title'), '<p>' . $lang->get('user_login_noact_msg_intro') . ' '.$solution.'</p>' . $form);
   }
   
   /**
@@ -1779,7 +1806,9 @@
     global $db, $session, $paths, $template, $plugins; // Common objects
     global $lang;
     
-    $col_reason = ( $this->compat ) ? '"No reason entered (session manager is in compatibility mode)" AS reason' : 'reason';
+    $col_reason = ( $this->compat ) ? '\'No reason available (session manager is in compatibility mode)\' AS reason' : 'reason';
+    $remote_addr = ( strstr($_SERVER['REMOTE_ADDR'], ':') ) ? expand_ipv6_address($_SERVER['REMOTE_ADDR']) : $_SERVER['REMOTE_ADDR'];
+    
     $banned = false;
     if ( $this->user_logged_in )
     {
@@ -1819,7 +1848,7 @@
             {
               continue;
             }
-            if ( preg_match("/$regexp/", $_SERVER['REMOTE_ADDR']) )
+            if ( preg_match("/$regexp/", $remote_addr) )
             {
               $reason = $reason_temp;
               $banned = true;
@@ -1862,8 +1891,11 @@
             // check range
             $regexp = parse_ip_range_regex($ban_value);
             if ( !$regexp )
+            {
+              die("bad regexp for $ban_value");
               continue;
-            if ( preg_match("/$regexp/", $_SERVER['REMOTE_ADDR']) )
+            }
+            if ( preg_match("/$regexp/", $remote_addr) )
             {
               $reason = $reason_temp;
               $banned = true;
@@ -1879,7 +1911,7 @@
       }
       $db->free_result();
     }
-    if ( $banned && $paths->get_pageid_from_url() != $paths->nslist['Special'].'CSS' )
+    if ( $banned && !$this->on_critical_page(true) )
     {
       // This guy is banned - kill the session, kill the database connection, bail out, and be pretty about it
       die_semicritical($lang->get('user_ban_msg_title'), '<p>' . $lang->get('user_ban_msg_body') . '</p><div class="error-box"><b>' . $lang->get('user_ban_lbl_reason') . '</b><br />' . $reason . '</div>');
--- a/includes/template.php	Fri Aug 21 20:37:55 2009 -0400
+++ b/includes/template.php	Fri Aug 21 20:41:38 2009 -0400
@@ -1178,7 +1178,7 @@
     
     $this->assign_vars(array(
         'PAGE_NAME' => htmlspecialchars($this->page->ns->cdata['name']),
-        'PAGE_URLNAME' => sanitize_page_id($this->page_id),
+        'PAGE_URLNAME' => $paths->nslist[$this->namespace] . sanitize_page_id($this->page_id),
         'TOOLBAR' => $tb,
         'TOOLBAR_EXTRAS' => $this->toolbar_menu,
         'STYLE_LINK' => makeUrlNS('Special', 'CSS', null, true), //contentPath.$paths->nslist['Special'].'CSS' . $p,
@@ -3015,7 +3015,7 @@
     {
       $js_dynamic .= '<script type="text/javascript" src="install.php?mode=langjs"></script>';
     }
-    $js_dynamic .= '<script type="text/javascript">var title="'. $title .'"; var scriptPath="'.scriptPath.'"; var cdnPath="'.scriptPath.'"; var ENANO_SID=""; var AES_BITS='.AES_BITS.'; var AES_BLOCKSIZE=' . AES_BLOCKSIZE . '; var pagepass=\'\'; var ENANO_LANG_ID = 1;</script>';
+    $js_dynamic .= '<script type="text/javascript">var title="'. $title .'"; var scriptPath="'.scriptPath.'"; var cdnPath="'.scriptPath.'"; var ENANO_SID=""; var AES_BITS='.AES_BITS.'; var AES_BLOCKSIZE=' . AES_BLOCKSIZE . '; var pagepass=\'\'; var ENANO_LANG_ID = 1; var msg_loading_component = \'Loading %component%...\';</script>';
     
     global $site_name, $site_desc;
     $site_default_name = ( !empty($site_name) ) ? $site_name : 'Critical error';
--- a/plugins/SpecialUserFuncs.php	Fri Aug 21 20:37:55 2009 -0400
+++ b/plugins/SpecialUserFuncs.php	Fri Aug 21 20:41:38 2009 -0400
@@ -405,6 +405,10 @@
           echo '<input type="hidden" name="get_fwd" value="' . $get_string . '" />';
         }
       }
+      else if ( isset($_POST['get_fwd']) )
+      {
+        echo '<input type="hidden" name="get_fwd" value="' . htmlspecialchars($_POST['get_fwd']) . '" />';
+      }
       ?>
     </form>
     <?php
@@ -421,6 +425,7 @@
   global $lang;
   require_once( ENANO_ROOT . '/includes/math.php' );
   
+  $paths->fullpage = $GLOBALS['title'];
   if ( $paths->getParam(0) === 'action.json' )
   {
     if ( !isset($_POST['r']) )