UNPKG

@detachhead/openstack-swift-client

Version:
104 lines (88 loc) 2.71 kB
"use strict"; const EventEmitter = require('events'); const requestp = require('request-promise'); class KeystoneV3Authenticator extends EventEmitter { constructor(credentials) { super(); this.credentials = credentials; this.currentToken = null; } tryFindEndpointUrl(catalog, service, iface) { if (typeof iface === 'undefined') { iface = "public"; } const catalogEntry = catalog.find(x => x.name === service); if (!catalogEntry) { return null; } const endpoint = catalogEntry.endpoints.find(x => x.interface === iface); if (!endpoint) { return null; } return endpoint.url; } async getToken() { const credentials = this.credentials; const model = { auth: { identity: { methods: [ 'password' ], password: { user: { name: credentials.username, password: credentials.password, domain: { id: credentials.domainId } } } }, scope: { project: { id: credentials.projectId, domain: { id: credentials.domainId } } } } }; const response = await requestp({ method: 'POST', uri: credentials.endpointUrl + '/auth/tokens', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, json: model, resolveWithFullResponse: true }); const catalog = response.body.token.catalog; const swiftUrl = this.tryFindEndpointUrl(catalog, 'swift', credentials.endpointUrlInterface) || this.tryFindEndpointUrl(catalog, 'radosgw-swift', credentials.endpointUrlInterface); // many OpenStack clouds use ceph radosgw to provide swift if (!swiftUrl) { throw new Error('could not find swift or radosgw-swift service in catalog'); } return { token: response.headers['x-subject-token'], expires: new Date(response.body.token.expires_at), // expires_at is an ISO 8601 Date: swiftUrl: swiftUrl } }; async authenticate() { if (!this.currentToken) { this.currentToken = await this.getToken(); } const tokenPreRefreshInterval = 10000; // renew tokens 10s before they expire const requestedTokenExpiry = new Date(Date.now() + tokenPreRefreshInterval) if (requestedTokenExpiry > this.currentToken.expires) { this.currentToken = await this.getToken(); } const validToken = this.currentToken; return { url: validToken.swiftUrl, token: validToken.token }; } } module.exports = KeystoneV3Authenticator;