Changeset 26382


Ignore:
Timestamp:
06/16/10 22:30:50 (7 years ago)
Author:
flack
Message:

reorder functions for better readability

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/developers/flack/acltuning/midcom.core/midcom/services/auth/acl.php

    r26331 r26382  
    363363
    364364    /**
    365      * Returns the system-wide basic privilege set.
    366      *
    367      * @return Array Privilege Name / Value map.
    368      */
    369     function get_default_privileges()
    370     {
    371         return self::$_default_privileges;
    372     }
    373 
    374     /**
    375      * Returns the system-wide basic owner privilege set.
    376      *
    377      * @return Array Privilege Name / Value map.
    378      */
    379     function get_owner_default_privileges()
    380     {
    381         return self::$_owner_default_privileges;
    382     }
    383 
    384     /**
    385      * Merges a new set of default privileges into the current set.
    386      * Existing keys will be silently overwritten.
    387      *
    388      * This is usually only called by the framework startup and the
    389      * component loader.
    390      *
    391      * If only a single default value is set (type integer), then this value is taken
    392      * for the default and the owner privilege is unset (meaning INHERIT). If two
    393      * values (type array of integers) is set, the first privilege value is used for
    394      * default, the second one for the owner privilege set.
    395      *
    396      * @param Array $privileges An associative privilege_name => default_values listing.
    397      */
    398     function register_default_privileges ($privileges)
    399     {
    400         foreach ($privileges as $name => $values)
    401         {
    402             if (! is_array($values))
    403             {
    404                 $values = array($values, MIDCOM_PRIVILEGE_INHERIT);
    405             }
    406 
    407             self::$_default_privileges[$name] = $values[0];
    408             if ($values[1] != MIDCOM_PRIVILEGE_INHERIT)
    409             {
    410                 self::$_owner_default_privileges[$name] = $values[1];
    411             }
    412         }
    413     }
    414 
    415 
    416     /**
    417      * This helper function loads and prepares the list of class magic privileges for
    418      * usage. It will assign them to the $_*_default_class_privileges members.
    419      *
    420      * @param string $class The class name for which defaults should be loaded.
    421      * @access private
    422      */
    423     private function _load_class_magic_privileges($class)
    424     {
    425         // Check if we have loaded these privileges already...
    426         if (array_key_exists($class, self::$_default_magic_class_privileges))
    427         {
    428             return;
    429         }
    430 
    431         $object = new $class();
    432 
    433         if (!method_exists($object, 'get_class_magic_default_privileges'))
    434         {
    435             self::$_default_magic_class_privileges[$class] = array
    436             (
    437                 'EVERYONE' => array(),
    438                 'ANONYMOUS' => array(),
    439                 'USERS' => array()
    440             );
    441             return;
    442         }
    443 
    444         $privs = $object->get_class_magic_default_privileges();
    445 
    446         self::$_default_magic_class_privileges[$class] = $privs;
    447 
    448         return;
    449     }
    450 
    451     /**
    452365     * This internal helper will initialize the default privileges array with all core
    453366     * privileges currently defined.
     
    487400
    488401    /**
     402     * Merges a new set of default privileges into the current set.
     403     * Existing keys will be silently overwritten.
     404     *
     405     * This is usually only called by the framework startup and the
     406     * component loader.
     407     *
     408     * If only a single default value is set (type integer), then this value is taken
     409     * for the default and the owner privilege is unset (meaning INHERIT). If two
     410     * values (type array of integers) is set, the first privilege value is used for
     411     * default, the second one for the owner privilege set.
     412     *
     413     * @param Array $privileges An associative privilege_name => default_values listing.
     414     */
     415    function register_default_privileges ($privileges)
     416    {
     417        foreach ($privileges as $name => $values)
     418        {
     419            if (! is_array($values))
     420            {
     421                $values = array($values, MIDCOM_PRIVILEGE_INHERIT);
     422            }
     423
     424            self::$_default_privileges[$name] = $values[0];
     425            if ($values[1] != MIDCOM_PRIVILEGE_INHERIT)
     426            {
     427                self::$_owner_default_privileges[$name] = $values[1];
     428            }
     429        }
     430    }
     431
     432    /**
     433     * Returns the system-wide basic privilege set.
     434     *
     435     * @return Array Privilege Name / Value map.
     436     */
     437    function get_default_privileges()
     438    {
     439        return self::$_default_privileges;
     440    }
     441
     442    /**
     443     * Returns the system-wide basic owner privilege set.
     444     *
     445     * @return Array Privilege Name / Value map.
     446     */
     447    function get_owner_default_privileges()
     448    {
     449        return self::$_owner_default_privileges;
     450    }
     451
     452
     453    /**
     454     * This helper function loads and prepares the list of class magic privileges for
     455     * usage. It will assign them to the $_*_default_class_privileges members.
     456     *
     457     * @param string $class The class name for which defaults should be loaded.
     458     * @access private
     459     */
     460    private function _load_class_magic_privileges($class)
     461    {
     462        // Check if we have loaded these privileges already...
     463        if (array_key_exists($class, self::$_default_magic_class_privileges))
     464        {
     465            return;
     466        }
     467
     468        $object = new $class();
     469
     470        if (!method_exists($object, 'get_class_magic_default_privileges'))
     471        {
     472            self::$_default_magic_class_privileges[$class] = array
     473            (
     474                'EVERYONE' => array(),
     475                'ANONYMOUS' => array(),
     476                'USERS' => array()
     477            );
     478            return;
     479        }
     480
     481        $privs = $object->get_class_magic_default_privileges();
     482
     483        self::$_default_magic_class_privileges[$class] = $privs;
     484
     485        return;
     486    }
     487
     488    private function _get_user_per_class_privileges($classname, $user)
     489    {
     490        static $cache = array();
     491
     492        $cache_id = $user->id . '::' . $classname;
     493
     494        if (array_key_exists($cache_id, $cache))
     495        {
     496            return $cache[$cache_id];
     497        }
     498
     499        $tmp_object = new $classname;
     500
     501        $cache[$cache_id] = $user->get_per_class_privileges($tmp_object);
     502
     503        return $cache[$cache_id];
     504    }
     505   
     506    /**
     507     * Determine the user identifier for accessing the privilege cache. This is the passed user's
     508     * identifier with the current user and anonymous as fallback
     509     *
     510     * @param mixed $user The user to check for as string or object.
     511     * @return string The identifier
     512     */
     513    public function get_user_id($user = null)
     514    {
     515        $user_id = 'ANONYMOUS';
     516
     517        // TODO: Clean if/else shorthands, make sure this works correctly for magic assignees as well
     518        if (is_null($user))
     519        {
     520            $user = $this->auth->user;
     521
     522            if (!empty($user))
     523            {
     524                $user_id = $user->id;
     525            }
     526        }
     527        else if (is_string($user))
     528        {
     529            if ($user != 'EVERYONE'
     530                && (    mgd_is_guid($user)
     531                    || is_numeric($user)))
     532            {
     533                $user = $this->auth->get_user($user);
     534                $user_id = $user->id;
     535            }
     536            else
     537            {
     538                $user_id = $user;
     539                $user = null;
     540            }
     541        }
     542        else if (is_object($user))
     543        {
     544            $user_id = $user->id;
     545        }
     546        else
     547        {
     548            $user_id = $user;
     549        }
     550
     551        return $user_id;
     552    }
     553
     554    /**
    489555     * This is a simple helper function which validates whether a given privilege
    490556     * exists by its name. Essentially this checks if a corresponding default privilege
     
    498564    {
    499565        return (array_key_exists($name, self::$_default_privileges));
    500     }
    501 
    502     /**
    503      * Checks whether a user has a certain privilege on the given (via guid and class) content object.
    504      * Works on the currently authenticated user by default, but can take another
    505      * user as an optional argument.
    506      *
    507      * @param string $privilege The privilege to check for
    508      * @param string $object_guid A Midgard GUID pointing to an object
    509      * @param string $object_class Class of the object in question
    510      * @param string $user_id The user against which to check the privilege, defaults to the currently authenticated user.
    511      *     You may specify "EVERYONE" instead of an object to check what an anonymous user can do.
    512      * @return boolean True if the privilege has been granted, false otherwise.
    513      */
    514     function can_do_byguid($privilege, $object_guid, $object_class, $user_id)
    515     {
    516         if ($this->_internal_sudo)
    517         {
    518             //debug_push_class(__CLASS__, __FUNCTION__);
    519             //debug_add('INTERNAL SUDO mode is enabled. Generic Read-Only mode set.', MIDCOM_LOG_DEBUG);
    520             //debug_pop();
    521             return $this->_can_do_internal_sudo($privilege);
    522         }
    523 
    524         if ($this->auth->_component_sudo)
    525         {
    526             return true;
    527         }
    528 
    529         $cache_key = "{$user_id}::{$object_guid}";
    530 
    531         if (!isset(self::$_privileges_cache[$cache_key]))
    532         {
    533             //debug_push_class(__CLASS__, __FUNCTION__);
    534             //debug_add("Cache {$privilege_key} miss, fetching privileges for {$object_guid}");
    535             //debug_pop();
    536 
    537             $this->_load_privileges_byguid($object_guid, $object_class, $user_id);
    538         }
    539 
    540         if (!array_key_exists($privilege, self::$_privileges_cache[$cache_key]))
    541         {
    542             debug_push_class(__CLASS__, __FUNCTION__);
    543             debug_add("The privilege {$privilege} is unknown at this point. Assuming not granted privilege.", MIDCOM_LOG_WARN);
    544             debug_pop();
    545             return false;
    546         }
    547 
    548         return self::$_privileges_cache[$cache_key][$privilege];
    549     }
    550 
    551     function can_do_byclass($privilege, $user, $class, $component)
    552     {
    553         if ($this->_internal_sudo)
    554         {
    555             debug_push_class(__CLASS__, __FUNCTION__);
    556             debug_add('INTERNAL SUDO mode is enabled. Generic Read-Only mode set.', MIDCOM_LOG_DEBUG);
    557             debug_pop();
    558             return $this->_can_do_internal_sudo($privilege);
    559         }
    560 
    561         // Initialize this one to be sure to have it.
    562         $default_magic_class_privileges = Array();
    563 
    564         if ($class !== null)
    565         {
    566             if (!is_object($class))
    567             {
    568                 if (!class_exists($class))
    569                 {
    570                     if (   is_null($component)
    571                         || !$_MIDCOM->componentloader->load_graceful($component))
    572                     {
    573                         debug_push_class(__CLASS__, __FUNCTION__);
    574                         debug_add("can_user_do check to undefined class '{$class}'.", MIDCOM_LOG_ERROR);
    575                         debug_pop();
    576                         return false;
    577                     }
    578                 }
    579 
    580                 $tmp_object = new $class();
    581             }
    582             else
    583             {
    584                 $tmp_object = $class;
    585                 $class = get_class($tmp_object);
    586             }
    587             $this->_load_class_magic_privileges($class);
    588         }
    589         else
    590         {
    591             $tmp_object = null;
    592         }
    593 
    594         if (is_null($user))
    595         {
    596             $user_privileges = Array();
    597             $user_per_class_privileges = Array();
    598             if ($tmp_object !== null)
    599             {
    600                 $default_magic_class_privileges = array_merge
    601                 (
    602                     self::$_default_magic_class_privileges[$class]['EVERYONE'],
    603                     self::$_default_magic_class_privileges[$class]['ANONYMOUS']
    604                 );
    605             }
    606         }
    607         else
    608         {
    609             $user_privileges = $user->get_privileges();
    610             if ($tmp_object === null)
    611             {
    612                 $user_per_class_privileges = array();
    613             }
    614             else
    615             {
    616                 $user_per_class_privileges = $user->get_per_class_privileges($tmp_object);
    617                 $default_magic_class_privileges = array_merge
    618                 (
    619                     self::$_default_magic_class_privileges[$class]['EVERYONE'],
    620                     self::$_default_magic_class_privileges[$class]['USERS']
    621                 );
    622             }
    623         }
    624 
    625         // Remember to synchronize this merging chain with the one in get_privileges();
    626         $full_privileges = array_merge
    627         (
    628             self::$_default_privileges,
    629             $default_magic_class_privileges,
    630             $user_privileges,
    631             $user_per_class_privileges
    632         );
    633 
    634         // Check for Ownership:
    635         if ($full_privileges['midgard:owner'] == MIDCOM_PRIVILEGE_ALLOW)
    636         {
    637             $full_privileges = array_merge
    638             (
    639                 $full_privileges,
    640                 $_MIDCOM->auth->get_owner_default_privileges()
    641             );
    642         }
    643 
    644         if (! array_key_exists($privilege, $full_privileges))
    645         {
    646             debug_push_class(__CLASS__, __FUNCTION__);
    647             debug_add("Warning, the privilege {$privilege} is unknown at this point. Assuming not granted privilege.");
    648             debug_pop();
    649             return false;
    650         }
    651 
    652         return ($full_privileges[$privilege] == MIDCOM_PRIVILEGE_ALLOW);
    653     }
    654 
    655     /**
    656      * This internal helper checks if a privilege is available during internal
    657      * sudo mode, as outlined in the corresponding variable.
    658      *
    659      * @param string $privilege The privilege to check for
    660      * @return boolean True if the privilege has been granted, false otherwise.
    661      * @access private
    662      * @see $_internal_sudo
    663      */
    664     private function _can_do_internal_sudo($privilege)
    665     {
    666         switch($privilege)
    667         {
    668             case 'midgard:create':
    669             case 'midgard:update':
    670             case 'midgard:delete':
    671             case 'midgard:privileges':
    672                 // We do not allow this, for security reasons.
    673                 return false;
    674 
    675             default:
    676                 // allow everything else.
    677                 return true;
    678         }
    679     }
    680 
    681     /**
    682      * Determine the user identifier for accessing the privilege cache. This is the passed user's
    683      * identifier with the current user and anonymous as fallback
    684      *
    685      * @param mixed $user The user to check for as string or object.
    686      * @return string The identifier
    687      */
    688     public function get_user_id($user = null)
    689     {
    690         $user_id = 'ANONYMOUS';
    691 
    692         // TODO: Clean if/else shorthands, make sure this works correctly for magic assignees as well
    693         if (is_null($user))
    694         {
    695             $user = $this->auth->user;
    696 
    697             if (!empty($user))
    698             {
    699                 $user_id = $user->id;
    700             }
    701         }
    702         else if (is_string($user))
    703         {
    704             if ($user != 'EVERYONE'
    705                 && (    mgd_is_guid($user)
    706                     || is_numeric($user)))
    707             {
    708                 $user = $this->auth->get_user($user);
    709                 $user_id = $user->id;
    710             }
    711             else
    712             {
    713                 $user_id = $user;
    714                 $user = null;
    715             }
    716         }
    717         else if (is_object($user))
    718         {
    719             $user_id = $user->id;
    720         }
    721         else
    722         {
    723             $user_id = $user;
    724         }
    725 
    726         return $user_id;
    727566    }
    728567
     
    764603        return self::$_privileges_cache[$cache_id];
    765604    }
    766 
    767605
    768606    /**
     
    829667        }
    830668        self::$_privileges_cache[$cache_id] = $full_privileges;
    831     }
    832 
    833     private function _get_user_per_class_privileges($classname, $user)
    834     {
    835         static $cache = array();
    836 
    837         $cache_id = $user->id . '::' . $classname;
    838 
    839         if (array_key_exists($cache_id, $cache))
    840         {
    841             return $cache[$cache_id];
    842         }
    843 
    844         $tmp_object = new $classname;
    845 
    846         $cache[$cache_id] = $user->get_per_class_privileges($tmp_object);
    847 
    848         return $cache[$cache_id];
    849     }
    850 
    851 
    852     private static function _get_parent_class($classname)
    853     {
    854         static $cache = array();
    855 
    856         if (array_key_exists($classname, $cache))
    857         {
    858             return $cache[$classname];
    859         }
    860 
    861         $tmp_object = new $classname();
    862 
    863         $cache[$classname] = $tmp_object->get_dba_parent_class();
    864 
    865         return $cache[$classname];
    866669    }
    867670
     
    1046849    }
    1047850
     851    function can_do_byclass($privilege, $user, $class, $component)
     852    {
     853        if ($this->_internal_sudo)
     854        {
     855            debug_push_class(__CLASS__, __FUNCTION__);
     856            debug_add('INTERNAL SUDO mode is enabled. Generic Read-Only mode set.', MIDCOM_LOG_DEBUG);
     857            debug_pop();
     858            return $this->_can_do_internal_sudo($privilege);
     859        }
     860
     861        // Initialize this one to be sure to have it.
     862        $default_magic_class_privileges = Array();
     863
     864        if ($class !== null)
     865        {
     866            if (!is_object($class))
     867            {
     868                if (!class_exists($class))
     869                {
     870                    if (   is_null($component)
     871                        || !$_MIDCOM->componentloader->load_graceful($component))
     872                    {
     873                        debug_push_class(__CLASS__, __FUNCTION__);
     874                        debug_add("can_user_do check to undefined class '{$class}'.", MIDCOM_LOG_ERROR);
     875                        debug_pop();
     876                        return false;
     877                    }
     878                }
     879
     880                $tmp_object = new $class();
     881            }
     882            else
     883            {
     884                $tmp_object = $class;
     885                $class = get_class($tmp_object);
     886            }
     887            $this->_load_class_magic_privileges($class);
     888        }
     889        else
     890        {
     891            $tmp_object = null;
     892        }
     893
     894        if (is_null($user))
     895        {
     896            $user_privileges = Array();
     897            $user_per_class_privileges = Array();
     898            if ($tmp_object !== null)
     899            {
     900                $default_magic_class_privileges = array_merge
     901                (
     902                    self::$_default_magic_class_privileges[$class]['EVERYONE'],
     903                    self::$_default_magic_class_privileges[$class]['ANONYMOUS']
     904                );
     905            }
     906        }
     907        else
     908        {
     909            $user_privileges = $user->get_privileges();
     910            if ($tmp_object === null)
     911            {
     912                $user_per_class_privileges = array();
     913            }
     914            else
     915            {
     916                $user_per_class_privileges = $user->get_per_class_privileges($tmp_object);
     917                $default_magic_class_privileges = array_merge
     918                (
     919                    self::$_default_magic_class_privileges[$class]['EVERYONE'],
     920                    self::$_default_magic_class_privileges[$class]['USERS']
     921                );
     922            }
     923        }
     924
     925        // Remember to synchronize this merging chain with the one in get_privileges();
     926        $full_privileges = array_merge
     927        (
     928            self::$_default_privileges,
     929            $default_magic_class_privileges,
     930            $user_privileges,
     931            $user_per_class_privileges
     932        );
     933
     934        // Check for Ownership:
     935        if ($full_privileges['midgard:owner'] == MIDCOM_PRIVILEGE_ALLOW)
     936        {
     937            $full_privileges = array_merge
     938            (
     939                $full_privileges,
     940                $_MIDCOM->auth->get_owner_default_privileges()
     941            );
     942        }
     943
     944        if (! array_key_exists($privilege, $full_privileges))
     945        {
     946            debug_push_class(__CLASS__, __FUNCTION__);
     947            debug_add("Warning, the privilege {$privilege} is unknown at this point. Assuming not granted privilege.");
     948            debug_pop();
     949            return false;
     950        }
     951
     952        return ($full_privileges[$privilege] == MIDCOM_PRIVILEGE_ALLOW);
     953    }
     954
     955    /**
     956     * Checks whether a user has a certain privilege on the given (via guid and class) content object.
     957     * Works on the currently authenticated user by default, but can take another
     958     * user as an optional argument.
     959     *
     960     * @param string $privilege The privilege to check for
     961     * @param string $object_guid A Midgard GUID pointing to an object
     962     * @param string $object_class Class of the object in question
     963     * @param string $user_id The user against which to check the privilege, defaults to the currently authenticated user.
     964     *     You may specify "EVERYONE" instead of an object to check what an anonymous user can do.
     965     * @return boolean True if the privilege has been granted, false otherwise.
     966     */
     967    function can_do_byguid($privilege, $object_guid, $object_class, $user_id)
     968    {
     969        if ($this->_internal_sudo)
     970        {
     971            //debug_push_class(__CLASS__, __FUNCTION__);
     972            //debug_add('INTERNAL SUDO mode is enabled. Generic Read-Only mode set.', MIDCOM_LOG_DEBUG);
     973            //debug_pop();
     974            return $this->_can_do_internal_sudo($privilege);
     975        }
     976
     977        if ($this->auth->_component_sudo)
     978        {
     979            return true;
     980        }
     981
     982        $cache_key = "{$user_id}::{$object_guid}";
     983
     984        if (!isset(self::$_privileges_cache[$cache_key]))
     985        {
     986            //debug_push_class(__CLASS__, __FUNCTION__);
     987            //debug_add("Cache {$privilege_key} miss, fetching privileges for {$object_guid}");
     988            //debug_pop();
     989
     990            $this->_load_privileges_byguid($object_guid, $object_class, $user_id);
     991        }
     992
     993        if (!array_key_exists($privilege, self::$_privileges_cache[$cache_key]))
     994        {
     995            debug_push_class(__CLASS__, __FUNCTION__);
     996            debug_add("The privilege {$privilege} is unknown at this point. Assuming not granted privilege.", MIDCOM_LOG_WARN);
     997            debug_pop();
     998            return false;
     999        }
     1000
     1001        return self::$_privileges_cache[$cache_key][$privilege];
     1002    }
     1003
     1004
     1005    /**
     1006     * This internal helper checks if a privilege is available during internal
     1007     * sudo mode, as outlined in the corresponding variable.
     1008     *
     1009     * @param string $privilege The privilege to check for
     1010     * @return boolean True if the privilege has been granted, false otherwise.
     1011     * @access private
     1012     * @see $_internal_sudo
     1013     */
     1014    private function _can_do_internal_sudo($privilege)
     1015    {
     1016        switch($privilege)
     1017        {
     1018            case 'midgard:create':
     1019            case 'midgard:update':
     1020            case 'midgard:delete':
     1021            case 'midgard:privileges':
     1022                // We do not allow this, for security reasons.
     1023                return false;
     1024
     1025            default:
     1026                // allow everything else.
     1027                return true;
     1028        }
     1029    }
     1030
    10481031}
    10491032
Note: See TracChangeset for help on using the changeset viewer.