说到底其实我是做Joomla出身的,因为第一家公司做的是美国的项目所以用Joomla进行二次开发来做CSM(Content System Management)网站, 国外对这个用得很多.之前用的是1.0 版本的, Joomla 1.0 版本应该说已经相当成熟了, 很多开源的组件,可以说只有你想不到的, 没有找不到的. 1.0 感觉还是处于面向过程的阶段, 尽管里面是有很多关于对象的概念, 但是还是有点乱. 最近一段时间突然想看下1.5的版本的内容. 看到之后觉得突然叫我从1.0 转到1.5还是有点难度的. 一边学一边做些笔记.

不过今天先回顾一些旧的内容, 无论是1.0 版本还是1.5版本,joomla本质的东西还是一样.

if (!$user->authorize( 'com_banners', 'manage' )) {
    
$mainframe->redirect( 'index.php', JText::_('ALERTNOTAUTH') );
}

 

 每个组件开头都要判断登陆的用户是否有权限来操作当前的组件.如果要追究 joomla 到底是怎么处理权限问题, 还是要饶一大个圈的.先从数据库的新加一个用户开始说起.

1. jos_users
id              
63
name          Linda Liu
username    linda
email          linda
@linda.com
password   
usertype     Super Administrator
block         
0
sendEmail   
0
gid            
25
registerDate  
2009-05-27 07:49:32
lastvisitDate 
0000-00-00 00:00:00
activation    
params        admin_language
=en-GB\nlanguage=en-GB\neditor=tinymce\nhelpsite=\ntimezone=0\n\n

usertype 是表 jos_core_acl_aro_groups 的字段 name 的值
gid代表groupid, jos_core_acl_aro_groups 里面对应的Super Administrator对应的id值

2. jos_core_acl_aro_groups

        [1]ROOT(id:17)[22]
                    |
         [2]USERS(id:28)[21]
                    |
    --------------------------------------
    |                                                   |
[3]Public Frontend(id:29)[12]     [13]Public Backend(id:30)[20]
    |                                                   |
[4]Registered(id:18)[11]           [14]Manager(id:23)[19]
    |                                                   |
[5]Author(id:19)[10]              [15]Administrator(id:24)[18]
    |                                                   |
[6]Editor(id:20)[9]              [16]Super Administrator(id:25)[17]
    |
[7]Publisher(id:21)[8]

 这棵树还是蛮明显的,分前后台,越到下面权限越大

3. jos_core_acl_aro
同样每增加一个用户(如论前后台都会添加一条记录到 jos_core_acl_aro)
id    section_value  value    order_value    name        hidden
11   users             63       0                   Linda Liu   0
                            用户id                      用户的名字

4. jos_core_acl_aro_sections
id     value    order_value    name    hidden
10    users    1                  Users   0

jos_core_acl_aro_sections的value就是 jos_core_acl_aro用到的section_value的值,我几乎就只看到一条记录

5.jos_core_acl_groups_aro_map
group_id        section_value              aro_id
25                                                  11
jos_core_acl_aro_groups的groupid    jos_core_acl_aro的id值

6. 下面就从调用到的函数一点点追究下去.

$user->authorize( 'com_banners', 'manage' );

//class JUser-------------------------------------------------
//6.1

function authorize( $acoSection, $aco, $axoSection = null, $axo = null )
{
    
$acl    = & JFactory::getACL(); //取得JAuthorization对象 看6.2
    $value    = $acl->getCheckMode() == 1 ? $this->id : $this->usertype;
    
// the native calls (Check Mode 1) work on the user id, not the user type
    // 这里用了用户类型来做判断 $value = Super Administrator


    
return $acl->acl_check( $acoSection, $aco, 'users', $value, $axoSection, $axo );
    
//$acl->acl_check('com_banners', 'manage', 'users', Super Administrator, null, null)
}

//class JFactory-----------------------------------------------
//6.2

function &getACL( )
{
    
static $instance;

    
if (!is_object($instance)) {
        
$instance = JFactory::_createACL(); //看6.3
    }

    
return $instance;
}
//class JFactory-----------------------------------------------
//6.3

function &_createACL()
{
    
//TODO :: take the authorization class out of the application package
    jimport( 'joomla.user.authorization' ); //把authorization文件包含进来
    
    
$db =&  JFactory::getDBO();

    
$options = array(
        
'db'                => &$db,
        
'db_table_prefix'    => $db->getPrefix() . 'core_acl_',
        
'debug'                => 0
    );
    
$acl = new JAuthorization( $options ); //看6.4

    
return $acl;
}

//class JAuthorization------------------------------------------------------
//6.4

/*

 * 注意:
 * 有时我们自己会添加一些额外的组件到后台, 然后需要一些 Manager 角色的用户来做管理,
 * 那么就要把这个组件的访问权限添加到acl中,以前我在做1.0版本的时候是直接在这个函数里添加不知道是不是有别的更好的办法
 * $this->addACL( 'com_helloword', 'manage', 'users', 'manager');
*/
function JAuthorization($options = NULL)
{
    parent
::gacl( $options );

    
// ARO value is currently the user type,
    // this changes to user id in proper implementation
    // No hierarchial inheritance so have to do that the long way

    
    
$this->acl = array();
    
//这里开始配置这个后台组件的访问权限
    //数组的几个值分别是 组件名, 操作动作, section, 用户权, $axo_section_value=NULL, $axo_value=NULL, 返回值
    // special ACl with return value to edit user

    $this->addACL( 'com_user', 'edit', 'users', 'super administrator', null, null, '' );
    
$this->addACL( 'com_user', 'edit', 'users', 'administrator', null, null, '' );
    
$this->addACL( 'com_user', 'edit', 'users', 'manager', null, null, '' );
    
// return value defines xml setup file variant
    $this->addACL( 'com_user', 'edit', 'users', 'author', null, null, 'author' );
    
$this->addACL( 'com_user', 'edit', 'users', 'editor', null, null, 'author' );
    
$this->addACL( 'com_user', 'edit', 'users', 'publisher', null, null, 'author' );
    
$this->addACL( 'com_user', 'edit', 'users', 'registered', null, null, 'registered' );

    
// backend login
    $this->addACL( 'login', 'administrator', 'users', 'administrator' );
    
$this->addACL( 'login', 'administrator', 'users', 'super administrator' );
    
$this->addACL( 'login', 'administrator', 'users', 'manager' );

    
$this->addACL( 'login', 'site', 'users', 'administrator' );
    
$this->addACL( 'login', 'site', 'users', 'super administrator' );
    
$this->addACL( 'login', 'site', 'users', 'manager' );

    
$this->addACL( 'login', 'site', 'users', 'registered' );
    
$this->addACL( 'login', 'site', 'users', 'author' );
    
$this->addACL( 'login', 'site', 'users', 'editor' );
    
$this->addACL( 'login', 'site', 'users', 'publisher' );
    
// backend menus

    
$this->addACL( 'com_banners', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_banners', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_banners', 'manage', 'users', 'manager' );

    
$this->addACL( 'com_checkin', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_checkin', 'manage', 'users', 'administrator' );

    
$this->addACL( 'com_cache', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_cache', 'manage', 'users', 'administrator' );

    
$this->addACL( 'com_config', 'manage', 'users', 'super administrator' );
    
//$this->addACL( 'com_config', 'manage', 'users', 'administrator' );

    
$this->addACL( 'com_contact', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_contact', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_contact', 'manage', 'users', 'manager' );

    
$this->addACL( 'com_components', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_components', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_components', 'manage', 'users', 'manager' );

    
$this->addACL( 'com_frontpage', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_frontpage', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_frontpage', 'manage', 'users', 'manager' );
    
$this->addACL( 'com_frontpage', 'edit', 'users', 'manager' );

    
// access to installers and base installer
    $this->addACL( 'com_installer', 'installer', 'users', 'administrator' );
    
$this->addACL( 'com_installer', 'installer', 'users', 'super administrator' );

    
$this->addACL( 'com_installer', 'component', 'users', 'administrator' );
    
$this->addACL( 'com_installer', 'component', 'users', 'super administrator' );

    
$this->addACL( 'com_installer', 'language', 'users', 'super administrator' );
    
$this->addACL( 'com_installer', 'language', 'users', 'administrator' );

    
$this->addACL( 'com_installer', 'module', 'users', 'administrator' );
    
$this->addACL( 'com_installer', 'module', 'users', 'super administrator' );

    
$this->addACL( 'com_installer', 'plugin', 'users', 'administrator' );
    
$this->addACL( 'com_installer', 'plugin', 'users', 'super administrator' );

    
$this->addACL( 'com_installer', 'template', 'users', 'super administrator' );
    
$this->addACL( 'com_installer', 'template', 'users', 'administrator' );

    
$this->addACL( 'com_languages', 'manage', 'users', 'super administrator' );

    
$this->addACL( 'com_plugins', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_plugins', 'manage', 'users', 'administrator' );
    
// uncomment following to allow managers to edit modules
    //array( 'administration', 'edit', 'users', 'manager', 'modules', 'all' );


    
$this->addACL( 'com_massmail', 'manage', 'users', 'super administrator' );

    
$this->addACL( 'com_media', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_media', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_media', 'manage', 'users', 'manager' );
    
$this->addACL( 'com_media', 'popup', 'users', 'super administrator' );
    
$this->addACL( 'com_media', 'popup', 'users', 'administrator' );
    
$this->addACL( 'com_media', 'popup', 'users', 'manager' );
    
$this->addACL( 'com_media', 'popup', 'users', 'registered' );
    
$this->addACL( 'com_media', 'popup', 'users', 'author' );
    
$this->addACL( 'com_media', 'popup', 'users', 'editor' );
    
$this->addACL( 'com_media', 'popup', 'users', 'publisher' );

    
$this->addACL( 'com_menus', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_menus', 'manage', 'users', 'super administrator' );

    
$this->addACL( 'com_modules', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_modules', 'manage', 'users', 'administrator' );

    
$this->addACL( 'com_newsfeeds', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_newsfeeds', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_newsfeeds', 'manage', 'users', 'manager' );

    
$this->addACL( 'com_poll', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_poll', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_poll', 'manage', 'users', 'manager' );

    
$this->addACL( 'com_templates', 'manage', 'users', 'super administrator' );
    
//$this->addACL( 'com_templates', 'manage', 'user', 'administrator' )

    
$this->addACL( 'com_trash', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_trash', 'manage', 'users', 'super administrator' );

    
// email block users property
    $this->addACL( 'com_users', 'block user', 'users', 'administrator' );
    
$this->addACL( 'com_users', 'block user', 'users', 'super administrator' );

    
$this->addACL( 'com_users', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_users', 'manage', 'users', 'super administrator' );

    
$this->addACL( 'com_weblinks', 'manage', 'users', 'super administrator' );
    
$this->addACL( 'com_weblinks', 'manage', 'users', 'administrator' );
    
$this->addACL( 'com_weblinks', 'manage', 'users', 'manager' );

    
// email system events
    $this->addACL( 'com_users', 'email_events', 'users', 'administrator' );
    
$this->addACL( 'com_users', 'email_events', 'users', 'super administrator' );
    
$this->addACL( 'workflow', 'email_events', 'users', 'administrator', null, null );
    
$this->addACL( 'workflow', 'email_events', 'users', 'super administrator', null, null );

    
// actions
    $this->addACL( 'com_content', 'add', 'users', 'author', 'content', 'all' );
    
$this->addACL( 'com_content', 'add', 'users', 'editor', 'content', 'all' );
    
$this->addACL( 'com_content', 'add', 'users', 'publisher', 'content', 'all' );
    
$this->addACL( 'com_content', 'edit', 'users', 'author', 'content', 'own' );
    
$this->addACL( 'com_content', 'edit', 'users', 'editor', 'content', 'all' );
    
$this->addACL( 'com_content', 'edit', 'users', 'publisher', 'content', 'all' );
    
$this->addACL( 'com_content', 'publish', 'users', 'publisher', 'content', 'all' );

    
$this->addACL( 'com_content', 'add', 'users', 'manager', 'content', 'all' );
    
$this->addACL( 'com_content', 'edit', 'users', 'manager', 'content', 'all' );
    
$this->addACL( 'com_content', 'publish', 'users', 'manager', 'content', 'all' );

    
$this->addACL( 'com_content', 'add', 'users', 'administrator', 'content', 'all' );
    
$this->addACL( 'com_content', 'edit', 'users', 'administrator', 'content', 'all' );
    
$this->addACL( 'com_content', 'publish', 'users', 'administrator', 'content', 'all' );

    
$this->addACL( 'com_content', 'add', 'users', 'super administrator', 'content', 'all' );
    
$this->addACL( 'com_content', 'edit', 'users', 'super administrator', 'content', 'all' );
    
$this->addACL( 'com_content', 'publish', 'users', 'super administrator', 'content', 'all' );
}

//class JAuthorization------------------------------------------------------
//6.5
//添加后台组件的访问权限到JAuthorization的acl变量中.

function addACL( $aco_section_value, $aco_value, $aro_section_value, $aro_value, $axo_section_value=NULL, $axo_value=NULL, $return_value=NULL )
{
    
$this->acl[] = array$aco_section_value, $aco_value, $aro_section_value, $aro_value, $axo_section_value, $axo_value, $return_value );
    
$this->acl_count++;
}


//class JAuthorization------------------------------------------------------
//6.6
//判断用户是否有权限访问.

function acl_check( $aco_section_value, $aco_value, $aro_section_value, $aro_value, $axo_section_value=NULL, $axo_value=NULL, $root_aro_group=NULL, $root_axo_group=NULL )
{
    
if ($this->_checkMode === 1) {
        
return parent::acl_check( $aco_section_value, $aco_value, $aro_section_value, $aro_value, $axo_section_value, $axo_value, $root_aro_group, $root_axo_group );
    }

    
$this->debug_text( "\n<br /> ACO=$aco_section_value:$aco_value, ARO=$aro_section_value:$aro_value, AXO=$axo_section_value|$axo_value" );

    
$acl_result = 0;
    
for ($i=0$i < $this->acl_count; $i++)
    {
        
$acl =& $this->acl[$i];
        
//$acl[0] 组件名
        if (strcasecmp$aco_section_value, $acl[0] ) == 0) {
            
//要进行的操作:manage, add, edit.
            if (strcasecmp$aco_value, $acl[1] ) == 0) {
                
//$acl[2]:section名称, users
                if (strcasecmp$aro_section_value, $acl[2] ) == 0) {
                    
//$acl[3]:用户组:Super Administrator, Manager..
                    if (strcasecmp$aro_value, $acl[3] ) == 0) {
                        
//$axo_section_value为空直接跳到else部分
                        if ($axo_section_value && $acl[4]) {
                            
if (strcasecmp$axo_section_value, $acl[4] ) == 0) {
                                
if (strcasecmp$axo_value, $acl[5] ) == 0) {
                                    
$acl_result = @$acl[6? $acl[6: 1;
                                    
break;
                                }
                            }
                        } 
else {
                            
//取出结果
                            $acl_result = @$acl[6? $acl[6: 1;
                            
break;
                        }
                    }
                }
            }
        }
    }
    
//最后返回结果.
    return $acl_result;
}

//通过返回来的值判断是否有访问的权限
if (!$user->authorize( 'com_banners', 'manage' )) {
    $mainframe->redirect( 'index.php', JText::_('ALERTNOTAUTH') );
}