PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/boto-2.5.2/boto/sts/connection.py

#
Python | 134 lines | 95 code | 11 blank | 28 comment | 10 complexity | 24de7b4a29c68aed6dff212135ebef02 MD5 | raw file
  1. # Copyright (c) 2011 Mitch Garnaat http://garnaat.org/
  2. # Copyright (c) 2011, Eucalyptus Systems, Inc.
  3. #
  4. # Permission is hereby granted, free of charge, to any person obtaining a
  5. # copy of this software and associated documentation files (the
  6. # "Software"), to deal in the Software without restriction, including
  7. # without limitation the rights to use, copy, modify, merge, publish, dis-
  8. # tribute, sublicense, and/or sell copies of the Software, and to permit
  9. # persons to whom the Software is furnished to do so, subject to the fol-
  10. # lowing conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included
  13. # in all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
  17. # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
  18. # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  19. # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. # IN THE SOFTWARE.
  22. from boto.connection import AWSQueryConnection
  23. from boto.regioninfo import RegionInfo
  24. from credentials import Credentials, FederationToken
  25. import boto
  26. import boto.utils
  27. import datetime
  28. import threading
  29. _session_token_cache = {}
  30. class STSConnection(AWSQueryConnection):
  31. DefaultRegionName = 'us-east-1'
  32. DefaultRegionEndpoint = 'sts.amazonaws.com'
  33. APIVersion = '2011-06-15'
  34. def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
  35. is_secure=True, port=None, proxy=None, proxy_port=None,
  36. proxy_user=None, proxy_pass=None, debug=0,
  37. https_connection_factory=None, region=None, path='/',
  38. converter=None):
  39. if not region:
  40. region = RegionInfo(self, self.DefaultRegionName,
  41. self.DefaultRegionEndpoint,
  42. connection_cls=STSConnection)
  43. self.region = region
  44. self._mutex = threading.Semaphore()
  45. AWSQueryConnection.__init__(self, aws_access_key_id,
  46. aws_secret_access_key,
  47. is_secure, port, proxy, proxy_port,
  48. proxy_user, proxy_pass,
  49. self.region.endpoint, debug,
  50. https_connection_factory, path)
  51. def _required_auth_capability(self):
  52. return ['sign-v2']
  53. def _check_token_cache(self, token_key, duration=None, window_seconds=60):
  54. token = _session_token_cache.get(token_key, None)
  55. if token:
  56. now = datetime.datetime.utcnow()
  57. expires = boto.utils.parse_ts(token.expiration)
  58. delta = expires - now
  59. if delta < datetime.timedelta(seconds=window_seconds):
  60. msg = 'Cached session token %s is expired' % token_key
  61. boto.log.debug(msg)
  62. token = None
  63. return token
  64. def _get_session_token(self, duration=None):
  65. params = {}
  66. if duration:
  67. params['DurationSeconds'] = duration
  68. return self.get_object('GetSessionToken', params,
  69. Credentials, verb='POST')
  70. def get_session_token(self, duration=None, force_new=False):
  71. """
  72. Return a valid session token. Because retrieving new tokens
  73. from the Secure Token Service is a fairly heavyweight operation
  74. this module caches previously retrieved tokens and returns
  75. them when appropriate. Each token is cached with a key
  76. consisting of the region name of the STS endpoint
  77. concatenated with the requesting user's access id. If there
  78. is a token in the cache meeting with this key, the session
  79. expiration is checked to make sure it is still valid and if
  80. so, the cached token is returned. Otherwise, a new session
  81. token is requested from STS and it is placed into the cache
  82. and returned.
  83. :type duration: int
  84. :param duration: The number of seconds the credentials should
  85. remain valid.
  86. :type force_new: bool
  87. :param force_new: If this parameter is True, a new session token
  88. will be retrieved from the Secure Token Service regardless
  89. of whether there is a valid cached token or not.
  90. """
  91. token_key = '%s:%s' % (self.region.name, self.provider.access_key)
  92. token = self._check_token_cache(token_key, duration)
  93. if force_new or not token:
  94. boto.log.debug('fetching a new token for %s' % token_key)
  95. self._mutex.acquire()
  96. token = self._get_session_token(duration)
  97. _session_token_cache[token_key] = token
  98. self._mutex.release()
  99. return token
  100. def get_federation_token(self, name, duration=None, policy=None):
  101. """
  102. :type name: str
  103. :param name: The name of the Federated user associated with
  104. the credentials.
  105. :type duration: int
  106. :param duration: The number of seconds the credentials should
  107. remain valid.
  108. :type policy: str
  109. :param policy: A JSON policy to associate with these credentials.
  110. """
  111. params = {'Name' : name}
  112. if duration:
  113. params['DurationSeconds'] = duration
  114. if policy:
  115. params['Policy'] = policy
  116. return self.get_object('GetFederationToken', params,
  117. FederationToken, verb='POST')