mirror of
https://github.com/ansible/awx.git
synced 2026-03-17 17:07:33 -02:30
License check added immediately after login. If key is invalid, user will bis not permitted to continue. If expiration date has past, server is in demo mode, or all allowed hosts have been used, a warning dialog is displayed.
This commit is contained in:
@@ -207,8 +207,8 @@ angular.module('ansible', [
|
||||
|
||||
otherwise({redirectTo: '/'});
|
||||
}])
|
||||
.run(['$rootScope', '$location', 'Authorization','LoadBasePaths',
|
||||
function($rootScope, $location, Authorization, LoadBasePaths) {
|
||||
.run(['$rootScope', 'CheckLicense', '$location', 'Authorization','LoadBasePaths',
|
||||
function($rootScope, CheckLicense, $location, Authorization, LoadBasePaths) {
|
||||
|
||||
LoadBasePaths();
|
||||
|
||||
@@ -226,6 +226,7 @@ angular.module('ansible', [
|
||||
if ($rootScope.current_user == undefined || $rootScope.current_user == null) {
|
||||
Authorization.restoreUserInfo(); //user must have hit browser refresh
|
||||
}
|
||||
CheckLicense();
|
||||
}
|
||||
// Make the correct tab active
|
||||
var base = ($location.path().replace(/^\//,'').split('/')[0]);
|
||||
@@ -236,13 +237,13 @@ angular.module('ansible', [
|
||||
base.replace(/\_/g,' ');
|
||||
$('.nav-tabs a[href="#' + base + '"]').tab('show');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (! Authorization.isTokenValid() ) {
|
||||
// When the app first loads, redirect to login page
|
||||
$location.path('/login');
|
||||
}
|
||||
|
||||
|
||||
// If browser refresh, activate the correct tab
|
||||
var base = ($location.path().replace(/^\//,'').split('/')[0]);
|
||||
if (base == '') {
|
||||
|
||||
@@ -41,20 +41,32 @@ function Authenticate($scope, $rootScope, $location, Authorization, ToggleClass,
|
||||
|
||||
// Call the API to get an auth token
|
||||
$scope.systemLogin = function(username, password) {
|
||||
|
||||
$('.api-error').empty();
|
||||
var token;
|
||||
|
||||
Authorization.retrieveToken(username, password)
|
||||
.success( function(data, status, headers, config) {
|
||||
token = data.token;
|
||||
Authorization.setToken(data.token);
|
||||
$scope.reset();
|
||||
|
||||
// Get all the profile/access info regarding the logged in user
|
||||
Authorization.getUser()
|
||||
.success(function(data, status, headers, config) {
|
||||
$('#login-modal').modal('hide');
|
||||
Authorization.setUserInfo(data);
|
||||
$location.path('/organizations');
|
||||
Authorization.getLicense()
|
||||
.success(function(data, status, headers, config) {
|
||||
Authorization.setLicense(data['license_info']);
|
||||
$location.path('/organizations');
|
||||
})
|
||||
.error(function(data, status, headers, config) {
|
||||
Alert('Error', 'Failed to access user information. GET returned status: ' + status);
|
||||
});
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
Alert('Error', 'Failed to get user data from /api/v1/me. GET status: ' + status);
|
||||
Alert('Error', 'Failed to access license information. GET returned status: ' + status);
|
||||
});
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
@@ -79,3 +91,6 @@ function Authenticate($scope, $rootScope, $location, Authorization, ToggleClass,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Authenticate.$inject = ['$scope', '$rootScope', '$location', 'Authorization', 'ToggleClass', 'Alert'];
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
angular.module('AccessHelper', ['RestServices', 'Utilities'])
|
||||
.factory('CheckAccess', ['$rootScope', 'Alert', 'Rest', 'GetBasePath','ProcessErrors', 'Alert',
|
||||
function($rootScope, Alert, Rest, GetBasePath, ProcessErrors, Prompt) {
|
||||
angular.module('AccessHelper', ['RestServices', 'Utilities', 'ngCookies'])
|
||||
.factory('CheckAccess', ['$rootScope', 'Alert', 'Rest', 'GetBasePath','ProcessErrors',
|
||||
function($rootScope, Alert, Rest, GetBasePath, ProcessErrors) {
|
||||
return function(params) {
|
||||
var me = $rootScope.current_user;
|
||||
var access = false;
|
||||
@@ -33,4 +33,59 @@ angular.module('AccessHelper', ['RestServices', 'Utilities'])
|
||||
}
|
||||
return access;
|
||||
}
|
||||
}])
|
||||
|
||||
.factory('CheckLicense', ['$rootScope', '$cookieStore', 'Alert', '$location', 'Authorization',
|
||||
function($rootScope, $cookieStore, Alert, $location, Authorization) {
|
||||
return function() {
|
||||
// Check license status and alert the user, if needed
|
||||
var status = 'success';
|
||||
var hdr, msg;
|
||||
var license = $cookieStore.get('license');
|
||||
if (license && !Authorization.licenseTested()) {
|
||||
// This is our first time evaluating the license
|
||||
license['tested'] = true;
|
||||
$cookieStore.remove('license');
|
||||
$cookieStore.put('license', license);
|
||||
$rootScope.license_tested = true;
|
||||
if (license['key_valid'] !== undefined && license['key_valid'] == false) {
|
||||
// The license is invalid. Stop the user from logging in.
|
||||
status = 'alert-error';
|
||||
hdr = 'License Error';
|
||||
msg = 'Something is wrong with your /etc/awx/license file on this server. ' +
|
||||
'Please contact <a href="mailto:info@ansibleworks.com">info@ansibleworks.com</a> for assistance.';
|
||||
//action = function() { window.location = '#/logout'; };
|
||||
Alert(hdr, msg, status, null, false, true);
|
||||
}
|
||||
else if (license['demo'] !== undefined && license['demo'] == true) {
|
||||
// demo
|
||||
status = 'alert-info';
|
||||
hdr = 'AWX Demo';
|
||||
msg = 'Thank you for trying AnsibleWorks AWX. You can use this edition to manage up to 5 hosts. ' +
|
||||
'Should you wish to acquire a license for additional servers, please visit ' +
|
||||
'<a href="http://ansibleworks.com/ansibleworks-awx" target="_blank"><strong>ansibleworks.com/ansibleworks-awx</strong></a>, or ' +
|
||||
'contact <a href="mailto:info@ansibleworks.com"><strong>info@ansibleworks.com</strong></a> for assistance.';
|
||||
Alert(hdr, msg, status);
|
||||
}
|
||||
if (license['date_warning'] !== undefined && license['date_warning'] == true) {
|
||||
status = 'alert-info';
|
||||
hdr = 'License Expired';
|
||||
msg = 'Your AnsibleWorks AWX License has expired and is no longer compliant. ' +
|
||||
'You can continue, but you will be unable to add any additional hosts. Please ' +
|
||||
'visit <a href="http://ansibleworks.com/ansibleworks-awx" target="_blank"><strong>ansibleworks.com/ansibleworks-awx</strong></a> ' +
|
||||
'for license and renewal information, or contact <a href="mailto:info@ansibleworks.com"><strong>info@ansibleworks.com</strong></a> ' +
|
||||
'for assistance.';
|
||||
Alert(hdr, msg, status);
|
||||
}
|
||||
if (license['free_instances'] !== undefined && parseInt(license['free_instances']) <= 0) {
|
||||
status = 'alert-info';
|
||||
hdr = 'License Warning';
|
||||
msg = 'Your AnsibleWorks AWX License has reached capacity for the number of managed ' +
|
||||
'hosts allowed. You will not be able to add any additional hosts. To extend your license, please visit ' +
|
||||
'<a href="http://ansibleworks.com/ansibleworks-awx" target="_blank"><strong>ansibleworks.com/ansibleworks-awx.</strong></a>, or ' +
|
||||
'contact <a href="mailto:info@ansibleworks.com"><strong>info@ansibleworks.com</strong></a> for more information.';
|
||||
Alert(hdr, msg, status, null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}]);
|
||||
@@ -69,6 +69,36 @@ angular.module('AuthService', ['ngCookies'])
|
||||
$rootScope.userLoggedIn = false;
|
||||
},
|
||||
|
||||
getLicense: function() {
|
||||
return $http({
|
||||
method: 'GET',
|
||||
url: '/api/v1/config/',
|
||||
headers: { 'Authorization': 'Token ' + this.getToken() }
|
||||
});
|
||||
},
|
||||
|
||||
setLicense: function(license) {
|
||||
license['tested'] = false;
|
||||
$cookieStore.put('license', license);
|
||||
},
|
||||
|
||||
licenseTested: function() {
|
||||
var result;
|
||||
if ($rootScope.license_test !== undefined) {
|
||||
result = $rootScope.license_test;
|
||||
}
|
||||
else {
|
||||
var license = $cookieStore.get('license');
|
||||
if (license && license.tested !== undefined) {
|
||||
result = license.tested;
|
||||
}
|
||||
else {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
getUser: function() {
|
||||
return $http({
|
||||
method: 'GET',
|
||||
|
||||
@@ -16,7 +16,7 @@ angular.module('RestServices',['ngCookies','AuthService'])
|
||||
|
||||
pReplace: function() {
|
||||
//in our url, replace :xx params with a value, assuming
|
||||
// we can find it in user supplied params.
|
||||
//we can find it in user supplied params.
|
||||
var key,rgx;
|
||||
for (key in this.params) {
|
||||
rgx = new RegExp("\\:" + key,'gm');
|
||||
|
||||
@@ -27,13 +27,36 @@ angular.module('Utilities',[])
|
||||
}
|
||||
})
|
||||
|
||||
.factory('Alert', ['$rootScope', function($rootScope) {
|
||||
return function(hdr, msg) {
|
||||
.factory('Alert', ['$rootScope', '$location', function($rootScope, $location) {
|
||||
return function(hdr, msg, cls, action, secondAlert, disableButtons) {
|
||||
// Pass in the header and message you want displayed on TB modal dialog found in index.html.
|
||||
// Assumes an id of 'alert-modal'
|
||||
$rootScope.alertHeader = hdr;
|
||||
$rootScope.alertBody = msg;
|
||||
$('#alert-modal').modal({ show: true, keyboard: true, backdrop: 'static' });
|
||||
// Assumes an #id of 'alert-modal'. Pass in an optional TB alert class (i.e. alert-error, alert-success,
|
||||
// alert-info...). Pass an optional function(){}, if you want a specific action to occur when user
|
||||
// clicks 'OK' button. Set secondAlert to true, when a second dialog is needed.
|
||||
if (secondAlert) {
|
||||
$rootScope.alertHeader2 = hdr;
|
||||
$rootScope.alertBody2 = msg;
|
||||
$rootScope.alertClass2 = (cls) ? cls : 'alert-error'; //default alert class is alert-error
|
||||
$('#alert-modal2').modal({ show: true, keyboard: true , backdrop: 'static' });
|
||||
$rootScope.disableButtons2 = (disableButtons) ? true : false;
|
||||
if (action) {
|
||||
$('#alert-modal2').on('hidden', function() {
|
||||
action();
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
$rootScope.alertHeader = hdr;
|
||||
$rootScope.alertBody = msg;
|
||||
$rootScope.alertClass = (cls) ? cls : 'alert-error'; //default alert class is alert-error
|
||||
$('#alert-modal').modal({ show: true, keyboard: true , backdrop: 'static' });
|
||||
$rootScope.disableButtons = (disableButtons) ? true : false;
|
||||
if (action) {
|
||||
$('#alert-modal').on('hidden', function() {
|
||||
action();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}])
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<script src="{{ STATIC_URL }}lib/angular/angular.js"></script>
|
||||
<script src="{{ STATIC_URL }}lib/angular/angular-resource.js"></script>
|
||||
<script src="{{ STATIC_URL }}lib/angular/angular-cookies.js"></script>
|
||||
<script src="{{ STATIC_URL }}lib/angular/angular-sanitize.min.js"></script>
|
||||
{% if settings.USE_MINIFIED_JS %} {# FIXME: Change to use minified JS once we are building it. #}
|
||||
<script src="{{ STATIC_URL }}js/awx-min.js"></script> <!-- FIXME: Change to whatever we end up calling the minified file. -->
|
||||
{% else %}
|
||||
@@ -189,18 +190,31 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Alerts/error handling dialog -->
|
||||
<!-- Alerts/error handling dialogs -->
|
||||
<div id="alert-modal" class="modal hide">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-target="#alert-modal"
|
||||
data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<button type="button" class="close" ng-hide="disableButtons" data-target="#alert-modal"
|
||||
data-dismiss="modal" class="modal" aria-hidden="true">×</button>
|
||||
<h3 ng-bind="alertHeader"></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-error" ng-bind="alertBody"></div>
|
||||
<div class="alert" ng-class="alertClass" ng-bind-html-unsafe="alertBody"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" data-target="#alert-modal" data-dismiss="modal" class="btn">OK</a>
|
||||
<a href="#" ng-hide="disableButtons" data-target="#form-modal" data-dismiss="modal" class="btn">OK</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="alert-modal2" class="modal hide">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-target="#alert-modal2"
|
||||
data-dismiss="modal" ng-hide="disableButtons2" aria-hidden="true">×</button>
|
||||
<h3 ng-bind="alertHeader2"></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert" ng-class="alertClass2" ng-bind-html-unsafe="alertBody2"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" ng-hide="disableButtons2" data-target="#form-modal2" data-dismiss="modal" class="alert-button2" class="btn">OK</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user