1

I have implementation of a collection of items (model, collection, view for the collection, view and template file for individual item). In addition to that I have some session variables (for example user credentials/session properties/permissions). I'd like to show different fields and options for each item depending on the user permissions (normal users can just view them, admins can edit/delete etc). What is the cleanest way of doing that? Any way of passing session through through view constructors or adding a reference to the session structure to each model doesn't seem right. It's sounds like what I want is to have these session structure global and want to have access to it from within the template of my view, but I doubt thats the right approach.

Thanks

Dmitry Fink
  • 1,032
  • 1
  • 13
  • 31

1 Answers1

2

The way I've approached the same problem is to setup the models and collections with permission checking and then implementing the logic in the model class, like this:

PermissionModel = Backbone.Model.extend({

  hasPermission: function(permission){
    // pessimistic default implementation, override in inherited model classes
    return false;
  }

});

Inherit your models from this model and then use global flag checking for permission logic if the app is relatively simple and some kind of ACL if it is more complex. Eg.

hasPermission: function(permission){
  switch (permission) {
    case "read":
      return true;
    case "write":
      return window.app.user.isAdmin(); //app.user is defined in the app initialization
    default:
      return false;
  }
}

In your templates you can use this logic. If you use Handlebars, you can define a template helper:

{{#ifPermission model "read"}}You have permission{{/ifPermission}}
Jens Alm
  • 3,027
  • 4
  • 22
  • 24
  • I'd recommend putting the visibility logic in the server code: if the person doesn't have permission to see **X** then **X** should never even get to the client. – mu is too short Aug 17 '12 at 22:00
  • Very true, that is what we do in production, I just used "read" and "write" as example permissions. Any client side permission checking should be for convenience only (to hide controls, etc). Formal permission checking, read and write should be server side. Never trust the client :) – Jens Alm Aug 17 '12 at 23:50
  • That is exactly what I am trying to do, I am trying to hide the button "Delete", the button would trigger model destruction, but server would double check the permissions before allowing that ajax command to go through. – Dmitry Fink Aug 18 '12 at 00:14
  • Anyway, back to your solition, I am not familiar with handlebars yet, I am using _ templates for my views, is there any way to refer to the hasPermission function from the template itself? In all the examples I am tought to pass this.model.toJSON() to the template engine, I assume it just leaves the attributes and strips anything else from the model. – Dmitry Fink Aug 18 '12 at 00:17
  • 1
    @DmitryFink: You can use your own function for sending data to the view so you could `toTmplJSON: function() { var o = _(this.attributes).clone(); o.hasPermissionX = this.hasPermission('X'); return o }` and then use `toTmplJSON` to feed data to the template. Or hand the whole model to the template if you don't mind `<%= m.get('x') %>`. The stuff inside `<%=...%>` is pretty much any JavaScript expression you want. I think the `toTmplJSON` approach would be more common than the others. – mu is too short Aug 18 '12 at 01:41
  • @JensAlm I am developing an application. It has a login-view. After the user login logs in, i pull other information related to the account. Where do I store this additional information? B'coz if I store it in a model/collection, and refresh the page. The values in the collection are erased. Can you help me with this? – Anish Nair Jul 09 '13 at 05:32
  • @AnishNair that particular behavior fits our use case. However if you want the data to persist between logins you can eg use a SessionStorage backend for you backbone models (see https://gist.github.com/davemo/3875274) or you can set a cookie (see http://stackoverflow.com/questions/4825683/how-do-i-create-and-read-a-value-from-cookie) – Jens Alm Jul 09 '13 at 09:35