includes/sessions.php
changeset 554 e87390b1f9b0
parent 542 5841df0ab575
child 555 ac4c6a7f01d8
equal deleted inserted replaced
553:7c7f08825cad 554:e87390b1f9b0
   167    * State variable to track if a session timed out
   167    * State variable to track if a session timed out
   168    * @var bool
   168    * @var bool
   169    */
   169    */
   170   
   170   
   171   var $sw_timed_out = false;
   171   var $sw_timed_out = false;
       
   172   
       
   173   /**
       
   174    * Token appended to some important forms to prevent CSRF.
       
   175    * @var string
       
   176    */
       
   177   
       
   178   var $csrf_token = false;
   172   
   179   
   173   /**
   180   /**
   174    * Switch to track if we're started or not.
   181    * Switch to track if we're started or not.
   175    * @access private
   182    * @access private
   176    * @var bool
   183    * @var bool
   495           $this->style =         $userdata['style'];
   502           $this->style =         $userdata['style'];
   496           $this->signature =     $userdata['signature'];
   503           $this->signature =     $userdata['signature'];
   497           $this->reg_time =      $userdata['reg_time'];
   504           $this->reg_time =      $userdata['reg_time'];
   498         }
   505         }
   499         $this->auth_level =    USER_LEVEL_MEMBER;
   506         $this->auth_level =    USER_LEVEL_MEMBER;
       
   507         // generate an anti-CSRF token
       
   508         $this->csrf_token =    sha1($this->username . $this->sid . $this->user_id);
   500         if(!isset($template->named_theme_list[$this->theme]))
   509         if(!isset($template->named_theme_list[$this->theme]))
   501         {
   510         {
   502           if($this->compat || !is_object($template))
   511           if($this->compat || !is_object($template))
   503           {
   512           {
   504             $this->theme = 'oxygen';
   513             $this->theme = 'oxygen';
  1070       );
  1079       );
  1071     }
  1080     }
  1072   }
  1081   }
  1073   
  1082   
  1074   /**
  1083   /**
  1075    * Attempts to log in using the old table structure and algorithm.
  1084    * Attempts to log in using the old table structure and algorithm. This is for upgrades from old 1.0.x releases.
  1076    * @param string $username
  1085    * @param string $username
  1077    * @param string $password This should be an MD5 hash
  1086    * @param string $password This should be an MD5 hash
  1078    * @return string 'success' if successful, or error message on failure
  1087    * @return string 'success' if successful, or error message on failure
  1079    */
  1088    */
  1080   
  1089   
  2741     
  2750     
  2742     $objcache[$namespace][$page_id] = new Session_ACLPageInfo( $page_id, $namespace, $this->acl_types, $this->acl_descs, $this->acl_deps, $this->acl_base_cache );
  2751     $objcache[$namespace][$page_id] = new Session_ACLPageInfo( $page_id, $namespace, $this->acl_types, $this->acl_descs, $this->acl_deps, $this->acl_base_cache );
  2743     $object =& $objcache[$namespace][$page_id];
  2752     $object =& $objcache[$namespace][$page_id];
  2744     
  2753     
  2745     return $object;
  2754     return $object;
  2746     
  2755   }
       
  2756   
       
  2757   /**
       
  2758    * Fetch the permissions that apply to an arbitrary user for the page specified. The object you get will have the get_permissions method
       
  2759    * and several other abilities.
       
  2760    * @param int|string $user_id_or_name; user ID *or* username of the user
       
  2761    * @param string $page_id; if null, will be default effective permissions. 
       
  2762    * @param string $namespace; if null, will be default effective permissions.
       
  2763    * @return object
       
  2764    */
       
  2765   
       
  2766   function fetch_page_acl_user($user_id_or_name, $page_id, $namespace)
       
  2767   {
       
  2768     global $db, $session, $paths, $template, $plugins; // Common objects
       
  2769     
       
  2770     // cache user info
       
  2771     static $user_info_cache = null;
       
  2772     
       
  2773     if ( isset($user_info_cache[$user_id_or_name]) )
       
  2774     {
       
  2775       $user_id =& $user_info_cache[$user_id_or_name]['user_id'];
       
  2776       $groups =& $user_info_cache[$user_id_or_name]['groups'];
       
  2777     }
       
  2778     else
       
  2779     {
       
  2780       $uid_column = ( is_int($user_id_or_name) ) ? "user_id = $user_id_or_name" : "username = '" . $db->escape($user_id_or_name) . "'";
       
  2781       $q = $db->sql_query('SELECT u.user_id, m.group_id, g.group_name FROM ' . table_prefix . "users AS u\n"
       
  2782                         . "  LEFT JOIN " . table_prefix . "group_members AS m\n"
       
  2783                         . "    ON ( ( u.user_id = m.user_id AND m.pending = 0 ) OR m.member_id IS NULL )\n"
       
  2784                         . "  LEFT JOIN " . table_prefix . "groups AS g\n"
       
  2785                         . "    ON ( g.group_id = m.group_id )\n"
       
  2786                         . "  WHERE $uid_column;");
       
  2787       if ( !$q )
       
  2788         $db->_die();
       
  2789       
       
  2790       $groups = array();
       
  2791       
       
  2792       if ( $row = $db->fetchrow() )
       
  2793       {
       
  2794         $user_id = intval($row['user_id']);
       
  2795         if ( $row['group_id'] )
       
  2796         {
       
  2797           do
       
  2798           {
       
  2799             $groups[ intval($row['group_id'] ) ] = $row['group_name'];
       
  2800           }
       
  2801           while ( $row = $db->fetchrow() );
       
  2802         }
       
  2803         $db->free_result();
       
  2804       }
       
  2805       else
       
  2806       {
       
  2807         $db->free_result();
       
  2808         throw new Exception('Unknown user ID or username');
       
  2809       }
       
  2810       
       
  2811       $user_info_cache[$user_id_or_name] = array(
       
  2812           'user_id' => $user_id,
       
  2813           'groups' => $groups
       
  2814         );
       
  2815     }
       
  2816     
       
  2817     // cache base permissions
       
  2818     static $base_cache = array();
       
  2819     if ( !isset($base_cache[$user_id_or_name]) )
       
  2820     {
       
  2821       $base_cache[$user_id_or_name] = $this->acl_types;
       
  2822       $current_perms =& $base_cache[$user_id_or_name];
       
  2823       $current_perms['__resolve_table'] = array();
       
  2824       
       
  2825       $bs = 'SELECT rules, target_type, target_id, rule_id, page_id, namespace FROM '.table_prefix.'acl' . "\n"
       
  2826              . '  WHERE page_id IS NULL AND namespace IS NULL AND' . "\n"
       
  2827              . '  ( ';
       
  2828     
       
  2829       $q = Array();
       
  2830       $q[] = '( target_type='.ACL_TYPE_USER.' AND target_id= ' . $user_id . ' )';
       
  2831       if(count($groups) > 0)
       
  2832       {
       
  2833         foreach($groups as $g_id => $g_name)
       
  2834         {
       
  2835           $q[] = '( target_type='.ACL_TYPE_GROUP.' AND target_id='.intval($g_id).' )';
       
  2836         }
       
  2837       }
       
  2838       $bs .= implode(" OR \n    ", $q) . " ) \n  ORDER BY target_type ASC, target_id ASC;";
       
  2839       $q = $this->sql($bs);
       
  2840       foreach ( $this->acl_types as $perm_type => $_ )
       
  2841       {
       
  2842         // init the resolver table with blanks
       
  2843         $current_perms['__resolve_table'][$perm_type] = array(
       
  2844             'src' => ACL_INHERIT_GLOBAL_EVERYONE,
       
  2845             'rule_id' => -1
       
  2846           );
       
  2847       }
       
  2848       if ( $row = $db->fetchrow() )
       
  2849       {
       
  2850         do {
       
  2851           $rules = $this->string_to_perm($row['rules']);
       
  2852           $is_everyone = ( $row['target_type'] == ACL_TYPE_GROUP && $row['target_id'] == 1 );
       
  2853           // track where these rulings are coming from
       
  2854           $src = ( $is_everyone ) ? ACL_INHERIT_GLOBAL_EVERYONE : ( $row['target_type'] == ACL_TYPE_GROUP ? ACL_INHERIT_GLOBAL_GROUP : ACL_INHERIT_GLOBAL_USER );
       
  2855           foreach ( $rules as $perm_type => $_ )
       
  2856           {
       
  2857             $current_perms['__resolve_table'][$perm_type] = array(
       
  2858                 'src' => $src,
       
  2859                 'rule_id' => $row['rule_id']
       
  2860               );
       
  2861           }
       
  2862           // merge it in
       
  2863           $current_perms = $this->acl_merge($current_perms, $rules, $is_everyone, $_defaults_used);
       
  2864         } while ( $row = $db->fetchrow() );
       
  2865       }
       
  2866     }
       
  2867     
       
  2868     // cache of permission objects (to save RAM and SQL queries)
       
  2869     static $objcache = array();
       
  2870     
       
  2871     if ( count($objcache) == 0 )
       
  2872     {
       
  2873       foreach ( $paths->nslist as $key => $_ )
       
  2874       {
       
  2875         $objcache[$key] = array();
       
  2876       }
       
  2877     }
       
  2878     
       
  2879     if ( !isset($objcache[$namespace][$page_id]) )
       
  2880     {
       
  2881       $objcache[$namespace][$page_id] = array();
       
  2882     }
       
  2883     
       
  2884     if ( isset($objcache[$namespace][$page_id][$user_id_or_name]) )
       
  2885     {
       
  2886       return $objcache[$namespace][$page_id][$user_id_or_name];
       
  2887     }
       
  2888     
       
  2889     //if ( !isset( $paths->pages[$paths->nslist[$namespace] . $page_id] ) )
       
  2890     //{
       
  2891     //  // Page does not exist
       
  2892     //  return false;
       
  2893     //}
       
  2894     
       
  2895     $objcache[$namespace][$page_id][$user_id_or_name] = new Session_ACLPageInfo(
       
  2896       $page_id,                                        // $page_id, 
       
  2897       $namespace,                                      // $namespace,
       
  2898       $this->acl_types,                                // $acl_types,
       
  2899       $this->acl_descs,                                // $acl_descs,
       
  2900       $this->acl_deps,                                 // $acl_deps,
       
  2901       $base_cache[$user_id_or_name],                   // $base,
       
  2902       $user_info_cache[$user_id_or_name]['user_id'],   // $user_id = null,
       
  2903       $user_info_cache[$user_id_or_name]['groups'],    // $groups = null,
       
  2904       $base_cache[$user_id_or_name]['__resolve_table'] // $resolve_table = array()
       
  2905     );
       
  2906     $object =& $objcache[$namespace][$page_id][$user_id_or_name];
       
  2907     
       
  2908     return $object;
  2747   }
  2909   }
  2748   
  2910   
  2749   /**
  2911   /**
  2750    * Read all of our permissions from the database and process/apply them. This should be called after the page is determined.
  2912    * Read all of our permissions from the database and process/apply them. This should be called after the page is determined.
  2751    * @access private
  2913    * @access private
  2896   
  3058   
  2897   /**
  3059   /**
  2898    * Merges two ACL arrays. Both parameters should be permission list arrays. The second group takes precedence over the first, but AUTH_DENY always prevails.
  3060    * Merges two ACL arrays. Both parameters should be permission list arrays. The second group takes precedence over the first, but AUTH_DENY always prevails.
  2899    * @param array $perm1 The first set of permissions
  3061    * @param array $perm1 The first set of permissions
  2900    * @param array $perm2 The second set of permissions
  3062    * @param array $perm2 The second set of permissions
       
  3063    * @param bool $is_everyone If true, applies exceptions for "Everyone" group
       
  3064    * @param array|reference $defaults_used Array that will be filled with default usage data
  2901    * @return array
  3065    * @return array
  2902    */
  3066    */
  2903    
  3067    
  2904   function acl_merge($perm1, $perm2)
  3068   function acl_merge($perm1, $perm2, $is_everyone = false, &$defaults_used)
  2905   {
  3069   {
  2906     $ret = $perm1;
  3070     $ret = $perm1;
  2907     foreach ( $perm2 as $type => $level )
  3071     if ( !is_array(@$defaults_used) )
  2908     {
  3072     {
  2909       if ( isset( $ret[$type] ) )
  3073       $defaults_used = array();
  2910       {
  3074     }
  2911         if ( $ret[$type] != AUTH_DENY )
  3075     foreach ( $perm1 as $i => $p )
  2912           $ret[$type] = $level;
  3076     {
  2913       }
  3077       if ( isset($perm2[$i]) )
  2914       // else
  3078       {
  2915       // {
  3079         if ( $is_everyone && !$defaults_used[$i] )
  2916       //   $ret[$type] = $level;
       
  2917       // }
       
  2918     }
       
  2919     return $ret;
       
  2920   }
       
  2921   
       
  2922   /**
       
  2923    * Merges two ACL arrays, but instead of calculating inheritance for missing permission types, just returns 'i' for that type. Useful
       
  2924    * for explicitly requiring inheritance in ACL editing interfaces
       
  2925    * @param array $perm1 The first set of permissions
       
  2926    * @param array $perm2 The second, authoritative set of permissions
       
  2927    */
       
  2928   
       
  2929   function acl_merge_inherit($perm1, $perm2)
       
  2930   {
       
  2931     foreach ( $perm1 as $type => $level )
       
  2932     {
       
  2933       $perm1[$type][$level] = 'i';
       
  2934     }
       
  2935     $ret = $perm1;
       
  2936     foreach ( $perm2 as $type => $level )
       
  2937     {
       
  2938       if ( isset( $ret[$type] ) )
       
  2939       {
       
  2940         if ( $ret[$type] != AUTH_DENY )
       
  2941           $ret[$type] = $level;
       
  2942       }
       
  2943     }
       
  2944     return $ret;
       
  2945   }
       
  2946   
       
  2947   /**
       
  2948    * Merges the ACL array sent with the current permissions table, deciding precedence based on whether defaults are in effect or not.
       
  2949    * @param array The array to merge into the master ACL list
       
  2950    * @param bool If true, $perm is treated as the "new default"
       
  2951    * @param int 1 if this is a site-wide ACL, 2 if page-specific. Defaults to 2.
       
  2952    */
       
  2953   
       
  2954   function acl_merge_with_current($perm, $is_everyone = false, $scope = 2)
       
  2955   {
       
  2956     foreach ( $this->perms as $i => $p )
       
  2957     {
       
  2958       if ( isset($perm[$i]) )
       
  2959       {
       
  2960         if ( $is_everyone && !$this->acl_defaults_used[$i] )
       
  2961           continue;
  3080           continue;
  2962         // Decide precedence
  3081         // Decide precedence
  2963         if ( isset($this->acl_defaults_used[$i]) )
  3082         if ( isset($defaults_used[$i]) )
  2964         {
  3083         {
  2965           // echo "$i: default in use, overriding to: {$perm[$i]}<br />";
  3084           // echo "$i: default in use, overriding to: {$perm2[$i]}<br />";
  2966           // Defaults are in use, override
  3085           // Defaults are in use, override
  2967           
  3086           
  2968           // CHANGED - 1.1.4:
  3087           // CHANGED - 1.1.4:
  2969           // For some time this has been intentionally relaxed so that the following
  3088           // For some time this has been intentionally relaxed so that the following
  2970           // exception is available to Deny permissions:
  3089           // exception is available to Deny permissions:
  2971           //   If the rule applies to the group "Everyone" on the entire site,
  3090           //   If the rule applies to the group "Everyone" on the entire site,
  2972           //   Deny settings could be overriden.
  3091           //   Deny settings could be overriden.
  2973           // This is documented at: http://docs.enanocms.org/Help:4.2
  3092           // This is documented at: http://docs.enanocms.org/Help:4.2
  2974           if ( $this->perms[$i] != AUTH_DENY )
  3093           if ( $perm1[$i] != AUTH_DENY )
  2975           {
  3094           {
  2976             $this->perms[$i] = $perm[$i];
  3095             $perm1[$i] = $perm2[$i];
  2977             $this->acl_defaults_used[$i] = ( $is_everyone );
  3096             $defaults_used[$i] = ( $is_everyone );
  2978           }
  3097           }
  2979         }
  3098         }
  2980         else
  3099         else
  2981         {
  3100         {
  2982           // echo "$i: default NOT in use";
  3101           // echo "$i: default NOT in use";
  2983           // Defaults are not in use, merge as normal
  3102           // Defaults are not in use, merge as normal
  2984           if ( $this->perms[$i] != AUTH_DENY )
  3103           if ( $perm1[$i] != AUTH_DENY )
  2985           {
  3104           {
  2986             // echo ", but overriding";
  3105             // echo ", but overriding";
  2987             $this->perms[$i] = $perm[$i];
  3106             $perm1[$i] = $perm2[$i];
  2988           }
  3107           }
  2989           // echo "<br />";
  3108           // echo "<br />";
  2990         }
  3109         }
  2991       }
  3110       }
  2992     }
  3111     }
       
  3112     return $perm1;
       
  3113   }
       
  3114   
       
  3115   /**
       
  3116    * Merges two ACL arrays, but instead of calculating inheritance for missing permission types, just returns 'i' for that type. Useful
       
  3117    * for explicitly requiring inheritance in ACL editing interfaces
       
  3118    * @param array $perm1 The first set of permissions
       
  3119    * @param array $perm2 The second, authoritative set of permissions
       
  3120    */
       
  3121   
       
  3122   function acl_merge_inherit($perm1, $perm2)
       
  3123   {
       
  3124     foreach ( $perm1 as $type => $level )
       
  3125     {
       
  3126       $perm1[$type][$level] = 'i';
       
  3127     }
       
  3128     $ret = $perm1;
       
  3129     foreach ( $perm2 as $type => $level )
       
  3130     {
       
  3131       if ( isset( $ret[$type] ) )
       
  3132       {
       
  3133         if ( $ret[$type] != AUTH_DENY )
       
  3134           $ret[$type] = $level;
       
  3135       }
       
  3136     }
       
  3137     return $ret;
       
  3138   }
       
  3139   
       
  3140   /**
       
  3141    * Merges the ACL array sent with the current permissions table, deciding precedence based on whether defaults are in effect or not.
       
  3142    * @param array The array to merge into the master ACL list
       
  3143    * @param bool If true, $perm is treated as the "new default"
       
  3144    * @param int 1 if this is a site-wide ACL, 2 if page-specific. Defaults to 2.
       
  3145    */
       
  3146   
       
  3147   function acl_merge_with_current($perm, $is_everyone = false, $scope = 2)
       
  3148   {
       
  3149     $this->perms = $this->acl_merge($this->perms, $perm, $is_everyone, $this->acl_defaults_used);
  2993   }
  3150   }
  2994   
  3151   
  2995   /**
  3152   /**
  2996    * Merges two ACL arrays. Both parameters should be permission list arrays. The second group takes precedence
  3153    * Merges two ACL arrays. Both parameters should be permission list arrays. The second group takes precedence
  2997    * over the first, without exceptions. This is used to merge the hardcoded defaults with admin-specified
  3154    * over the first, without exceptions. This is used to merge the hardcoded defaults with admin-specified
  3656    */
  3813    */
  3657   
  3814   
  3658   var $wiki_mode = false;
  3815   var $wiki_mode = false;
  3659   
  3816   
  3660   /**
  3817   /**
       
  3818    * Tracks where permissions were calculated using the ACL_INHERIT_* constants. Layout:
       
  3819    * array(
       
  3820    *   [permission_name] => array(
       
  3821    *       [src] => ACL_INHERIT_*
       
  3822    *       [rule_id] => integer
       
  3823    *     ),
       
  3824    *   ...
       
  3825    * )
       
  3826    *
       
  3827    * @var array
       
  3828    */
       
  3829   
       
  3830   var $perm_resolve_table = array();
       
  3831   
       
  3832   #
       
  3833   # USER PARAMETERS
       
  3834   #
       
  3835   
       
  3836   /**
       
  3837    * User ID
       
  3838    * @var int
       
  3839    */
       
  3840   
       
  3841   var $user_id = 1;
       
  3842   
       
  3843   /**
       
  3844    * Group membership associative array (group_id => group_name)
       
  3845    * @var array
       
  3846    */
       
  3847   
       
  3848   var $groups = array();
       
  3849   
       
  3850   /**
  3661    * Constructor.
  3851    * Constructor.
  3662    * @param string $page_id The ID of the page to check
  3852    * @param string $page_id The ID of the page to check
  3663    * @param string $namespace The namespace of the page to check.
  3853    * @param string $namespace The namespace of the page to check.
  3664    * @param array $acl_types List of ACL types
  3854    * @param array $acl_types List of ACL types
  3665    * @param array $acl_descs List of human-readable descriptions for permissions (associative)
  3855    * @param array $acl_descs List of human-readable descriptions for permissions (associative)
  3666    * @param array $acl_deps List of dependencies for permissions. For example, viewing history/diffs depends on the ability to read the page.
  3856    * @param array $acl_deps List of dependencies for permissions. For example, viewing history/diffs depends on the ability to read the page.
  3667    * @param array $base What to start with - this is an attempt to reduce the number of SQL queries.
  3857    * @param array $base What to start with - this is an attempt to reduce the number of SQL queries.
  3668    */
  3858    * @param int|string $user_id_or_name Username or ID to search for, defaults to current user
  3669    
  3859    * @param array $resolve_table Debugging info for tracking where rules came from, defaults to a blank array.
  3670   function Session_ACLPageInfo($page_id, $namespace, $acl_types, $acl_descs, $acl_deps, $base)
  3860    */
       
  3861    
       
  3862   function __construct($page_id, $namespace, $acl_types, $acl_descs, $acl_deps, $base, $user_id = null, $groups = null, $resolve_table = array())
  3671   {
  3863   {
  3672     global $db, $session, $paths, $template, $plugins; // Common objects
  3864     global $db, $session, $paths, $template, $plugins; // Common objects
       
  3865     
       
  3866     // hack
       
  3867     if ( isset($base['__resolve_table']) )
       
  3868     {
       
  3869       unset($base['__resolve_table']);
       
  3870     }
  3673     
  3871     
  3674     $this->acl_deps = $acl_deps;
  3872     $this->acl_deps = $acl_deps;
  3675     $this->acl_types = $acl_types;
  3873     $this->acl_types = $acl_types;
  3676     $this->acl_descs = $acl_descs;
  3874     $this->acl_descs = $acl_descs;
  3677     
  3875     
  3678     $this->perms = $acl_types;
  3876     $this->perms = $acl_types;
  3679     $this->perms = $session->acl_merge_complete($this->perms, $base);
  3877     $this->perms = $session->acl_merge_complete($this->perms, $base);
       
  3878     
       
  3879     $this->perm_resolve_table = array();
       
  3880     if ( is_array($resolve_table) )
       
  3881       $this->perm_resolve_table = $resolve_table;
       
  3882     
       
  3883     if ( is_int($user_id) && is_array($groups) )
       
  3884     {
       
  3885       $this->user_id = $user_id;
       
  3886       $this->groups = $groups;
       
  3887     }
       
  3888     else
       
  3889     {
       
  3890       $this->user_id = $session->user_id;
       
  3891       $this->groups = $session->groups;
       
  3892     }
       
  3893     
       
  3894     $this->page_id = $page_id;
       
  3895     $this->namespace = $namespace;
       
  3896     
       
  3897     $this->__calculate();
       
  3898   }
       
  3899   
       
  3900   /**
       
  3901    * Performs the actual permission calculation.
       
  3902    * @access private
       
  3903    */
       
  3904   
       
  3905   private function __calculate()
       
  3906   {
       
  3907     global $db, $session, $paths, $template, $plugins; // Common objects
       
  3908     
       
  3909     $page_id =& $this->page_id;
       
  3910     $namespace =& $this->namespace;
  3680     
  3911     
  3681     // PAGE group info
  3912     // PAGE group info
  3682     $pg_list = $paths->get_page_groups($page_id, $namespace);
  3913     $pg_list = $paths->get_page_groups($page_id, $namespace);
  3683     $pg_info = '';
  3914     $pg_info = '';
  3684     foreach ( $pg_list as $g_id )
  3915     foreach ( $pg_list as $g_id )
  3685     {
  3916     {
  3686       $pg_info .= ' ( page_id=\'' . $g_id . '\' AND namespace=\'__PageGroup\' ) OR';
  3917       $pg_info .= ' ( page_id=\'' . $g_id . '\' AND namespace=\'__PageGroup\' ) OR';
  3687     }
  3918     }
  3688     
  3919     
  3689     // Build a query to grab ACL info
  3920     // Build a query to grab ACL info
  3690     $bs = 'SELECT rules,target_type,target_id FROM '.table_prefix.'acl WHERE ' . "\n"
  3921     $bs = 'SELECT rules,target_type,target_id,page_id,namespace,rule_id FROM '.table_prefix.'acl WHERE ' . "\n"
  3691           . '  ( ';
  3922           . '  ( ';
  3692     $q = Array();
  3923     $q = Array();
  3693     $q[] = '( target_type='.ACL_TYPE_USER.' AND target_id='.$session->user_id.' )';
  3924     $q[] = '( target_type='.ACL_TYPE_USER.' AND target_id='.$this->user_id.' )';
  3694     if(count($session->groups) > 0)
  3925     if(count($this->groups) > 0)
  3695     {
  3926     {
  3696       foreach($session->groups as $g_id => $g_name)
  3927       foreach($this->groups as $g_id => $g_name)
  3697       {
  3928       {
  3698         $q[] = '( target_type='.ACL_TYPE_GROUP.' AND target_id='.intval($g_id).' )';
  3929         $q[] = '( target_type='.ACL_TYPE_GROUP.' AND target_id='.intval($g_id).' )';
  3699       }
  3930       }
  3700     }
  3931     }
  3701     // The reason we're using an ORDER BY statement here is because ACL_TYPE_GROUP is less than ACL_TYPE_USER, causing the user's individual
  3932     // The reason we're using an ORDER BY statement here is because ACL_TYPE_GROUP is less than ACL_TYPE_USER, causing the user's individual
  3702     // permissions to override group permissions.
  3933     // permissions to override group permissions.
  3703     $bs .= implode(" OR\n    ", $q) . ' ) AND (' . $pg_info . ' page_id=\''.$db->escape($page_id).'\' AND namespace=\''.$db->escape($namespace).'\' )     
  3934     $bs .= implode(" OR\n    ", $q) . ' ) AND (' . $pg_info . ' ( page_id=\''.$db->escape($page_id).'\' AND namespace=\''.$db->escape($namespace).'\' ) )     
  3704       ORDER BY target_type ASC, page_id ASC, namespace ASC;';
  3935       ORDER BY target_type ASC, page_id ASC, namespace ASC;';
  3705     $q = $session->sql($bs);
  3936     $q = $session->sql($bs);
  3706     if ( $row = $db->fetchrow() )
  3937     if ( $row = $db->fetchrow() )
  3707     {
  3938     {
  3708       do {
  3939       do {
  3709         $rules = $session->string_to_perm($row['rules']);
  3940         $rules = $session->string_to_perm($row['rules']);
  3710         $is_everyone = ( $row['target_type'] == ACL_TYPE_GROUP && $row['target_id'] == 1 );
  3941         $is_everyone = ( $row['target_type'] == ACL_TYPE_GROUP && $row['target_id'] == 1 );
       
  3942         // log where this comes from
       
  3943         if ( $row['namespace'] == '__PageGroup' )
       
  3944         {
       
  3945           $src = ( $is_everyone ) ? ACL_INHERIT_PG_EVERYONE : ( $row['target_type'] == ACL_TYPE_GROUP ? ACL_INHERIT_PG_GROUP : ACL_INHERIT_PG_USER );
       
  3946         }
       
  3947         else
       
  3948         {
       
  3949           $src = ( $is_everyone ) ? ACL_INHERIT_LOCAL_EVERYONE : ( $row['target_type'] == ACL_TYPE_GROUP ? ACL_INHERIT_LOCAL_GROUP : ACL_INHERIT_LOCAL_USER );
       
  3950         }
       
  3951         foreach ( $rules as $perm_type => $perm_value )
       
  3952         {
       
  3953           if ( $this->perms[$perm_type] == AUTH_DENY )
       
  3954             continue;
       
  3955           
       
  3956           $this->perm_resolve_table[$perm_type] = array(
       
  3957               'src' => $src,
       
  3958               'rule_id' => $row['rule_id']
       
  3959             );
       
  3960         }
  3711         $this->acl_merge_with_current($rules, $is_everyone);
  3961         $this->acl_merge_with_current($rules, $is_everyone);
  3712       } while ( $row = $db->fetchrow() );
  3962       } while ( $row = $db->fetchrow() );
  3713     }
  3963     }
  3714     
  3964     
  3715     $this->page_id = $page_id;
  3965     $this->page_id = $page_id;