mirror of
https://github.com/ansible/awx.git
synced 2026-03-06 03:01:06 -03:30
Merge pull request #904 from ansible/oauth_n_session
Implement session-based and OAuth 2 authentications
This commit is contained in:
@@ -52,6 +52,7 @@ const watch = {
|
||||
publicPath: '/static/',
|
||||
host: '127.0.0.1',
|
||||
port: 3000,
|
||||
https: true,
|
||||
proxy: {
|
||||
'/': {
|
||||
target: TARGET,
|
||||
|
||||
@@ -374,7 +374,7 @@ angular
|
||||
}
|
||||
});
|
||||
|
||||
if (!Authorization.getToken() || !Authorization.isUserLoggedIn()) {
|
||||
if (!Authorization.isUserLoggedIn()) {
|
||||
// User not authenticated, redirect to login page
|
||||
if (!/^\/(login|logout)/.test($location.path())) {
|
||||
$rootScope.preAuthUrl = $location.path();
|
||||
|
||||
@@ -21,21 +21,13 @@ export default
|
||||
$injector) {
|
||||
return {
|
||||
setToken: function (token, expires) {
|
||||
// set the session cookie
|
||||
$cookies.remove('token');
|
||||
$cookies.remove('token_expires');
|
||||
$cookies.remove('userLoggedIn');
|
||||
|
||||
if (token && !(/^"[a-f0-9]+"$/ig.test(token))) {
|
||||
$cookies.put('token', `"${token}"`);
|
||||
} else {
|
||||
$cookies.put('token', token);
|
||||
}
|
||||
|
||||
$cookies.put('token_expires', expires);
|
||||
$cookies.put('userLoggedIn', true);
|
||||
$cookies.put('sessionExpired', false);
|
||||
$rootScope.token = token;
|
||||
|
||||
$rootScope.userLoggedIn = true;
|
||||
$rootScope.token_expires = expires;
|
||||
$rootScope.sessionExpired = false;
|
||||
@@ -44,43 +36,34 @@ export default
|
||||
isUserLoggedIn: function () {
|
||||
if ($rootScope.userLoggedIn === undefined) {
|
||||
// Browser refresh may have occurred
|
||||
$rootScope.userLoggedIn = $cookies.get('userLoggedIn');
|
||||
$rootScope.sessionExpired = $cookies.get('sessionExpired');
|
||||
$rootScope.userLoggedIn = ($cookies.get('userLoggedIn') === 'true');
|
||||
$rootScope.sessionExpired = ($cookies.get('sessionExpired') === 'true');
|
||||
}
|
||||
return $rootScope.userLoggedIn;
|
||||
},
|
||||
|
||||
getToken: function () {
|
||||
if ($rootScope.token) {
|
||||
return $rootScope.token;
|
||||
}
|
||||
|
||||
let token = $cookies.get('token');
|
||||
|
||||
return token ? token.replace(/"/g, '') : undefined;
|
||||
},
|
||||
|
||||
retrieveToken: function (username, password) {
|
||||
return $http({
|
||||
method: 'POST',
|
||||
url: GetBasePath('authtoken'),
|
||||
data: {
|
||||
"username": username,
|
||||
"password": password
|
||||
},
|
||||
headers: {
|
||||
'Cache-Control': 'no-store',
|
||||
'Pragma': 'no-cache'
|
||||
}
|
||||
var getCSRFToken = $http({
|
||||
method: 'GET',
|
||||
url: `/api/login/`
|
||||
});
|
||||
|
||||
return getCSRFToken.then(function({data}) {
|
||||
var csrfmiddlewaretoken = /name='csrfmiddlewaretoken' value='([0-9a-zA-Z]+)' \//.exec(data)[1];
|
||||
// TODO: data needs to be encoded
|
||||
return $http({
|
||||
method: 'POST',
|
||||
url: `/api/login/`,
|
||||
data: `username=${username}&password=${password}&csrfmiddlewaretoken=${csrfmiddlewaretoken}&next=%2fapi%2f`,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
deleteToken: function () {
|
||||
return $http({
|
||||
method: 'DELETE',
|
||||
url: GetBasePath('authtoken'),
|
||||
headers: {
|
||||
'Authorization': 'Token ' + this.getToken()
|
||||
}
|
||||
method: 'GET',
|
||||
url: '/api/logout/'
|
||||
});
|
||||
},
|
||||
|
||||
@@ -125,7 +108,6 @@ export default
|
||||
SocketService.disconnect();
|
||||
$cookies.remove('token_expires');
|
||||
$cookies.remove('current_user');
|
||||
$cookies.remove('token');
|
||||
$cookies.put('userLoggedIn', false);
|
||||
$cookies.put('sessionExpired', false);
|
||||
$cookies.putObject('current_user', {});
|
||||
@@ -134,7 +116,6 @@ export default
|
||||
$rootScope.userLoggedIn = false;
|
||||
$rootScope.sessionExpired = false;
|
||||
$rootScope.licenseMissing = true;
|
||||
$rootScope.token = null;
|
||||
$rootScope.token_expires = null;
|
||||
$rootScope.login_username = null;
|
||||
$rootScope.login_password = null;
|
||||
@@ -168,11 +149,7 @@ export default
|
||||
getUser: function () {
|
||||
return $http({
|
||||
method: 'GET',
|
||||
url: GetBasePath('me'),
|
||||
headers: {
|
||||
'Authorization': 'Token ' + this.getToken(),
|
||||
"X-Auth-Token": 'Token ' + this.getToken()
|
||||
}
|
||||
url: GetBasePath('me')
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ export default ['$log', '$cookies', '$compile', '$rootScope',
|
||||
Authorization.retrieveToken(username, password)
|
||||
.then(function (data) {
|
||||
$('#login-modal').modal('hide');
|
||||
Authorization.setToken(data.data.token, data.data.expires);
|
||||
Authorization.setToken(data.data.expires);
|
||||
scope.$emit('AuthorizationGetUser');
|
||||
},
|
||||
function (data) {
|
||||
|
||||
@@ -55,8 +55,8 @@
|
||||
*/
|
||||
|
||||
export default
|
||||
['$http', '$rootScope', '$q', 'Authorization',
|
||||
function ($http, $rootScope, $q, Authorization) {
|
||||
['$http', '$rootScope', '$q',
|
||||
function ($http, $rootScope, $q) {
|
||||
return {
|
||||
|
||||
headers: {},
|
||||
@@ -113,150 +113,88 @@ export default
|
||||
args = (args) ? args : {};
|
||||
this.params = (args.params) ? args.params : null;
|
||||
this.pReplace();
|
||||
var expired = this.checkExpired(),
|
||||
token = Authorization.getToken();
|
||||
var expired = this.checkExpired();
|
||||
if (expired) {
|
||||
return this.createResponse({
|
||||
detail: 'Token is expired'
|
||||
detail: 'Session is expired'
|
||||
}, 401);
|
||||
} else if (token) {
|
||||
this.setHeader({
|
||||
Authorization: 'Token ' + token
|
||||
});
|
||||
this.setHeader({
|
||||
"X-Auth-Token": 'Token ' + token
|
||||
});
|
||||
} else {
|
||||
return $http({
|
||||
method: 'GET',
|
||||
url: this.url,
|
||||
headers: this.headers,
|
||||
params: this.params
|
||||
});
|
||||
} else {
|
||||
return this.createResponse({
|
||||
detail: 'Invalid token'
|
||||
}, 401);
|
||||
}
|
||||
},
|
||||
post: function (data) {
|
||||
var token = Authorization.getToken(),
|
||||
expired = this.checkExpired();
|
||||
var expired = this.checkExpired();
|
||||
if (expired) {
|
||||
return this.createResponse({
|
||||
detail: 'Token is expired'
|
||||
detail: 'Session is expired'
|
||||
}, 401);
|
||||
} else if (token) {
|
||||
this.setHeader({
|
||||
Authorization: 'Token ' + token
|
||||
});
|
||||
this.setHeader({
|
||||
"X-Auth-Token": 'Token ' + token
|
||||
});
|
||||
} else {
|
||||
return $http({
|
||||
method: 'POST',
|
||||
url: this.url,
|
||||
headers: this.headers,
|
||||
data: data
|
||||
});
|
||||
} else {
|
||||
return this.createResponse({
|
||||
detail: 'Invalid token'
|
||||
}, 401);
|
||||
}
|
||||
},
|
||||
put: function (data) {
|
||||
var token = Authorization.getToken(),
|
||||
expired = this.checkExpired();
|
||||
var expired = this.checkExpired();
|
||||
if (expired) {
|
||||
return this.createResponse({
|
||||
detail: 'Token is expired'
|
||||
detail: 'Session is expired'
|
||||
}, 401);
|
||||
} else if (token) {
|
||||
this.setHeader({
|
||||
Authorization: 'Token ' + token
|
||||
});
|
||||
this.setHeader({
|
||||
"X-Auth-Token": 'Token ' + token
|
||||
});
|
||||
} else {
|
||||
return $http({
|
||||
method: 'PUT',
|
||||
url: this.url,
|
||||
headers: this.headers,
|
||||
data: data
|
||||
});
|
||||
} else {
|
||||
return this.createResponse({
|
||||
detail: 'Invalid token'
|
||||
}, 401);
|
||||
}
|
||||
},
|
||||
patch: function (data) {
|
||||
var token = Authorization.getToken(),
|
||||
expired = this.checkExpired();
|
||||
var expired = this.checkExpired();
|
||||
if (expired) {
|
||||
return this.createResponse({
|
||||
detail: 'Token is expired'
|
||||
detail: 'Session is expired'
|
||||
}, 401);
|
||||
} else if (token) {
|
||||
this.setHeader({
|
||||
Authorization: 'Token ' + token
|
||||
});
|
||||
this.setHeader({
|
||||
"X-Auth-Token": 'Token ' + token
|
||||
});
|
||||
} else {
|
||||
return $http({
|
||||
method: 'PATCH',
|
||||
url: this.url,
|
||||
headers: this.headers,
|
||||
data: data
|
||||
});
|
||||
} else {
|
||||
return this.createResponse({
|
||||
detail: 'Invalid token'
|
||||
}, 401);
|
||||
}
|
||||
},
|
||||
destroy: function (data) {
|
||||
var token = Authorization.getToken(),
|
||||
expired = this.checkExpired();
|
||||
var expired = this.checkExpired();
|
||||
if (expired) {
|
||||
return this.createResponse({
|
||||
detail: 'Token is expired'
|
||||
detail: 'Session is expired'
|
||||
}, 401);
|
||||
} else if (token) {
|
||||
this.setHeader({
|
||||
Authorization: 'Token ' + token
|
||||
});
|
||||
this.setHeader({
|
||||
"X-Auth-Token": 'Token ' + token
|
||||
});
|
||||
} else {
|
||||
return $http({
|
||||
method: 'DELETE',
|
||||
url: this.url,
|
||||
headers: this.headers,
|
||||
data: data
|
||||
});
|
||||
} else {
|
||||
return this.createResponse({
|
||||
detail: 'Invalid token'
|
||||
}, 401);
|
||||
}
|
||||
},
|
||||
options: function (cache) {
|
||||
var params,
|
||||
token = Authorization.getToken(),
|
||||
expired = this.checkExpired();
|
||||
if (expired) {
|
||||
return this.createResponse({
|
||||
detail: 'Token is expired'
|
||||
detail: 'Session is expired'
|
||||
}, 401);
|
||||
} else if (token) {
|
||||
this.setHeader({
|
||||
Authorization: 'Token ' + token
|
||||
});
|
||||
this.setHeader({
|
||||
"X-Auth-Token": 'Token ' + token
|
||||
});
|
||||
} else {
|
||||
params = {
|
||||
method: 'OPTIONS',
|
||||
url: this.url,
|
||||
@@ -265,10 +203,6 @@ export default
|
||||
cache: (cache ? true : false)
|
||||
};
|
||||
return $http(params);
|
||||
} else {
|
||||
return this.createResponse({
|
||||
detail: 'Invalid token'
|
||||
}, 401);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -165,7 +165,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
Alert('Conflict', data.conflict || "Resource currently in use.");
|
||||
} else if (status === 410) {
|
||||
Alert('Deleted Object', 'The requested object was previously deleted and can no longer be accessed.');
|
||||
} else if ((status === 'Token is expired') || (status === 401 && data.detail && data.detail === 'Token is expired') ||
|
||||
} else if ((status === 'Session is expired') || (status === 401 && data.detail && data.detail === 'Token is expired') ||
|
||||
(status === 401 && data && data.detail && data.detail === 'Invalid token')) {
|
||||
if ($rootScope.sessionTimer) {
|
||||
$rootScope.sessionTimer.expireSession('idle');
|
||||
|
||||
@@ -8,15 +8,17 @@ import {
|
||||
AWX_E2E_PASSWORD
|
||||
} from './settings';
|
||||
|
||||
let authenticated;
|
||||
|
||||
const session = axios.create({
|
||||
baseURL: AWX_E2E_URL,
|
||||
xsrfHeaderName: 'X-CSRFToken',
|
||||
xsrfCookieName: 'csrftoken',
|
||||
httpsAgent: new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
})
|
||||
}),
|
||||
auth: {
|
||||
username: AWX_E2E_USERNAME,
|
||||
password: AWX_E2E_PASSWORD
|
||||
}
|
||||
});
|
||||
|
||||
const getEndpoint = location => {
|
||||
@@ -27,36 +29,15 @@ const getEndpoint = location => {
|
||||
return `${AWX_E2E_URL}/api/v2${location}`;
|
||||
};
|
||||
|
||||
const authenticate = () => {
|
||||
if (authenticated) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const uri = getEndpoint('/authtoken/');
|
||||
|
||||
const credentials = {
|
||||
username: AWX_E2E_USERNAME,
|
||||
password: AWX_E2E_PASSWORD
|
||||
};
|
||||
|
||||
return session.post(uri, credentials).then(res => {
|
||||
session.defaults.headers.Authorization = `Token ${res.data.token}`;
|
||||
authenticated = true;
|
||||
|
||||
return res;
|
||||
});
|
||||
};
|
||||
|
||||
const request = (method, location, data) => {
|
||||
const uri = getEndpoint(location);
|
||||
const action = session[method.toLowerCase()];
|
||||
|
||||
return authenticate()
|
||||
.then(() => action(uri, data))
|
||||
return action(uri, data)
|
||||
.then(res => {
|
||||
console.log([ // eslint-disable-line no-console
|
||||
res.config.method.toUpperCase(),
|
||||
uri,
|
||||
res.config.url,
|
||||
res.status,
|
||||
res.statusText
|
||||
].join(' '));
|
||||
|
||||
Reference in New Issue
Block a user