简体   繁体   中英

What is the best practice to register routes based on permissions in Ember.js?

In my Ember application, I have a map of routes and CRUD permissions that is returned from the server. If a user doesn't have read access to a page, I can easily exclude the menu item but for Create and Update operations I need to make some changes in router.js.

So currently this is the router I have:

    import Ember from 'ember';
import config from './config/environment';

const Router = Ember.Router.extend({
    location: config.locationType
});

Router.map(function () {
    this.route('product-types', function () {
        this.route('view', {path: '/:product-type_id'});
        this.route('edit', {path: '/:product-type_id/edit'});
    });
    this.route('products');

    this.route('members', function () {
        this.route('view', {path: '/:member_id'}, function () {
            this.route('member-accounts', function () {
                this.route('new');
            });
        });
        this.route('edit', {path: '/:member_id/edit'});
        this.route('new');
    });
    this.route('tasks', function () {
        this.route('view', {path: '/:task_id'});
    });

});

export default Router;

So I wish somehow to be able to simply not register the route to :new and or :edit if the user doesn't have the right permissions:

this.route('product-types', function () {
    if(permission['product-types'].edit()) {
         this.route('edit', {path: '/:product-type_id/edit'});
    }
});

But I'm looking for a better solution as the routes are growing in huge numbers. So I'd like to perhaps customize this Ember's router to do this automatically. Is that possible?

The other problem is Delete. Because Delete doesn't have any specific route I'd like to be able to pass that permission to each model by default automatically so that each model checks if delete is possible or not and then hide the delete button.

I am not worry about a user hacks the js files and enables the pages and tries to access the forbidden pages because they can't do anything as the server will stop them and will check all the permissions but I want here a mechanism to hide/display pages, buttons based on permissions. Any help is appreciated.

I think you'll be able to solve a lot of your problems with mixins. For your routing permissions, I recommend you have a look at ember-simple-auth's UnauthenticatedRouteMixin . Here is some of the related code :

export default Ember.Mixin.create({
  /**
    The session service.
    @property session
    @readOnly
    @type SessionService
    @public
  */
  session: service('session'),

  /**
    Checks whether the session is authenticated and if it is aborts the current
    transition and instead transitions to the
    {{#crossLink "Configuration/routeIfAlreadyAuthenticated:property"}}{{/crossLink}}.
    __If `beforeModel` is overridden in a route that uses this mixin, the route's
   implementation must call `this._super(...arguments)`__ so that the mixin's
   `beforeModel` method is actually executed.
    @method beforeModel
    @param {Transition} transition The transition that lead to this route
    @public
  */
  beforeModel(transition) {
    if (this.get('session').get('isAuthenticated')) {
      transition.abort();
      Ember.assert('The route configured as Configuration.routeIfAlreadyAuthenticated cannot implement the UnauthenticatedRouteMixin mixin as that leads to an infinite transitioning loop!', this.get('routeName') !== Configuration.routeIfAlreadyAuthenticated);
      this.transitionTo(Configuration.routeIfAlreadyAuthenticated);
    } else {
      return this._super(...arguments);
    }
  }
});

The delete button issue you should be able to solve with either another mixin where you check permission in a delete action, or add a mixin to components that inject permission related logic, or a combination of sorts..

You can try using a service that will contain the permissions for the current user, and some calculations based on those, which you inject into the necessary component. Which could be a delete button or a form component or something, and toggle the delete button display on the form component. That would look something like this:

//services/permissions.js
export default Ember.Service.extend({

    hasPermission: Ember.computed('permissions', function(){
        return true/false // permission logic here
    })

})

//components/component-permissions
export default Ember.Component.extend({
    permissions: Ember.inject.service(),
  hasPermission: Ember.computed.alias('permissions.hasPermission')
});

//templates/components/components-permissions
{{#if hasPermission}}
    <button class='i-am-a-delete-button'>Delete</button>
{{/if}}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM