2015-03-02 58 views
1

我在数据库中简化了以下关系。什么是检查用户是否有权访问实体的最佳方法

1 User -> n Projects 
1 Project -> n Tasks 
etc. 

所以,现在我经常发现自己在在代码执行以下操作

// Get the current logged in User 
$user = Session::getUser(); 
$project = $this->projects->findById($project_id); 
if (! $project->hasOwner($user)) 
    // user does not own the project 

而这就是与该项目有关系变得更糟。例如,那么我必须检查用户是否拥有这些项目,然后检查这些任务是否属于该项目。

我在想也许使用Eager Loading在这里,所以我可以只对给定的结果进行过滤。但是,然后数据库必须加载更多的数据,然后通常是必需的。对 ?

// Get the current logged in User 
$user = Session::getUser(); 
$project = $user->projects()->find($project_id); 
if (! $project) 
    // user does not own the project 

但即使我这样做,它感觉重复和哈克。我想知道是否有更好的方法来解决这个问题?

回答

1

虽然用户可以访问他们的项目,但您需要为将来与其他用户共享项目及其访问类型做出规定。

因此,强烈建议使用project_permission表。

结构应该如下:

id | project_id | grantee_user_id | access_user_id |键入| created_at | updated_at | deleted_at

您将有3种类型的权限:

  1. 所有者 - 完全权限
  2. 编辑访问
  3. 只读访问

您的权限模型:

class ProjectPermission extends Eloquent { 
    protected $table = "project_permission"; 

    /* 
    * Types 
    */ 

    const OWNER = 1; 
    const EDIT = 2; 
    const READ = 3; 

    /* 
    * Scopes 
    */ 

    public function scopeOwner($query) 
    { 
     return $query->whereType(self::OWNER); 
    } 

    public function scopeEdit($query) 
    { 
     return $query->whereType(self::EDIT); 
    } 

    public function scopeRead($query) 
    { 
     return $query->whereType(self::READ); 
    } 

    public function project() 
    { 
     return $this->belongTo('Project','project_id'); 
    } 

} 

和项目m odel:

class Project extends Eloquent { 
    ... 
    //Always eager load project permission 
    public $with = ['permission']; 

    public function permission() 
    { 
     return $this->hasMany('ProjectPermission','project_id'); 
    } 

    public function scopeUserIsOwner($query,$user_id) 
    { 
     return $query->has('permission'=>function($q){ 
      return $q->owner()->where('access_user_id','=',$user_id); 
     }); 
    } 

    public function scopeCurrentUserIsOwner($query,$user_id) 
    { 
     $user = Session::getUser(); 
     $user_id = $user ? $user->id : 0; 

     return $query->has('permission'=>function($q){ 
      return $q->owner()->where('access_user_id','=',$user_id); 
     }); 
    } 

    /* 
    * @param int $user_id 
    * @return boolean 
    */ 
    public function hasAccessOwner($user_id) 
    { 
     return (bool)$this->permission()->whereType(\ProjectPermission::OWNER)->->whereAccessUserId($user_id)->count(); 
    } 
} 

理想情况下,您应该只加载用户有权访问的项目。如果需要检查访问,hasAccess..功能将证明是方便的。

相关问题