1
0
mirror of https://github.com/ansible/awx.git synced 2024-11-02 18:21:12 +03:00

AC-363 token expiration now handled exclusively on server.

This commit is contained in:
chouseknecht 2013-09-06 17:21:05 -04:00
parent 1763d373eb
commit f8e1d2e0e3
13 changed files with 72 additions and 93 deletions

View File

@ -230,8 +230,8 @@ angular.module('ansible', [
otherwise({redirectTo: '/'});
}])
.run(['$rootScope', 'CheckLicense', '$location', 'Authorization','LoadBasePaths', 'ViewLicense',
function($rootScope, CheckLicense, $location, Authorization, LoadBasePaths, ViewLicense) {
.run(['$cookieStore', '$rootScope', 'CheckLicense', '$location', 'Authorization','LoadBasePaths', 'ViewLicense',
function($cookieStore, $rootScope, CheckLicense, $location, Authorization, LoadBasePaths, ViewLicense) {
LoadBasePaths();
@ -239,8 +239,8 @@ angular.module('ansible', [
$rootScope.crumbCache = new Array();
$rootScope.$on("$routeChangeStart", function(event, next, current) {
// Evaluate the token on each navigation request. Redirect to login page when not valid
if (Authorization.isTokenValid() == false) {
// On each navigation request, check that the user is logged in
if (Authorization.isUserLoggedIn() == false) {
if ( next.templateUrl != (urlPrefix + 'partials/login.html') ) {
$location.path('/login');
}
@ -262,8 +262,10 @@ angular.module('ansible', [
}
});
if (! Authorization.isTokenValid() ) {
if (!Authorization.getToken()) {
// When the app first loads, redirect to login page
$rootScope.sessionExpired = false;
$cookieStore.put('sessionExpired', false);
$location.path('/login');
}

View File

@ -9,10 +9,7 @@
*/
var $AnsibleConfig =
{
session_timeout: 3600, // cookie expiration in seconds. session will expire after this many
// seconds of inactivity.
{
tooltip_delay: {show: 500, hide: 100}, // Default number of milliseconds to delay displaying/hiding tooltips
debug_mode: true, // Enable console logging messages

View File

@ -10,7 +10,7 @@
'use strict';
function Authenticate($window, $scope, $rootScope, $location, Authorization, ToggleClass, Alert)
function Authenticate($cookieStore, $window, $scope, $rootScope, $location, Authorization, ToggleClass, Alert)
{
var setLoginFocus = function() {
$('#login-username').focus();
@ -18,6 +18,7 @@ function Authenticate($window, $scope, $rootScope, $location, Authorization, Tog
// Display the login dialog
$('#login-modal').modal({ show: true, keyboard: false, backdrop: 'static' });
// Set focus to username field
$('#login-modal').on('shown.bs.modal', function() {
setLoginFocus();
@ -36,18 +37,8 @@ function Authenticate($window, $scope, $rootScope, $location, Authorization, Tog
Authorization.logout();
}
scope.sessionTimeout = ($AnsibleConfig.session_timeout / 60).toFixed(2);
if ($rootScope.userLoggedIn) {
// If we're logged in, check for session timeout
scope.sessionExpired = Authorization.didSessionExpire();
}
else {
scope.sessionExpired = false;
}
$rootScope.userLoggedIn = false; //hide the logout link. if you got here, you're logged out.
//gets set back to true by Authorization.setToken().
$rootScope.userLoggedIn = false; //hide the logout link. if you got here, you're logged out.
$cookieStore.put('userLoggedIn', false); //gets set back to true by Authorization.setToken().
$('#login-password').bind('keypress', function(e) {
var code = (e.keyCode ? e.keyCode : e.which);
@ -73,16 +64,7 @@ function Authenticate($window, $scope, $rootScope, $location, Authorization, Tog
.success( function(data, status, headers, config) {
$('#login-modal').modal('hide');
token = data.token;
Authorization.setToken(data.token);
scope.reset();
// Force request to /organizations to query with the correct token -in the event a new user
// has logged in.
var today = new Date();
today.setTime(today.getTime() + ($AnsibleConfig.session_timeout * 1000));
$rootScope.token = token;
$rootScope.userLoggedIn = true;
$rootScope.token_expire = today.getTime();
Authorization.setToken(data.token, data.expires);
// Get all the profile/access info regarding the logged in user
Authorization.getUser()
@ -126,5 +108,5 @@ function Authenticate($window, $scope, $rootScope, $location, Authorization, Tog
}
}
Authenticate.$inject = ['$window', '$scope', '$rootScope', '$location', 'Authorization', 'ToggleClass', 'Alert'];
Authenticate.$inject = ['$cookieStore', '$window', '$scope', '$rootScope', '$location', 'Authorization', 'ToggleClass', 'Alert'];

View File

@ -29,6 +29,9 @@ function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Res
SelectionInit({ scope: scope, list: list, url: url, returnToCaller: 1 });
if (scope.PostRefreshRemove) {
scope.PostRefreshRemove();
}
scope.PostRefershRemove = scope.$on('PostRefresh', function() {
// After a refresh, populate the organization name on each row
for(var i=0; i < scope.credentials.length; i++) {

View File

@ -176,7 +176,7 @@ function OrganizationsEdit ($scope, $rootScope, $compile, $location, $log, $rout
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to retrieve organization: ' + $routeParams.id + '. GET status: ' + status });
{ hdr: 'Error!', msg: 'Failed to retrieve organization: ' + $routeParams.id + '. GET status: ' + status });
});
@ -194,7 +194,7 @@ function OrganizationsEdit ($scope, $rootScope, $compile, $location, $log, $rout
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, OrganizationForm,
{ hdr: 'Error!', msg: 'Failed to update organization: ' + id + '. PUT status: ' + status });
{ hdr: 'Error!', msg: 'Failed to update organization: ' + id + '. PUT status: ' + status });
});
};

View File

@ -54,6 +54,7 @@ angular.module('JobTemplateFormDefinition', [])
addRequired: true,
editRequired: true,
ngClick: 'lookUpInventory()',
awRequiredWhen: {variable: "inventoryrequired", init: "true" },
column: 1
},
project: {
@ -64,6 +65,7 @@ angular.module('JobTemplateFormDefinition', [])
addRequired: true,
editRequired: true,
ngClick: 'lookUpProject()',
awRequiredWhen: {variable: "projectrequired", init: "true" },
column: 1
},
playbook: {
@ -73,6 +75,7 @@ angular.module('JobTemplateFormDefinition', [])
id: 'playbook-select',
addRequired: true,
editRequired: true,
awRequiredWhen: {variable: "playbookrequired", init: "true" },
column: 1
},
credential: {

View File

@ -15,7 +15,7 @@
*/
angular.module('RefreshRelatedHelper', ['RestServices', 'Utilities'])
.factory('RefreshRelated', ['Alert', 'Rest', function(Alert, Rest) {
.factory('RefreshRelated', ['ProcessErrors', 'Rest', function(ProcessErrors, Rest) {
return function(params) {
var scope = params.scope;
@ -40,7 +40,8 @@ angular.module('RefreshRelatedHelper', ['RestServices', 'Utilities'])
})
.error ( function(data, status, headers, config) {
scope[iterator + 'SearchSpin'] = true;
Alert('Error!', 'Failed to retrieve related set: ' + set + '. GET returned status: ' + status);
ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Failed to retrieve ' + set + '. GET returned status: ' + status });
});
}
}]);

View File

@ -15,7 +15,7 @@
*/
angular.module('RefreshHelper', ['RestServices', 'Utilities'])
.factory('Refresh', ['Alert', 'Rest', function(Alert, Rest) {
.factory('Refresh', ['ProcessErrors', 'Rest', function(ProcessErrors, Rest) {
return function(params) {
var scope = params.scope;
@ -37,7 +37,8 @@ angular.module('RefreshHelper', ['RestServices', 'Utilities'])
})
.error ( function(data, status, headers, config) {
scope[iterator + 'SearchSpin'] = false;
Alert('Error!', 'Failed to retrieve ' + set + '. GET returned status: ' + status);
ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Failed to retrieve ' + set + '. GET returned status: ' + status });
});
}
}]);

View File

@ -13,11 +13,11 @@ angular.module('JobHostDefinition', [])
name: 'jobhosts',
iterator: 'jobhost',
editTitle: 'Job Host Summary',
index: true,
indexShow: 'host_id == null',
hover: true,
fields: {
job: {
id: {
label: 'Job ID',
ngClick: "showJob(\{\{ jobhost.job \}\})",
columnShow: 'host_id !== null',

View File

@ -1,67 +1,45 @@
/*********************************************
* Copyright (c) 2013 AnsibleWorks, Inc.
*
* User authentication functions
* AuthService.js
*
* User authentication functions
*/
angular.module('AuthService', ['ngCookies'])
.factory('Authorization', ['$http', '$rootScope', '$location', '$cookieStore', function($http, $rootScope, $location, $cookieStore) {
angular.module('AuthService', ['ngCookies', 'Utilities'])
.factory('Authorization', ['$http', '$rootScope', '$location', '$cookieStore', 'GetBasePath',
function($http, $rootScope, $location, $cookieStore, GetBasePath) {
return {
setToken: function(token) {
setToken: function(token, expires) {
// set the session cookie
var today = new Date();
today.setTime(today.getTime() + ($AnsibleConfig.session_timeout * 1000));
$cookieStore.remove('token');
$cookieStore.remove('token_expire');
$cookieStore.remove('token_expires');
$cookieStore.remove('userLoggedIn');
$cookieStore.put('token', token);
$cookieStore.put('token_expire', today.getTime());
$cookieStore.put('token_expires', expires);
$cookieStore.put('userLoggedIn', true);
$cookieStore.put('sessionExpired', false);
$rootScope.token = token;
$rootScope.userLoggedIn = true;
$rootScope.token_expire = today.getTime();
$rootScope.token_expires = expires;
$rootScope.sessionExpired = false;
},
isTokenValid: function() {
// check if token exists and is not expired
var response = false;
var token = ($rootScope.token) ? $rootScope.token : $cookieStore.get('token');
var token_expire = ($rootScope.token_expire) ? $rootScope.token_expire : $cookieStore.get('token_expire');
if (token && token_expire) {
var exp = new Date(token_expire);
var today = new Date();
if (today < exp) {
this.setToken(token); //push expiration into the future while user is active
response = true;
}
isUserLoggedIn: function() {
if ($rootScope.userLoggedIn == undefined) {
// Browser refresh may have occurred
$rootScope.userLoggedIn = $cookieStore.get('userLoggedIn');
$rootScope.sessionExpired = $cookieStore.get('sessionExpired');
}
return response;
return $rootScope.userLoggedIn;
},
didSessionExpire: function() {
// use only to test why user was sent to login page.
var response = false;
var token_expire = ($rootScope.token_expire) ? $rootScope.token_expire : $cookieStore.get('token_expire');
if (token_expire) {
var exp = new Date(token_expire);
var today = new Date();
if (exp < today) {
response = true;
}
}
return response;
},
getToken: function() {
if ( this.isTokenValid() ) {
return ($rootScope.token) ? $rootScope.token : $cookieStore.get('token');
}
else {
$location.path('/login');
}
},
return ($rootScope.token) ? $rootScope.token : $cookieStore.get('token');
},
retrieveToken: function(username, password) {
return $http({ method: 'POST', url: '/api/v1/authtoken/',
return $http({ method: 'POST', url: GetBasePath('authtoken'),
data: {"username": username, "password": password} });
},
@ -70,15 +48,17 @@ angular.module('AuthService', ['ngCookies'])
// should prevent content flash from the prior user.
var scope = angular.element(document.getElementById('main-view')).scope();
scope.$destroy();
$rootScope.$destroy();
$rootScope.$destroy();
$cookieStore.remove('accordions');
$cookieStore.remove('token');
$cookieStore.remove('token_expire');
$cookieStore.remove('current_user');
$cookieStore.put('userLoggedIn', false);
$cookieStore.put('sessionExpired', false);
$rootScope.current_user = {};
$rootScope.license_tested = undefined;
$rootScope.userLoggedIn = false;
$rootScope.sessionExpired = false;
$rootScope.token = null;
$rootScope.token_expire = new Date(1970, 0, 1, 0, 0, 0, 0);
},
@ -86,7 +66,7 @@ angular.module('AuthService', ['ngCookies'])
getLicense: function() {
return $http({
method: 'GET',
url: '/api/v1/config/',
url: GetBasePath('config'),
headers: { 'Authorization': 'Token ' + this.getToken() }
});
},

View File

@ -78,8 +78,14 @@ angular.module('Utilities',[])
}
}])
.factory('ProcessErrors', ['$log', 'Alert', function($log, Alert) {
.factory('ProcessErrors', ['$cookieStore', '$log', '$location', '$rootScope', 'Alert',
function($cookieStore, $log, $location, $rootScope, Alert) {
return function(scope, data, status, form, defaultMsg) {
if ($AnsibleConfig.debug_mode && console) {
console.log('Debug status: ' + status);
console.log('Debug data: ');
console.log(data);
}
if (status == 403) {
var msg = 'The API responded with a 403 Access Denied error. ';
if (data['detail']) {
@ -90,6 +96,11 @@ angular.module('Utilities',[])
}
Alert(defaultMsg.hdr, msg);
}
else if (status == 401 && data.detail && data.detail == 'Token is expired') {
$rootScope.sessionExpired = true;
$cookieStore.put('sessionExpired', true);
$location.path('/login');
}
else if (data.non_field_errors) {
Alert('Error!', data.non_field_errors);
}
@ -250,4 +261,3 @@ angular.module('Utilities',[])
}
}
}]);

View File

@ -25,9 +25,9 @@
<script src="{{ STATIC_URL }}js/awx-min.js"></script>
{% else %}
<script src="{{ STATIC_URL }}js/app.js"></script>
<script src="{{ STATIC_URL }}lib/ansible/authenticate.js"></script>
<script src="{{ STATIC_URL }}lib/ansible/rest-services.js"></script>
<script src="{{ STATIC_URL }}lib/ansible/utilities.js"></script>
<script src="{{ STATIC_URL }}lib/ansible/AuthService.js"></script>
<script src="{{ STATIC_URL }}lib/ansible/RestServices.js"></script>
<script src="{{ STATIC_URL }}lib/ansible/Utilities.js"></script>
<script src="{{ STATIC_URL }}lib/ansible/form-generator.js"></script>
<script src="{{ STATIC_URL }}lib/ansible/list-generator.js"></script>
<script src="{{ STATIC_URL }}lib/ansible/prompt-dialog.js"></script>