Declarative authorization (permissions) for basic views

Introduction: Anyone coming from the Rails community is probably familiar with server-side cancan for declaring authorization of model actions. IE. can? (: read, draft)

Reference Information. But in the UI layer on the frontend, I didn't find anything that provides the same type of abstraction to handle what users see and what permission they have (obviously there is always an inner server layer as well) For example, are you showing a button to the user? Are we adding the contenteditable element attribute? If the user clicks like, do we try to register it or present it as a login dialog?

Question: Does anyone know of a framework / tool / library / best practice for solving this UI problem?

Followup: Is the question being evaluated in a view or a template? Is this a feature of the template language or the set of boolean variables that we pass to the template?

Except: I had an idea for a tool to simulate cancan where the method signature would be like App.can ("like", project, user), where the project and user are BB model objects. The problem may lie in the number of different actions that a user can perform on any given object. IE. as a project, edit the project, comment on the project, invite a friend to the project, etc. Some of them can be boiled down to RESTful actions, but I think most would agree that the UI contains more types of actions.

+3


source to share


2 answers


We had the same situation in our project where everything on the page should show and hide according to the permissions granted to the user and here is the solution I came up with.

You need to first save the user rights and load them on the client side; then you can check them like this

1-Declare the filterByPermission function on your base view (all your views must inherit from this)

class SampleProject.Views.BaseView extends Backbone.View

  filterByPermission:=>
    #these views will be removed incase user does not have a specific permission
    if @views_permissions?
      for permission, selector of @views_permissions
        unless SampleProject.current_user.has_permission permission
          @$(selector).remove()

    #these views will be removed incase user has a specific permission
    if @remove_views_permissions?
      for permission, selector of @remove_views_permissions
        if SampleProject.current_user.has_permission permission
          @$(selector).remove()

      



2 and then you can go to another view that inherits the base view and defines your permissions in "views_permissions" (something similar to hash events)

class SampleProject.Views.UsersIndex extends SampleProject.Views.BaseView
  views_permissions:
    "create_users":  "#js_create_user_li, #new_user_modal"
    "import_users": "#js_import_btn_li, #import_form_li"
    "edit_users"  :  "#edit_user_modal"
    "delete_users"  :  "#js_delete_user_li, .js-user-selector-header"

  render:=>
    #render your view here
    @filterByPermission()

      

3-call @filterByPermission () after your view has rendered.

This way you have one place to manage views according to permissions without adding if statements throughout your code.

+2


source


Not sure exactly which frameworks are out there, but you can use Rails or whatever server platform renders your permissions as objects JavaScript

.

For example:

var userAuth = { userId: 1234, userType: 'Admin',
                 /** A little more complex permission scenario */
                 privileges: [{ProjectA: 'admin'}, 
                              {ProjectB: 'user'}, 
                              {ProjectC: 'noaccess'}]};

      



This way, in your view or template, you can declaratively render a portion of a UI element based on the permission of the currently logged in user. For example, using a template Underscore

, you can execute some JavaScript logic and check.

/** Operate using a declared variable */
<% if (userAuth.userType === 'Admin') {%>
    <div>This is only shown to admin.</div>
<% } %>

/** OR operate on the actual property on the working model */
<% if (myModelProperty === 'Admin') {%>
    <div>This is only shown to admin.</div>
<% } %>

      

This type of checks can also be performed at the very actual View

to limit certain functionality based on the user, etc.

+1


source







All Articles