uaa-client
Version:
REST support for UAA in cloud foundry using javascript.
225 lines (198 loc) • 6.35 kB
JavaScript
;
var util = require('./util');
// btoa shim
global.Buffer = global.Buffer || require('buffer').Buffer;
if (typeof btoa === 'undefined') {
global.btoa = function(str) {
return new Buffer(str).toString('base64');
};
}
if (typeof atob === 'undefined') {
global.atob = function(b64Encoded) {
return new Buffer(b64Encoded, 'base64').toString();
};
}
class UaaClient {
constructor(uaaUrl) {
console.log('constructor for Uaa');
this.uaaUrl = uaaUrl;
}
login(client, secret) {
var options = {
url: this.concatToUrl('oauth/token'),
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Basic ' + btoa(client + ':' + secret),
},
body: 'client_id=' + encodeURIComponent(client) + '&grant_type=client_credentials',
};
return util.requestP(options);
}
// https://docs.cloudfoundry.org/api/uaa/#create94
createClient(clientOptions, token){
var options = {
url: this.concatToUrl('oauth/clients'),
method: 'POST',
body: JSON.stringify(clientOptions),
};
return util.requestP(options, token);
}
// https://docs.cloudfoundry.org/api/uaa/#create94
getClients(token){
return util.requestP({url: this.concatToUrl('oauth/clients')}, token);
}
// TODO permissions error when done in tests
deleteClient(clientId, token){
var options = {
url: this.concatToUrl('oauth/clients', clientId),
method: 'DELETE',
headers: {
Authorization: 'Bearer ' + token,
},
};
return util.requestP(options, token);
}
// http://www.simplecloud.info/specs/draft-scim-api-01.html#get-resources-ops}
getUsers(token) {
var options = {
method: 'GET',
url: this.concatToUrl('Users'),
};
return util.requestP(options, token);
}
// For body see link below
// https://github.com/cloudfoundry/uaa/blob/master/docs/UAA-APIs.rst#create-a-user-post-users
addUser(addUserOptions, token){
const options = {
method: 'POST',
url: this.concatToUrl('Users'),
body: JSON.stringify(addUserOptions),
};
return util.requestP(options, token);
}
removeUser(userId, token) {
const options = {
method: 'DELETE',
url: this.concatToUrl('Users', userId),
};
return util.requestP(options, token);
}
// https://github.com/cloudfoundry/uaa/blob/master/docs/UAA-APIs.rst#change-password-put-users-id-password
updatePassword(userId, oldPassword, newPassword, token) {
const options = {
method: 'PUT',
url: this.concatToUrl('Users', userId, 'password'),
headers: {
Accept: 'application/json',
},
body: {
oldPassword,
password: newPassword,
},
};
return util.requestP(options, token);
}
// UAA REST API see https://docs.cloudfoundry.org/api/uaa/#create94
// TODO move this to base then remove the base dependency or else somehowe remove base dependency
// login required before doing other scripting functions
// token automatically cached to token module
login2(user, password){
return new Promise((resolve, reject) => {
util.requestP({ url: this.concatToUrl('info') })
.then(result => {
var infoBody = typeof result.body == 'string' ? JSON.parse(result.body) : result.body;
var authorizationEndpoint = infoBody.authorization_endpoint + '/oauth/token';
console.log('info result:', JSON.stringify(result, null, 2));
console.log('authorization endpoint:', authorizationEndpoint);
var options = {
url: authorizationEndpoint,
method:'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Basic Y2Y6',
},
body: `grant_type=password&password=${password}&scope=&username=${user}`,
};
util.requestP(options)
.then(result => {
var aToken = typeof result.body == 'string' ? JSON.parse(result.body) : result.body;
resolve(aToken);
})
.catch(error => {
reject(error);
});
})
.catch(reject);
});
}
// login(username, password) {
// const url = `${this.uaaUrl}/oauth/token`;
// let options = {
// method: 'POST',
// url: url,
// headers: {
// Authorization: 'Basic Y2Y6',
// 'Content-Type': 'application/x-www-form-urlencoded',
// },
// };
// if (password !== undefined) {
// options.form = {
// grant_type: 'password',
// client_id: 'cf',
// username: username,
// password: password,
// };
// }
// else {
// options.form = {
// grant_type: 'password',
// client_id: 'cf',
// passcode: username,
// };
// }
// return this.REST.request(options, this.HttpStatus.OK, true);
// }
refreshToken(refreshToken) {
const options = {
method: 'POST',
url: this.concatToUrl('oauth/token'),
headers: {
Authorization: 'Basic Y2Y6',
'Content-Type': 'application/x-www-form-urlencoded',
},
form: {
grant_type: 'refresh_token',
refresh_token: refreshToken,
},
};
return this.REST.request(options, this.HttpStatus.OK, true);
}
decodeAccessToken(accessToken) {
var tokenString;
if (typeof accessToken !== 'string') accessToken = accessToken.access_token;
var bearerTypeAndToken = accessToken.split(' ');
if (bearerTypeAndToken.length === 2) tokenString = bearerTypeAndToken[1];
else if (bearerTypeAndToken.length === 1) tokenString = bearerTypeAndToken[0];
else throw new Error('Invalid token format');
var tokenParts = tokenString.split('.');
if (tokenParts.length !== 3) throw new Error('Invalid token format');
var encodedTokenInfo = tokenParts[1];
var tokenInfo = {};
try {
var buf = new Buffer(encodedTokenInfo, 'base64');
tokenInfo = JSON.parse(buf.toString('utf8'));
}
catch (e) {
console.log(e);
throw new Error('Invalid token format');
}
return tokenInfo;
}
concatToUrl(...rest){
var s = this.uaaUrl;
rest.forEach(anArg => s = s.endsWith('/') ? s + anArg : s + '/' + anArg);
return s;
}
}
module.exports = UaaClient;