Changeset 2850

Show
Ignore:
Timestamp:
11/23/08 21:35:41 (7 weeks ago)
Author:
bjohnson
Message:

Converting ACL class to use a bitmask permission flag. Almost guaranteed to
have bugs.

Location:
trunk/htdocs/system/classes
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/htdocs/system/classes/acl.php

    r2848 r2850  
    2424    const ACCESS_NONEXISTANT_PERMISSION = true; 
    2525 
    26     private static $access_ids = array(); 
    27     private static $access_names = array(); 
    28  
    29     /** 
    30      * Static initializer to fill the $access_ids array 
    31      */ 
    32     public static function __static() 
    33     { 
    34         /*self::$access_ids = DB::get_keyvalue( 'SELECT name, id FROM {permissions};' ); 
    35  
    36         if ( ! isset(self::$access_ids) ) { 
    37             self::$access_ids = array(); 
    38         } 
    39         */ 
    40         self::$access_ids = array( 0 => 'read', 1 => 'write', 2 => 'deny' ); 
    41         self::$access_names = array_flip( self::$access_ids ); 
    42     } 
    43  
    44     /** 
    45      * Convert a permission access name (read, write, denied) into an ID 
    46      * @param string The access name 
    47      * @return mixed the ID of the permission, or boolean FALSE if it does not exist 
    48      **/ 
    49     public static function access_id( $name ) 
    50     { 
    51         // if $name is numeric, assume it is already an access ID 
    52         if ( is_numeric( $name ) ) { 
    53             return $name; 
    54         } 
    55         return isset( self::$access_ids[$name] ) ? self::$access_ids[$name] : FALSE; 
    56     } 
    57  
    58     /** 
    59      * Convert a permission access ID into a name 
    60      * @param ID The access ID 
    61      * @return mixed the name of the permission, or boolean FALSE if it does not exist 
    62      **/ 
    63     public static function access_name( $id ) 
    64     { 
    65         // if $id is not numeric, assume it is already an access name 
    66         if ( ! is_numeric( $id ) ) { 
    67             return $id; 
    68         } 
    69         return isset( self::$access_names[$id] ) ? self::$access_names[$id] : FALSE; 
    70     } 
    71  
    72     /** 
    73      * Check access. Implements hierarchy of access terms. 
    74      * @param mixed $access_given The ID or name of the access given 
    75      * @param mixed $access_check The ID or name of the access to check against 
     26    private static $access_names = array( 'read', 'write' ); 
     27 
     28    /** 
     29     * Check the permission bitmask for a particular access type. 
     30     * @param mixed $permission The permission bitmask 
     31     * @param mixed $access The name of the access to check against (read, write, delete) 
    7632     * @return bool Returns true if the given access meets exceeds the access to check against 
    7733     */ 
    78     public static function access_check( $access_given, $access_check ) 
    79     { 
    80         $access_given = self::access_name( $access_given ); 
    81         $access_check = self::access_name( $access_check ); 
    82  
    83         if ( $access_given == 'deny' ) { 
    84             return false; 
    85         } 
    86         if ( $access_given == 'full' ) { 
    87             return true; 
    88         } 
    89         if ( $access_given == 'read' || $access_given == 'write' ) { 
    90             if ( $access_check == 'full' ) { 
    91                 return false; 
    92             } 
    93             if ( $access_given == $access_check ) { 
    94                 return true; 
    95             } 
    96             else { 
    97                 return false; 
    98             } 
    99         } 
    100         // unknown access 
    101         return false; 
     34    public static function access_check( $permission_flag, $access ) 
     35    {        
     36        $bitmask = new Bitmask( self::$access_names, $permission ); 
     37         
     38        return $bitmask->$access; 
    10239    } 
    10340 
     
    13269        $perm = ACL::token_id( $name ); 
    13370        $admin = UserGroup::get( 'admin'); 
    134         if( $admin ) { 
    135             ACL::grant_group( $admin->id, $perm ); 
     71        if ( $admin ) { 
     72            ACL::grant_group( $admin->id, $perm, 'full' ); 
    13673        } 
    13774 
     
    259196     * @param mixed $group A group ID or name 
    260197     * @param mixed $permission An action ID or name 
    261      * @param string $access Check for 'read', 'write', or 'full' access 
     198     * @param string $access Check for 'read', 'write', or 'delete' access 
    262199     * @return bool Whether the group can perform the action 
    263200    **/ 
    264     public static function group_can( $group, $permission, $access = 'full' ) 
     201    public static function group_can( $group, $permission, $access = 'write' ) 
    265202    { 
    266203        // Use only numeric ids internally 
     
    284221     * @param mixed $user A user object, user ID or a username 
    285222     * @param mixed $permission A permission ID or name 
    286      * @param string $access Check for 'read', 'write', or 'full' access 
     223     * @param string $access Check for 'read', 'write', or 'delete' access 
    287224     * @return bool Whether the user can perform the action 
    288225    **/ 
    289     public static function user_can( $user, $permission, $access = 'full' ) 
     226    public static function user_can( $user, $permission, $access = 'write' ) 
    290227    { 
    291228        // Use only numeric ids internally 
     
    339276  ON ug.group_id = gp.group_id 
    340277  AND ug.user_id = :user_id 
    341   AND gp.token_id = :token_id; 
     278  AND gp.token_id = :token_id 
     279  ORDER BY gp.permission_id 
     280  LIMIT 1; 
    342281SQL; 
    343282        $result = DB::get_value( $sql, array( ':user_id' => $user_id, ':token_id' => $permission ) ); 
     
    355294     * Get all the tokens for a given user with a particular kind of access 
    356295     * @param mixed $user A user object, user ID or a username 
    357      * @param string $access Check for 'read', 'write', or 'full' access 
     296     * @param string $access Check for 'read' or 'write' access 
    358297     * @return array of token IDs 
    359298    **/ 
    360299    public static function user_tokens( $user, $access = 'write' ) 
    361300    { 
    362         // convert $user and $access to IDs 
     301        // convert $user to an ID 
    363302        if ( is_numeric( $user ) ) { 
    364303            $user_id = $user; 
     
    369308            $user_id = $user->id; 
    370309        } 
    371         $access_id = self::access_id( $access ); 
    372          
    373         $tokens = DB::get_results( 'SELECT token_id FROM {user_token_permissions} WHERE user_id = ? AND permission_id = ?', array( $user_id, $access_id) ); 
     310         
     311        $result = DB::get_results( 'SELECT token_id, permission_id FROM {user_token_permissions} WHERE user_id = ?', array( $user_id ) ); 
     312        $bitmask = new Bitmask ( self::$access_names ); 
     313        $tokens = array(); 
     314 
     315        foreach ( $result as $token ) { 
     316            $bitmask->value = $token->permission_id; 
     317            if ( $bitmask->$access ) { 
     318                $tokens[] = $token->token_id; 
     319            } 
     320        } 
    374321        return $tokens; 
    375322    } 
     
    384331    public static function grant_group( $group_id, $token_id, $access = 'full' ) 
    385332    { 
     333        $permission_id = DB::get_value( 'SELECT permission_id FROM {group_token_permissions} WHERE group_id=? AND token_id=?', 
     334            array( $group_id, $token_id ) ); 
     335        if ( $permission_id ===  false ) { 
     336            $permission_id = 0; // default is 'deny' (bitmask 0) 
     337        } 
     338         
     339        $bitmask = new Bitmask( self::$access_names, $permission_id ); 
     340         
     341        if ( $access == 'full' || $access == 'deny' ) { 
     342            if ( $access == 'full' ) { 
     343                $access = true; 
     344            } 
     345            else { 
     346                $access = false; 
     347            } 
     348            foreach ( self::$access_names as $access_name ) { 
     349                $bitmask->$access_name = $access; 
     350            } 
     351        } 
     352        else { 
     353            $bitmask->$access = true; 
     354        } 
     355 
    386356        // DB::update will insert if the token is not already in the group tokens table 
    387357        $result = DB::update( 
    388358            '{group_token_permissions}', 
    389             array( 'permission_id' => self::$access_ids[$access] ), 
     359            array( 'permission_id' => $bitmask->value ), 
    390360            array( 'group_id' => $group_id, 'token_id' => self::token_id( $token_id ) ) 
    391361        ); 
     
    406376    public static function grant_user( $user_id, $token_id, $access = 'full' ) 
    407377    { 
     378        $permission_id = DB::get_value( 'SELECT permission_id FROM {user_token_permissions} WHERE group_id=? AND token_id=?', 
     379            array( $user_id, $token_id ) ); 
     380        if ( $permission_id ===  false ) { 
     381            $permission_id = 0; // default is 'deny' (bitmask 0) 
     382        } 
     383         
     384        $bitmask = new Bitmask( self::$access_names, $permission_id ); 
     385         
     386        if ( $access == 'full' || $access == 'deny' ) { 
     387            if ( $access == 'full' ) { 
     388                $access = true; 
     389            } 
     390            else { 
     391                $access = false; 
     392            } 
     393            foreach ( self::$access_names as $access_name ) { 
     394                $bitmask->$access_name = $access; 
     395            } 
     396        } 
     397        else { 
     398            $bitmask->$access = true; 
     399        } 
     400 
    408401        $result = DB::update( 
    409402            '{user_token_permissions}', 
    410             array( 'permission_id' => self::$access_ids[$access] ), 
     403            array( 'permission_id' => $bitmask->value ), 
    411404            array( 'user_id' => $user_id, 'token_id' => self::token_id( $token_id ) ) 
    412405        ); 
  • trunk/htdocs/system/classes/bitmask.php

    r2849 r2850  
    55class Bitmask { 
    66    public $flags = array();  // set of flag bit masks 
    7     protected $value = 0;        // internal integer value of the bitmask 
     7    public $value = 0;        // internal integer value of the bitmask 
    88 
    99    /**