chain.go 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * MinIO Go Library for Amazon S3 Compatible Cloud Storage
  3. * Copyright 2017 MinIO, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package credentials
  18. // A Chain will search for a provider which returns credentials
  19. // and cache that provider until Retrieve is called again.
  20. //
  21. // The Chain provides a way of chaining multiple providers together
  22. // which will pick the first available using priority order of the
  23. // Providers in the list.
  24. //
  25. // If none of the Providers retrieve valid credentials Value, ChainProvider's
  26. // Retrieve() will return the no credentials value.
  27. //
  28. // If a Provider is found which returns valid credentials Value ChainProvider
  29. // will cache that Provider for all calls to IsExpired(), until Retrieve is
  30. // called again after IsExpired() is true.
  31. //
  32. // creds := credentials.NewChainCredentials(
  33. // []credentials.Provider{
  34. // &credentials.EnvAWSS3{},
  35. // &credentials.EnvMinio{},
  36. // })
  37. //
  38. // // Usage of ChainCredentials.
  39. // mc, err := minio.NewWithCredentials(endpoint, creds, secure, "us-east-1")
  40. // if err != nil {
  41. // log.Fatalln(err)
  42. // }
  43. //
  44. type Chain struct {
  45. Providers []Provider
  46. curr Provider
  47. }
  48. // NewChainCredentials returns a pointer to a new Credentials object
  49. // wrapping a chain of providers.
  50. func NewChainCredentials(providers []Provider) *Credentials {
  51. return New(&Chain{
  52. Providers: append([]Provider{}, providers...),
  53. })
  54. }
  55. // Retrieve returns the credentials value, returns no credentials(anonymous)
  56. // if no credentials provider returned any value.
  57. //
  58. // If a provider is found with credentials, it will be cached and any calls
  59. // to IsExpired() will return the expired state of the cached provider.
  60. func (c *Chain) Retrieve() (Value, error) {
  61. for _, p := range c.Providers {
  62. creds, _ := p.Retrieve()
  63. // Always prioritize non-anonymous providers, if any.
  64. if creds.AccessKeyID == "" && creds.SecretAccessKey == "" {
  65. continue
  66. }
  67. c.curr = p
  68. return creds, nil
  69. }
  70. // At this point we have exhausted all the providers and
  71. // are left without any credentials return anonymous.
  72. return Value{
  73. SignerType: SignatureAnonymous,
  74. }, nil
  75. }
  76. // IsExpired will returned the expired state of the currently cached provider
  77. // if there is one. If there is no current provider, true will be returned.
  78. func (c *Chain) IsExpired() bool {
  79. if c.curr != nil {
  80. return c.curr.IsExpired()
  81. }
  82. return true
  83. }