Doing things the right way?

I’ve been using Yii for a while now so I think I’m familiar enough to force my way through problems one way or another, but I really don’t know if I’m doing it the right way. I’ve started a new project and for the sake of keeping things clean for the future, I’d like to do things the “Yii” way. My project consists of 3 tiers of users: Admins, Managers, and basic Users. The User model and RBAC are set up so that I can easily check the current user’s tier with Yii::$app->user->identity.

I don’t know if that’s good thing though. I feel worried when I use Yii::$app->user->identity. Mostly because a lot of the security of my application state relies on it, and I just don’t know if there’s potential for me to misuse it. Obviously I don’t use it when there’s potential for it to be null, but other than that I’ve just been throwing it around willy nilly. Is there a time when I shouldn’t?

And besides security, is it ever bad practice to use it? For instance, all user tiers in my application share the same views. The views display slightly differently (or not at all if the RBAC disallows it) depending on the type of account. Right now I get the current user with Yii::$app->user->identity in the controller and pass it to the view being rendered. In the views I have a bunch of

if ($currentUserModel->accountType == something)

checks in various places. Does this break MVC or is that just if I were to access "User::" within the view? Should I make separate actions or views for each user type instead?

The same question hit me twice when I was making the create/update forms. I want the users to have a different level of control over their account depending on what tier they’re in. I want them to visually see different text input boxes, but what’s stopping them from opening up a dev tool in their browser and putting something like this in there?




<input type="text"

       class="form-control" 

       id="user-guesscolumnname" 

       name="User[guesscolumnname]" 

       value="value-they-shouldnt-be-able-to-change">



Does Yii have something built in to stop this? If not I could either create a buffer model and do some logic checking in the controller after loading it from the form. Or should I create different actions/views and also separate form models for each user. What’s more appropriate?

I guess what caused all these questions was the rbac rule method Yii::$app->user->can(‘some-action’). I’ve been struggling through the Authorization guide and when I saw this I really had no idea where to put it. If my understanding is correct, I can call it pretty much anytime I want for any reason I want. Is it best used by wrapping my entire action with it?




public function actionSomeAction()

{

    if (Yii::$app->user->can('some-action')) {

        // do stuff

    }

}



I apologize for this post being so long. I don’t come from a web/php background, so I just want to make sure I’m not going about it in a way I definitely shouldn’t. I don’t need really long well thought out answers. If the way I structure things is up to my own personal tastes/needs then a simple “It’s up to you” would suffice.

Having a special field like “accountType” has nothing to do with RBAC. In fact, when using RBAC you don’t really need that since there are already roles and assigments and you can do checks like \Yii::$app->user->can(‘createPost’).

Passing user around doesn’t really break MVC. For view clarity sake you may do checks needed in controller and pass booleans such as $canCreatePost around.

About the forms question. Of course, Yii has tools to prevent submitting arbitrary data via modifying forms. That’s called validation and should be always done at the server side regardless on how you get data. For your particular case check validation, scenarios, safe attributes.

In case forms are significantly different I’d advice against using scenarios in favor or separate form models.

About where to place RBAC checks… well, where needed. For example, a permission "managePosts" in a blog should be checked both in a view when displaying "edit" button and before accessing edit action.