summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boto/auth.py26
-rw-r--r--boto/connection.py5
-rw-r--r--boto/provider.py9
-rw-r--r--boto/s3/connection.py25
-rw-r--r--tests/unit/s3/test_connection.py35
5 files changed, 81 insertions, 19 deletions
diff --git a/boto/auth.py b/boto/auth.py
index b479d126..4374f73b 100644
--- a/boto/auth.py
+++ b/boto/auth.py
@@ -98,21 +98,26 @@ SIGV4_DETECT = [
class HmacKeys(object):
"""Key based Auth handler helper."""
- def __init__(self, host, config, provider):
+ def __init__(self, host, config, provider, anon=False):
if provider.access_key is None or provider.secret_key is None:
- raise boto.auth_handler.NotReadyToAuthenticate()
+ if not anon:
+ raise boto.auth_handler.NotReadyToAuthenticate()
+ else:
+ self._hmac = None
+ self._hmac_256 = None
self.host = host
self.update_provider(provider)
def update_provider(self, provider):
self._provider = provider
- self._hmac = hmac.new(self._provider.secret_key.encode('utf-8'),
- digestmod=sha)
- if sha256:
- self._hmac_256 = hmac.new(self._provider.secret_key.encode('utf-8'),
- digestmod=sha256)
- else:
- self._hmac_256 = None
+ if self._provider.secret_key: # Anonymous handler has no key.
+ self._hmac = hmac.new(self._provider.secret_key.encode('utf-8'),
+ digestmod=sha)
+ if sha256:
+ self._hmac_256 = hmac.new(
+ self._provider.secret_key.encode('utf-8'), digestmod=sha256)
+ else:
+ self._hmac_256 = None
def algorithm(self):
if self._hmac_256:
@@ -152,7 +157,8 @@ class AnonAuthHandler(AuthHandler, HmacKeys):
capability = ['anon']
def __init__(self, host, config, provider):
- super(AnonAuthHandler, self).__init__(host, config, provider)
+ AuthHandler.__init__(self, host, config, provider)
+ HmacKeys.__init__(self, host, config, provider, anon=True)
def add_auth(self, http_request, **kwargs):
pass
diff --git a/boto/connection.py b/boto/connection.py
index 2fef4487..34b428f1 100644
--- a/boto/connection.py
+++ b/boto/connection.py
@@ -543,6 +543,8 @@ class AWSAuthConnection(object):
self.http_connection_kwargs['timeout'] = config.getint(
'Boto', 'http_socket_timeout', 70)
+ is_anonymous_connection = getattr(self, 'anon', False)
+
if isinstance(provider, Provider):
# Allow overriding Provider
self.provider = provider
@@ -552,7 +554,8 @@ class AWSAuthConnection(object):
aws_access_key_id,
aws_secret_access_key,
security_token,
- profile_name)
+ profile_name,
+ anon=is_anonymous_connection)
# Allow config file to override default host, port, and host header.
if self.provider.host:
diff --git a/boto/provider.py b/boto/provider.py
index e08afa30..494f3f7d 100644
--- a/boto/provider.py
+++ b/boto/provider.py
@@ -179,7 +179,7 @@ class Provider(object):
}
def __init__(self, name, access_key=None, secret_key=None,
- security_token=None, profile_name=None):
+ security_token=None, profile_name=None, anon=False):
self.host = None
self.port = None
self.host_header = None
@@ -187,6 +187,7 @@ class Provider(object):
self.secret_key = secret_key
self.security_token = security_token
self.profile_name = profile_name
+ self.anon = anon
self.name = name
self.acl_class = self.AclClassMap[self.name]
self.canned_acls = self.CannedAclsMap[self.name]
@@ -244,6 +245,9 @@ class Provider(object):
security_token = property(get_security_token, set_security_token)
def _credentials_need_refresh(self):
+ if self.anon:
+ return False
+
if self._credential_expiry_time is None:
return False
else:
@@ -264,6 +268,9 @@ class Provider(object):
def get_credentials(self, access_key=None, secret_key=None,
security_token=None, profile_name=None):
+ if self.anon:
+ return
+
access_key_name, secret_key_name, security_token_name, \
profile_name_name = self.CredentialMap[self.name]
diff --git a/boto/s3/connection.py b/boto/s3/connection.py
index fa3fbd72..f364a6b0 100644
--- a/boto/s3/connection.py
+++ b/boto/s3/connection.py
@@ -171,20 +171,31 @@ class S3Connection(AWSAuthConnection):
host=NoHostProvided, debug=0, https_connection_factory=None,
calling_format=DefaultCallingFormat, path='/',
provider='aws', bucket_class=Bucket, security_token=None,
- suppress_consec_slashes=True, anon=False,
+ suppress_consec_slashes=True, anon=None,
validate_certs=None, profile_name=None):
+ self.bucket_class = bucket_class
+
+ if isinstance(calling_format, six.string_types):
+ calling_format=boto.utils.find_class(calling_format)()
+ self.calling_format = calling_format
+
+ # Fetching config options at init time, instead of using a class-level
+ # default (set at class declaration time) as the default arg value,
+ # allows our tests to ensure that the config file options are
+ # respected.
+ if anon is None:
+ # Only fetch from the config option if a non-default arg value was
+ # provided.
+ anon = boto.config.getbool('s3', 'no_sign_request', False)
+ self.anon = anon
+
no_host_provided = False
- # Try falling back to the boto config file's value, if present.
if host is NoHostProvided:
host = boto.config.get('s3', 'host')
if host is None:
host = self.DefaultHost
no_host_provided = True
- if isinstance(calling_format, six.string_types):
- calling_format=boto.utils.find_class(calling_format)()
- self.calling_format = calling_format
- self.bucket_class = bucket_class
- self.anon = anon
+
super(S3Connection, self).__init__(host,
aws_access_key_id, aws_secret_access_key,
is_secure, port, proxy, proxy_port, proxy_user, proxy_pass,
diff --git a/tests/unit/s3/test_connection.py b/tests/unit/s3/test_connection.py
index 05c561b4..8fd33a0a 100644
--- a/tests/unit/s3/test_connection.py
+++ b/tests/unit/s3/test_connection.py
@@ -59,6 +59,41 @@ class TestAnon(MockServiceWithConfigTestCase):
url = conn.generate_url(0, 'GET', bucket='examplebucket', key='test.txt')
self.assertNotIn('Signature=', url)
+ def test_anon_default_taken_from_config_opt(self):
+ self.config = {
+ 's3': {
+ # Value must be a string for `config.getbool` to not crash.
+ 'no_sign_request': 'True',
+ }
+ }
+
+ conn = self.connection_class(
+ aws_access_key_id='less',
+ aws_secret_access_key='more',
+ host='s3.amazonaws.com',
+ )
+ url = conn.generate_url(
+ 0, 'GET', bucket='examplebucket', key='test.txt')
+ self.assertNotIn('Signature=', url)
+
+ def test_explicit_anon_arg_overrides_config_value(self):
+ self.config = {
+ 's3': {
+ # Value must be a string for `config.getbool` to not crash.
+ 'no_sign_request': 'True',
+ }
+ }
+
+ conn = self.connection_class(
+ aws_access_key_id='less',
+ aws_secret_access_key='more',
+ host='s3.amazonaws.com',
+ anon=False
+ )
+ url = conn.generate_url(
+ 0, 'GET', bucket='examplebucket', key='test.txt')
+ self.assertIn('Signature=', url)
+
class TestPresigned(MockServiceWithConfigTestCase):
connection_class = S3Connection