import string
import socket
import ssl
+import os
from boto.s3.connection import S3Connection
from nose.tools import eq_ as eq
from nose.plugins.attrib import attr
+from nose.plugins.skip import SkipTest
from .utils import assert_raises
import AnonymousAuth
_add_custom_headers(headers=headers, remove=remove)
return bucket.new_key('foo')
+def tag(*tags):
+ def wrap(func):
+ for tag in tags:
+ setattr(func, tag, True)
+ return func
+ return wrap
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/invalid MD5')
-@attr(assertion='fails 400')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_md5_invalid_garbage():
- key = _setup_bad_object({'Content-MD5':'AWS HAHAHA'})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 400)
- eq(e.reason, 'Bad Request')
- eq(e.error_code, 'InvalidDigest')
-
+#
+# common tests
+#
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/invalid MD5')
eq(e.reason, 'Bad Request')
eq(e.error_code, 'InvalidDigest')
-
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/mismatched MD5')
eq(e.reason, 'Bad Request')
eq(e.error_code, 'BadDigest')
-
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/empty MD5')
eq(e.error_code, 'InvalidDigest')
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/non-graphics in MD5')
assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/no MD5 header')
# strangely, amazon doesn't report an error with a non-expect 100 also, our
# error comes back as html, and not xml as I normally expect
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/Expect 200')
# this is a really long test, and I don't know if it's valid...
# again, accepts this with no troubles
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/empty expect')
key.set_contents_from_string('bar')
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/no expect')
# this is a really long test..
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/non-graphic expect')
key.set_contents_from_string('bar')
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/empty content length')
eq(e.error_code, None)
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/negative content length')
eq(e.reason, 'Bad Request')
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/no content length')
eq(e.reason, 'Length Required')
eq(e.error_code,'MissingContentLength')
+
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/non-graphic content length')
eq(e.error_code, None)
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/content length too long')
eq(e.error_code, 'RequestTimeout')
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/content length too short')
-@attr(assertion='fails 400')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_contentlength_mismatch_below():
- content = 'bar'
- length = len(content) - 1
- key = _setup_bad_object({'Content-Length': length})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, content)
- eq(e.status, 400)
- # dho is 'Bad request', which doesn't match the http response code
- eq(e.reason, 'Bad Request')
- eq(e.error_code, 'BadDigest')
-
-
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/content type text/plain')
key.set_contents_from_string('bar')
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/empty content type')
key.set_contents_from_string('bar')
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/no content type')
key.set_contents_from_string('bar')
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/non-graphic content type')
assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/empty user agent')
-@attr(assertion='succeeds')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_ua_empty():
- key = _setup_bad_object({'User-Agent': ''})
- key.set_contents_from_string('bar')
-
-
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/non-graphic user agent')
-@attr(assertion='succeeds')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_ua_unreadable():
- key = _setup_bad_object({'User-Agent': '\x07'})
- key.set_contents_from_string('bar')
-
-
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/no user agent')
-@attr(assertion='succeeds')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_ua_none():
- key = _setup_bad_object(remove=('User-Agent',))
- key.set_contents_from_string('bar')
-
-
-@nose.with_setup(teardown=_clear_custom_headers)
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/invalid authorization')
-@attr(assertion='fails 400')
-def test_object_create_bad_authorization_invalid():
- key = _setup_bad_object({'Authorization': 'AWS HAHAHA'})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 400)
- eq(e.reason, 'Bad Request')
- eq(e.error_code, 'InvalidArgument')
-
-
# the teardown is really messed up here. check it out
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/non-graphic authorization')
eq(e.error_code, 'AccessDenied')
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/empty authorization')
# the teardown is really messed up here. check it out
+@tag('auth_common')
@attr(resource='object')
@attr(method='put')
@attr(operation='create w/no authorization')
eq(e.error_code, 'AccessDenied')
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/incorrect authorization')
-@attr(assertion='fails 403')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_authorization_incorrect():
- key = _setup_bad_object({'Authorization': 'AWS AKIAIGR7ZNNBHC5BKSUB:FWeDfwojDSdS2Ztmpfeubhd9isU='})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 403)
- eq(e.reason, 'Forbidden')
- assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch', 'InvalidAccessKeyId')
-
-
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/invalid date')
-@attr(assertion='fails 403')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_date_invalid():
- key = _setup_bad_object({'Date': 'Bad Date'})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 403)
- eq(e.reason, 'Forbidden')
- eq(e.error_code, 'AccessDenied')
-
-
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/empty date')
-@attr(assertion='fails 403')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_date_empty():
- key = _setup_bad_object({'Date': ''})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 403)
- eq(e.reason, 'Forbidden')
- eq(e.error_code, 'AccessDenied')
-
-
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/non-graphic date')
-@attr(assertion='fails 403')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_date_unreadable():
- key = _setup_bad_object({'Date': '\x07'})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 403)
- eq(e.reason, 'Forbidden')
- eq(e.error_code, 'AccessDenied')
-
-
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/no date')
-@attr(assertion='fails 403')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_date_none():
- key = _setup_bad_object(remove=('Date',))
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 403)
- eq(e.reason, 'Forbidden')
- eq(e.error_code, 'AccessDenied')
-
-
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/date in past')
-@attr(assertion='fails 403')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_date_before_today():
- key = _setup_bad_object({'Date': 'Tue, 07 Jul 2010 21:53:04 GMT'})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 403)
- eq(e.reason, 'Forbidden')
- eq(e.error_code, 'RequestTimeTooSkewed')
-
-
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/date in future')
-@attr(assertion='fails 403')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_date_after_today():
- key = _setup_bad_object({'Date': 'Tue, 07 Jul 2030 21:53:04 GMT'})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 403)
- eq(e.reason, 'Forbidden')
- eq(e.error_code, 'RequestTimeTooSkewed')
-
-
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/date before epoch')
-@attr(assertion='fails 403')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_date_before_epoch():
- key = _setup_bad_object({'Date': 'Tue, 07 Jul 1950 21:53:04 GMT'})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 403)
- eq(e.reason, 'Forbidden')
- eq(e.error_code, 'AccessDenied')
-
-
-@attr(resource='object')
-@attr(method='put')
-@attr(operation='create w/date after 9999')
-@attr(assertion='fails 403')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_object_create_bad_date_after_end():
- key = _setup_bad_object({'Date': 'Tue, 07 Jul 9999 21:53:04 GMT'})
-
- e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
- eq(e.status, 403)
- eq(e.reason, 'Forbidden')
- eq(e.error_code, 'RequestTimeTooSkewed')
-
-
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/no content length')
_add_custom_headers(remove=('Content-Length',))
get_new_bucket()
+
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='acls')
@attr(operation='set w/no content length')
_add_custom_headers(remove=('Content-Length',))
key.set_acl('public-read')
+
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='acls')
@attr(operation='set w/invalid permission')
# strangely, amazon doesn't report an error with a non-expect 100 also, our
# error comes back as html, and not xml as I normally expect
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/expect 200')
# this is a really long test, and I don't know if it's valid...
# again, accepts this with no troubles
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/expect empty')
_add_custom_headers({'Expect': ''})
bucket = get_new_bucket()
+
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/expect nongraphic')
)
return TargetConnection(targets.main.default.conf, conn)
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/empty content length')
conn = _create_new_connection()
_add_custom_headers({'Content-Length': ''})
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket, conn)
-
eq(e.status, 400)
eq(e.reason, 'Bad Request')
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/negative content length')
eq(e.reason, 'Bad Request')
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/no content length')
bucket = get_new_bucket()
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/non-graphic content length')
def test_bucket_create_bad_contentlength_unreadable():
_add_custom_headers({'Content-Length': '\x07'})
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
eq(e.status, 400)
eq(e.reason, 'Bad Request')
eq(e.error_code, None)
-@attr(resource='bucket')
-@attr(method='put')
-@attr(operation='create w/empty user agent')
-@attr(assertion='succeeds')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_ua_empty():
- _add_custom_headers({'User-Agent': ''})
- bucket = get_new_bucket()
-
-
-@attr(resource='bucket')
-@attr(method='put')
-@attr(operation='create w/non-graphic user agent')
-@attr(assertion='succeeds')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_ua_unreadable():
- _add_custom_headers({'User-Agent': '\x07'})
- bucket = get_new_bucket()
-
-
-@attr(resource='bucket')
-@attr(method='put')
-@attr(operation='create w/no user agent')
-@attr(assertion='succeeds')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_ua_none():
- _add_custom_headers(remove=('User-Agent',))
- bucket = get_new_bucket()
-
-
-@attr(resource='bucket')
-@attr(method='put')
-@attr(operation='create w/invalid authorization')
-@attr(assertion='fails 400')
-@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_authorization_invalid():
- _add_custom_headers({'Authorization': 'AWS HAHAHA'})
- e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
- eq(e.status, 400)
- eq(e.reason, 'Bad Request')
- eq(e.error_code, 'InvalidArgument')
-
-
# the teardown is really messed up here. check it out
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/non-graphic authorization')
def test_bucket_create_bad_authorization_unreadable():
_add_custom_headers({'Authorization': '\x07'})
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
eq(e.status, 403)
eq(e.reason, 'Forbidden')
eq(e.error_code, 'AccessDenied')
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/empty authorization')
def test_bucket_create_bad_authorization_empty():
_add_custom_headers({'Authorization': ''})
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
eq(e.status, 403)
eq(e.reason, 'Forbidden')
eq(e.error_code, 'AccessDenied')
# the teardown is really messed up here. check it out
+@tag('auth_common')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/no authorization')
def test_bucket_create_bad_authorization_none():
_add_custom_headers(remove=('Authorization',))
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
eq(e.status, 403)
eq(e.reason, 'Forbidden')
eq(e.error_code, 'AccessDenied')
-@attr(resource='bucket')
+#
+# AWS2 specific tests
+#
+
+@tag('auth_aws2')
+@attr(resource='object')
@attr(method='put')
-@attr(operation='create w/invalid date')
-@attr(assertion='fails 403')
+@attr(operation='create w/invalid MD5')
+@attr(assertion='fails 400')
@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_date_invalid():
- _add_custom_headers({'Date': 'Bad Date'})
- e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
- eq(e.status, 403)
- eq(e.reason, 'Forbidden')
- eq(e.error_code, 'AccessDenied')
+def test_object_create_bad_md5_invalid_garbage_aws2():
+ key = _setup_bad_object({'Content-MD5':'AWS HAHAHA'})
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 400)
+ eq(e.reason, 'Bad Request')
+ eq(e.error_code, 'InvalidDigest')
-@attr(resource='bucket')
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/content length too short')
+@attr(assertion='fails 400')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_contentlength_mismatch_below_aws2():
+ content = 'bar'
+ length = len(content) - 1
+ key = _setup_bad_object({'Content-Length': length})
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, content)
+ eq(e.status, 400)
+ # dho is 'Bad request', which doesn't match the http response code
+ eq(e.reason, 'Bad Request')
+ eq(e.error_code, 'BadDigest')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/incorrect authorization')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_authorization_incorrect_aws2():
+ key = _setup_bad_object({'Authorization': 'AWS AKIAIGR7ZNNBHC5BKSUB:FWeDfwojDSdS2Ztmpfeubhd9isU='})
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch', 'InvalidAccessKeyId')
+
+
+@tag('auth_aws2')
+@nose.with_setup(teardown=_clear_custom_headers)
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/invalid authorization')
+@attr(assertion='fails 400')
+def test_object_create_bad_authorization_invalid_aws2():
+ key = _setup_bad_object({'Authorization': 'AWS HAHAHA'})
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 400)
+ eq(e.reason, 'Bad Request')
+ eq(e.error_code, 'InvalidArgument')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/empty user agent')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_ua_empty_aws2():
+ key = _setup_bad_object({'User-Agent': ''})
+ key.set_contents_from_string('bar')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/non-graphic user agent')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_ua_unreadable_aws2():
+ key = _setup_bad_object({'User-Agent': '\x07'})
+ key.set_contents_from_string('bar')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/no user agent')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_ua_none_aws2():
+ key = _setup_bad_object(remove=('User-Agent',))
+ key.set_contents_from_string('bar')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/invalid date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_invalid_aws2():
+ key = _setup_bad_object({'Date': 'Bad Date'})
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'AccessDenied')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
@attr(method='put')
@attr(operation='create w/empty date')
@attr(assertion='fails 403')
@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_date_empty():
- _add_custom_headers({'Date': ''})
+def test_object_create_bad_date_empty_aws2():
+ key = _setup_bad_object({'Date': ''})
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'AccessDenied')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/non-graphic date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_unreadable_aws2():
+ key = _setup_bad_object({'Date': '\x07'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'AccessDenied')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/no date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_none_aws2():
+ key = _setup_bad_object(remove=('Date',))
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'AccessDenied')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/date in past')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_before_today_aws2():
+ key = _setup_bad_object({'Date': 'Tue, 07 Jul 2010 21:53:04 GMT'})
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'RequestTimeTooSkewed')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/date in future')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_after_today_aws2():
+ key = _setup_bad_object({'Date': 'Tue, 07 Jul 2030 21:53:04 GMT'})
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'RequestTimeTooSkewed')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/date before epoch')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_before_epoch_aws2():
+ key = _setup_bad_object({'Date': 'Tue, 07 Jul 1950 21:53:04 GMT'})
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'AccessDenied')
+
+
+@tag('auth_aws2')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/date after 9999')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_after_end_aws2():
+ key = _setup_bad_object({'Date': 'Tue, 07 Jul 9999 21:53:04 GMT'})
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'RequestTimeTooSkewed')
+
+
+@tag('auth_aws2')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/invalid authorization')
+@attr(assertion='fails 400')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_authorization_invalid_aws2():
+ _add_custom_headers({'Authorization': 'AWS HAHAHA'})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+ eq(e.status, 400)
+ eq(e.reason, 'Bad Request')
+ eq(e.error_code, 'InvalidArgument')
+
+
+@tag('auth_aws2')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/empty user agent')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_ua_empty_aws2():
+ _add_custom_headers({'User-Agent': ''})
+ bucket = get_new_bucket()
+
+
+@tag('auth_aws2')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/non-graphic user agent')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_ua_unreadable_aws2():
+ _add_custom_headers({'User-Agent': '\x07'})
+ bucket = get_new_bucket()
+
+
+@tag('auth_aws2')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/no user agent')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_ua_none_aws2():
+ _add_custom_headers(remove=('User-Agent',))
+ bucket = get_new_bucket()
+
+
+@tag('auth_aws2')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/invalid date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_date_invalid_aws2():
+ _add_custom_headers({'Date': 'Bad Date'})
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'AccessDenied')
+
+@tag('auth_aws2')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/empty date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_date_empty_aws2():
+ _add_custom_headers({'Date': ''})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
eq(e.status, 403)
eq(e.reason, 'Forbidden')
eq(e.error_code, 'AccessDenied')
+@tag('auth_aws2')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/non-graphic date')
@attr(assertion='fails 403')
@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_date_unreadable():
+def test_bucket_create_bad_date_unreadable_aws2():
_add_custom_headers({'Date': '\x07'})
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
eq(e.status, 403)
eq(e.reason, 'Forbidden')
eq(e.error_code, 'AccessDenied')
+@tag('auth_aws2')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/no date')
@attr(assertion='fails 403')
@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_date_none():
+def test_bucket_create_bad_date_none_aws2():
_add_custom_headers(remove=('Date',))
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
eq(e.status, 403)
eq(e.reason, 'Forbidden')
eq(e.error_code, 'AccessDenied')
+@tag('auth_aws2')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/date in past')
@attr(assertion='fails 403')
@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_date_before_today():
+def test_bucket_create_bad_date_before_today_aws2():
_add_custom_headers({'Date': 'Tue, 07 Jul 2010 21:53:04 GMT'})
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
eq(e.status, 403)
eq(e.reason, 'Forbidden')
eq(e.error_code, 'RequestTimeTooSkewed')
+@tag('auth_aws2')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/date in future')
@attr(assertion='fails 403')
@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_date_after_today():
+def test_bucket_create_bad_date_after_today_aws2():
_add_custom_headers({'Date': 'Tue, 07 Jul 2030 21:53:04 GMT'})
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
eq(e.status, 403)
eq(e.reason, 'Forbidden')
eq(e.error_code, 'RequestTimeTooSkewed')
+@tag('auth_aws2')
@attr(resource='bucket')
@attr(method='put')
@attr(operation='create w/date before epoch')
@attr(assertion='fails 403')
@nose.with_setup(teardown=_clear_custom_headers)
-def test_bucket_create_bad_date_before_epoch():
+def test_bucket_create_bad_date_before_epoch_aws2():
_add_custom_headers({'Date': 'Tue, 07 Jul 1950 21:53:04 GMT'})
e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
-
eq(e.status, 403)
eq(e.reason, 'Forbidden')
eq(e.error_code, 'AccessDenied')
+
+#
+# AWS4 specific tests
+#
+
+def check_aws4_support():
+ if 'S3_USE_SIGV4' not in os.environ:
+ raise SkipTest
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/invalid MD5')
+@attr(assertion='fails 400')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_md5_invalid_garbage_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'Content-MD5':'AWS4 HAHAHA'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 400)
+ eq(e.reason, 'Bad Request')
+ eq(e.error_code, 'InvalidDigest')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/content length too short')
+@attr(assertion='fails 400')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_contentlength_mismatch_below_aws4():
+ check_aws4_support()
+ content = 'bar'
+ length = len(content) - 1
+ key = _setup_bad_object({'Content-Length': length})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, content)
+ eq(e.status, 400)
+ # dho is 'Bad request', which doesn't match the http response code
+ eq(e.reason, 'Bad Request')
+ eq(e.error_code, 'XAmzContentSHA256Mismatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/incorrect authorization')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_authorization_incorrect_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'Authorization': 'AWS4-HMAC-SHA256 Credential=AKIAIGR7ZNNBHC5BKSUB/20150930/us-east-1/s3/aws4_request,SignedHeaders=host;user-agent,Signature=FWeDfwojDSdS2Ztmpfeubhd9isU='})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch', 'InvalidAccessKeyId')
+
+
+@tag('auth_aws4')
+@nose.with_setup(teardown=_clear_custom_headers)
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/invalid authorization')
+@attr(assertion='fails 400')
+def test_object_create_bad_authorization_invalid_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'Authorization': 'AWS4-HMAC-SHA256 Credential=HAHAHA'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 400)
+ eq(e.reason, 'Bad Request')
+ assert e.error_code in ('AuthorizationHeaderMalformed', 'InvalidArgument')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/empty user agent')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_ua_empty_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'User-Agent': ''})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/non-graphic user agent')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_ua_unreadable_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'User-Agent': '\x07'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/no user agent')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_ua_none_aws4():
+ check_aws4_support()
+ key = _setup_bad_object(remove=('User-Agent',))
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/invalid date')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_invalid_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'Date': 'Bad Date'})
+ key.set_contents_from_string('bar')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/invalid x-amz-date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_amz_date_invalid_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'X-Amz-Date': 'Bad Date'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/empty date')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_empty_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'Date': ''})
+ key.set_contents_from_string('bar')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/empty x-amz-date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_amz_date_empty_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'X-Amz-Date': ''})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/non-graphic date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_unreadable_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'Date': '\x07'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/non-graphic x-amz-date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_amz_date_unreadable_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'X-Amz-Date': '\x07'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/no date')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_none_aws4():
+ check_aws4_support()
+ key = _setup_bad_object(remove=('Date',))
+ key.set_contents_from_string('bar')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/no x-amz-date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_amz_date_none_aws4():
+ check_aws4_support()
+ key = _setup_bad_object(remove=('X-Amz-Date',))
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/date in past')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_before_today_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'Date': 'Tue, 07 Jul 2010 21:53:04 GMT'})
+ key.set_contents_from_string('bar')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/x-amz-date in past')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_amz_date_before_today_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'X-Amz-Date': '20100707T215304Z'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('RequestTimeTooSkewed', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/date in future')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_after_today_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'Date': 'Tue, 07 Jul 2030 21:53:04 GMT'})
+ key.set_contents_from_string('bar')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/x-amz-date in future')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_amz_date_after_today_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'X-Amz-Date': '20300707T215304Z'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('RequestTimeTooSkewed', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/date before epoch')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_before_epoch_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'Date': 'Tue, 07 Jul 1950 21:53:04 GMT'})
+ key.set_contents_from_string('bar')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/x-amz-date before epoch')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_amz_date_before_epoch_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'X-Amz-Date': '19500707T215304Z'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/date after 9999')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_date_after_end_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'Date': 'Tue, 07 Jul 9999 21:53:04 GMT'})
+ key.set_contents_from_string('bar')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create w/x-amz-date after 9999')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_bad_amz_date_after_end_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'X-Amz-Date': '99990707T215304Z'})
+
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('RequestTimeTooSkewed', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(operation='create with missing signed custom header')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_missing_signed_custom_header_aws4():
+ check_aws4_support()
+ key = _setup_bad_object({'x-zoo': 'zoo'})
+ _add_custom_non_auth_headers(remove=('x-zoo',))
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='object')
+@attr(method='put')
+@attr(opearation='create with missing signed header')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_object_create_missing_signed_header_aws4():
+ check_aws4_support()
+ key = _setup_bad_object()
+ _add_custom_non_auth_headers(remove=('Content-MD5',))
+ e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar')
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/invalid authorization')
+@attr(assertion='fails 400')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_authorization_invalid_aws4():
+ check_aws4_support()
+ _add_custom_headers({'Authorization': 'AWS4 HAHAHA'})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+
+ eq(e.status, 400)
+ eq(e.reason, 'Bad Request')
+ eq(e.error_code, 'InvalidArgument')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/empty user agent')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_ua_empty_aws4():
+ check_aws4_support()
+ _add_custom_headers({'User-Agent': ''})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/non-graphic user agent')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_ua_unreadable_aws4():
+ check_aws4_support()
+ _add_custom_headers({'User-Agent': '\x07'})
+
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/no user agent')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_ua_none_aws4():
+ check_aws4_support()
+ _add_custom_headers(remove=('User-Agent',))
+
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/invalid date')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_date_invalid_aws4():
+ check_aws4_support()
+ _add_custom_headers({'Date': 'Bad Date'})
+ get_new_bucket()
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/invalid x-amz-date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_amz_date_invalid_aws4():
+ check_aws4_support()
+ _add_custom_headers({'X-Amz-Date': 'Bad Date'})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/empty date')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_date_empty_aws4():
+ check_aws4_support()
+ _add_custom_headers({'Date': ''})
+ get_new_bucket()
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/empty x-amz-date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_amz_date_empty_aws4():
+ check_aws4_support()
+ _add_custom_headers({'X-Amz-Date': ''})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/non-graphic date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_date_unreadable_aws4():
+ check_aws4_support()
+ _add_custom_headers({'Date': '\x07'})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ eq(e.error_code, 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/non-graphic x-amz-date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_amz_date_unreadable_aws4():
+ check_aws4_support()
+ _add_custom_headers({'X-Amz-Date': '\x07'})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/no date')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_date_none_aws4():
+ check_aws4_support()
+ _add_custom_headers(remove=('Date',))
+ get_new_bucket()
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/no x-amz-date')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_amz_date_none_aws4():
+ check_aws4_support()
+ _add_custom_headers(remove=('X-Amz-Date',))
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/date in past')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_date_before_today_aws4():
+ check_aws4_support()
+ _add_custom_headers({'Date': 'Tue, 07 Jul 2010 21:53:04 GMT'})
+ get_new_bucket()
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/x-amz-date in past')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_amz_date_before_today_aws4():
+ check_aws4_support()
+ _add_custom_headers({'X-Amz-Date': '20100707T215304Z'})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('RequestTimeTooSkewed', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/date in future')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_date_after_today_aws4():
+ check_aws4_support()
+ _add_custom_headers({'Date': 'Tue, 07 Jul 2030 21:53:04 GMT'})
+ get_new_bucket()
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/x-amz-date in future')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_amz_date_after_today_aws4():
+ check_aws4_support()
+ _add_custom_headers({'X-Amz-Date': '20300707T215304Z'})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('RequestTimeTooSkewed', 'SignatureDoesNotMatch')
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/date before epoch')
+@attr(assertion='succeeds')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_date_before_epoch_aws4():
+ check_aws4_support()
+ _add_custom_headers({'Date': 'Tue, 07 Jul 1950 21:53:04 GMT'})
+ get_new_bucket()
+
+
+@tag('auth_aws4')
+@attr(resource='bucket')
+@attr(method='put')
+@attr(operation='create w/x-amz-date before epoch')
+@attr(assertion='fails 403')
+@nose.with_setup(teardown=_clear_custom_headers)
+def test_bucket_create_bad_amz_date_before_epoch_aws4():
+ check_aws4_support()
+ _add_custom_headers({'X-Amz-Date': '19500707T215304Z'})
+ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket)
+
+ eq(e.status, 403)
+ eq(e.reason, 'Forbidden')
+ assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')