Как скрыть учетную запись администратора от других пользователей

Я работаю над yii2, у меня есть немного user roles, Админ имеет все уровни доступа. Другие пользователи имеют низкий уровень доступа. Существует список пользователей, который виден другому пользователю. В этом списке доступны все детали пользователей в системе. Теперь я хочу скрыть некоторую информацию о пользователях от других пользователей. Роли, которые я хочу скрыть 1,6,7,8 и роль, которую я хочу скрыть, 5, Помимо упомянутых ролей пользователя должны быть видны 5, Для этого я обновил контроллер индекса.

 $searchModel = new UserSearch();

    $queryParams=Yii::$app->request->queryParams;
    //check if user or one of the managers
    $isAdmin=in_array(Yii::$app->user->identity->user_role,[1]);

    //set params if normal user
    if(!$isAdmin){
        $queryParams['UserSearch']['user_role']=in_array(Yii::$app->user->identity->user_role,[2,3,4,5]);
    }

    $dataProvider = $searchModel->search($queryParams);

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider
    ]);

Сейчас, когда я запускаю свой проект, я вижу только администратора. В $queryParams['UserSearch']['user_role']= Я пытался передать единственное значение роли пользователя 5 и это показывает только мне 5 Роль пользователей. Но я хочу показать пользователям с ролью 2,3,4,5,

Обновление 1

Моя поисковая модель

class UserSearch extends User
{
/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['id','group_id'], 'integer'],
        [['email','username', 'name','contact_number','group_id','user_role'], 'safe'],
    ];
}

/**
 * @inheritdoc
 */
public function scenarios()
{
    // bypass scenarios() implementation in the parent class
    return Model::scenarios();
}

/**
 * Creates data provider instance with search query applied
 *
 * @param array $params
 *
 * @return ActiveDataProvider
 */
public function search($params)
{
    $query = User::find();

    // add conditions that should always apply here

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    $this->load($params);

    if (!$this->validate()) {
        // uncomment the following line if you do not want to return any records when validation fails
        // $query->where('0=1');
        return $dataProvider;
    }

    // grid filtering conditions
    $query->andFilterWhere([
        'id' => $this->id,
        'status' => $this->status,
    ]);

    $query->andFilterWhere(['like', 'id', $this->id])
        ->andFilterWhere(['like', 'name', $this->name])
        ->andFilterWhere(['like', 'username', $this->username])
        ->andFilterWhere(['like', 'email', $this->email])
        ->andFilterWhere(['like', 'contact_number', $this->contact_number])
        ->andFilterWhere(['=', 'user_role', $this->user_role])
        ->andFilterWhere(['=', 'group_id', $this->group_id]);


   // $query->andFilterWhere(['=','user_type','user']);
    if(Yii::$app->user->identity->user_role == Roles::ROLE_TEAM_LEAD && Yii::$app->user->identity->group_id != ''){
        $query->andFilterWhere(['=','group_id', Yii::$app->user->identity->group_id])->andWhere('user_role=4');
    }
    //$query->andFilterWhere(['!=', 'id', Yii::$app->user->id]);

    return $dataProvider;
}
 }

Любая помощь будет высоко оценен.

3 ответа

Решение

Измени свою линию

$queryParams['UserSearch']['user_role']=in_array(Yii::$app->user->identity->user_role,[2,3,4,5]);

в

$queryParams['UserSearch']['user_role']=in_array(Yii::$app->user->identity->user_role,[2,3,4,5])?[1,6,7,8]:'';

и внутри вашей поисковой модели измените условие

->andFilterWhere(['=', 'user_role', $this->user_role])

в

->andFilterWhere(['NOT IN', 'user_role', $this->user_role])

Так что ваши search() метод будет выглядеть

public function search( $params ) {
    $query = User::find ();

    // add conditions that should always apply here

    $dataProvider = new ActiveDataProvider ( [
        'query' => $query ,
    ] );

    $this->load ( $params );

    if ( !$this->validate () ) {
        // uncomment the following line if you do not want to return any records when validation fails
        // $query->where('0=1');
        return $dataProvider;
    }

    // grid filtering conditions
    $query->andFilterWhere ( [
        'id' => $this->id ,
        'status' => $this->status ,
    ] );

    $query->andFilterWhere ( [ 'like' , 'id' , $this->id ] )
            ->andFilterWhere ( [ 'like' , 'name' , $this->name ] )
            ->andFilterWhere ( [ 'like' , 'username' , $this->username ] )
            ->andFilterWhere ( [ 'like' , 'email' , $this->email ] )
            ->andFilterWhere ( [ 'like' , 'contact_number' , $this->contact_number ] )
            ->andFilterWhere ( [ 'NOT IN' , 'user_role' , $this->user_role ] )
            ->andFilterWhere ( [ '=' , 'group_id' , $this->group_id ] );


    // $query->andFilterWhere(['=','user_type','user']);
    if ( Yii::$app->user->identity->user_role == Roles::ROLE_TEAM_LEAD && Yii::$app->user->identity->group_id != '' ) {
        $query->andFilterWhere ( [ '=' , 'group_id' , Yii::$app->user->identity->group_id ] )->andWhere ( 'user_role=4' );
    }
    //$query->andFilterWhere(['!=', 'id', Yii::$app->user->id]);

    return $dataProvider;
}

Почему вы меняете index просматривать с помощью вашего контроллера? Как я вижу, в вашем классе поиска уже есть проверка user role,

 if(Yii::$app->user->identity->user_role == Roles::ROLE_TEAM_LEAD && Yii::$app->user->identity->group_id != ''){
        $query->andFilterWhere(['=','group_id', Yii::$app->user->identity->group_id])->andWhere('user_role=4');
    }

После этого вы можете добавить

if(Yii::$app->user->identity->user_role == Roles::ROLE_INVENTORY_MANAGEMENT && Yii::$app->user->identity->group_id =='')
    {
        $query->andFilterWhere(['=','group_id', Yii::$app->user->identity->group_id])->andWhere('user_role IN (2,3,4,5)');
    }

Итак, ваш окончательный код будет таким

if(Yii::$app->user->identity->user_role == Roles::ROLE_TEAM_LEAD && Yii::$app->user->identity->group_id != ''){
        $query->andFilterWhere(['=','group_id', Yii::$app->user->identity->group_id])->andWhere('user_role=4');
    }
    else if(Yii::$app->user->identity->user_role == Roles::ROLE_INVENTORY_MANAGEMENT && Yii::$app->user->identity->group_id =='')
    {
        $query->andFilterWhere(['=','group_id', Yii::$app->user->identity->group_id])->andWhere('user_role IN (2,3,4,5)');
    }

Я надеюсь, что это также работает с вашими фильтрами:)

Если все найденные элементы модели должны скрывать / показывать защищенную информацию, вы можете добавить второй параметр в search() функция, которая будет показывать скрытую информацию о безопасности при построении запроса Например:

    $searchModel = new UserSearch();
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams,
        Yii::$app->user->identity->user_role === User::ADMIN_ROLE);

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);

или вы можете добавить условие запроса на контроллере:

    $searchModel = new UserSearch();
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

    if(Yii::$app->user->identity->user_role === User::ADMIN_ROLE) {
        $dataProvider->query->andWhere(/* come condition*/);
    }

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);

Если ваш проект будет использовать контроль доступа в других местах кода, настоятельно рекомендуем использовать контроль доступа на основе ролей (RBAC), который включен в конфигурацию Yii2 по умолчанию. Используя это будущее, вы можете просто проверить права пользователя без дополнительных столбцов на user Таблица. Это может выглядеть так:

    $searchModel = new UserSearch();
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

    if(Yii::$app->user->can(Roles::USER_VIEW_PRIVATE_INFO)) {
        $dataProvider->query->andWhere(/* come condition*/);
    }

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);
Другие вопросы по тегам