Rui Sousa
Rui Sousa

Reputation: 57

Yii2: Update user permissions

I'm trying to update user including his permissions. This is how i'm doing it. Seems i'm missing something but i don't know what it is yet.

public function actionUpdate($id)
{
$model = $this->findModel($id);
$perfis = $model->authAssignment;

foreach ($perfis as $perfil) {
  array_push($model->perfil_array, $perfil->item_name);
}

if ($model->load(Yii::$app->request->post()) && $model->validate()) {
  $itemsSaved = false;
  $permissionsList = Yii::$app->request->post()['User']['perfil_array'];
  if (!empty($permissionsList)) {
      foreach ($permissionsList as $permission) {
         $newPermission = new AuthAssignment;
         $newPermission->item_name = $permission;
         $newPermission->user_id = $id;
         if($newPermission->save()){
            print_r("ok");
         } else {
            print_r($newPermission->getErrors()); die;
         }
      }
   }
   if ($model->save()) {
      $itemsSaved = true;
   } else {
     print_r($model->getErrors());die;
     return $this->render('update', [
     'model' => $model,]);
   }
   if ($itemsSaved) {
      return $this->redirect(['view', 'id' => $model->id]);
   }
}
return $this->render('update', ['model' => $model,]);
}

I'm getting all the posted permissions from the form checkboxes and save it to AuthAssignment table but it throwing this error.

Array
(
    [item_name] => Array
        (
            [0] => The combination "Admin"-"10" of Item Name and User ID has already been taken.
        )

    [user_id] => Array
        (
            [0] => The combination "Admin"-"10" of Item Name and User ID has already been taken.
        )

)

User model:

class User extends ActiveRecord implements IdentityInterface
{
    const STATUS_DELETED = 0;
    const STATUS_ACTIVE = 10;

    public $currentPassword;
    public $newPassword;
    public $newPasswordConfirm;
    public $perfil;
    public $perfil_array = [];

    public function attributeLabels()
    {
        return [
            'currentPassword' => 'Palavra passe atual',
            'newPassword' => 'Nova palavra passe',
            'newPasswordConfirm' => 'Confirmar nova palavra passse',
            'created_at' =>  'Data Criação',
            'updated_at' =>  'Data Atualização',
        ];
    }
    public function rules()
    {
        return [
            ['status', 'default', 'value' => self::STATUS_ACTIVE],
            ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],                
        ];
    }
    public function getAuthAssignment() {
        return $this->hasMany(AuthAssignment::className(), ['user_id' => 'id']);
    }

How can i remove all the permissions for the user i'm updating before updating?

Upvotes: 1

Views: 1106

Answers (2)

Rui Sousa
Rui Sousa

Reputation: 57

This is how managed to do it after some research.

if ($model->load(Yii::$app->request->post()) && $model->validate()) {
    $itemsSaved = false;
    $permissionsList = Yii::$app->request->post()['User']['perfil_array'];
    if (!empty($permissionsList)) {
        $permissions = AuthAssignment::find()
        ->where(['user_id' => $id])->all();
        if (!empty($permissions)) {
            foreach ($permissions as $permission) {
                $permission->delete();
            }
        }
        foreach ($permissionsList as $permission) {
            $newPermission = new AuthAssignment;
            if ($newPermission->item_name != $permission) {
                $newPermission->item_name = $permission;
                $newPermission->user_id = $id;
            }
            if($newPermission->save()){
                print_r("okkkkkkkkk");
            } else {
                print_r($newPermission->getErrors());
            }
        } 
  }
  if ($model->save()) {
      $itemsSaved = true;
  } else {
      print_r($model->getErrors());die;
      return $this->render('update', [
      'model' => $model,]);
  }
  if ($itemsSaved) {
      return $this->redirect(['view', 'id' => $model->id]);
  }


}

I find all the permissions for that particular user and remove all of them before assigning new permissions. Don't know if it isthe best way to do it but it works.

Upvotes: 0

Raul Sauco
Raul Sauco

Reputation: 2705

You could try checking if the entry exists, one way to do it would be to check if the user has the permission already.

if (!empty($permissionsList)) {

    // Get the authentication component
    $auth = Yii::$app->authManager;

    foreach ($permissionsList as $permission) {

        // Check if the user has the permission
        if (!$auth->checkAccess($id, $permission)) {

            // Check if the permission exists
            if ($auth->getPermission($permission) !== null) {

                // Create the new permission and add it to the rbac system
                $newPermission = $auth->createPermission($permission);
                $newPermission->description = 'my cool description';                      
                $auth->add($newPermission);

            }             

            /* 
             * Once here we know that the permission exists, it 
             * was there before or we created it.
             * I am going to assume that the user exists.
             * We can go ahead and give that user the permission.
             */
            try {
                $auth->assign($newPermission, $id);
            } catch (Exception $e) {
                Yii::error($e, __METHOD__);
            }
        }
    }
}

Upvotes: 1

Related Questions