aws-sdk 2.0.1 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/.eslintrc +20 -0
  2. package/.gitignore +10 -0
  3. package/.travis.yml +20 -0
  4. package/.yardopts +20 -0
  5. package/.yardopts_guide +21 -0
  6. package/Gemfile +16 -0
  7. package/Gemfile.lock +34 -0
  8. package/README.md +5 -6
  9. package/Rakefile +14 -0
  10. package/UPGRADING.md +9 -4
  11. package/configuration.sample +5 -0
  12. package/dist/BUNDLE_LICENSE.txt +96 -0
  13. package/dist/aws-sdk.js +9594 -0
  14. package/dist/aws-sdk.min.js +21 -0
  15. package/dist-tools/.eslintrc +10 -0
  16. package/dist-tools/browser-builder.js +142 -0
  17. package/dist-tools/strategies/cache.js +68 -0
  18. package/dist-tools/strategies/default.js +165 -0
  19. package/dist-tools/test/browser-builder.mocha.spec.coffee +182 -0
  20. package/dist-tools/test/helpers.coffee +16 -0
  21. package/doc-src/guide/browser-building.md +93 -0
  22. package/doc-src/guide/browser-configuring-wif.md +287 -0
  23. package/doc-src/guide/browser-configuring.md +218 -0
  24. package/doc-src/guide/browser-examples.md +220 -0
  25. package/doc-src/guide/browser-intro.md +46 -0
  26. package/doc-src/guide/browser-making-requests.md +279 -0
  27. package/doc-src/guide/browser-services.md +75 -0
  28. package/doc-src/guide/index.md +41 -0
  29. package/doc-src/guide/node-configuring.md +272 -0
  30. package/doc-src/guide/node-examples.md +341 -0
  31. package/doc-src/guide/node-intro.md +32 -0
  32. package/doc-src/guide/node-making-requests.md +309 -0
  33. package/doc-src/guide/node-services.md +159 -0
  34. package/doc-src/templates/api-versions/model_documentor.rb +366 -0
  35. package/doc-src/templates/api-versions/plugin.rb +230 -0
  36. package/doc-src/templates/api-versions/templates/default/class/html/setup.rb +9 -0
  37. package/doc-src/templates/api-versions/templates/default/class/html/waiter_details_list.erb +7 -0
  38. package/doc-src/templates/api-versions/templates/default/class/html/waiter_summary.erb +7 -0
  39. package/doc-src/templates/api-versions/templates/default/docstring/html/experimental.erb +4 -0
  40. package/doc-src/templates/api-versions/templates/default/docstring/setup.rb +9 -0
  41. package/doc-src/templates/api-versions/templates/default/fulldoc/html/css/common.css +6 -0
  42. package/doc-src/templates/api-versions/templates/default/fulldoc/html/setup.rb +62 -0
  43. package/doc-src/templates/api-versions/templates/default/layout/html/services.erb +10 -0
  44. package/doc-src/templates/api-versions/templates/default/layout/html/setup.rb +28 -0
  45. package/doc-src/templates/api-versions/templates/default/module/html/box_info.erb +45 -0
  46. package/doc-src/templates/api-versions/templates/default/module/html/children.erb +8 -0
  47. package/doc-src/templates/api-versions/templates/default/tags/setup.rb +3 -0
  48. package/doc-src/templates/api-versions/templates/default/waiter_details/html/method_signature.erb +3 -0
  49. package/doc-src/templates/api-versions/templates/default/waiter_details/html/setup.rb +5 -0
  50. package/doc-src/templates/default/layout/html/footer.erb +31 -0
  51. package/doc-src/templates/default/layout/html/layout.erb +23 -0
  52. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/css/highlight.github.css +127 -0
  53. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/css/style.css +1192 -0
  54. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/img/logo.png +0 -0
  55. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/app.js +33 -0
  56. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/highlight.pack.js +27 -0
  57. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/AUTHORS +55 -0
  58. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/LICENSE +25 -0
  59. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/doctools.js +247 -0
  60. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/file.png +0 -0
  61. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/searchtools.js +568 -0
  62. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/underscore.js +23 -0
  63. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/search.erb +29 -0
  64. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/search_index.erb +1 -0
  65. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/setup.rb +75 -0
  66. package/doc-src/templates/flasky_sphinx_guide/layout/html/layout.erb +93 -0
  67. package/doc-src/templates/flasky_sphinx_guide/layout/html/setup.rb +9 -0
  68. package/doc-src/templates/flasky_sphinx_guide/layout/html/sidebar.erb +45 -0
  69. package/doc-src/templates/flasky_sphinx_guide/onefile/html/layout.erb +51 -0
  70. package/doc-src/templates/flasky_sphinx_guide/onefile/html/setup.rb +1 -0
  71. package/eslint-rules/no-require-in-service.js +10 -0
  72. package/features/autoscaling/autoscaling.feature +21 -0
  73. package/features/autoscaling/step_definitions/autoscaling.js +49 -0
  74. package/features/cloudformation/cloudformation.feature +22 -0
  75. package/features/cloudformation/step_definitions/cloudformation.js +26 -0
  76. package/features/cloudfront/cloudfront.feature +28 -0
  77. package/features/cloudfront/step_definitions/cloudfront-latest.js +54 -0
  78. package/features/cloudfront/step_definitions/cloudfront.js +21 -0
  79. package/features/cloudsearch/cloudsearch.feature +34 -0
  80. package/features/cloudsearch/step_definitions/cloudsearch.js +42 -0
  81. package/features/cloudtrail/cloudtrail.feature +17 -0
  82. package/features/cloudtrail/step_definitions/cloudtrail.js +14 -0
  83. package/features/cloudwatch/cloudwatch.feature +15 -0
  84. package/features/cloudwatch/step_definitions/cloudwatch.js +48 -0
  85. package/features/datapipeline/datapipeline.feature +23 -0
  86. package/features/datapipeline/step_definitions/datapipeline.js +79 -0
  87. package/features/directconnect/directconnect.feature +20 -0
  88. package/features/directconnect/step_definitions/directconnect.js +44 -0
  89. package/features/dynamodb/crc32.feature +18 -0
  90. package/features/dynamodb/step_definitions/dynamodb.js +154 -0
  91. package/features/dynamodb/tables.feature +50 -0
  92. package/features/ec2/ec2.feature +28 -0
  93. package/features/ec2/step_definitions/ec2.js +65 -0
  94. package/features/elasticache/elasticache.feature +20 -0
  95. package/features/elasticache/step_definitions/elasticache.js +34 -0
  96. package/features/elasticbeanstalk/elasticbeanstalk.feature +22 -0
  97. package/features/elasticbeanstalk/step_definitions/elasticbeanstalk.js +38 -0
  98. package/features/elastictranscoder/elastictranscoder.feature +24 -0
  99. package/features/elastictranscoder/step_definitions/elastictranscoder.js +56 -0
  100. package/features/elb/elb.feature +19 -0
  101. package/features/elb/step_definitions/elb.js +37 -0
  102. package/features/emr/emr.feature +16 -0
  103. package/features/emr/step_definitions/emr.js +45 -0
  104. package/features/extra/assertions.js +29 -0
  105. package/features/extra/dummy.feature +0 -0
  106. package/features/extra/fixtures/testfile.txt +1 -0
  107. package/features/extra/helpers.js +113 -0
  108. package/features/extra/hooks.js +107 -0
  109. package/features/extra/world.js +12 -0
  110. package/features/glacier/glacier.feature +47 -0
  111. package/features/glacier/step_definitions/glacier.js +112 -0
  112. package/features/iam/iam.feature +24 -0
  113. package/features/iam/step_definitions/iam.js +66 -0
  114. package/features/importexport/importexport.feature +53 -0
  115. package/features/importexport/step_definitions/importexport.js +42 -0
  116. package/features/kinesis/kinesis.feature +9 -0
  117. package/features/kinesis/step_definitions/kinesis.js +10 -0
  118. package/features/opsworks/opsworks.feature +26 -0
  119. package/features/opsworks/step_definitions/opsworks.js +42 -0
  120. package/features/rds/rds.feature +32 -0
  121. package/features/rds/step_definitions/rds.js +72 -0
  122. package/features/redshift/redshift.feature +20 -0
  123. package/features/redshift/step_definitions/redshift.js +33 -0
  124. package/features/route53/route53.feature +41 -0
  125. package/features/route53/step_definitions/route53.js +97 -0
  126. package/features/s3/buckets.feature +40 -0
  127. package/features/s3/objects.feature +122 -0
  128. package/features/s3/step_definitions/buckets.js +136 -0
  129. package/features/s3/step_definitions/hooks.js +39 -0
  130. package/features/s3/step_definitions/objects.js +204 -0
  131. package/features/s3/step_definitions/proxy.js +44 -0
  132. package/features/ses/ses.feature +20 -0
  133. package/features/ses/step_definitions/ses.js +22 -0
  134. package/features/simpledb/simpledb.feature +29 -0
  135. package/features/simpledb/step_definitions/simpledb.js +46 -0
  136. package/features/sns/sns.feature +15 -0
  137. package/features/sns/step_definitions/sns.js +33 -0
  138. package/features/sqs/messages.feature +21 -0
  139. package/features/sqs/queues.feature +18 -0
  140. package/features/sqs/step_definitions/messages.js +46 -0
  141. package/features/sqs/step_definitions/queues.js +33 -0
  142. package/features/sqs/step_definitions/sqs.js +7 -0
  143. package/features/storagegateway/step_definitions/storagegateway.js +16 -0
  144. package/features/storagegateway/storagegateway.feature +13 -0
  145. package/features/sts/step_definitions/sts.js +35 -0
  146. package/features/sts/sts.feature +29 -0
  147. package/features/support/step_definitions/support.js +35 -0
  148. package/features/support/support.feature +18 -0
  149. package/features/swf/step_definitions/swf.js +38 -0
  150. package/features/swf/swf.feature +15 -0
  151. package/index.js +2 -0
  152. package/lib/core.js +2 -2
  153. package/lib/credentials/shared_ini_file_credentials.js +0 -1
  154. package/lib/event_listeners.js +13 -1
  155. package/lib/http/node.js +19 -30
  156. package/lib/model/resource_waiter.js +0 -4
  157. package/lib/model/shape.js +2 -1
  158. package/lib/protocol/rest_xml.js +1 -1
  159. package/lib/region_config.js +31 -0
  160. package/lib/region_config.json +56 -0
  161. package/lib/request.js +37 -45
  162. package/lib/sequential_executor.js +17 -34
  163. package/lib/service.js +17 -44
  164. package/lib/services/cloudsearchdomain.js +69 -0
  165. package/lib/services/route53.js +0 -12
  166. package/lib/services/s3.js +3 -19
  167. package/lib/signers/v4.js +2 -1
  168. package/lib/util.js +28 -3
  169. package/package.json +3 -3
  170. package/scripts/console +11 -3
  171. package/scripts/coverage +126 -0
  172. package/tasks/apis.rake +122 -0
  173. package/tasks/browser.rake +89 -0
  174. package/tasks/docs.rake +36 -0
  175. package/tasks/lib/cucumber_generator.rb +40 -0
  176. package/tasks/util.rake +33 -0
  177. package/test/browser/js/jasmine-1.3.1.js +2600 -0
  178. package/test/browser/js/jasmine-html.js +681 -0
  179. package/test/browser/runner.html +109 -0
  180. package/test/browser/runner.js +92 -0
  181. package/test/browser/sample/appinfo.sample.js +15 -0
  182. package/test/browser/sample/console.html +429 -0
  183. package/test/browser/sample/css/smoothness/images/animated-overlay.gif +0 -0
  184. package/test/browser/sample/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  185. package/test/browser/sample/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  186. package/test/browser/sample/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  187. package/test/browser/sample/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  188. package/test/browser/sample/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  189. package/test/browser/sample/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  190. package/test/browser/sample/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  191. package/test/browser/sample/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  192. package/test/browser/sample/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  193. package/test/browser/sample/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  194. package/test/browser/sample/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  195. package/test/browser/sample/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  196. package/test/browser/sample/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  197. package/test/browser/sample/css/smoothness/jquery-ui-1.10.1.custom.css +1175 -0
  198. package/test/browser/sample/css/smoothness/jquery-ui-1.10.1.custom.min.css +5 -0
  199. package/test/browser/sample/img/loading.gif +0 -0
  200. package/test/browser/sample/js/jquery-1.9.1.js +9597 -0
  201. package/test/browser/sample/js/jquery-ui-1.10.1.custom.js +14903 -0
  202. package/test/browser/sample/js/jquery-ui-1.10.1.custom.min.js +6 -0
  203. package/test/browser/sample/s3upload.html +111 -0
  204. package/test/browser.spec.coffee +207 -0
  205. package/test/config.spec.coffee +202 -0
  206. package/test/credential_provider_chain.spec.coffee +90 -0
  207. package/test/credentials.spec.coffee +452 -0
  208. package/test/endpoint.spec.coffee +80 -0
  209. package/test/event_listeners.spec.coffee +493 -0
  210. package/test/helpers.coffee +150 -0
  211. package/test/http_request.spec.coffee +55 -0
  212. package/test/json/builder.spec.coffee +129 -0
  213. package/test/json/parser.spec.coffee +108 -0
  214. package/test/metadata_service.spec.coffee +54 -0
  215. package/test/model/api.spec.coffee +67 -0
  216. package/test/model/shape.spec.coffee +23 -0
  217. package/test/node_http_client.spec.coffee +40 -0
  218. package/test/param_validator.spec.coffee +456 -0
  219. package/test/protocol/json.spec.coffee +167 -0
  220. package/test/protocol/query.spec.coffee +191 -0
  221. package/test/protocol/rest.spec.coffee +237 -0
  222. package/test/protocol/rest_json.spec.coffee +255 -0
  223. package/test/protocol/rest_xml.spec.coffee +329 -0
  224. package/test/query/query_param_serializer.spec.coffee +327 -0
  225. package/test/region_config.spec.coffee +50 -0
  226. package/test/request.spec.coffee +316 -0
  227. package/test/resource_waiter.spec.coffee +89 -0
  228. package/test/response.spec.coffee +81 -0
  229. package/test/sequential_executor.spec.coffee +118 -0
  230. package/test/service.spec.coffee +230 -0
  231. package/test/services/cloudfront.spec.coffee +44 -0
  232. package/test/services/cloudsearchdomain.spec.coffee +23 -0
  233. package/test/services/dynamodb.spec.coffee +32 -0
  234. package/test/services/ec2.spec.coffee +78 -0
  235. package/test/services/elastictranscoder.spec.coffee +43 -0
  236. package/test/services/glacier.spec.coffee +61 -0
  237. package/test/services/rds.spec.coffee +38 -0
  238. package/test/services/route53.spec.coffee +77 -0
  239. package/test/services/s3.spec.coffee +538 -0
  240. package/test/services/simpledb.spec.coffee +12 -0
  241. package/test/services/sqs.spec.coffee +130 -0
  242. package/test/services/sts.spec.coffee +72 -0
  243. package/test/services/swf.spec.coffee +6 -0
  244. package/test/signers/presign.spec.coffee +36 -0
  245. package/test/signers/s3.spec.coffee +297 -0
  246. package/test/signers/v2.spec.coffee +68 -0
  247. package/test/signers/v4.spec.coffee +135 -0
  248. package/test/util.spec.coffee +510 -0
  249. package/test/xml/builder.spec.coffee +529 -0
  250. package/test/xml/parser.spec.coffee +587 -0
  251. package/lib/services/simpledb.js +0 -15
@@ -0,0 +1,72 @@
1
+ helpers = require('../helpers')
2
+ AWS = helpers.AWS
3
+
4
+ describe 'AWS.STS', ->
5
+
6
+ sts = null
7
+ beforeEach ->
8
+ sts = new AWS.STS()
9
+
10
+ describe 'credentialsFrom', ->
11
+ it 'returns null if no data is provided', ->
12
+ expect(sts.credentialsFrom(null)).toEqual(null)
13
+
14
+ it 'creates a TemporaryCredentials object with hydrated data', ->
15
+ creds = sts.credentialsFrom Credentials:
16
+ AccessKeyId: 'KEY'
17
+ SecretAccessKey: 'SECRET'
18
+ SessionToken: 'TOKEN'
19
+ Expiration: new Date(0)
20
+ expect(creds instanceof AWS.TemporaryCredentials)
21
+ expect(creds.accessKeyId).toEqual('KEY')
22
+ expect(creds.secretAccessKey).toEqual('SECRET')
23
+ expect(creds.sessionToken).toEqual('TOKEN')
24
+ expect(creds.expireTime).toEqual(new Date(0))
25
+ expect(creds.expired).toEqual(false)
26
+
27
+ it 'updates an existing Credentials object with hydrated data', ->
28
+ data = Credentials:
29
+ AccessKeyId: 'KEY'
30
+ SecretAccessKey: 'SECRET'
31
+ SessionToken: 'TOKEN'
32
+ Expiration: new Date(0)
33
+ creds = new AWS.Credentials
34
+ sts.credentialsFrom(data, creds)
35
+ expect(creds instanceof AWS.Credentials)
36
+ expect(creds.accessKeyId).toEqual('KEY')
37
+ expect(creds.secretAccessKey).toEqual('SECRET')
38
+ expect(creds.sessionToken).toEqual('TOKEN')
39
+ expect(creds.expireTime).toEqual(new Date(0))
40
+ expect(creds.expired).toEqual(false)
41
+
42
+ describe 'assumeRoleWithWebIdentity', ->
43
+ service = new AWS.STS
44
+
45
+ it 'sends an unsigned GET request (params in query string)', ->
46
+ helpers.mockHttpResponse 200, {}, '{}'
47
+ params = RoleArn: 'ARN', RoleSessionName: 'NAME', WebIdentityToken: 'TOK'
48
+ service.assumeRoleWithWebIdentity params, ->
49
+ hr = this.request.httpRequest
50
+ expect(hr.method).toEqual('GET')
51
+ expect(hr.body).toEqual('')
52
+ expect(hr.headers['Authorization']).toEqual(undefined)
53
+ expect(hr.headers['Content-Type']).toEqual(undefined)
54
+ expect(hr.path).toEqual('/?Action=AssumeRoleWithWebIdentity&' +
55
+ 'RoleArn=ARN&RoleSessionName=NAME&Version=' +
56
+ service.api.apiVersion + '&WebIdentityToken=TOK')
57
+
58
+ describe 'assumeRoleWithSAML', ->
59
+ service = new AWS.STS
60
+
61
+ it 'sends an unsigned GET request (params in query string)', ->
62
+ helpers.mockHttpResponse 200, {}, '{}'
63
+ params = RoleArn: 'ARN', PrincipalArn: 'PARN', SAMLAssertion: 'OK'
64
+ service.assumeRoleWithSAML params, ->
65
+ hr = this.request.httpRequest
66
+ expect(hr.method).toEqual('GET')
67
+ expect(hr.body).toEqual('')
68
+ expect(hr.headers['Authorization']).toEqual(undefined)
69
+ expect(hr.headers['Content-Type']).toEqual(undefined)
70
+ expect(hr.path).toEqual('/?Action=AssumeRoleWithSAML&' +
71
+ 'PrincipalArn=PARN&RoleArn=ARN&SAMLAssertion=OK&' +
72
+ 'Version=' + service.api.apiVersion)
@@ -0,0 +1,6 @@
1
+ helpers = require('../helpers')
2
+ AWS = helpers.AWS
3
+
4
+ describe 'AWS.SWF', ->
5
+ it 'is also AWS.SimpleWorkflow', ->
6
+ expect(AWS.SWF).toBe(AWS.SimpleWorkflow)
@@ -0,0 +1,36 @@
1
+ helpers = require('../helpers')
2
+ AWS = helpers.AWS
3
+ cw = new AWS.CloudWatch()
4
+
5
+ describe 'AWS.Signers.Presign', ->
6
+ resultUrl = "https://monitoring.mock-region.amazonaws.com/?" +
7
+ "Action=ListMetrics&Version=#{cw.api.apiVersion}&" +
8
+ "X-Amz-Algorithm=AWS4-HMAC-SHA256&" +
9
+ "X-Amz-Credential=akid%2F19700101%2Fmock-region%2Fmonitoring%2Faws4_request&" +
10
+ "X-Amz-Date=19700101T000000Z&X-Amz-Expires=3600&X-Amz-Security-Token=session&" +
11
+ "X-Amz-Signature=953bd6d74e86c12adc305f656473d614269d2f20a0c18c5edbb3d7f57ca2b439&" +
12
+ "X-Amz-SignedHeaders=host"
13
+
14
+ beforeEach ->
15
+ spyOn(AWS.util.date, 'getDate').andReturn(new Date(0))
16
+
17
+ it 'presigns requests', ->
18
+ cw.listMetrics().presign (err, url) ->
19
+ expect(url).toEqual(resultUrl)
20
+
21
+ it 'presigns synchronously', ->
22
+ expect(cw.listMetrics().presign()).toEqual(resultUrl)
23
+
24
+ it 'allows specifying different expiry time', ->
25
+ expect(cw.listMetrics().presign(900)).toMatch('X-Amz-Expires=900&')
26
+
27
+ it 'limits expiry time to a week in SigV4', ->
28
+ cw.listMetrics().presign 9999999, (err) ->
29
+ expect(err.code).toEqual('InvalidExpiryTime')
30
+ expect(err.message).toEqual(
31
+ 'Presigning does not support expiry time greater than a week with SigV4 signing.')
32
+
33
+ it 'only supports s3 or v4 signers', ->
34
+ new AWS.EC2().describeInstances().presign (err) ->
35
+ expect(err.code).toEqual('UnsupportedSigner')
36
+ expect(err.message).toEqual('Presigning only supports S3 or SigV4 signing.')
@@ -0,0 +1,297 @@
1
+ AWS = require('../helpers').AWS
2
+
3
+ describe 'AWS.Signers.S3', ->
4
+
5
+ # these can be overriden in tests
6
+ method = null
7
+ path = null
8
+ headers = null
9
+ body = null
10
+ date = null
11
+ virtualHostedBucket = null
12
+ accessKeyId = null
13
+ secretAccessKey = null
14
+ sessionToken = null
15
+
16
+ # reset the overriden variable before each test
17
+ beforeEach ->
18
+ method = 'POST'
19
+ path = '/'
20
+ virtualHostedBucket = null
21
+ date = new Date(0)
22
+ headers = {}
23
+ body = null
24
+ accessKeyId = 'akid'
25
+ secretAccessKey = 'secret'
26
+ sessionToken = null
27
+
28
+ buildRequest = () ->
29
+ req = new AWS.HttpRequest('https://s3.amazonaws.com')
30
+ req.method = method
31
+ req.path = path
32
+ req.headers = headers
33
+ req.body = body
34
+ req.virtualHostedBucket = virtualHostedBucket
35
+ req
36
+
37
+ credentials = () ->
38
+ creds = {}
39
+ creds.accessKeyId = accessKeyId
40
+ creds.secretAccessKey = secretAccessKey
41
+ creds.sessionToken = sessionToken if (sessionToken)
42
+ creds
43
+
44
+ addAuth = (req) ->
45
+ signer = new AWS.Signers.S3(req || buildRequest())
46
+ signer.addAuthorization(credentials(), date)
47
+ signer.request
48
+
49
+ stringToSign = (req) ->
50
+ signer = new AWS.Signers.S3(req || buildRequest())
51
+ signer.stringToSign()
52
+
53
+ describe 'addAuthorization', ->
54
+ it 'sets the date header when not present', ->
55
+ req = buildRequest()
56
+ addAuth(req)
57
+ expect(req.headers['X-Amz-Date']).toEqual(AWS.util.date.rfc822(date))
58
+
59
+ it 'overwrites Date if present', ->
60
+ req = buildRequest()
61
+ req.headers['X-Amz-Date'] = 'date-string'
62
+ addAuth(req)
63
+ expect(req.headers['X-Amz-Date']).toEqual(AWS.util.date.rfc822(date))
64
+
65
+ it 'omits the security token header when session token is blank', ->
66
+ sessionToken = null
67
+ req = addAuth()
68
+ expect(req.headers['x-amz-security-token']).toEqual(undefined)
69
+
70
+ it 'adds a security token header when session token available', ->
71
+ sessionToken = 'session'
72
+ req = addAuth()
73
+ expect(req.headers['x-amz-security-token']).toEqual('session')
74
+
75
+ it 'adds an Authorization header which contains akid and signature', ->
76
+
77
+ creds = { accessKeyId: 'AKID', secretAccessKey: 'secret' }
78
+
79
+ req = buildRequest()
80
+
81
+ signer = new AWS.Signers.S3(req)
82
+
83
+ spyOn(signer, 'stringToSign')
84
+ signer.stringToSign.andReturn('string-to-sign')
85
+ signer.addAuthorization(creds, date)
86
+
87
+ expect(req.headers['Authorization']).toEqual('AWS AKID:Gg5WLabTOvH0WMd15wv7lWe4zK0=')
88
+
89
+ it 'properly signs special characters', ->
90
+
91
+ creds = { accessKeyId: 'AKID', secretAccessKey: 'secret' }
92
+
93
+ req = buildRequest()
94
+
95
+ signer = new AWS.Signers.S3(req)
96
+
97
+ spyOn(signer, 'stringToSign')
98
+ signer.stringToSign.andReturn('!@#$%^&*();\':"{}[],./?`~')
99
+ signer.addAuthorization(creds, date)
100
+
101
+ expect(req.headers['Authorization']).toEqual('AWS AKID:2E04i7QCa0uZTYtxue9dEqto3dg=')
102
+
103
+
104
+ describe 'stringToSign', ->
105
+
106
+ beforeEach ->
107
+ headers['X-Amz-Date'] = 'DATE-STRING'
108
+
109
+ it 'builds a basic string to sign', ->
110
+ expect(stringToSign()).toEqual("""
111
+ POST
112
+
113
+
114
+
115
+ x-amz-date:DATE-STRING
116
+ /
117
+ """)
118
+
119
+ it 'includes content md5 and content type when present', ->
120
+ headers['Content-Type'] = 'CONTENT-TYPE'
121
+ headers['Content-MD5'] = 'CONTENT-MD5'
122
+ expect(stringToSign()).toEqual("""
123
+ POST
124
+ CONTENT-MD5
125
+ CONTENT-TYPE
126
+
127
+ x-amz-date:DATE-STRING
128
+ /
129
+ """)
130
+
131
+ it 'includes the http method, whatever it is', ->
132
+ method = 'VERB'
133
+ expect(stringToSign()).toEqual("""
134
+ VERB
135
+
136
+
137
+
138
+ x-amz-date:DATE-STRING
139
+ /
140
+ """)
141
+
142
+ it 'includes any x-amz- style headers, but not others', ->
143
+ headers['X-Amz-Abc'] = 'abc'
144
+ headers['X-Amz-Xyz'] = 'xyz'
145
+ headers['random-header'] = 'random'
146
+ expect(stringToSign()).toEqual("""
147
+ POST
148
+
149
+
150
+
151
+ x-amz-abc:abc
152
+ x-amz-date:DATE-STRING
153
+ x-amz-xyz:xyz
154
+ /
155
+ """)
156
+
157
+ it 'includes x-amz- headers that are lower-cased', ->
158
+ headers['x-amz-Abc'] = 'abc'
159
+ headers['x-amz-Xyz'] = 'xyz'
160
+ headers['random-header'] = 'random'
161
+ expect(stringToSign()).toEqual("""
162
+ POST
163
+
164
+
165
+
166
+ x-amz-abc:abc
167
+ x-amz-date:DATE-STRING
168
+ x-amz-xyz:xyz
169
+ /
170
+ """)
171
+
172
+ it 'sorts headers by their name', ->
173
+ headers['x-amz-mno'] = 'mno'
174
+ headers['x-amz-Xyz'] = 'xyz'
175
+ headers['x-amz-Abc'] = 'abc'
176
+ expect(stringToSign()).toEqual("""
177
+ POST
178
+
179
+
180
+
181
+ x-amz-abc:abc
182
+ x-amz-date:DATE-STRING
183
+ x-amz-mno:mno
184
+ x-amz-xyz:xyz
185
+ /
186
+ """)
187
+
188
+ it 'builds a canonical resource from the path', ->
189
+ path = '/bucket_name/key'
190
+ expect(stringToSign()).toEqual("""
191
+ POST
192
+
193
+
194
+
195
+ x-amz-date:DATE-STRING
196
+ /bucket_name/key
197
+ """)
198
+
199
+ it 'appends the bucket to the path when it is part of the hostname', ->
200
+ path = '/'
201
+ virtualHostedBucket = 'bucket-name'
202
+ expect(stringToSign()).toEqual("""
203
+ POST
204
+
205
+
206
+
207
+ x-amz-date:DATE-STRING
208
+ /bucket-name/
209
+ """)
210
+
211
+ it 'appends the subresource portion of the path querystring', ->
212
+ path = '/?acl'
213
+ virtualHostedBucket = 'bucket-name'
214
+ expect(stringToSign()).toEqual("""
215
+ POST
216
+
217
+
218
+
219
+ x-amz-date:DATE-STRING
220
+ /bucket-name/?acl
221
+ """)
222
+
223
+ it 'includes the sub resource value when present', ->
224
+ path = '/bucket_name/key?versionId=123'
225
+ expect(stringToSign()).toEqual("""
226
+ POST
227
+
228
+
229
+
230
+ x-amz-date:DATE-STRING
231
+ /bucket_name/key?versionId=123
232
+ """)
233
+
234
+ it 'omits non-sub-resource querystring params from the resource string', ->
235
+ path = '/?versionId=abc&next-marker=xyz'
236
+ expect(stringToSign()).toEqual("""
237
+ POST
238
+
239
+
240
+
241
+ x-amz-date:DATE-STRING
242
+ /?versionId=abc
243
+ """)
244
+
245
+ it 'sorts sub resources by name', ->
246
+ path = '/?logging&acl&website&torrent=123' # made up example
247
+ expect(stringToSign()).toEqual("""
248
+ POST
249
+
250
+
251
+
252
+ x-amz-date:DATE-STRING
253
+ /?acl&logging&torrent=123&website
254
+ """)
255
+
256
+ it 'sorts sub resources by name', ->
257
+ path = '/?logging&acl&website&torrent=123' # made up example
258
+ expect(stringToSign()).toEqual("""
259
+ POST
260
+
261
+
262
+
263
+ x-amz-date:DATE-STRING
264
+ /?acl&logging&torrent=123&website
265
+ """)
266
+
267
+ it 'includes the un-decoded query string param for sub resources', ->
268
+ path = '/?versionId=a%2Bb' # a+b
269
+ expect(stringToSign()).toEqual("""
270
+ POST
271
+
272
+
273
+
274
+ x-amz-date:DATE-STRING
275
+ /?versionId=a%2Bb
276
+ """)
277
+
278
+ it 'includes the non-encoded query string get header overrides', ->
279
+ path = '/?response-content-type=a%2Bb' # a+b
280
+ expect(stringToSign()).toEqual("""
281
+ POST
282
+
283
+
284
+
285
+ x-amz-date:DATE-STRING
286
+ /?response-content-type=a+b
287
+ """)
288
+
289
+ it 'omits the date header when not present', ->
290
+ delete headers['X-Amz-Date']
291
+ expect(stringToSign()).toEqual("""
292
+ POST
293
+
294
+
295
+
296
+ /
297
+ """)
@@ -0,0 +1,68 @@
1
+ AWS = require('../helpers').AWS
2
+
3
+ describe 'AWS.Signers.V2', ->
4
+
5
+ credentials = null
6
+ date = null
7
+ request = null
8
+ signer = null
9
+
10
+ buildRequest = ->
11
+ request = new AWS.HttpRequest(new AWS.Endpoint('localhost'))
12
+ request.params = {}
13
+ request
14
+
15
+ buildSigner = (request) ->
16
+ new AWS.Signers.V2(request)
17
+
18
+ signRequest = (request) ->
19
+ signer = new AWS.Signers.V2(request)
20
+ signer.addAuthorization(credentials, date)
21
+
22
+ beforeEach ->
23
+ credentials = { accessKeyId:'akid', secretAccessKey:'secret' }
24
+ date = new Date(1935346573456)
25
+ signRequest(buildRequest())
26
+
27
+ stringify = AWS.util.queryParamsToString
28
+
29
+ describe 'constructor', ->
30
+
31
+ it 'builds a signer for a request object', ->
32
+ expect(signer.request).toBe(request)
33
+
34
+ describe 'addAuthorization', ->
35
+
36
+ it 'adds a url encoded iso8601 timestamp param', ->
37
+ expect(stringify(request.params)).toMatch(/Timestamp=2031-04-30T20%3A16%3A13.456Z/)
38
+
39
+ it 'adds a SignatureVersion param', ->
40
+ expect(stringify(request.params)).toMatch(/SignatureVersion=2/)
41
+
42
+ it 'adds a SignatureMethod param', ->
43
+ expect(stringify(request.params)).toMatch(/SignatureMethod=HmacSHA256/)
44
+
45
+ it 'adds an AWSAccessKeyId param', ->
46
+ expect(stringify(request.params)).toMatch(/AWSAccessKeyId=akid/)
47
+
48
+ it 'omits SecurityToken when sessionToken has been omitted', ->
49
+ expect(stringify(request.params)).not.toMatch(/SecurityToken/)
50
+
51
+ it 'adds the SecurityToken when sessionToken is provided', ->
52
+ credentials.sessionToken = 'session'
53
+ signRequest(buildRequest())
54
+ expect(stringify(request.params)).toMatch(/SecurityToken=session/)
55
+
56
+ it 'populates the body', ->
57
+ expect(request.body).toEqual('AWSAccessKeyId=akid&Signature=%2FrumhWptMPvyb4aaeOv5iGpl6%2FLfs5uVHu8k1d3NNfc%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2031-04-30T20%3A16%3A13.456Z')
58
+
59
+ it 'populates content-length header', ->
60
+ expect(request.headers['Content-Length']).toEqual(165)
61
+
62
+ it 'signs additional body params', ->
63
+ request = buildRequest()
64
+ request.params['Param.1'] = 'abc'
65
+ request.params['Param.2'] = 'xyz'
66
+ signRequest(request)
67
+ expect(request.body).toEqual('AWSAccessKeyId=akid&Param.1=abc&Param.2=xyz&Signature=3pcXIWw0eVd4wFmp%2Blo24L93UTMGcYSNE%2BFYNNqzDts%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2031-04-30T20%3A16%3A13.456Z')
68
+
@@ -0,0 +1,135 @@
1
+ helpers = require('../helpers')
2
+ AWS = helpers.AWS
3
+
4
+ beforeEach ->
5
+ spyOn(AWS.util, 'userAgent').andReturn('aws-sdk-js/0.1')
6
+
7
+ buildRequest = ->
8
+ ddb = new AWS.DynamoDB({region: 'region', endpoint: 'localhost', apiVersion: '2011-12-05'})
9
+ req = ddb.makeRequest('listTables', {ExclusiveStartTableName: 'bår'})
10
+ req.build()
11
+ req.httpRequest.headers['X-Amz-User-Agent'] = 'aws-sdk-js/0.1'
12
+ req.httpRequest
13
+
14
+ buildSigner = (request) ->
15
+ return new AWS.Signers.V4(request || buildRequest(), 'dynamodb')
16
+
17
+ describe 'AWS.Signers.V4', ->
18
+ date = new Date(1935346573456)
19
+ datetime = AWS.util.date.iso8601(date).replace(/[:\-]|\.\d{3}/g, '')
20
+ creds = null
21
+ signature = '0e24aaa0cc86cdc1b73143a147e731cf8c93d450cfcf1d18b2b7473f810b7a1d'
22
+ authorization = 'AWS4-HMAC-SHA256 Credential=akid/20310430/region/dynamodb/aws4_request, ' +
23
+ 'SignedHeaders=host;x-amz-date;x-amz-security-token;x-amz-target;x-amz-user-agent, ' +
24
+ 'Signature=' + signature
25
+ signer = null
26
+
27
+ beforeEach ->
28
+ creds = accessKeyId: 'akid', secretAccessKey: 'secret', sessionToken: 'session'
29
+ signer = buildSigner()
30
+ signer.addHeaders(creds, datetime)
31
+
32
+ describe 'constructor', ->
33
+ it 'can build a signer for a request object', ->
34
+ req = buildRequest()
35
+ signer = buildSigner(req)
36
+ expect(signer.request).toBe(req)
37
+
38
+ describe 'addAuthorization', ->
39
+ headers = {
40
+ 'Content-Type': 'application/x-amz-json-1.0',
41
+ 'Content-Length': 34,
42
+ 'X-Amz-Target': 'DynamoDB_20111205.ListTables',
43
+ 'Host': 'localhost',
44
+ 'X-Amz-Date': datetime,
45
+ 'x-amz-security-token' : 'session',
46
+ 'Authorization' : authorization
47
+ }
48
+
49
+ for key, value of headers
50
+ it 'should add ' + key + ' header', ->
51
+ signer.addAuthorization(creds, date)
52
+ key = this.description.match(/(\S+) header/)[1]
53
+ expect(signer.request.headers[key]).toEqual(headers[key])
54
+
55
+ describe 'authorization', ->
56
+ it 'should return authorization part for signer', ->
57
+ expect(signer.authorization(creds, datetime)).toEqual(authorization)
58
+
59
+ describe 'signature', ->
60
+ it 'should generate proper signature', ->
61
+ expect(signer.signature(creds, datetime)).toEqual(signature)
62
+
63
+ describe 'caching', ->
64
+ callCount = null
65
+ calls = null
66
+
67
+ beforeEach ->
68
+ spyOn(AWS.util.crypto, 'hmac')
69
+ signer.signature(creds, datetime)
70
+ calls = AWS.util.crypto.hmac.calls
71
+ callCount = calls.length
72
+
73
+ it 'caches subsequent requests', ->
74
+ signer.signature(creds, datetime)
75
+ expect(calls.length).toEqual(callCount + 1)
76
+ signer.signature(creds, datetime)
77
+ expect(calls.length).toEqual(callCount + 2)
78
+
79
+ it 'busts cache if region changes', ->
80
+ signer.request.region = 'new-region'
81
+ signer.signature(creds, datetime)
82
+ expect(calls.length).toEqual(callCount + 5)
83
+
84
+ it 'busts cache if service changes', ->
85
+ signer.serviceName = 'newService'
86
+ signer.signature(creds, datetime)
87
+ expect(calls.length).toEqual(callCount + 5)
88
+
89
+ it 'busts cache if access key changes', ->
90
+ creds.accessKeyId = 'NEWAKID'
91
+ signer.signature(creds, datetime)
92
+ expect(calls.length).toEqual(callCount + 5)
93
+
94
+ it 'busts cache if date changes', ->
95
+ newDate = new Date(date.getTime() + 1000000000)
96
+ newDatetime = AWS.util.date.iso8601(newDate).replace(/[:\-]|\.\d{3}/g, '')
97
+ signer.signature(creds, newDatetime)
98
+ expect(calls.length).toEqual(callCount + 5)
99
+
100
+ describe 'stringToSign', ->
101
+ it 'should sign correctly generated input string', ->
102
+ expect(signer.stringToSign(datetime)).toEqual 'AWS4-HMAC-SHA256\n' +
103
+ datetime + '\n' +
104
+ '20310430/region/dynamodb/aws4_request\n' +
105
+ signer.hexEncodedHash(signer.canonicalString())
106
+
107
+ describe 'canonicalHeaders', ->
108
+ it 'should return headers', ->
109
+ expect(signer.canonicalHeaders()).toEqual [
110
+ 'host:localhost',
111
+ 'x-amz-date:' + datetime,
112
+ 'x-amz-security-token:session',
113
+ 'x-amz-target:DynamoDB_20111205.ListTables',
114
+ 'x-amz-user-agent:aws-sdk-js/0.1'
115
+ ].join('\n')
116
+
117
+ it 'should ignore Authorization header', ->
118
+ signer.request.headers = {'Authorization': 'foo'}
119
+ expect(signer.canonicalHeaders()).toEqual('')
120
+
121
+ it 'should lowercase all header names (not values)', ->
122
+ signer.request.headers = {'FOO': 'BAR'}
123
+ expect(signer.canonicalHeaders()).toEqual('foo:BAR')
124
+
125
+ it 'should sort headers by key', ->
126
+ signer.request.headers = {abc: 'a', bca: 'b', Qux: 'c', bar: 'd'}
127
+ expect(signer.canonicalHeaders()).toEqual('abc:a\nbar:d\nbca:b\nqux:c')
128
+
129
+ it 'should compact multiple spaces in keys/values to a single space', ->
130
+ signer.request.headers = {'Header': 'Value with Multiple \t spaces'}
131
+ expect(signer.canonicalHeaders()).toEqual('header:Value with Multiple spaces')
132
+
133
+ it 'should strip starting and end of line spaces', ->
134
+ signer.request.headers = {'Header': ' \t Value \t '}
135
+ expect(signer.canonicalHeaders()).toEqual('header:Value')