| 제목 | 기본 퍼미션 라이브러리 | ||
|---|---|---|---|
| 글쓴이 | 에반스 | 작성시각 | 2017/03/08 19:54:22 |
|
|
|||
|
안녕하세요. 다들 기본적으로 사용하는 User - Role 퍼미션 라이브러리를 만들어 봤습니다. 어떤 기능을 사용할 때 전에 권한 설정을 검사하는 거죠. 가독성이 좋게 포맷되어 있습니다. $this->permisson->user("evans")->can("view admin page"); evans 유저는 어드민 페이지를 볼 수 있다. 이런식으로 직관적으로 코딩할 수 있습니다. 유저, 역할, 퍼미션 이 세가지가 각각 N:M 관계로 테이블 구조가 만들어져 있습니다. 유저에게 직접 퍼미션을 줄 수 있지만, 역할에 퍼미션을 할당할 수도 있습니다.
혹시, 권한 인증 같은 게 어려우신 스타터에게 작은 도움이 되길 바랍니다. 에러나 수정사항은 Pull request 주시면 반영하도록 하겠습니다. https://github.com/korodo/codeigniter-permission/blob/master/Permission.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* 퍼미션 라이브러리.
*
* 반드시 Migrate 를 커멘드로 실행하세요.
*
* 예시) 컨트롤러에서 활용 예시..
*
* $this->load->library("permission");
*
* 유저에게 어드민 페이지 접근허가하기
* $this->permission->user('username')->can("access admin page");
*
* 접근 불허하기
* $this->permission->user('username')->cannot("access admin page");
*
* 패스워드 체크
* $this->user("username")->check("password");
*
* 허가여부 체크
* $this->permission->user('username')->isPermitted("access admin page");
* 유저에게 단일 퍼미션이 우선적으로 있는지 확인하고 이후 유저에게 부여된 역할통해 역할이 가진 퍼미션을 검사합니다.
*
* 간단하게 확인하기
* if ( permission("username", "permission_name") ){
* echo "퍼미션 통과"
* }else{
* echo "퍼미션 불가"
* }
*/
class Permission
{
protected $ci;
protected $user;
protected $perm;
protected $role;
protected $table = [];
public function __construct()
{
$this->ci =& get_instance();
// 테이블 명을 바꾸고 싶다면 아래 값을 변경하세요.
$this->table['user'] = "au_user";
$this->table['role'] = "au_role";
$this->table['perm'] = "au_permission";
$this->table['user_perm'] = "au_users_permissions";
$this->table['user_role'] = "au_users_roles";
$this->table['role_perm'] = "au_roles_permissions";
$this->ci->load->library("session");
}
/**
* 사용자를 설정
* @param [type] $username [description]
* @return [type] [description]
*/
public function user($username)
{
$this->user = $this->ci->db->where("username", $username)->get($this->table['user'])->row();
if($this->user){
$this->session->userdata['user'] = $this->user;
return $this;
}else{
show_error("잘못된 아이디 또는 패스워드입니다.");
return false;
}
}
function check($password){
if($this->user->password == do_hash($password)){
return true;
}else{
return false;
}
}
/**
* 사용자 또는 역할에 퍼미션을 할당합니다.
* @param [type] $permission [description]
* @return [type] [description]
*/
function can($permission)
{
$this->_getPerm($permission);
if($this->user){
if(!$this->isPermitted($permission)){
$this->_setUserPerm();
}
return $this;
}
if($this->role){
if(!$this->_isRoleHasPerm()){
$this->_setRolePerm();
}
return $this;
}
}
/**
* 할당된 퍼미션을 삭제합니다.
* @param [type] $permission [description]
* @return [type] [description]
*/
function cannot($permission)
{
$this->_getPerm($permission);
if($this->user){
if($this->isPermitted($permission)){
$this->_unsetUserPerm();
}
return $this;
}
if($this->role){
$this->_unsetRolePerm();
return $this;
}
}
/**
* 퍼미션을 종합적으로 확인합니다.
* @param [type] $permission [description]
* @return boolean [description]
*/
function isPermitted($permission)
{
$this->_checkUser();
if($this->user->id == 1 OR $this->_isSuperRole() ){
return true;
}
$this->_getPerm($permission);
if($this->_isUserPermitted()){
// 다이렉트 퍼미션 확인
return true;
}else{
//사용자의 역할을 기준으로 확인 user > user_role > role_id > role_perm
return $this->_isUserRolePermitted();
}
}
/**
* 사용자에게 역할을 할당합니다.
* @param [type] $role [description]
* @return boolean [description]
*/
function hasRole($role)
{
$this->_checkUser();
$this->_getRole($role);
if(!$this->isUserAssigned()){
$this->_assignedTo();
}
return $this;
}
/**
* 할당된 역할을 삭제합니다.
* @param [type] $role [description]
* @return [type] [description]
*/
function hasntRole($role)
{
$this->_checkUser();
$this->_getRole($role);
if( $this->isUserAssigned() )
{
$this->_unsetUserAssigned();
}
}
/**
* 역할을 설정합니다.
* @param [type] $role [description]
* @return [type] [description]
*/
function role($role){
$this->_getRole($role);
return $this;
}
/**
* 사용자에게 역할이 할당되어 있는지 체크 합니다.
* @param [type] $role [description]
* @return boolean [description]
*/
function isAssignedTo($role){
$this->_getRole($role);
return $this->isUserAssigned();
}
function isUserAssigned($role="")
{
$this->_checkUser();
if($role){
$this->_getRole($role);
}
$role = $this->ci->db->where(["user_id"=>$this->user->id , "role_id"=>$this->role->id])->get($this->table['user_role'])->row();
if($role){
return true;
}else{
return false;
}
}
protected function _isRoleHasPerm(){
if(!$this->role->id || !$this->perm->id){
show_error("역할 설정 또는 퍼미션 설정이 안되어 있습니다.");
}
$role = $this->ci->db->where( [ "role_id"=>$this->role->id, "permission_id"=>$this->perm->id ] )->get($this->table['role_perm'])->row();
if($role){
return true;
}else{
return false;
}
}
protected function _isUserRolePermitted(){
$perm = $this->ci->db->from($this->table['user'])
->join($this->table['user_role'], $this->table['user'] . ".id = ".$this->table['user_role'].".user_id" , "INNER")
->join($this->table['role_perm'], $this->table['user_role'].".role_id = " . $this->table['role_perm'] . ".permission_id","INNER")
->where( [ "permission_id"=>$this->perm->id , $this->table['user'].".id"=>$this->user->id ])->get()->row();
if($perm){
return true;
}else{
return false;
}
}
protected function _isSuperRole(){
$superRole = $this->ci->db->where("id", 1)->get($this->table['role'])->row();
return $this->isUserAssigned($superRole->name);
}
protected function _unsetUserAssigned()
{
$this->ci->db->where(["user_id"=>$this->user->id , "role_id"=>$this->role->id])->delete($this->table['user_role']);
}
protected function _assignedTo()
{
$this->ci->db->insert($this->table['user_role'],
["user_id"=>$this->user->id , "role_id"=>$this->role->id]);
}
protected function _getRole($role)
{
$this->role = $this->ci->db->where("name", $role)->get($this->table['role'])->row();
if(!$this->role){
show_error("해당 역할이 없습니다.");
}
}
protected function _setRole($role)
{
$this->ci->db->insert($this->table['user_role'], ['user_id'=>$this->user->id, 'role_id'=>$this->role->id ]);
}
/** 유저와 퍼미션 관계설정 */
protected function _unsetUserPerm()
{
$this->ci->db->where(["permission_id"=>$this->perm->id, "user_id"=>$this->user->id])->delete($this->table['user_perm']);
}
protected function _setUserPerm()
{
$this->ci->db->insert($this->table['user_perm'],
["user_id"=>$this->user->id , "permission_id"=>$this->perm->id]);
}
protected function _unsetRolePerm()
{
$this->ci->db->where(["permission_id"=>$this->perm->id, "role_id"=>$this->role->id])->delete($this->table['role_perm']);
}
protected function _setRolePerm()
{
$this->ci->db->insert($this->table['role_perm'],
["role_id"=>$this->role->id , "permission_id"=>$this->perm->id]);
}
protected function _getPerm($permission)
{
$this->perm = $this->ci->db->where("name", $permission)->get($this->table['perm'])->row();
if(!$this->perm){
show_error("No exist Permission Name");
}
}
protected function _isUserPermitted()
{
$perm = $this->ci->db->where([ "user_id"=>$this->user->id, "permission_id"=>$this->perm->id ])->get($this->table['user_perm'])->row();
if( $perm ){
return true;
}else{
return false;
}
}
protected function _checkUser()
{
if(!$this->user){
show_error("No permission without user setting");
}
}
/**
* 사용자 등록
* @param [type] $username [description]
* @param [type] $password [description]
* @return [type] [description]
*/
function registerUser($username, $password){
$this->ci->db->insert($this->table['user'], ['username'=>$username, "password"=>do_hash($password)]);
return $this->ci->db->insert_id();
}
/**
* 역할 등록
* @param [type] $name [description]
* @return [type] [description]
*/
function registerRole($name){
$this->ci->db->insert($this->table['role'], ['name'=>$username]);
return $this->ci->db->insert_id();
}
/**
* 퍼미션 등록
* @param [type] $name [description]
* @return [type] [description]
*/
function registerPermission($name){
$this->ci->db->insert($this->table['perm'], ['name'=>$username]);
return $this->ci->db->insert_id();
}
function unitTest(){
$success = 0;
echo "<pre>";
if( $this->user("admin")->isPermitted("access SUPER") ){
echo "permitted SUPER \n";
$success++;
}
if ( !$this->user("tester")->isPermitted("access SUPER") ){
echo $this->user->username ."퍼밋 실패. 퍼밋 생성 후 재 실행 \n";
$this->user("tester")->can("access SUPER"); // 퍼미션을 줍니다.
$success++;
}
if($this->isPermitted("access SUPER")){
echo $this->user->username . "퍼미션 성공. 퍼밋 제거 후 재 실행 \n";
$this->user("tester")->cannot("access SUPER");
$success++;
}
if(!$this->isPermitted("access SUPER")){
echo $this->user->username . "퍼미션 실패. 퍼미션 제거 성공. 역할 설정 및 재 실행 \n";
$this->user("tester")->hasRole("Administer");
$success++;
}
if($this->isPermitted("access SUPER")){
echo $this->user->username . "퍼미션 성공. 역할 제거 및 재 실행 \n";
$this->user("tester")->hasntRole("Administer");
$success++;
}
if(!$this->isPermitted("access SUPER")){
echo $this->user->username . "퍼미션 실패, 역할제거 성공 \n";
$success++;
}
echo "\n \n \n ". $success;
if($success == 6 ){
echo "최종 성공";
}else{
echo "테스트 실패";
}
echo "</pre>";
}
function migrate(){
if( !$this->input->is_cli_request() ){
show_error("마이그레이션은 콘솔을 통해 접근하세요.");
}
$sql = "
CREATE TABLE `au_permission` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE `au_role` (
`id` int(10) unsigned NOT NULL,
`name` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE `au_roles_permissions` (
`permission_id` int(10) unsigned DEFAULT NULL ,
`role_id` int(10) unsigned DEFAULT NULL ,
KEY `FK_au_role_TO_au_roles_permissions` (`permission_id`),
KEY `FK_au_permission_TO_au_roles_permissions` (`role_id`),
CONSTRAINT `FK_au_permission_TO_au_roles_permissions` FOREIGN KEY (`role_id`) REFERENCES `au_permission` (`id`),
CONSTRAINT `FK_au_role_TO_au_roles_permissions` FOREIGN KEY (`permission_id`) REFERENCES `au_role` (`id`)
) ENGINE=InnoDB;
CREATE TABLE `au_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT ,
`username` varchar(100) CHARACTER SET utf8 NOT NULL ,
`password` varchar(100) NOT NULL ,
PRIMARY KEY (`id`),
UNIQUE KEY `username_UNIQUE` (`username`)
) ENGINE=InnoDB;
CREATE TABLE `au_users_permissions` (
`user_id` int(10) unsigned DEFAULT NULL ,
`permission_id` int(10) unsigned DEFAULT NULL ,
KEY `FK_au_user_TO_au_users_permissions` (`user_id`),
KEY `FK_au_permission_TO_au_users_permissions` (`permission_id`),
CONSTRAINT `FK_au_permission_TO_au_users_permissions` FOREIGN KEY (`permission_id`) REFERENCES `au_permission` (`id`),
CONSTRAINT `FK_au_user_TO_au_users_permissions` FOREIGN KEY (`user_id`) REFERENCES `au_user` (`id`)
) ENGINE=InnoDB;
CREATE TABLE `au_users_roles` (
`user_id` int(10) unsigned DEFAULT NULL ,
`role_id` int(10) unsigned DEFAULT NULL ,
KEY `FK_au_user_TO_au_users_roles` (`user_id`),
KEY `FK_au_role_TO_au_users_roles` (`role_id`),
CONSTRAINT `FK_au_role_TO_au_users_roles` FOREIGN KEY (`role_id`) REFERENCES `au_role` (`id`),
CONSTRAINT `FK_au_user_TO_au_users_roles` FOREIGN KEY (`user_id`) REFERENCES `au_user` (`id`)
) ENGINE=InnoDB;
";
$this->ci->db->query($sql);
$this->seed();
}
protected function seed(){
$this->ci->db->insert($this->table['user'], ['username'=>'admin', 'password'=>do_hash("admin")]);
$this->ci->db->insert($this->table['role'], ['name'=>'Administer']);
$this->ci->db->insert($this->table['perm'], ['name'=>'access SUPER']);
$this->ci->db->insert($this->table['user_role'], ['user_id'=>1, 'role_id'=>1]);
$this->ci->db->insert($this->table['role_perm'], ['role_id'=>1, 'permission_id'=>1]);
$this->ci->db->insert($this->table['user_perm'], ['user_id'=>1, 'permission_id'=>1]);
$this->registerUser("tester", "tester");
}
}
function permission($username, $permission){
$perm = new Permission;
return $perm->user($username)->isPermitted($permission);
}
/* End of file Permission.php */
/* Location: ./application/libraries/Permission.php */
|
|||
| 다음글 | 폼빌더... (1) | ||
| 이전글 | rest api 만들때 폼검증부분 관련.. (5) | ||
|
한대승(불의회상)
/
2017/03/09 08:29:38 /
추천
0
|
|
변종원(웅파)
/
2017/03/23 12:52:53 /
추천
0
tank auth랑 잘 녹이면 좋을 것 같네요. 라이브러리 감사합니다.
|
|
아주머니
/
2017/04/25 14:38:11 /
추천
0
링크가 사라졌네요 ㅜ 써보려고하는데 migrate부터 계속 오류가 나서 써볼 수가 없네요.. |
자주 사용되는 라이브러리인데 새로운 프로젝트 진행시 적용해 보아야겠습니다.
공유해 주셔서 감사 합니다.