Avoid forced logout when 403 error encountered
Before this change when a 403 error was encountered, such as failure to
have the permission to perform an operation, the user would get logged
out from UI pages written in the AngularJS framework. For example, if an
admin user lacks the get_project permission and tries to access the
images page, project->compute->images, the 403 will forcibly log out
the user.
This change keeps the user logged in when a 403 error is encountered and
displays an error message. The change only affects AngularJS pages.
Change-Id: I10a6eeb96dd1418449e1d15b1a3869cd4de9cafa
Closes-bug: #1840844
(cherry picked from commit ab0e96df95
)
This commit is contained in:
parent
60cfb0a8cf
commit
65a49dd165
|
@ -27,7 +27,7 @@
|
|||
.factory('horizon.framework.redirect', redirect)
|
||||
.config(registerNotFound)
|
||||
.constant('horizon.framework.events', {
|
||||
FORCE_LOGOUT: 'FORCE_LOGOUT'
|
||||
AUTH_ERROR: 'AUTH_ERROR'
|
||||
});
|
||||
|
||||
config.$inject = [
|
||||
|
@ -130,11 +130,11 @@
|
|||
responseError: function (error) {
|
||||
if (error.status === 401) {
|
||||
var msg = gettext('Unauthorized. Redirecting to login');
|
||||
handleRedirectMessage(msg, $rootScope, $window, frameworkEvents, toastService);
|
||||
handleRedirectMessage(msg, $rootScope, $window, frameworkEvents, toastService, true);
|
||||
}
|
||||
if (error.status === 403) {
|
||||
var msg2 = gettext('Forbidden. Redirecting to login');
|
||||
handleRedirectMessage(msg2, $rootScope, $window, frameworkEvents, toastService);
|
||||
var msg2 = gettext('Forbidden. Insufficient permissions of the requested operation');
|
||||
handleRedirectMessage(msg2, $rootScope, $window, frameworkEvents, toastService, false);
|
||||
}
|
||||
return $q.reject(error);
|
||||
},
|
||||
|
@ -144,14 +144,17 @@
|
|||
};
|
||||
}
|
||||
|
||||
function handleRedirectMessage(msg, $rootScope, $window, frameworkEvents, toastService) {
|
||||
function handleRedirectMessage(
|
||||
msg, $rootScope, $window, frameworkEvents, toastService, forceLogout) {
|
||||
var toast = toastService.find('error', msg);
|
||||
//Suppress the multiple duplicate redirect toast messages.
|
||||
if (!toast) {
|
||||
toastService.add('error', msg);
|
||||
$rootScope.$broadcast(frameworkEvents.FORCE_LOGOUT, msg);
|
||||
$rootScope.$broadcast(frameworkEvents.AUTH_ERROR, msg);
|
||||
}
|
||||
if (forceLogout) {
|
||||
$window.location.replace($window.WEBROOT + 'auth/logout');
|
||||
}
|
||||
$window.location.replace($window.WEBROOT + 'auth/logout');
|
||||
}
|
||||
|
||||
registerNotFound.$inject = [
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
});
|
||||
|
||||
describe('when forbidden', function() {
|
||||
it('should redirect to /auth/logout and add a forbidden toast message ', inject(
|
||||
it('should add a forbidden toast message ', inject(
|
||||
function($http, $httpBackend, $window, $injector, $rootScope) {
|
||||
$window.WEBROOT = '/dashboard/';
|
||||
$httpBackend.when('GET', '/api').respond(403, '');
|
||||
|
@ -69,7 +69,6 @@
|
|||
$http.get('/api').error(function() {
|
||||
expect(toastService.add).toHaveBeenCalled();
|
||||
expect($rootScope.$broadcast).toHaveBeenCalled();
|
||||
expect($window.location.replace).toHaveBeenCalledWith('/dashboard/auth/logout');
|
||||
});
|
||||
$httpBackend.flush();
|
||||
})
|
||||
|
|
|
@ -142,7 +142,7 @@
|
|||
$scope.$broadcast(wizardEvents.ON_INIT_ERROR);
|
||||
}
|
||||
|
||||
$scope.$on(frameworkEvents.FORCE_LOGOUT, function(evt, arg) {
|
||||
$scope.$on(frameworkEvents.AUTH_ERROR, function(evt, arg) {
|
||||
viewModel.hasError = true;
|
||||
viewModel.errorMessage = arg;
|
||||
return;
|
||||
|
|
|
@ -62,14 +62,14 @@
|
|||
expect(scope.viewModel.errorMessage).toBe('in valid');
|
||||
});
|
||||
|
||||
it('call onInitSuccess with logout event', function() {
|
||||
rootScope.$broadcast(frameworkEvents.FORCE_LOGOUT, 'logout');
|
||||
it('call onInitSuccess with auth_error event', function() {
|
||||
rootScope.$broadcast(frameworkEvents.AUTH_ERROR, 'auth_error');
|
||||
ctrl.onInitSuccess();
|
||||
scope.$apply();
|
||||
expect(scope.viewModel.hasError).toBe(true);
|
||||
});
|
||||
|
||||
it('call onInitSuccess without logout event', function() {
|
||||
it('call onInitSuccess without auth_error event', function() {
|
||||
spyOn(scope, '$broadcast');
|
||||
ctrl.onInitSuccess();
|
||||
scope.$apply();
|
||||
|
@ -77,8 +77,8 @@
|
|||
expect(scope.$broadcast).toHaveBeenCalledWith(wizardEvents.ON_INIT_SUCCESS);
|
||||
});
|
||||
|
||||
it('call onInitError with logout event', function() {
|
||||
rootScope.$broadcast(frameworkEvents.FORCE_LOGOUT, 'logout');
|
||||
it('call onInitError with auth_error event', function() {
|
||||
rootScope.$broadcast(frameworkEvents.AUTH_ERROR, 'auth_error');
|
||||
ctrl.onInitError();
|
||||
scope.$apply();
|
||||
expect(scope.viewModel.hasError).toBe(true);
|
||||
|
|
Loading…
Reference in New Issue