Skip to content
This repository has been archived by the owner on Aug 30, 2021. It is now read-only.

Commit

Permalink
Merge pull request #796 from trainerbill/UnauthorizedRoute2
Browse files Browse the repository at this point in the history
Unauthorized client side routing
  • Loading branch information
lirantal committed Aug 25, 2015
2 parents 979c4e5 + ed89f9e commit 2b015b0
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 18 deletions.
17 changes: 10 additions & 7 deletions modules/core/client/app/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
angular.module(ApplicationConfiguration.applicationModuleName, ApplicationConfiguration.applicationModuleVendorDependencies);

// Setting HTML5 Location Mode
angular.module(ApplicationConfiguration.applicationModuleName).config(['$locationProvider',
function ($locationProvider) {
angular.module(ApplicationConfiguration.applicationModuleName).config(['$locationProvider', '$httpProvider',
function ($locationProvider, $httpProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');

$httpProvider.interceptors.push('authInterceptor');
}
]);

angular.module(ApplicationConfiguration.applicationModuleName).run(function ($rootScope, $state, Authentication) {

// Check authentication before changing state
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
if (toState.data && toState.data.roles && toState.data.roles.length > 0) {
Expand All @@ -24,11 +27,11 @@ angular.module(ApplicationConfiguration.applicationModuleName).run(function ($ro

if (!allowed) {
event.preventDefault();
$state.go('authentication.signin', {}, {
notify: false
}).then(function () {
$rootScope.$broadcast('$stateChangeSuccess', 'authentication.signin', {}, toState, toParams);
});
if (Authentication.user !== undefined && typeof Authentication.user === 'object') {
$state.go('forbidden');
} else {
$state.go('authentication.signin');
}
}
}
});
Expand Down
36 changes: 25 additions & 11 deletions modules/core/client/config/core.client.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,30 @@ angular.module('core').config(['$stateProvider', '$urlRouterProvider',

// Home state routing
$stateProvider
.state('home', {
url: '/',
templateUrl: 'modules/core/client/views/home.client.view.html'
})
.state('not-found', {
url: '/not-found',
templateUrl: 'modules/core/client/views/404.client.view.html',
data: {
ignoreState: true
}
});
.state('home', {
url: '/',
templateUrl: 'modules/core/client/views/home.client.view.html'
})
.state('not-found', {
url: '/not-found',
templateUrl: 'modules/core/client/views/404.client.view.html',
data: {
ignoreState: true
}
})
.state('bad-request', {
url: '/bad-request',
templateUrl: 'modules/core/client/views/400.client.view.html',
data: {
ignoreState: true
}
})
.state('forbidden', {
url: '/forbidden',
templateUrl: 'modules/core/client/views/403.client.view.html',
data: {
ignoreState: true
}
});
}
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

angular.module('core').factory('authInterceptor', ['$q', '$injector',
function ($q, $injector) {
return {
responseError: function(rejection) {
if (!rejection.config.ignoreAuthModule) {
switch (rejection.status) {
case 401:
$injector.get('$state').transitionTo('authentication.signin');
break;
case 403:
$injector.get('$state').transitionTo('forbidden');
break;
}
}
// otherwise, default behaviour
return $q.reject(rejection);
}
};
}
]);
6 changes: 6 additions & 0 deletions modules/core/client/views/400.client.view.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<h1>Bad Request</h1>
<div class="alert alert-danger" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
You made a bad request
</div>
6 changes: 6 additions & 0 deletions modules/core/client/views/403.client.view.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<h1>Forbidden</h1>
<div class="alert alert-danger" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
You are not authorized to access this resource
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use strict';

(function() {
describe('authInterceptor', function() {
//Initialize global variables
var authInterceptor,
$q,
$state,
httpProvider;

// Load the main application module
beforeEach(module(ApplicationConfiguration.applicationModuleName));

//Load httpProvider
beforeEach(module(function($httpProvider) {
httpProvider = $httpProvider;
}));

beforeEach(inject(function(_authInterceptor_, _$q_, _$state_) {
authInterceptor = _authInterceptor_;
$q = _$q_;
$state = _$state_;
spyOn($q,'reject');
spyOn($state,'transitionTo');
}));

it('Auth Interceptor should be object', function() {
expect( typeof authInterceptor).toEqual('object');
});

it('Auth Interceptor should contain responseError function', function() {
expect( typeof authInterceptor.responseError).toEqual('function');
});

it('httpProvider Interceptor should have authInterceptor', function() {
expect(httpProvider.interceptors).toContain('authInterceptor');
});

describe('Forbidden Interceptor', function() {
it('should redirect to forbidden route', function () {
var response = {status:403,config:{}};
var promise = authInterceptor.responseError(response);
expect($q.reject).toHaveBeenCalled();
expect($state.transitionTo).toHaveBeenCalledWith('forbidden');
});
});

describe('Authorization Interceptor', function() {
it('should redirect to signIn page for unauthorized access', function () {
var response = {status:401,config:{}};
var promise = authInterceptor.responseError(response);
expect($q.reject).toHaveBeenCalled();
expect($state.transitionTo).toHaveBeenCalledWith('authentication.signin');
});
});
});
})();

0 comments on commit 2b015b0

Please sign in to comment.