123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- var AWS = require('./core');
- /**
- * Represents your AWS security credentials, specifically the
- * {accessKeyId}, {secretAccessKey}, and optional {sessionToken}.
- * Creating a `Credentials` object allows you to pass around your
- * security information to configuration and service objects.
- *
- * Note that this class typically does not need to be constructed manually,
- * as the {AWS.Config} and {AWS.Service} classes both accept simple
- * options hashes with the three keys. These structures will be converted
- * into Credentials objects automatically.
- *
- * ## Expiring and Refreshing Credentials
- *
- * Occasionally credentials can expire in the middle of a long-running
- * application. In this case, the SDK will automatically attempt to
- * refresh the credentials from the storage location if the Credentials
- * class implements the {refresh} method.
- *
- * If you are implementing a credential storage location, you
- * will want to create a subclass of the `Credentials` class and
- * override the {refresh} method. This method allows credentials to be
- * retrieved from the backing store, be it a file system, database, or
- * some network storage. The method should reset the credential attributes
- * on the object.
- *
- * @!attribute expired
- * @return [Boolean] whether the credentials have been expired and
- * require a refresh. Used in conjunction with {expireTime}.
- * @!attribute expireTime
- * @return [Date] a time when credentials should be considered expired. Used
- * in conjunction with {expired}.
- * @!attribute accessKeyId
- * @return [String] the AWS access key ID
- * @!attribute secretAccessKey
- * @return [String] the AWS secret access key
- * @!attribute sessionToken
- * @return [String] an optional AWS session token
- */
- AWS.Credentials = AWS.util.inherit({
- /**
- * A credentials object can be created using positional arguments or an options
- * hash.
- *
- * @overload AWS.Credentials(accessKeyId, secretAccessKey, sessionToken=null)
- * Creates a Credentials object with a given set of credential information
- * as positional arguments.
- * @param accessKeyId [String] the AWS access key ID
- * @param secretAccessKey [String] the AWS secret access key
- * @param sessionToken [String] the optional AWS session token
- * @example Create a credentials object with AWS credentials
- * var creds = new AWS.Credentials('akid', 'secret', 'session');
- * @overload AWS.Credentials(options)
- * Creates a Credentials object with a given set of credential information
- * as an options hash.
- * @option options accessKeyId [String] the AWS access key ID
- * @option options secretAccessKey [String] the AWS secret access key
- * @option options sessionToken [String] the optional AWS session token
- * @example Create a credentials object with AWS credentials
- * var creds = new AWS.Credentials({
- * accessKeyId: 'akid', secretAccessKey: 'secret', sessionToken: 'session'
- * });
- */
- constructor: function Credentials() {
- // hide secretAccessKey from being displayed with util.inspect
- AWS.util.hideProperties(this, ['secretAccessKey']);
- this.expired = false;
- this.expireTime = null;
- this.refreshCallbacks = [];
- if (arguments.length === 1 && typeof arguments[0] === 'object') {
- var creds = arguments[0].credentials || arguments[0];
- this.accessKeyId = creds.accessKeyId;
- this.secretAccessKey = creds.secretAccessKey;
- this.sessionToken = creds.sessionToken;
- } else {
- this.accessKeyId = arguments[0];
- this.secretAccessKey = arguments[1];
- this.sessionToken = arguments[2];
- }
- },
- /**
- * @return [Integer] the number of seconds before {expireTime} during which
- * the credentials will be considered expired.
- */
- expiryWindow: 15,
- /**
- * @return [Boolean] whether the credentials object should call {refresh}
- * @note Subclasses should override this method to provide custom refresh
- * logic.
- */
- needsRefresh: function needsRefresh() {
- var currentTime = AWS.util.date.getDate().getTime();
- var adjustedTime = new Date(currentTime + this.expiryWindow * 1000);
- if (this.expireTime && adjustedTime > this.expireTime) {
- return true;
- } else {
- return this.expired || !this.accessKeyId || !this.secretAccessKey;
- }
- },
- /**
- * Gets the existing credentials, refreshing them if they are not yet loaded
- * or have expired. Users should call this method before using {refresh},
- * as this will not attempt to reload credentials when they are already
- * loaded into the object.
- *
- * @callback callback function(err)
- * When this callback is called with no error, it means either credentials
- * do not need to be refreshed or refreshed credentials information has
- * been loaded into the object (as the `accessKeyId`, `secretAccessKey`,
- * and `sessionToken` properties).
- * @param err [Error] if an error occurred, this value will be filled
- */
- get: function get(callback) {
- var self = this;
- if (this.needsRefresh()) {
- this.refresh(function(err) {
- if (!err) self.expired = false; // reset expired flag
- if (callback) callback(err);
- });
- } else if (callback) {
- callback();
- }
- },
- /**
- * @!method getPromise()
- * Returns a 'thenable' promise.
- * Gets the existing credentials, refreshing them if they are not yet loaded
- * or have expired. Users should call this method before using {refresh},
- * as this will not attempt to reload credentials when they are already
- * loaded into the object.
- *
- * Two callbacks can be provided to the `then` method on the returned promise.
- * The first callback will be called if the promise is fulfilled, and the second
- * callback will be called if the promise is rejected.
- * @callback fulfilledCallback function()
- * Called if the promise is fulfilled. When this callback is called, it
- * means either credentials do not need to be refreshed or refreshed
- * credentials information has been loaded into the object (as the
- * `accessKeyId`, `secretAccessKey`, and `sessionToken` properties).
- * @callback rejectedCallback function(err)
- * Called if the promise is rejected.
- * @param err [Error] if an error occurred, this value will be filled
- * @return [Promise] A promise that represents the state of the `get` call.
- * @example Calling the `getPromise` method.
- * var promise = credProvider.getPromise();
- * promise.then(function() { ... }, function(err) { ... });
- */
- /**
- * @!method refreshPromise()
- * Returns a 'thenable' promise.
- * Refreshes the credentials. Users should call {get} before attempting
- * to forcibly refresh credentials.
- *
- * Two callbacks can be provided to the `then` method on the returned promise.
- * The first callback will be called if the promise is fulfilled, and the second
- * callback will be called if the promise is rejected.
- * @callback fulfilledCallback function()
- * Called if the promise is fulfilled. When this callback is called, it
- * means refreshed credentials information has been loaded into the object
- * (as the `accessKeyId`, `secretAccessKey`, and `sessionToken` properties).
- * @callback rejectedCallback function(err)
- * Called if the promise is rejected.
- * @param err [Error] if an error occurred, this value will be filled
- * @return [Promise] A promise that represents the state of the `refresh` call.
- * @example Calling the `refreshPromise` method.
- * var promise = credProvider.refreshPromise();
- * promise.then(function() { ... }, function(err) { ... });
- */
- /**
- * Refreshes the credentials. Users should call {get} before attempting
- * to forcibly refresh credentials.
- *
- * @callback callback function(err)
- * When this callback is called with no error, it means refreshed
- * credentials information has been loaded into the object (as the
- * `accessKeyId`, `secretAccessKey`, and `sessionToken` properties).
- * @param err [Error] if an error occurred, this value will be filled
- * @note Subclasses should override this class to reset the
- * {accessKeyId}, {secretAccessKey} and optional {sessionToken}
- * on the credentials object and then call the callback with
- * any error information.
- * @see get
- */
- refresh: function refresh(callback) {
- this.expired = false;
- callback();
- },
- /**
- * @api private
- * @param callback
- */
- coalesceRefresh: function coalesceRefresh(callback, sync) {
- var self = this;
- if (self.refreshCallbacks.push(callback) === 1) {
- self.load(function onLoad(err) {
- AWS.util.arrayEach(self.refreshCallbacks, function(callback) {
- if (sync) {
- callback(err);
- } else {
- // callback could throw, so defer to ensure all callbacks are notified
- AWS.util.defer(function () {
- callback(err);
- });
- }
- });
- self.refreshCallbacks.length = 0;
- });
- }
- },
- /**
- * @api private
- * @param callback
- */
- load: function load(callback) {
- callback();
- }
- });
- /**
- * @api private
- */
- AWS.Credentials.addPromisesToClass = function addPromisesToClass(PromiseDependency) {
- this.prototype.getPromise = AWS.util.promisifyMethod('get', PromiseDependency);
- this.prototype.refreshPromise = AWS.util.promisifyMethod('refresh', PromiseDependency);
- };
- /**
- * @api private
- */
- AWS.Credentials.deletePromisesFromClass = function deletePromisesFromClass() {
- delete this.prototype.getPromise;
- delete this.prototype.refreshPromise;
- };
- AWS.util.addPromises(AWS.Credentials);
|