Php implements simple ACL.

Source: Internet
Author: User
Finally, I have finished a simple implementation. For more information about php learning, see. Copy codeThe code is as follows:
-- ACL Tables
-- Table structure 'aclresources'
Drop table if exists 'aclresources ';
Create table if not exists 'aclresources '(
'Rsid 'varchar (64) not null,
'Access' int (4) not null default 0,
'Desc' varchar (240) not null default '',
'Created _ at' int (10) unsigned not null default 1,
'Updated _ at' int (10) unsigned not null default 0,
Primary key ('rsid ')
) Default charset = utf8 COLLATE = utf8_unicode_ci;
-- Table structure 'aclroles'
Drop table if exists 'aclroes ';
Create table if not exists 'aclroles '(
'Id' int (10) unsigned not null auto_increment,
'Rolename' varchar (32) not null,
'Desc' varchar (240) not null default '',
'Created _ at' int (10) unsigned not null default 1,
'Updated _ at' int (10) unsigned not null default 0,
Primary key ('id '),
Unique key 'rolename' ('rolename ')
) Default charset = utf8 COLLATE = utf8_unicode_ci;
-- Table structure 'ref _ aclresources_aclroles'
Drop table if exists 'ref _ aclresources_aclroles ';
Create table if not exists 'ref _ aclresources_aclroles '(
'Rsid 'varchar (64) not null,
'Role _ id' int (10) unsigned not null,
Primary key ('rsid ', 'role _ id ')
) Default charset = utf8 COLLATE = utf8_unicode_ci;
-- Table structure 'ref _ users_aclroles'
Drop table if exists 'ref _ users_aclroles ';
Create table if not exists 'ref _ users_aclroles '(
'User _ id' int (10) unsigned not null auto_increment,
'Role _ id' int (10) unsigned not null,
Primary key ('User _ id', 'role _ id ')
) Default charset = utf8 COLLATE = utf8_unicode_ci;
-- Table structure 'users'
Drop table if exists 'users ';
Create table 'users '(
'Id' int (10) unsigned not null auto_increment,
'Email 'varchar (128) not null,
'Password' varchar (64) not null,
'Nickname' varchar (32) not null default '',
'Roles' varchar (240) not null default '',
'Created _ at' int (10) unsigned not null default 1,
'Updated _ at' int (10) unsigned not null default 0,
Primary key ('id '),
Unique key 'user _ email '('email ')
) Default charset = utf8 COLLATE = utf8_unicode_ci;

Php
Copy codeThe code is as follows:
/**
* Simple ACL permission control
*
* Table definition
*
* 1. resource definition (rsid, access, desc, created_at, updated_at)
* 2. role definition (id, rolename, desc, created_at, updated_at)
* 3. resource-role Association (rsid, role_id)
* 4. user-role Association (user_id, role_id)
*
* Dependent db. php sqlobject. php
*
* @ Author vb2005xu.iteye.com
*/
Class AclBase {
// --- ACL access authorization

/**
* No one is allowed to access
*/
Const NOBODY = 0;

/**
* Allow access by anyone
*/
Const EVERYONE = 1;

/**
* Allow access by users with roles
*/
Const HAS_ROLE = 2;

/**
* Allow access by a user without a role
*/
Const NO_ROLE = 3;
/**
* A resource-role associated with a defined role can be accessed.
*/
Const ALLOCATE_ROLES = 4;

// Define the relevant table name
Public $ tbResources = 'aclresources ';
Public $ tbRoles = 'aclroles ';
Public $ tbRefResourcesRoles = 'ref _ aclresources_aclroles ';
Public $ tbRefUsersRoles = 'ref _ users_aclroles ';

/**
* Format the resource access permission and return
*
* @ Return int
*/
Static function formatAccessValue ($ access ){
Static $ arr = array (self: NOBODY, self: EVERYONE, self: HAS_ROLE, self: NO_ROLE, self: ALLOCATE_ROLES );
Return in_array ($ access, $ arr )? $ Access: self: NOBODY;
}

/**
* Create a resource and return the primary key of the resource record.
*
* @ Param string $ rsid
* @ Param int $ access
* @ Param string $ desc
*
* @ Return int
*/
Function createResource ($ rsid, $ access, $ desc ){
If (empty ($ rsid) return false;

$ Resource = array (
'Rsid '=> $ rsid,
'Access' => self: formatAccessValue ($ access ),
'Desc' => $ desc,
'Created _ at' => CURRENT_TIMESTAMP
);

Return SingleTableCRUD: insert ($ this-> tbResources, $ resource );
}

/**
* Modify the resource and return the successful status.
*
* @ Param array $ resource
* @ Return int
*/
Function updateResource (array $ resource ){
If (! Isset ($ resource ['rsid ']) return false;

$ Resource ['updated _ at'] = CURRENT_TIMESTAMP;

Return SingleTableCRUD: update ($ this-> tbResources, $ resource, 'rsid ');
}

/**
* Deleting a resource
*
* @ Param string $ rsid
* @ Return int
*/
Function deleteResource ($ rsid ){
If (empty ($ rsid) return false;
Return SingleTableCRUD: delete ($ this-> tbResources, array ('rsid '=> $ rsid ));
}

/**
* Create a role and return the primary key of the role record.
*
* @ Param string $ rolename
* @ Param string $ desc
*
* @ Return int
*/
Function createRole ($ rolename, $ desc ){
If (empty ($ rolename) return false;

$ Role = array (
'Rolename' => $ rolename,
'Desc' => $ desc,
'Created _ at' => CURRENT_TIMESTAMP
);

Return SingleTableCRUD: insert ($ this-> tbRoles, $ role );
}

/**
* Modify the role and return the successful status.
*
* @ Param array $ role
* @ Return int
*/
Function updateRole (array $ role ){
If (! Isset ($ role ['id']) return false;

If (isset ($ role ['rolename']) unset ($ role ['rolename']);
$ Role ['updated _ at'] = CURRENT_TIMESTAMP;

Return SingleTableCRUD: update ($ this-> tbRoles, $ role, 'id ');
}

/**
* Delete a role
*
* @ Param int $ role_id
* @ Return int
*/
Function deleteRole ($ role_id ){
If (empty ($ role_id) return false;
Return SingleTableCRUD: delete ($ this-> tbRoles, array ('role _ id' => (int) $ role_id ));
}

/**
* Specify a role for the resource. each time, all relevant records in the table are removed before being inserted.
*
* @ Param int $ rsid
* @ Param mixed $ roleIds
* @ Param boolean $ setNull whether to clear resources from the associated table if the role id does not exist
*/
Function allocateRolesForResource ($ rsid, $ roleIds, $ setNull = false, $ defaultAccess =-1 ){
If (empty ($ rsid) return false;

$ RoleIds = normalize ($ roleIds ,',');
If (empty ($ roleIds )){
If ($ setNull ){
SingleTableCRUD: delete ($ this-> tbRefResourcesRoles, array ('rsid '=> $ rsid ));

If ($ defaaccess access! =-1 ){
$ DefaultAccess = self: formatAccessValue ($ defaultAccess );
$ This-> updateResource (array ('rsid '=> $ rsid, 'access' => $ defaultAccess ));
}
Return true;
}
Return false;
}

SingleTableCRUD: delete ($ this-> tbRefResourcesRoles, array ('rsid '=> $ rsid ));

$ RoleIds = array_unique ($ roleIds );

Foreach ($ roleIds as $ role_id ){
SingleTableCRUD: insert ($ this-> tbRefResourcesRoles, array ('rsid '=> $ rsid, 'role _ id' => (int) $ role_id ));
}
Return true;
}

Function cleanRolesForResource ($ rsid ){
If (empty ($ rsid) return false;
Return SingleTableCRUD: delete ($ this-> tbRefResourcesRoles, array ('rsid '=> $ rsid ));
}

Function cleanResourcesForRole ($ role_id ){
If (empty ($ role_id) return false;
Return SingleTableCRUD: delete ($ this-> tbRefResourcesRoles, array ('role _ id' => (int) $ role_id ));
}

/**
* Allocate resources to the role. each time, all relevant records in the table are removed before being inserted.
*
* @ Param int $ role_id
* @ Param mixed $ rsids
*
* @ Return boolean
*/
Function allocateResourcesForRole ($ role_id, $ rsids ){
If (empty ($ role_id) return false;

$ Role_id = (int) $ role_id;
$ Rsids = normalize ($ rsids ,',');
If (empty ($ rsids )){
Return false;
}

SingleTableCRUD: delete ($ this-> tbRefResourcesRoles, array ('role _ id' => $ role_id ));

$ Rsids = array_unique ($ rsids );

Foreach ($ rsids as $ rsid ){
SingleTableCRUD: insert ($ this-> tbRefResourcesRoles, array ('rsid '=> $ rsid, 'role _ id' => $ role_id ));
}
Return true;
}

/**
* Assign a role to the user. each time, all relevant records in the table are removed before being inserted.
*
* In this case, many users may have performance problems... how to optimize it later?
*
* @ Param int $ user_id
* @ Param mixed $ roleIds
*
* @ Return boolean
*/
Function allocateRolesForUser ($ user_id, $ roleIds ){
If (empty ($ user_id) return false;

$ User_id = (int) $ user_id;
$ RoleIds = normalize ($ roleIds ,',');
If (empty ($ roleIds )){
Return false;
}

SingleTableCRUD: delete ($ this-> tbRefUsersRoles, array ('User _ id' => $ user_id ));

$ RoleIds = array_unique ($ roleIds );

Foreach ($ roleIds as $ roleId ){
SingleTableCRUD: insert ($ this-> tbRefUsersRoles, array ('User _ id' => $ user_id, 'role _ id' => $ role_id ));
}
Return true;
}

/**
* Clear user role information
*
* @ Param int $ user_id
*
* @ Return boolean
*/
Function cleanRolesForUser ($ user_id ){
If (empty ($ user_id) return false;
Return SingleTableCRUD: delete ($ this-> tbRefUsersRoles, array ('User _ id' => (int) $ user_id ));
}

/**
* Clear the user association of a role.
*
* @ Param int $ role_id
*
* @ Return boolean
*/
Function cleanUsersForRole ($ role_id ){
If (empty ($ role_id) return false;
Return SingleTableCRUD: delete ($ this-> tbRefUsersRoles, array ('role _ id' => (int) $ role_id ));
}

}

The specific detection code is as follows:
Copy codeThe code is as follows:
/**
* Perform acl verification on resources
*
* @ Param string $ rsid resource ID
* @ Param array $ user specific user. If this parameter is not specified, the current user is verified.
*
* @ Return boolean
*/
Function aclVerity ($ rsid, array $ user = null ){

If (empty ($ rsid) return false;
If (! CoreApp: $ defaacl ACL ){
CoreApp: $ defaacl ACL = new AclFlat ();
}

$ RsRow = aclGetResource ($ rsid );

// No default resource access policy defined
If (! $ RsRow) return false;

CoreApp: writeLog ($ rsRow, 'test ');

$ RsRow ['access'] = AclBase: formatAccessValue ($ rsRow ['access']);

// Allow anyone to access
If (AclBase: EVERYONE ==$ rsRow ['access']) return true;

// No one is allowed to access
If (AclBase: NOBODY = $ rsRow ['access']) return false;

// Obtain user information
If (empty ($ user) $ user = isset ($ _ SESSION ['si-sysuser'])? $ _ SESSION ['si-sysuser']: null;

// If the user is not logged on, the user is deemed to have no access permission.
If (empty ($ user) return false;

$ User ['roles '] = empty ($ user ['roles'])? Null: normalize ($ user ['roles '],'; ');

$ UserHasRoles =! Empty ($ user ['roles ']);

/**
* Allow access by a user without a role
*/
If (AclBase: NO_ROLE = $ rsRow ['access']) return $ userHasRoles? False: true;

/**
* Allow access by users with roles
*/
If (AclBase: HAS_ROLE = $ rsRow ['access']) return $ userHasRoles? True: false;

// --- Perform resource verification for the user <-> role
If ($ userHasRoles ){
Foreach ($ user ['roles '] as $ role_id ){
If (aclGetRefResourcesRoles ($ rsid, $ role_id ))
Return true;
}
Dump ($ user );
}
Return false;
}

Copy codeThe code is as follows:
/**
* Perform acl verification on resources
*
* @ Param string $ rsid resource ID
* @ Param array $ user specific user. If this parameter is not specified, the current user is verified.
*
* @ Return boolean
*/
Function aclVerity ($ rsid, array $ user = null ){

If (empty ($ rsid) return false;
If (! CoreApp: $ defaacl ACL ){
CoreApp: $ defaacl ACL = new AclFlat ();
}

$ RsRow = aclGetResource ($ rsid );

// No default resource access policy defined
If (! $ RsRow) return false;

CoreApp: writeLog ($ rsRow, 'test ');

/*
* The verification procedure is as follows:
*
* 1. verify the access attribute of the resource.
* EVERYONE => true, NOBODY => false * verify other attributes below
* 2. obtain the role id set from the session (or user session table ).
* 3. if a user has a role, HAS_ROLE => true, NO_ROLE => false; and vice versa.
* 4. if resource access = ALLOCATE_ROLES
* 1. obtain the role id set corresponding to the resource from the cache (or $ tbRefResourcesRoles)
* 2. intersection the user's role id set with the role id set corresponding to the resource
* 3. intersection exists => true; otherwise => false
*/

$ RsRow ['access'] = AclBase: formatAccessValue ($ rsRow ['access']);

// Allow anyone to access
If (AclBase: EVERYONE ==$ rsRow ['access']) return true;

// No one is allowed to access
If (AclBase: NOBODY = $ rsRow ['access']) return false;

// Obtain user information
If (empty ($ user) $ user = isset ($ _ SESSION ['si-sysuser'])? $ _ SESSION ['si-sysuser']: null;

// If the user is not logged on, the user is deemed to have no access permission.
If (empty ($ user) return false;

$ User ['roles '] = empty ($ user ['roles'])? Null: normalize ($ user ['roles '],'; ');

$ UserHasRoles =! Empty ($ user ['roles ']);

/**
* Allow access by a user without a role
*/
If (AclBase: NO_ROLE = $ rsRow ['access']) return $ userHasRoles? False: true;

/**
* Allow access by users with roles
*/
If (AclBase: HAS_ROLE = $ rsRow ['access']) return $ userHasRoles? True: false;

// --- Perform resource verification for the user <-> role
If ($ userHasRoles ){
Foreach ($ user ['roles '] as $ role_id ){
If (aclGetRefResourcesRoles ($ rsid, $ role_id ))
Return true;
}
Dump ($ user );
}
Return false;
}
/**
* Regenerate the role resource access control table
*
* @ Param string $ actTable ACL table name
* @ Param boolean $ return whether to return the regenerated list
*
* @ Return mixed
*/
Function aclRebuildACT ($ actTable, $ return = false ){
If (empty ($ actTable) return false;

Global $ globalConf;
$ Rst = null;
$ CacheId = null;

Switch ($ actTable ){
Case CoreApp: $ defaultAcl-> tbResources:
$ CacheId = 'acl-resources ';
$ Rst = SingleTableCRUD: findAll (CoreApp ::$ defaacl ACL-> tbResources );
// Convert it into a hash table structure
If ($ rst ){
$ Rst = array_to_hashmap ($ rst, 'rsid ');
}
Break;
Case CoreApp: $ defaultAcl-> tbRoles:
$ CacheId = 'acl-roles ';
$ Rst = SingleTableCRUD: findAll (CoreApp ::$ defaacl ACL-> tbRoles );
// Convert it into a hash table structure
If ($ rst ){
$ Rst = array_to_hashmap ($ rst, 'id ');
}
Break;
Case CoreApp: $ defaultAcl-> tbRefResourcesRoles:
$ CacheId = 'acl-roles_has_resources ';
$ Rst = SingleTableCRUD: findAll (CoreApp ::$ defaacl ACL-> tbRefResourcesRoles );
If ($ rst ){
$ _ = Array ();
Foreach ($ rst as $ row ){
$ Ref_id = "{$ row ['rsid ']} <-|-> {$ row ['role _ id']}";
$ _ [$ Ref_id] = $ row;
}
Unset ($ rst );
$ Rst = $ _;
}
Break;
}

If ($ cacheId)
WriteCache ($ globalConf ['runtime'] ['cachedir'], $ cacheId, $ rst, true );

If ($ return) return $ rst;
}
/**
* Get role resource access control table data
*
* @ Param string $ actTable ACL table name
*
* @ Return mixed
*/
Function aclGetACT ($ actTable ){
If (empty ($ actTable) return false;

Static $ rst = array ();

$ CacheId = null;

Switch ($ actTable ){
Case CoreApp: $ defaultAcl-> tbResources:
$ CacheId = 'acl-resources ';
Break;
Case CoreApp: $ defaultAcl-> tbRoles:
$ CacheId = 'acl-roles ';
Break;
Case CoreApp: $ defaultAcl-> tbRefResourcesRoles:
$ CacheId = 'acl-roles_has_resources ';
Break;

}

If (! $ CacheId) return null;

If (isset ($ rst [$ cacheId]) return $ rst [$ cacheId];

Global $ globalConf;
// 900
$ Rst [$ cacheId] = getCache ($ globalConf ['runtime'] ['cachedir'], $ cacheId, 0 );
If (! $ Rst [$ cacheId]) {
$ Rst [$ cacheId] = aclRebuildACT ($ actTable, true );
}

Return $ rst [$ cacheId];
}
/**
* Retrieve resource records
*
* @ Param string $ rsid
*
* @ Return array
*/
Function aclGetResource ($ rsid ){
Static $ rst = null;
If (! $ Rst ){
$ Rst = aclGetACT (CoreApp: $ defaacl ACL-> tbResources );
If (! $ Rst) $ rst = array ();
}
Return isset ($ rst [$ rsid])? $ Rst [$ rsid]: null;
}
/**
* Get role Records
*
* @ Param int $ role_id
*
* @ Return array
*/
Function aclGetRole ($ role_id ){
Static $ rst = null;
If (! $ Rst ){
$ Rst = aclGetACT (CoreApp: $ defaacl ACL-> tbRoles );
If (! $ Rst) $ rst = array ();
}
Return isset ($ rst [$ role_id])? $ Rst [$ role_id]: null;
}
/**
* Obtains the user role Association record. this method can be used to check whether resources can be called by this role.
*
* @ Param string $ rsid
* @ Param int $ role_id
*
* @ Return array
*/
Function aclGetRefResourcesRoles ($ rsid, $ role_id ){
Static $ rst = null;
If (! $ Rst ){
$ Rst = aclGetACT (CoreApp: $ defaacl ACL-> tbRefResourcesRoles );
If (! $ Rst) $ rst = array ();
}
$ Ref_id = "{$ rsid} <-|-> {$ role_id }";
CoreApp: writeLog (isset ($ rst [$ ref_id])? $ Rst [$ ref_id]: 'nodata', $ ref_id );
Return isset ($ rst [$ ref_id])? $ Rst [$ ref_id]: null;
}

Http://code.google.com/p/php-excel/downloads/list mini easy to use EXCEL xml output scheme

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.