Repository: ambari Updated Branches: refs/heads/branch-2.1 dddc760f3 -> 782bf7d92
AMBARI-13419. Implement forced logout based on user inactivity (rzang) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/782bf7d9 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/782bf7d9 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/782bf7d9 Branch: refs/heads/branch-2.1 Commit: 782bf7d926dbbfbe7d8b68f8959e56878eb7e482 Parents: dddc760 Author: Richard Zang <[email protected]> Authored: Wed Oct 14 18:17:39 2015 -0700 Committer: Richard Zang <[email protected]> Committed: Wed Oct 14 18:22:29 2015 -0700 ---------------------------------------------------------------------- .../app/scripts/controllers/mainCtrl.js | 39 ++++++- .../admin-web/app/scripts/services/Cluster.js | 13 +++ .../controllers/global/cluster_controller.js | 1 + ambari-web/app/controllers/main.js | 104 +++++++++++++++++-- ambari-web/app/views/main/views/details.js | 1 + 5 files changed, 148 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/782bf7d9/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js index 0e40c8c..e16d1dc 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js @@ -18,7 +18,7 @@ 'use strict'; angular.module('ambariAdminConsole') -.controller('MainCtrl',['$scope', '$window','Auth', 'Alert', '$modal', 'Cluster', 'View', function($scope, $window, Auth, Alert, $modal, Cluster, View) { +.controller('MainCtrl',['$scope','$rootScope','$window','Auth', 'Alert', '$modal', 'Cluster', 'View', function($scope, $rootScope, $window, Auth, Alert, $modal, Cluster, View) { $scope.signOut = function() { var data = JSON.parse(localStorage.ambari); delete data.app.authenticated; @@ -87,5 +87,42 @@ angular.module('ambariAdminConsole') $scope.updateInstances(); }); + $scope.startInactiveTimeoutMonitoring = function(timeout) { + var TIME_OUT = timeout; + var active = true; + var lastActiveTime = Date.now(); + + var keepActive = function() { + //console.error('keepActive'); + if (active) { + lastActiveTime = Date.now(); + } + }; + + $(window).bind('mousemove', keepActive); + $(window).bind('keypress', keepActive); + $(window).bind('click', keepActive); + + var checkActiveness = function() { + //console.error("checkActiveness " + lastActiveTime + " : " + Date.now()); + if (Date.now() - lastActiveTime > TIME_OUT) { + //console.error("LOGOUT!"); + active = false; + $(window).unbind('mousemove', keepActive); + $(window).unbind('keypress', keepActive); + $(window).unbind('click', keepActive); + clearInterval($rootScope.userActivityTimeoutInterval); + $scope.signOut(); + } + }; + $rootScope.userActivityTimeoutInterval = window.setInterval(checkActiveness, 1000); + }; + + if (!$rootScope.userActivityTimeoutInterval) { + Cluster.getAmbariTimeout().then(function(timeout) { + if (Number(timeout) > 0) + $scope.startInactiveTimeoutMonitoring(timeout * 1000); + }); + } $scope.updateInstances(); }]); http://git-wip-us.apache.org/repos/asf/ambari/blob/782bf7d9/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js index c27ed91..a602cba 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js @@ -60,6 +60,19 @@ angular.module('ambariAdminConsole') return deferred.promise; }, + getAmbariTimeout: function() { + var deferred = $q.defer(); + var url = '/services/AMBARI/components/AMBARI_SERVER?fields=RootServiceComponents/properties/user.inactivity.timeout.default' + $http.get(Settings.baseUrl + url) + .then(function(data) { + deferred.resolve(data.data.RootServiceComponents.properties['user.inactivity.timeout.default']); + }) + .catch(function(data) { + deferred.reject(data); + }); + + return deferred.promise; + }, getPermissions: function() { var deferred = $q.defer(); http://git-wip-us.apache.org/repos/asf/ambari/blob/782bf7d9/ambari-web/app/controllers/global/cluster_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js index 5e69c5c..f411d37 100644 --- a/ambari-web/app/controllers/global/cluster_controller.js +++ b/ambari-web/app/controllers/global/cluster_controller.js @@ -359,6 +359,7 @@ App.ClusterController = Em.Controller.extend({ this.set('ambariProperties', data.RootServiceComponents.properties); // Absence of 'jdk.name' and 'jce.name' properties says that ambari configured with custom jdk. this.set('isCustomJDK', App.isEmptyObject(App.permit(data.RootServiceComponents.properties, ['jdk.name', 'jce.name']))); + App.router.get('mainController').monitorInactivity(); }, loadAmbariPropertiesError: function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/782bf7d9/ambari-web/app/controllers/main.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main.js b/ambari-web/app/controllers/main.js index 932c8af..b7b0b4a 100644 --- a/ambari-web/app/controllers/main.js +++ b/ambari-web/app/controllers/main.js @@ -21,6 +21,10 @@ require('models/background_operation'); App.MainController = Em.Controller.extend({ name: 'mainController', + isUserActive: true, + checkActivenessInterval: null, + lastUserActiveTime: null, + userTimeOut: 0, updateTitle: function(){ var name = App.router.get('clusterController.clusterName'); @@ -109,11 +113,11 @@ App.MainController = Em.Controller.extend({ clearTimeout(this.get("reloadTimeOut")); this.set('reloadTimeOut', - setTimeout(function () { - if (App.clusterStatus.get('isInstalled')) { - location.reload(); - } - }, App.pageReloadTime) + setTimeout(function () { + if (App.clusterStatus.get('isInstalled')) { + location.reload(); + } + }, App.pageReloadTime) ); }.observes("App.router.location.lastSetURL", "App.clusterStatus.isInstalled"), @@ -124,17 +128,17 @@ App.MainController = Em.Controller.extend({ isAllServicesInstalled: function() { return this.scRequest('isAllServicesInstalled'); }.property('App.router.mainServiceController.content.content.@each', - 'App.router.mainServiceController.content.content.length'), + 'App.router.mainServiceController.content.content.length'), isStartAllDisabled: function() { return this.scRequest('isStartAllDisabled'); }.property('App.router.mainServiceController.isStartStopAllClicked', - '[email protected]'), + '[email protected]'), isStopAllDisabled: function() { return this.scRequest('isStopAllDisabled'); }.property('App.router.mainServiceController.isStartStopAllClicked', - '[email protected]'), + '[email protected]'), gotoAddService: function() { App.router.get('mainServiceController').gotoAddService(); @@ -184,6 +188,88 @@ App.MainController = Em.Controller.extend({ }, getServerVersionErrorCallback: function () { console.log('ERROR: Cannot load Ambari server version'); - } + }, + + monitorInactivity: function() { + //console.error('======MONITOR==START========'); + var timeout = Number(App.router.get('clusterController.ambariProperties')['user.inactivity.timeout.default']); + var readonly_timeout = Number(App.router.get('clusterController.ambariProperties')['user.inactivity.timeout.role.readonly.default']); + var isAdmin = App.get('isAdmin'); + if (isAdmin && timeout > 0) { + this.set('userTimeOut', timeout * 1000); + } else if (!isAdmin && readonly_timeout > 0) { + this.set('userTimeOut', readonly_timeout * 1000); + } + if (this.get('userTimeOut') > 0) { + this.startMonitorInactivity(); + } + }, + + startMonitorInactivity: function() { + this.set('isUserActive', true); + this.set('lastUserActiveTime', Date.now()); + + this.rebindActivityEventMonitors(); + if (!this.get('checkActivenessInterval')) { + this.set('checkActivenessInterval', window.setInterval(this.checkActiveness, 1000)); + } + }, + + /* this will be triggerred by user driven events: 'mousemove', 'keypress' and 'click' */ + keepActive: function() { + var scope = App.router.get('mainController'); + //console.error('keepActive'); + if (scope.get('isUserActive')) { + scope.set('lastUserActiveTime', Date.now()); + } + }, + + checkActiveness: function() { + var scope = App.router.get('mainController'); + //console.error("checkActiveness " + scope.get('lastUserActiveTime') + " : " + Date.now()); + if (Date.now() - scope.get('lastUserActiveTime') > scope.get('userTimeOut')) { + scope.set('isUserActive', false); + //console.error("LOGOUT!"); + scope.unbindActivityEventMonitors(); + clearInterval(scope.get('checkActivenessInterval')); + App.router.logOff({}); + } + }, + rebindActivityEventMonitors: function() { + this.unbindActivityEventMonitors(); + this.bindActivityEventMonitors(); + }, + + bindActivityEventMonitors: function() { + $(window).bind('mousemove', this.keepActive); + $(window).bind('keypress', this.keepActive); + $(window).bind('click', this.keepActive); + // iframes need to be monitored as well + var iframes = $('iframe'); + if (iframes.length > 0) { + for (var i = 0; i < iframes.length; i++) { + var iframe = iframes[i]; + $(iframe.contentWindow).bind('mousemove', this.keepActive); + $(iframe.contentWindow).bind('keypress', this.keepActive); + $(iframe.contentWindow).bind('click', this.keepActive); + } + } + }, + + unbindActivityEventMonitors: function() { + $(window).unbind('mousemove', this.keepActive); + $(window).unbind('keypress', this.keepActive); + $(window).unbind('click', this.keepActive); + // iframes need to be monitored as well + var iframes = $('iframe'); + if (iframes.length > 0) { + for (var i = 0; i < iframes.length; i++) { + var iframe = iframes[i]; + $(iframe.contentWindow).unbind('mousemove', this.keepActive); + $(iframe.contentWindow).unbind('keypress', this.keepActive); + $(iframe.contentWindow).unbind('click', this.keepActive); + } + } + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/782bf7d9/ambari-web/app/views/main/views/details.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/views/details.js b/ambari-web/app/views/main/views/details.js index 956ac71..b85a661 100644 --- a/ambari-web/app/views/main/views/details.js +++ b/ambari-web/app/views/main/views/details.js @@ -49,6 +49,7 @@ App.MainViewsDetailsView = Em.View.extend({ }, 5000); self.set('interval', interval); this.resizeFunction(); + App.router.get('mainController').monitorInactivity(); }, resizeFunction : function() {
