Check if user has permission to access specific states

4.3k Views Asked by At

I use angular-permission and I want to check if user has access to specific states.

My state config:

    $stateProvider
        .state('app', {
            url: '/',
            abstract: true,
            data: {
                permissions: {
                    only: ['BASE']
                }
            }
        })

Is there a method or something which I can use in controllers to determine it?

// somewhere in controller
if (Permission.hasAccessToState('app')) {
    // I want to check if user has access to state without navigating to it
};

If anyone is interested, here is a corresponding discussion on github.

2

There are 2 best solutions below

2
On BEST ANSWER

I did not find something in the documentation wiki. But according to the source and comment there seems to be an Authorization Service available which u can take advantage of.

//inject PermissionMap and Authorization    
App.controller('Controller',function(PermissionMap,Authorization,$scope) {

     //get the state by name an assign it to `state`
      var permissionMap = new PermissionMap(state.data.permissions);

      var authorizationResult = Authorization.authorize(permissionMap);

      authorizationResult
        .then(function () {
          //authorized
        })
        .catch(function (rejectedPermission) {
          //unauthorized
        });
});

Check out this code and see if it works

UPDATE

After ur reply, i looked deeper into the code. Maybe we need StatePermissionMap and StateAuthorization instead.

 var statePermissionMap = new StatePermissionMap(state);

  StateAuthorization
      .authorize(statePermissionMap)
      .then(function () {
         //authorized
      })
      .catch(function (rejectedPermission) {
        //unauthorized
      })
1
On

There is nothing as such mentioned in the documentation, but here is how I achieved it.

Basically, I had user role in my $rootScope (as I fetched them from backend)

1) Define in all your state definitions, what all users have access to that state. Example:

      .state('state1', {
            url: '/state1',
            views: {
                content: {
                    templateUrl: 'state1-partial.html',
                    controller: 'StateOneController'
                }
            },
            data: {
                    access:['Admin','Manager'] //only admin and manager can access this state
            }
        })
       .state('state2', {
            url: '/state2',
            views: {
                content: {
                    templateUrl: 'state2-partial.html',
                    controller: 'StateTwoController'
                }
            },
            data: {
                    access:['Admin'] //only admin can access this state
            }
        })

2) Then in angular.module run function I access these when state change event occurs as:

Also I use a service isAuthorized here to validate if the user is authorized to access that state. If yes I navigate the user to that state else I throw an error.

angular.module('myApp').run(function($rootScope, $state,$stateParams,isAuthorized){
    $rootScope.$on('$stateChangeStart', function (event, toState, toParams,   fromState,fromParams) {

    var isAccessRequired = toState.data.access;
    var isAccessRequired = toState.data && toState.data.access;
        //prevent default routing


            if(isAccessRequired){
                //I stored userRoles in $rootScope.userRole in an array when fetching from backend.
                var hasAccess = isAuthorized($rootScope.userRole,toState.data.access);

                if(!hasAccess){
                    event.preventDefault();

                    //user doesnt have access, show error and dont take him anywhere


                }

            }


    });
});

3) In my service (isAuthorized):

(function(){
    'use strict';

    angular.module('myApp')

        .service('isAuthorized', function() {
           return function(role,access){

          //logic here that will see if data.access is present in the user roles, if yes it will return true else return false

                return flag;
           }


        });

})();