簡體   English   中英

只允許作者使用ACF在yii2中編輯他的帖子

[英]Allow only author to edit his post in yii2 using ACF

我使用訪問控制過濾器進行訪問管理,但無法完成一件事 - 例如,我如何才能讓項目經理更新項目並禁止其他人? 我通過matchCallback嘗試了它,但在這種情況下,所有項目經理都可以更新任何項目,因為返回了TRUE。

類似的更常用的規則 - 如何允許用戶使用ACF更新/刪除他是作者的帖子?

         'access' => [
            'class' => AccessControl::className(),
            'only' => ['index', 'view', 'create', 'update', 'delete'],
            'rules' => [
                [
                    'actions' => ['update'],
                    'allow' => true,
                    'roles' => ['@'],
                    'matchCallback' => function ($rule, $action) {

                        return Yii::$app->user->identity->getProjectParticipants()
                                    ->one()->isManager(Yii::$app->user->identity->id);
                    }
                ],
            ],
        ],

它可以實現如下:

use Yii;
use yii\web\Controller;
use yii\filters\AccessControl;

class MyController extends Controller
{

...

    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['update', 'delete'],
                'rules' => [
                    [
                        'actions' => ['update', 'delete'],
                        'allow' => true,
                        'roles' => ['@'],
                        'matchCallback' => function ($rule, $action) {
                            if (Yii::$app->user->can('admin') || $this->isUserAuthor()) {
                                return true;
                            }
                            return false;
                        }
                    ],
                ],
            ],
        ];
    }

    protected function findModel($id)
    {
        if (($model = MyModel::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }

    protected function isUserAuthor()
    {   
        return $this->findModel(Yii::$app->request->get('id'))->author->id == Yii::$app->user->id;
    }

...

}

這是通過自定義AccessRule解決的問題。 必須填寫代碼以檢查用戶是否是項目的作者。

namespace app\filters;

class AuthorAccessRule extends \yii\filters\AccessRule
{
    public $allow = true;  // Allow access if this rule matches
    public $roles = ['@']; // Ensure user is logged in.

    public function allows($action, $user, $request)
    {
        $parentRes = parent::allows($action, $user, $request);
        // $parentRes can be `null`, `false` or `true`.
        // True means the parent rule matched and allows access.
        if ($parentRes !== true) {
            return $parentRes;
        }
        return ($this->getProjectAuthorId($request) == $user->id);
     }

     private function getProjectAuthorId($request)
     {
         // Fill in code to receive the right project.
         // assuming the project id is given à la `project/update?id=1`
         $projectId = $request->get('id');
         $project = \app\models\Project::findOne($projectId);
         return isset($project) ? $project->author_id : null;
     }
}

可以通過在行為中包含此規則來使用該規則:

'authorAccess' => [
        'class' => AccessControl::className(),
        'only' => ['update'],
        'rules' => ['actions' => ['update']],
        'ruleConfig' => ['class' => '\app\filters\AuthorAccessRule'],
],

以下是我如何使用ACF和RBAC的組合。 如果我錯了或者有更好的方法,請糾正我。 它基於Basic模板。

  1. 用戶角色存儲在“用戶”表的“角色”列中。 在此示例中使用另一個表“country”。 假設您已使用Gii生成模型和控制器。

  2. 自定義PhpManager以使用數據庫表“user”中的角色。

class PhpManager extends \yii\rbac\PhpManager
{
    public function init()
    {
        parent::init();
    }

    public function getAssignments($userId)
    {
        if (!Yii::$app->user->isGuest) {
            $assignment = new Assignment();
            $assignment->userId = $userId;
            # Assume the role is stored in User table "role" column
            $assignment->roleName = Yii::$app->user->identity->role;
            return [$assignment->roleName => $assignment];
        }
    }
}

3.將authManager添加到web.app和console.app控制台文件。

    'authManager' => [
        'class' => 'app\components\PhpManager',
        'defaultRoles' => ['user', 'manager', 'admin', 'master'],
    ],
  1. 創建自定義的AccessRule。 來自speixoto博客的參考資料。

 # Reference # http://programming.peixoto.cf/2015/01/14/yii2-role-based-access-control-and-context-access-rule/#$$nmvkr0&&0SUmhOPVEeSW9grIhAgzZg$$ class ContextAccessRule extends AccessRule { public $modelClass; public $primaryKey; protected function matchRole($user) { if (parent::matchRole($user)) return true; $model = $this->findModel(); foreach ($this->roles as $role) { # Call the CheckAccess() function which process rules if ($user->can($role, ['model' => $model])) { return true; } } return false; } protected function findModel() { if (!isset($this->modelClass)) throw new InvalidConfigException(Yii::t('app', 'the "modelClass" must be set for "{class}".', ['class' => __CLASS__])); $primaryKey = $this->getPrimaryKey(); # Get the request params $queryParams = \\Yii::$app->getRequest()->getQueryParams(); # Load the model $model = call_user_func([$this->modelClass, 'findOne'], $queryParams[join(',', $primaryKey)]); if ($model !== null) { return $model; } else { throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exists.')); } } # Get the primary key of the model protected function getPrimaryKey() { if (!isset($this->primaryKey)) { return call_user_func([$this->modelClass, 'primaryKey']); } else { return $this->primaryKey; } } 

  1. 創建一個RbacController.php以生成RBAC文件(assignments.php,items.php,rules.php)到rbac文件夾中。

 class RbacController extends Controller { public function actionInit() { $auth = Yii::$app->authManager; $auth->removeAll(); ### CREATE & ADD ROLES $user = $auth->createRole('user'); $node = $auth->createRole('node'); $manager = $auth->createRole('manager'); $admin = $auth->createRole('admin'); $master = $auth->createRole('master'); $auth->add($user); $auth->add($node); $auth->add($manager); $auth->add($admin); $auth->add($master); $auth->addChild($manager, $user); $auth->addChild($manager, $node); $auth->addChild($admin, $manager); $auth->addChild($master, $admin); ### ADD RULES $ownerRule = new \\app\\components\\OwnerRule(); $auth->add($ownerRule); ### CREATE PERMISSIONS ### $pUpdateOwn = $auth->createPermission('updateOwn'); $pUpdateOwn->description = 'update own'; $pUpdateOwn->ruleName = $ownerRule->name; $auth->add($pUpdateOwn); $auth->addChild($pUpdateOwn, $pUpdate); $pDeleteOwn = $auth->createPermission('deleteOwn'); $pDeleteOwn->description = 'delete own'; $pDeleteOwn->ruleName = $ownerRule->name; $auth->add($pDeleteOwn); $auth->addChild($pDeleteOwn, $pDelete); ### ASSIGN PERMISSION TO ROLES $auth->addChild($user, $pUpdateOwn); $auth->addChild($user, $pDeleteOwn); $auth->addChild($manager, $pUpdateOwn); $auth->addChild($manager, $pDeleteOwn); } } 

  1. 從控制台,導航到項目根目錄。 運行./yii rbac/init (對於mac)將3個文件生成到rbac文件夾中。

  2. 在CountryController.php中,覆蓋以下函數以添加“訪問”行為。

  public function behaviors() { $behaviors = parent::behaviors(); $behaviors['verbs'] = [ 'class' => VerbFilter::className(), 'actions' => [ 'delete' => ['post'], ], ]; ['access'] = [ 'class' => AccessControl::className(), // 'only' => ['view', 'index', 'create', 'update', 'delete'], 'rules' => [ [ 'actions' => ['view', 'index'], 'allow' => true, 'roles' => ['?', '@'], ], [ 'actions' => ['create'], 'allow' => true, // Allow users, manager and admins to create 'roles' => ['user'], ], [ 'class' => 'app\\components\\ContextAccessRule', 'modelClass' => 'app\\models\\Country', 'actions' => ['update'], 'allow' => true, # allow owner and manager to udpate 'roles' => ['updateOwn', 'manager'] ], [ 'class' => 'app\\components\\ContextAccessRule', 'modelClass' => 'app\\models\\Country', 'actions' => ['delete'], 'allow' => true, # allow owner and manager to delete 'roles' => ['deleteOwn', 'manager'], ], ], # if user not login, and not allowed for current action, return following exception 'denyCallback' => function ($rule, $action) { throw new UnauthorizedHttpException('You are not authorized.'); }, ]; return $behaviors; } 
8.測試一下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM