gl-store-s3.js/node_modules/aws-sdk/lib/credentials/remote_credentials.js

209 lines
6.2 KiB
JavaScript

var AWS = require('../core'),
ENV_RELATIVE_URI = 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI',
ENV_FULL_URI = 'AWS_CONTAINER_CREDENTIALS_FULL_URI',
ENV_AUTH_TOKEN = 'AWS_CONTAINER_AUTHORIZATION_TOKEN',
FULL_URI_UNRESTRICTED_PROTOCOLS = ['https:'],
FULL_URI_ALLOWED_PROTOCOLS = ['http:', 'https:'],
FULL_URI_ALLOWED_HOSTNAMES = ['localhost', '127.0.0.1'],
RELATIVE_URI_HOST = '169.254.170.2';
/**
* Represents credentials received from specified URI.
*
* This class will request refreshable credentials from the relative URI
* specified by the AWS_CONTAINER_CREDENTIALS_RELATIVE_URI or the
* AWS_CONTAINER_CREDENTIALS_FULL_URI environment variable. If valid credentials
* are returned in the response, these will be used with zero configuration.
*
* This credentials class will by default timeout after 1 second of inactivity
* and retry 3 times.
* If your requests to the relative URI are timing out, you can increase
* the value by configuring them directly:
*
* ```javascript
* AWS.config.credentials = new AWS.RemoteCredentials({
* httpOptions: { timeout: 5000 }, // 5 second timeout
* maxRetries: 10, // retry 10 times
* retryDelayOptions: { base: 200 } // see AWS.Config for information
* });
* ```
*
* @see AWS.Config.retryDelayOptions
*
* @!macro nobrowser
*/
AWS.RemoteCredentials = AWS.util.inherit(AWS.Credentials, {
constructor: function RemoteCredentials(options) {
AWS.Credentials.call(this);
options = options ? AWS.util.copy(options) : {};
if (!options.httpOptions) options.httpOptions = {};
options.httpOptions = AWS.util.merge(
this.httpOptions, options.httpOptions);
AWS.util.update(this, options);
},
/**
* @api private
*/
httpOptions: { timeout: 1000 },
/**
* @api private
*/
maxRetries: 3,
/**
* @api private
*/
isConfiguredForEcsCredentials: function isConfiguredForEcsCredentials() {
return Boolean(
process &&
process.env &&
(process.env[ENV_RELATIVE_URI] || process.env[ENV_FULL_URI])
);
},
/**
* @api private
*/
getECSFullUri: function getECSFullUri() {
if (process && process.env) {
var relative = process.env[ENV_RELATIVE_URI],
full = process.env[ENV_FULL_URI];
if (relative) {
return 'http://' + RELATIVE_URI_HOST + relative;
} else if (full) {
var parsed = AWS.util.urlParse(full);
if (FULL_URI_ALLOWED_PROTOCOLS.indexOf(parsed.protocol) < 0) {
throw AWS.util.error(
new Error('Unsupported protocol: AWS.RemoteCredentials supports '
+ FULL_URI_ALLOWED_PROTOCOLS.join(',') + ' only; '
+ parsed.protocol + ' requested.'),
{ code: 'ECSCredentialsProviderFailure' }
);
}
if (FULL_URI_UNRESTRICTED_PROTOCOLS.indexOf(parsed.protocol) < 0 &&
FULL_URI_ALLOWED_HOSTNAMES.indexOf(parsed.hostname) < 0) {
throw AWS.util.error(
new Error('Unsupported hostname: AWS.RemoteCredentials only supports '
+ FULL_URI_ALLOWED_HOSTNAMES.join(',') + ' for ' + parsed.protocol + '; '
+ parsed.protocol + '//' + parsed.hostname + ' requested.'),
{ code: 'ECSCredentialsProviderFailure' }
);
}
return full;
} else {
throw AWS.util.error(
new Error('Variable ' + ENV_RELATIVE_URI + ' or ' + ENV_FULL_URI +
' must be set to use AWS.RemoteCredentials.'),
{ code: 'ECSCredentialsProviderFailure' }
);
}
} else {
throw AWS.util.error(
new Error('No process info available'),
{ code: 'ECSCredentialsProviderFailure' }
);
}
},
/**
* @api private
*/
getECSAuthToken: function getECSAuthToken() {
if (process && process.env && process.env[ENV_FULL_URI]) {
return process.env[ENV_AUTH_TOKEN];
}
},
/**
* @api private
*/
credsFormatIsValid: function credsFormatIsValid(credData) {
return (!!credData.accessKeyId && !!credData.secretAccessKey &&
!!credData.sessionToken && !!credData.expireTime);
},
/**
* @api private
*/
formatCreds: function formatCreds(credData) {
if (!!credData.credentials) {
credData = credData.credentials;
}
return {
expired: false,
accessKeyId: credData.accessKeyId || credData.AccessKeyId,
secretAccessKey: credData.secretAccessKey || credData.SecretAccessKey,
sessionToken: credData.sessionToken || credData.Token,
expireTime: new Date(credData.expiration || credData.Expiration)
};
},
/**
* @api private
*/
request: function request(url, callback) {
var httpRequest = new AWS.HttpRequest(url);
httpRequest.method = 'GET';
httpRequest.headers.Accept = 'application/json';
var token = this.getECSAuthToken();
if (token) {
httpRequest.headers.Authorization = token;
}
AWS.util.handleRequestWithRetries(httpRequest, this, callback);
},
/**
* Loads the credentials from the relative URI specified by container
*
* @callback callback function(err)
* Called when the request to the relative URI responds (or fails). When
* this callback is called with no error, it means that the credentials
* information has been loaded into the object (as the `accessKeyId`,
* `secretAccessKey`, `sessionToken`, and `expireTime` properties).
* @param err [Error] if an error occurred, this value will be filled
* @see get
*/
refresh: function refresh(callback) {
this.coalesceRefresh(callback || AWS.util.fn.callback);
},
/**
* @api private
*/
load: function load(callback) {
var self = this;
var fullUri;
try {
fullUri = this.getECSFullUri();
} catch (err) {
callback(err);
return;
}
this.request(fullUri, function(err, data) {
if (!err) {
try {
data = JSON.parse(data);
var creds = self.formatCreds(data);
if (!self.credsFormatIsValid(creds)) {
throw AWS.util.error(
new Error('Response data is not in valid format'),
{ code: 'ECSCredentialsProviderFailure' }
);
}
AWS.util.update(self, creds);
} catch (dataError) {
err = dataError;
}
}
callback(err, creds);
});
}
});