credential_provider_chain.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. var AWS = require('../core');
  2. /**
  3. * Creates a credential provider chain that searches for AWS credentials
  4. * in a list of credential providers specified by the {providers} property.
  5. *
  6. * By default, the chain will use the {defaultProviders} to resolve credentials.
  7. * These providers will look in the environment using the
  8. * {AWS.EnvironmentCredentials} class with the 'AWS' and 'AMAZON' prefixes.
  9. *
  10. * ## Setting Providers
  11. *
  12. * Each provider in the {providers} list should be a function that returns
  13. * a {AWS.Credentials} object, or a hardcoded credentials object. The function
  14. * form allows for delayed execution of the credential construction.
  15. *
  16. * ## Resolving Credentials from a Chain
  17. *
  18. * Call {resolve} to return the first valid credential object that can be
  19. * loaded by the provider chain.
  20. *
  21. * For example, to resolve a chain with a custom provider that checks a file
  22. * on disk after the set of {defaultProviders}:
  23. *
  24. * ```javascript
  25. * var diskProvider = new AWS.FileSystemCredentials('./creds.json');
  26. * var chain = new AWS.CredentialProviderChain();
  27. * chain.providers.push(diskProvider);
  28. * chain.resolve();
  29. * ```
  30. *
  31. * The above code will return the `diskProvider` object if the
  32. * file contains credentials and the `defaultProviders` do not contain
  33. * any credential settings.
  34. *
  35. * @!attribute providers
  36. * @return [Array<AWS.Credentials, Function>]
  37. * a list of credentials objects or functions that return credentials
  38. * objects. If the provider is a function, the function will be
  39. * executed lazily when the provider needs to be checked for valid
  40. * credentials. By default, this object will be set to the
  41. * {defaultProviders}.
  42. * @see defaultProviders
  43. */
  44. AWS.CredentialProviderChain = AWS.util.inherit(AWS.Credentials, {
  45. /**
  46. * Creates a new CredentialProviderChain with a default set of providers
  47. * specified by {defaultProviders}.
  48. */
  49. constructor: function CredentialProviderChain(providers) {
  50. if (providers) {
  51. this.providers = providers;
  52. } else {
  53. this.providers = AWS.CredentialProviderChain.defaultProviders.slice(0);
  54. }
  55. this.resolveCallbacks = [];
  56. },
  57. /**
  58. * @!method resolvePromise()
  59. * Returns a 'thenable' promise.
  60. * Resolves the provider chain by searching for the first set of
  61. * credentials in {providers}.
  62. *
  63. * Two callbacks can be provided to the `then` method on the returned promise.
  64. * The first callback will be called if the promise is fulfilled, and the second
  65. * callback will be called if the promise is rejected.
  66. * @callback fulfilledCallback function(credentials)
  67. * Called if the promise is fulfilled and the provider resolves the chain
  68. * to a credentials object
  69. * @param credentials [AWS.Credentials] the credentials object resolved
  70. * by the provider chain.
  71. * @callback rejectedCallback function(error)
  72. * Called if the promise is rejected.
  73. * @param err [Error] the error object returned if no credentials are found.
  74. * @return [Promise] A promise that represents the state of the `resolve` method call.
  75. * @example Calling the `resolvePromise` method.
  76. * var promise = chain.resolvePromise();
  77. * promise.then(function(credentials) { ... }, function(err) { ... });
  78. */
  79. /**
  80. * Resolves the provider chain by searching for the first set of
  81. * credentials in {providers}.
  82. *
  83. * @callback callback function(err, credentials)
  84. * Called when the provider resolves the chain to a credentials object
  85. * or null if no credentials can be found.
  86. *
  87. * @param err [Error] the error object returned if no credentials are
  88. * found.
  89. * @param credentials [AWS.Credentials] the credentials object resolved
  90. * by the provider chain.
  91. * @return [AWS.CredentialProviderChain] the provider, for chaining.
  92. */
  93. resolve: function resolve(callback) {
  94. var self = this;
  95. if (self.providers.length === 0) {
  96. callback(new Error('No providers'));
  97. return self;
  98. }
  99. if (self.resolveCallbacks.push(callback) === 1) {
  100. var index = 0;
  101. var providers = self.providers.slice(0);
  102. function resolveNext(err, creds) {
  103. if ((!err && creds) || index === providers.length) {
  104. AWS.util.arrayEach(self.resolveCallbacks, function (callback) {
  105. callback(err, creds);
  106. });
  107. self.resolveCallbacks.length = 0;
  108. return;
  109. }
  110. var provider = providers[index++];
  111. if (typeof provider === 'function') {
  112. creds = provider.call();
  113. } else {
  114. creds = provider;
  115. }
  116. if (creds.get) {
  117. creds.get(function (getErr) {
  118. resolveNext(getErr, getErr ? null : creds);
  119. });
  120. } else {
  121. resolveNext(null, creds);
  122. }
  123. }
  124. resolveNext();
  125. }
  126. return self;
  127. }
  128. });
  129. /**
  130. * The default set of providers used by a vanilla CredentialProviderChain.
  131. *
  132. * In the browser:
  133. *
  134. * ```javascript
  135. * AWS.CredentialProviderChain.defaultProviders = []
  136. * ```
  137. *
  138. * In Node.js:
  139. *
  140. * ```javascript
  141. * AWS.CredentialProviderChain.defaultProviders = [
  142. * function () { return new AWS.EnvironmentCredentials('AWS'); },
  143. * function () { return new AWS.EnvironmentCredentials('AMAZON'); },
  144. * function () { return new AWS.SsoCredentials(); },
  145. * function () { return new AWS.SharedIniFileCredentials(); },
  146. * function () { return new AWS.ECSCredentials(); },
  147. * function () { return new AWS.ProcessCredentials(); },
  148. * function () { return new AWS.TokenFileWebIdentityCredentials(); },
  149. * function () { return new AWS.EC2MetadataCredentials() }
  150. * ]
  151. * ```
  152. */
  153. AWS.CredentialProviderChain.defaultProviders = [];
  154. /**
  155. * @api private
  156. */
  157. AWS.CredentialProviderChain.addPromisesToClass = function addPromisesToClass(PromiseDependency) {
  158. this.prototype.resolvePromise = AWS.util.promisifyMethod('resolve', PromiseDependency);
  159. };
  160. /**
  161. * @api private
  162. */
  163. AWS.CredentialProviderChain.deletePromisesFromClass = function deletePromisesFromClass() {
  164. delete this.prototype.resolvePromise;
  165. };
  166. AWS.util.addPromises(AWS.CredentialProviderChain);