Where Should User Permission Checks Take Place in MVC?

mvcpermissions

Should user permission checks take place in the model or the controller? And who should handle the permission checks, the User object or some UserManagement helper?

Where should it happen?

Checking in the Controller:

class MyController {
  void performSomeAction() {
    if (user.hasRightPermissions()) {
      model.someAction();
    }
  }
  ...

Having the checks in the Controller helps making the Models simple actions, so we can keep all logic to the Controllers.

Checking in the Model:

class MyModel {
  void someAction() {
    if (user.hasRightPermissions()) {
      ...
    }
  }
  ...

By putting the checks in the Model, we complicate the Model, but also make sure we don't accidentally allow users to do stuff they aren't supposed to in the Controller.

And by who?

Once we've settled on the place, who should do the checks? The user?

Class User {
  bool hasPermissions(int permissionMask) {
    ...
  }
  ...

But it's not really the user's responsibility to know what he or she can acccess, so perhaps some helper class?

Class UserManagement {
  bool hasPermissions(User user, int permissionMask) {
    ...
  }
  ...

I know it's common to ask just a single question in, well, a question, but I think these can be answered nicely together.

Best Answer

As usual, "it depends"

  • permission checks will functionally work anywhere it's convenient to put them,
  • but if you're asking a technical question then the answer may be 'put the checks in the object that owns the data required to perform the check' (which is probably the controller).
  • but if you're asking a philosophical question, I suggest an alternate answer: don't show users actions that they are not permitted to perform.

So in the latter case you might have the permission check in the controller implemented as a boolean property, and bind that property to the Visible property of the button or panel in the user-interface that controls the action

as a user, it's frustrating to see buttons for actions that I cannot perform; feels like I'm being left out of the fun ;)