diff -Nru horizon-13.0.2/debian/changelog horizon-13.0.2/debian/changelog --- horizon-13.0.2/debian/changelog 2019-10-18 14:27:28.000000000 -0600 +++ horizon-13.0.2/debian/changelog 2020-04-27 11:29:24.000000000 -0600 @@ -1,3 +1,10 @@ +horizon (3:13.0.2-0ubuntu3) UNRELEASED; urgency=medium + + * d/p/Avoid_forced_logout_when_403_error_encountered.patch + - Change-Id: I10a6eeb96dd1418449e1d15b1a3869cd4de9cafa + + -- Nicolas Bock Mon, 27 Apr 2020 17:29:24 +0000 + horizon (3:13.0.2-0ubuntu2) bionic; urgency=medium * d/p/lp1840465.patch: Fix failing to list security groups diff -Nru horizon-13.0.2/debian/patches/Avoid_forced_logout_when_403_error_encountered.patch horizon-13.0.2/debian/patches/Avoid_forced_logout_when_403_error_encountered.patch --- horizon-13.0.2/debian/patches/Avoid_forced_logout_when_403_error_encountered.patch 1969-12-31 17:00:00.000000000 -0700 +++ horizon-13.0.2/debian/patches/Avoid_forced_logout_when_403_error_encountered.patch 2020-04-27 11:29:24.000000000 -0600 @@ -0,0 +1,136 @@ +From a2acb3e5c178cd5b18228c42d98129d68226f61c Mon Sep 17 00:00:00 2001 +From: Gloria Gu +Date: Tue, 20 Aug 2019 15:45:22 -0700 +Subject: [PATCH] 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 ab0e96df9506fb6f1783e0ee79b63934dabe0cbe) +(cherry picked from commit 81740d310f7078a10435ecbeb3e7a31bc62c7497) +--- + +Index: horizon-13.0.2/horizon/static/framework/framework.module.js +=================================================================== +--- horizon-13.0.2.orig/horizon/static/framework/framework.module.js ++++ horizon-13.0.2/horizon/static/framework/framework.module.js +@@ -25,7 +25,7 @@ + .run(run) + .factory('horizon.framework.redirect', httpRedirectLogin) + .constant('horizon.framework.events', { +- FORCE_LOGOUT: 'FORCE_LOGOUT' ++ AUTH_ERROR: 'AUTH_ERROR' + }); + + config.$inject = [ +@@ -128,25 +128,28 @@ + 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); + } + }; + } + +- 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'); + } + + })(); +Index: horizon-13.0.2/horizon/static/framework/framework.module.spec.js +=================================================================== +--- horizon-13.0.2.orig/horizon/static/framework/framework.module.spec.js ++++ horizon-13.0.2/horizon/static/framework/framework.module.spec.js +@@ -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(); + }) +Index: horizon-13.0.2/horizon/static/framework/widgets/wizard/wizard.controller.js +=================================================================== +--- horizon-13.0.2.orig/horizon/static/framework/widgets/wizard/wizard.controller.js ++++ horizon-13.0.2/horizon/static/framework/widgets/wizard/wizard.controller.js +@@ -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; +Index: horizon-13.0.2/horizon/static/framework/widgets/wizard/wizard.controller.spec.js +=================================================================== +--- horizon-13.0.2.orig/horizon/static/framework/widgets/wizard/wizard.controller.spec.js ++++ horizon-13.0.2/horizon/static/framework/widgets/wizard/wizard.controller.spec.js +@@ -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); diff -Nru horizon-13.0.2/debian/patches/series horizon-13.0.2/debian/patches/series --- horizon-13.0.2/debian/patches/series 2019-10-18 14:27:28.000000000 -0600 +++ horizon-13.0.2/debian/patches/series 2020-04-27 11:29:24.000000000 -0600 @@ -5,3 +5,4 @@ embedded-xstatic.patch add-juju-environment-download.patch lp1840465.patch +Avoid_forced_logout_when_403_error_encountered.patch