From c69f7db52268e8fce721f17c464c9b77c35a917b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 9 Apr 2015 13:01:37 -0700 Subject: [PATCH] GUAC-1126: Maintain session-local data through login/logout events broadcast from the authentication service. --- .../src/main/webapp/app/auth/authModule.js | 2 +- .../app/auth/service/authenticationService.js | 43 ++++++++++++++----- .../app/client/services/guacClientManager.js | 8 +++- .../app/login/controllers/loginController.js | 7 --- .../src/main/webapp/app/login/loginModule.js | 2 +- .../webapp/app/rest/services/cacheService.js | 9 +++- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/guacamole/src/main/webapp/app/auth/authModule.js b/guacamole/src/main/webapp/app/auth/authModule.js index 2ac7de1ef..f3f565798 100644 --- a/guacamole/src/main/webapp/app/auth/authModule.js +++ b/guacamole/src/main/webapp/app/auth/authModule.js @@ -23,4 +23,4 @@ /** * The module for authentication and management of tokens. */ -angular.module('auth', ['ngCookies', 'rest']); +angular.module('auth', ['ngCookies']); diff --git a/guacamole/src/main/webapp/app/auth/service/authenticationService.js b/guacamole/src/main/webapp/app/auth/service/authenticationService.js index 1909a7b06..7ad9f4995 100644 --- a/guacamole/src/main/webapp/app/auth/service/authenticationService.js +++ b/guacamole/src/main/webapp/app/auth/service/authenticationService.js @@ -22,6 +22,16 @@ /** * A service for authenticating a user against the REST API. + * + * This service broadcasts two events on $rootScope depending on the result of + * authentication operations: 'guacLogin' if authentication was successful and + * a new token was created, and 'guacLogout' if an existing token is being + * destroyed or replaced. Both events will be passed the related token as their + * sole parameter. + * + * If a login attempt results in an existing token being replaced, 'guacLogout' + * will be broadcast first for the token being replaced, followed by + * 'guacLogin' for the new token. */ angular.module('auth').factory('authenticationService', ['$injector', function authenticationService($injector) { @@ -30,7 +40,7 @@ angular.module('auth').factory('authenticationService', ['$injector', var $cookieStore = $injector.get('$cookieStore'); var $http = $injector.get('$http'); var $q = $injector.get('$q'); - var cacheService = $injector.get('cacheService'); + var $rootScope = $injector.get('$rootScope'); var service = {}; @@ -102,12 +112,25 @@ angular.module('auth').factory('authenticationService', ['$injector', var currentToken = service.getCurrentToken(); - // If a new token was received, ensure the old token is invalidated - if (currentToken && data.authToken !== currentToken) { - service.logout() - ['finally'](function logoutComplete() { + // If a new token was received, ensure the old token is invalidated, + // if any, and notify listeners of the new token + if (data.authToken !== currentToken) { + + // If an old token existed, explicitly logout first + if (currentToken) { + service.logout() + ['finally'](function logoutComplete() { + completeAuthentication(data); + $rootScope.$broadcast('guacLogin', data.authToken); + }); + } + + // Otherwise, simply complete authentication and notify of login + else { completeAuthentication(data); - }); + $rootScope.$broadcast('guacLogin', data.authToken); + } + } // Otherwise, just finish the auth process @@ -195,13 +218,13 @@ angular.module('auth').factory('authenticationService', ['$injector', */ service.logout = function logout() { - // Clear all caches - cacheService.clearCaches(); - // Clear authentication data var token = service.getCurrentToken(); $cookieStore.remove(AUTH_COOKIE_ID); + // Notify listeners that a token is being destroyed + $rootScope.$broadcast('guacLogout', token); + // Delete old token return $http({ method: 'DELETE', @@ -249,6 +272,6 @@ angular.module('auth').factory('authenticationService', ['$injector', return null; }; - + return service; }]); diff --git a/guacamole/src/main/webapp/app/client/services/guacClientManager.js b/guacamole/src/main/webapp/app/client/services/guacClientManager.js index 67d20b98d..81dc249fb 100644 --- a/guacamole/src/main/webapp/app/client/services/guacClientManager.js +++ b/guacamole/src/main/webapp/app/client/services/guacClientManager.js @@ -30,7 +30,8 @@ angular.module('client').factory('guacClientManager', ['$injector', var ManagedClient = $injector.get('ManagedClient'); // Required services - var $window = $injector.get('$window'); + var $window = $injector.get('$window'); + var $rootScope = $injector.get('$rootScope'); var service = {}; @@ -144,6 +145,11 @@ angular.module('client').factory('guacClientManager', ['$injector', // Disconnect all clients when window is unloaded $window.addEventListener('unload', service.clear); + // Clear clients on logout + $rootScope.$on('guacLogout', function handleLogout() { + service.clear(); + }); + return service; }]); diff --git a/guacamole/src/main/webapp/app/login/controllers/loginController.js b/guacamole/src/main/webapp/app/login/controllers/loginController.js index 6d5a781f2..e43faf3ca 100644 --- a/guacamole/src/main/webapp/app/login/controllers/loginController.js +++ b/guacamole/src/main/webapp/app/login/controllers/loginController.js @@ -26,7 +26,6 @@ angular.module('login').controller('loginController', ['$scope', '$injector', // Required services var $location = $injector.get('$location'); var authenticationService = $injector.get('authenticationService'); - var guacClientManager = $injector.get('guacClientManager'); var userPageService = $injector.get('userPageService'); /** @@ -54,16 +53,10 @@ angular.module('login').controller('loginController', ['$scope', '$injector', // Redirect to main view upon success .then(function loginSuccessful() { - - // Provide user with clean environment - guacClientManager.clear(); - - // Redirect to main view userPageService.getHomePage() .then(function homePageRetrieved(homePage) { $location.url(homePage.url); }); - }) // Reset and focus password upon failure diff --git a/guacamole/src/main/webapp/app/login/loginModule.js b/guacamole/src/main/webapp/app/login/loginModule.js index 289aefa9d..54e531233 100644 --- a/guacamole/src/main/webapp/app/login/loginModule.js +++ b/guacamole/src/main/webapp/app/login/loginModule.js @@ -23,4 +23,4 @@ /** * The module for the login functionality. */ -angular.module('login', ['client', 'element', 'navigation']); +angular.module('login', ['element', 'navigation']); diff --git a/guacamole/src/main/webapp/app/rest/services/cacheService.js b/guacamole/src/main/webapp/app/rest/services/cacheService.js index 16b7b567a..f21dd6388 100644 --- a/guacamole/src/main/webapp/app/rest/services/cacheService.js +++ b/guacamole/src/main/webapp/app/rest/services/cacheService.js @@ -28,7 +28,7 @@ angular.module('rest').factory('cacheService', ['$injector', // Required services var $cacheFactory = $injector.get('$cacheFactory'); - + var $rootScope = $injector.get('$rootScope'); // Service containing all caches var service = {}; @@ -63,7 +63,12 @@ angular.module('rest').factory('cacheService', ['$injector', service.connections.removeAll(); service.users.removeAll(); }; - + + // Clear caches on logout + $rootScope.$on('guacLogout', function handleLogout() { + service.clearCaches(); + }); + return service; }]);