cors 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6e34544029bab24989baf0b992473455fe72c74dc16f8abd9fae3bd48dad3738
4
+ data.tar.gz: 2b86a4a89e1577d08051d5599d44bcb43f2fd90fc04da1688c196cc4b4ad161d
5
+ SHA512:
6
+ metadata.gz: 347db7c99d84fff7342fc6f5c57574caf02135b6a4a87bdd2886afcaa9f1d4d6191a5c187a7b6454161786ea42198ed058329ea7a6ede863b6cae951f45a5b7f
7
+ data.tar.gz: e38b7fbb900d6507acc746348b85b8979264be0619f58f2e1611e77539994300f4ccc5e0bc8e91385e856a3df7168ec8ea781d8dfea1caf5ee295a77f38ee647
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  .yardoc/
2
2
  doc/
3
+ pkg/
@@ -1,24 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cors (1.0.1)
5
+ multi_json
6
+
1
7
  GEM
2
- remote: http://rubygems.org/
8
+ remote: https://rubygems.org/
3
9
  specs:
4
- diff-lcs (1.1.3)
5
- rake (0.9.2.2)
6
- redcarpet (2.1.1)
7
- rspec (2.11.0)
8
- rspec-core (~> 2.11.0)
9
- rspec-expectations (~> 2.11.0)
10
- rspec-mocks (~> 2.11.0)
11
- rspec-core (2.11.1)
12
- rspec-expectations (2.11.3)
13
- diff-lcs (~> 1.1.3)
14
- rspec-mocks (2.11.3)
15
- yard (0.8.2.1)
10
+ diff-lcs (1.3)
11
+ multi_json (1.13.1)
12
+ rake (12.3.3)
13
+ rspec (3.8.0)
14
+ rspec-core (~> 3.8.0)
15
+ rspec-expectations (~> 3.8.0)
16
+ rspec-mocks (~> 3.8.0)
17
+ rspec-core (3.8.2)
18
+ rspec-support (~> 3.8.0)
19
+ rspec-expectations (3.8.4)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.8.0)
22
+ rspec-mocks (3.8.1)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.8.0)
25
+ rspec-support (3.8.2)
26
+ yard (0.9.20)
16
27
 
17
28
  PLATFORMS
18
29
  ruby
19
30
 
20
31
  DEPENDENCIES
32
+ cors!
21
33
  rake
22
- redcarpet
23
34
  rspec
24
35
  yard
36
+
37
+ BUNDLED WITH
38
+ 1.16.6
data/README.md CHANGED
@@ -1,15 +1,22 @@
1
- # CORS policy validation- and signing library
1
+ # CORS policy validation- and signing library
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/elabs/cors.png)](http://travis-ci.org/elabs/cors)
3
+ [![Build Status](https://secure.travis-ci.org/varvet/cors.png)](http://travis-ci.org/varvet/cors)
4
4
 
5
5
  Cross-origin resource sharing (CORS) is great; it allows your visitors to asynchronously upload files to
6
- e.g. Filepicker or Amazon S3, without the files having to round-trip through your web server. Unfortunately,
6
+ e.g. Amazon S3, without the files having to round-trip through your web server. Unfortunately,
7
7
  giving your users complete write access to your online storage also exposes you to malicious intent.
8
8
 
9
9
  To combat harmful usage, good upload services that allow client-side upload, support a mechanism that allows
10
10
  you to validate and sign all upload requests to your online storage. By validating every request, you can
11
11
  give your visitors a nice upload experience, while keeping the bad visitors at bay.
12
12
 
13
+ ## Deprecation
14
+
15
+ The functionality of CORS is now provided by the ruby AWS SDK. We recommend
16
+ using that instead, as CORS will no longer receive updates:
17
+
18
+ [Amazon S3 SDK PresignedPost](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/PresignedPost.html)
19
+
13
20
  ## Usage
14
21
 
15
22
  ```ruby
@@ -36,10 +43,10 @@ end
36
43
 
37
44
  ## Supported services
38
45
 
39
- Out-of-the box, the CORS library comes with support for the Amazon S3 REST API. Support
40
- for Filepicker is planned.
46
+ Out-of-the box, the CORS library comes with support for the Amazon S3 REST API.
41
47
 
42
- - [Amazon S3 REST API](http://docs.amazonwebservices.com/AmazonS4/latest/dev/RESTAuthentication.html)
48
+ - [Amazon S3 REST API Authentication Header](http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html#ConstructingTheAuthenticationHeader)
49
+ - [Amazon S3 REST API POST Upload Policy](http://docs.amazonwebservices.com/AmazonS3/latest/dev/HTTPPOSTForms.html#HTTPPOSTConstructPolicy)
43
50
 
44
51
  ## License
45
52
 
@@ -10,7 +10,7 @@ Gem::Specification.new do |gem|
10
10
  gem.email = ["kim@burgestrand.se"]
11
11
  gem.homepage = "http://github.com/elabs/cors"
12
12
  gem.summary = "CORS policy validation- and signing library for Amazon S3 REST API."
13
- gem.description = <<-DESCRIPTION.gsub(/ +/, "")
13
+ gem.description = <<~DESCRIPTION
14
14
  Cross-origin resource sharing (CORS) is great; it allows your visitors to
15
15
  asynchronously upload files to e.g. Filepicker or Amazon S3, without the
16
16
  files having to round-trip through your web server. Unfortunately, giving
@@ -25,11 +25,18 @@ Gem::Specification.new do |gem|
25
25
 
26
26
  The CORS gem comes with support for the Amazon S3 REST API.
27
27
  DESCRIPTION
28
+ gem.post_install_message = <<~POST_INSTALL_MESSAGE
29
+ [DEPRECATED] The CORS gem is deprecated and will not receive further updates.
30
+ The functionality of CORS is now provided by the ruby AWS SDK:
31
+
32
+ https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/PresignedPost.html
33
+ POST_INSTALL_MESSAGE
28
34
 
29
35
  gem.files = `git ls-files`.split($/)
30
36
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
31
37
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
32
38
  gem.require_paths = ["lib"]
33
39
 
34
- gem.add_development_dependency "rspec", "~> 2.0"
40
+ gem.add_dependency "multi_json"
41
+ gem.add_development_dependency "rspec"
35
42
  end
@@ -3,6 +3,7 @@ require "cors/version"
3
3
  require "cors/rules"
4
4
  require "cors/policy"
5
5
  require "cors/policy/s3"
6
+ require "cors/policy/s3_post"
6
7
 
7
8
  # CORS policy validation and signature generation.
8
9
  #
@@ -71,7 +71,7 @@ module CORS
71
71
  # @see errors
72
72
  # @see valid?
73
73
  def initialize(attributes)
74
- self.attributes = Hash[attributes.map { |k, v| [k.to_s.downcase, v] }]
74
+ self.attributes = Hash[normalize_attributes(attributes)]
75
75
  self.errors = rules.validate(self.attributes)
76
76
  end
77
77
 
@@ -94,16 +94,25 @@ module CORS
94
94
  errors.empty?
95
95
  end
96
96
 
97
- # @note must be overridden by includers!
98
- # @return [String] the compiled manifest
99
- def manifest
100
- raise NotImplementedError, "#manifest has not been defined on #{inspect}"
97
+ # Signs the manifest, but only if it is {#valid?}.
98
+ #
99
+ # @note should not be overridden by the includers!
100
+ # @return (see #sign!)
101
+ def sign(*args, &block)
102
+ sign!(*args, &block) if valid?
101
103
  end
102
104
 
103
- # @note must be overridden by includers!
105
+ # @note should be overridden by includers!
104
106
  # @return [String] signature derived from the manifest
105
- def sign(*)
107
+ def sign!(*)
106
108
  raise NotImplementedError, "#sign has not been defined on #{inspect}"
107
109
  end
110
+
111
+ protected
112
+
113
+ def normalize_attributes(attributes)
114
+ attributes = attributes.map { |k, v| [k.to_s.downcase, v] }
115
+ attributes.select { |(k, _)| rules[k] }
116
+ end
108
117
  end
109
118
  end
@@ -28,8 +28,7 @@ module CORS::Policy
28
28
  #
29
29
  # @param [String] access_key
30
30
  # @param [String] secret_access_key
31
- def sign(access_key, secret_access_key)
32
- return if not valid?
31
+ def sign!(access_key, secret_access_key)
33
32
  digest = OpenSSL::HMAC.digest("sha1", secret_access_key, manifest)
34
33
  signature = Base64.strict_encode64(digest)
35
34
  "AWS #{access_key}:#{signature}"
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ require "multi_json"
3
+ require "base64"
4
+ require "time"
5
+ require "set"
6
+
7
+ module CORS::Policy
8
+ # POST form upload policy for Amazon S3.
9
+ class S3Post
10
+ include CORS::Policy
11
+
12
+ # Generate the policy used to sign the request.
13
+ #
14
+ # @param [Time] expiration
15
+ # @return [Hash] policy as a hash
16
+ def policy(expiration)
17
+ conditions = []
18
+ properties = attributes.dup
19
+
20
+ if properties.has_key?("content-length")
21
+ length = escape(properties.delete("content-length"))
22
+ conditions << [ "content-length-range", length, length ]
23
+ end
24
+
25
+ {
26
+ "expiration" => expiration.gmtime.iso8601,
27
+ "conditions" => conditions + properties.map do |(name, value)|
28
+ [ "eq", "$#{escape(name)}", escape(value) ]
29
+ end
30
+ }
31
+ end
32
+
33
+ # Generate a policy and encode it in URL-safe Base64 encoding.
34
+ #
35
+ # @param [Time] expiration
36
+ # @return [String] the policy, in JSON, in URL-safe base64 encoding.
37
+ def policy_base64(expiration)
38
+ json = MultiJson.dump(policy(expiration))
39
+ Base64.urlsafe_encode64(json)
40
+ end
41
+
42
+ # Sign the {#policy} for the given expiration.
43
+ #
44
+ # @param [String] secret_access_key
45
+ # @param [Time] expiration
46
+ # @return [String] signed policy in Base64-encoding.
47
+ def sign!(secret_access_key, expiration)
48
+ digest = OpenSSL::HMAC.digest("sha1", secret_access_key, policy_base64(expiration))
49
+ Base64.strict_encode64(digest)
50
+ end
51
+
52
+ protected
53
+
54
+ def escape(string)
55
+ return string unless string.is_a?(String)
56
+
57
+ unicode_safe = string.codepoints.each_with_object("") do |i, result|
58
+ result << if i <= 127 then i.chr else
59
+ "\\u#{i.to_s(16).rjust(4, "0")}"
60
+ end
61
+ end
62
+
63
+ unicode_safe.sub(/\A$/, "\$")
64
+ end
65
+ end
66
+ end
@@ -15,6 +15,7 @@ module CORS
15
15
  # @yieldparam [Rules] self
16
16
  def initialize
17
17
  @rules = []
18
+ @rules_map = Hash.new { |h, k| h[k] = [] }
18
19
  yield self if block_given?
19
20
  end
20
21
 
@@ -40,6 +41,14 @@ module CORS
40
41
  end
41
42
  end
42
43
 
44
+ # Retrieve a list of rules for a given attribute.
45
+ #
46
+ # @param name same name as given to {#required} or {#optional}
47
+ # @return [Array<Hash<:name, :matcher, :required>>, nil] list of rules for attribute, or nil.
48
+ def [](name)
49
+ @rules_map.fetch(name, nil)
50
+ end
51
+
43
52
  # Declare a required rule; the value must be present, and it must
44
53
  # match the given constraints or block matcher.
45
54
  #
@@ -76,6 +85,7 @@ module CORS
76
85
 
77
86
  { name: name, matcher: matcher, required: true }.tap do |rule|
78
87
  @rules << rule
88
+ @rules_map[name] << rule
79
89
  end
80
90
  end
81
91
 
@@ -1,4 +1,4 @@
1
1
  module CORS
2
2
  # @see http://semver.org/
3
- VERSION = "1.0.0"
3
+ VERSION = "1.0.1"
4
4
  end
@@ -0,0 +1,60 @@
1
+ describe CORS::Policy::S3Post do
2
+ let(:now) do
3
+ Time.at(1351696066)
4
+ end
5
+
6
+ let(:valid_attributes) do
7
+ {
8
+ "bucket" => "shokunin",
9
+ "key" => "upload/BEEFBEEFBEEF.jpg",
10
+ "x-amz-meta-filename" => "$dollar$.jpg",
11
+ "acl" => "public-read",
12
+ "content-type" => "image/jpeg",
13
+ "content-length" => 678,
14
+ }
15
+ end
16
+
17
+ let(:rules) do
18
+ lambda do |manifest|
19
+ manifest.required "bucket", "shokunin"
20
+ manifest.required "key", %r!\Aupload/[a-f0-9A-F]{12}\.(jpg|png)!
21
+ manifest.required "acl", "public-read"
22
+ manifest.optional "x-amz-meta-filename", //
23
+ manifest.required "content-type", %r|\Aimage/|
24
+ manifest.required "content-length" do |bytesize|
25
+ (0..1024).cover?(bytesize)
26
+ end
27
+ end
28
+ end
29
+
30
+ let(:manifest) { CORS::Policy::S3Post.create(&rules) }
31
+
32
+ describe "#manifest" do
33
+ it "generates the policy document as a hash" do
34
+ policy = manifest.new(valid_attributes).policy(now)
35
+ expect(policy["conditions"]).to eq([
36
+ [ "content-length-range", 678, 678 ],
37
+ [ "eq", "$bucket", "shokunin" ],
38
+ [ "eq", "$key", "upload/BEEFBEEFBEEF.jpg" ],
39
+ [ "eq", "$x-amz-meta-filename", "\$dollar$.jpg" ],
40
+ [ "eq", "$acl", "public-read" ],
41
+ [ "eq", "$content-type", "image/jpeg" ],
42
+ ])
43
+ end
44
+ end
45
+
46
+ describe "#policy" do
47
+ it "returns the Base64-encoded manifest" do
48
+ request = manifest.new(valid_attributes)
49
+ decoded = Base64.urlsafe_decode64(request.policy_base64(now))
50
+ expect(MultiJson.load(decoded)).to eq(request.policy(now))
51
+ end
52
+ end
53
+
54
+ describe "#sign!" do
55
+ it "unconditionally signs the manifest" do
56
+ request = manifest.new(valid_attributes)
57
+ expect(request.sign!("properties", now)).to eq("U1YETIAOqT9mEuCebm5B6BM6feQ=")
58
+ end
59
+ end
60
+ end
@@ -7,7 +7,7 @@ describe CORS::Policy::S3 do
7
7
  "x-amz-meta-filename" => "roflcopter.gif",
8
8
  "x-amz-date" => "2012-10-22T16:10:47+02:00",
9
9
  "x-amz-meta-ROFLCOPTER" => ["yes", "no", "maybe"],
10
- "x-not-amz-header" => "I am ignored",
10
+ "x-amz-meta-ignored" => "I am ignored",
11
11
  "filename" => "uploads/roflcopter.gif"
12
12
  }
13
13
  end
@@ -22,6 +22,10 @@ describe CORS::Policy::S3 do
22
22
  manifest.required "x-amz-date" do |date|
23
23
  "2012-10-22T16:10:47+02:00" == date
24
24
  end
25
+ manifest.optional "x-amz-meta-filename", //
26
+ manifest.optional "x-amz-meta-roflcopter" do
27
+ true
28
+ end
25
29
  manifest.required "filename", %r|uploads/|
26
30
  end
27
31
  end
@@ -31,7 +35,7 @@ describe CORS::Policy::S3 do
31
35
  describe "#manifest" do
32
36
  it "is built according to specifications" do
33
37
  manifest = CORS::Policy::S3.create(&rules).new(valid_attributes)
34
- manifest.manifest.should eq <<-MANIFEST.gsub(/^ +/, "").rstrip
38
+ expect(manifest.manifest).to eq <<-MANIFEST.gsub(/^ +/, "").rstrip
35
39
  PUT
36
40
  CCummMp6o4ZgypU7ePh7QA==
37
41
  image/jpeg
@@ -44,16 +48,10 @@ describe CORS::Policy::S3 do
44
48
  end
45
49
  end
46
50
 
47
- describe "#sign" do
48
- it "signs the manifest if it is valid" do
49
- manifest = CORS::Policy::S3.create(&rules).new(valid_attributes)
50
- manifest.sign("LAWL", "HELLO").should eq "AWS LAWL:WZGsk2VzLz85B6oU19a5+fvzxXM="
51
- end
52
-
53
- it "does not sign if the manifest is invalid" do
54
- manifest = CORS::Policy::S3.create(&rules).new(valid_attributes)
55
- manifest.should_receive(:valid?).and_return(false)
56
- manifest.sign("LAWL", "HELLO").should be_nil
51
+ describe "#sign!" do
52
+ it "unconditionally signs the manifest" do
53
+ policy = manifest.new(valid_attributes)
54
+ expect(policy.sign!("LAWL", "HELLO")).to eq "AWS LAWL:WZGsk2VzLz85B6oU19a5+fvzxXM="
57
55
  end
58
56
  end
59
57
  end
@@ -27,11 +27,15 @@ describe CORS::Policy do
27
27
  end
28
28
 
29
29
  it "normalizes the attribute keys" do
30
- manifest.new(cOOl: :Yo).attributes.should eq({ "cool" => :Yo })
30
+ expect(manifest.new(anYTHIng: :Yo).attributes).to eq({ "anything" => :Yo })
31
+ end
32
+
33
+ it "removes attributes not covered by any rules" do
34
+ expect(manifest.new(cOOl: :Yo).attributes).to eq({})
31
35
  end
32
36
 
33
37
  it "populates the hash of errors" do
34
- manifest.new({}).errors.should_not be_empty
38
+ expect(manifest.new({}).errors).to_not be_empty
35
39
  end
36
40
  end
37
41
 
@@ -41,20 +45,36 @@ describe CORS::Policy do
41
45
  end
42
46
 
43
47
  it "returns the raw rules" do
44
- manifest.rules.should be_a CORS::Rules
48
+ expect(manifest.rules).to be_a CORS::Rules
45
49
  end
46
50
  end
47
51
 
48
52
  describe "#valid?" do
49
53
  it "returns true if validation succeeds" do
50
54
  manifest.new(valid_attributes).tap do |manifest|
51
- manifest.should be_valid
52
- manifest.errors.should eq({})
55
+ expect(manifest).to be_valid
56
+ expect(manifest.errors).to eq({})
53
57
  end
54
58
  end
55
59
 
56
60
  it "returns false if validation fails" do
57
- manifest.new({}).should_not be_valid
61
+ expect(manifest.new({})).to_not be_valid
62
+ end
63
+ end
64
+
65
+ describe "#sign" do
66
+ it "delegates to sign! if the manifest is valid" do
67
+ request = manifest.new(valid_attributes)
68
+ allow(request).to receive(:sign!).and_return("OK")
69
+ expect(request.sign(:a, :b)).to eq "OK"
70
+ expect(request).to have_received(:sign!)
71
+ end
72
+
73
+ it "does nothing if the manifest is not valid" do
74
+ request = manifest.new({})
75
+ allow(request).to receive(:sign!)
76
+ expect(request).not_to have_received(:sign!)
77
+ expect(request.sign(:a, :b)).to be_nil
58
78
  end
59
79
  end
60
80
  end
@@ -9,11 +9,33 @@ describe CORS::Rules do
9
9
  end
10
10
 
11
11
  it "is enumerable" do
12
- rules.each_with_object([]) { |rule, result| result << rule }.should eq(list)
12
+ expect(rules.each_with_object([]) { |rule, result| result << rule }).to eq(list)
13
13
  end
14
14
 
15
15
  it "returns an enumerator without a block" do
16
- rules.each.with_object([]) { |rule, result| result << rule }.should eq(list)
16
+ expect(rules.each.with_object([]) { |rule, result| result << rule }).to eq(list)
17
+ end
18
+ end
19
+
20
+ describe "#[]" do
21
+ let(:yay) { [] }
22
+ let(:boo) { [] }
23
+
24
+ let(:rules) do
25
+ CORS::Rules.new do |r|
26
+ yay << r.required("yay", //)
27
+ yay << r.required("yay", /./)
28
+ boo << r.optional("boo", //)
29
+ end
30
+ end
31
+
32
+ it "returns the list of rules for a property" do
33
+ expect(rules["yay"]).to eq yay
34
+ expect(rules["boo"]).to eq boo
35
+ end
36
+
37
+ it "returns nil if there are no rules for the property" do
38
+ expect(rules["does_not_exist"]).to be_nil
17
39
  end
18
40
  end
19
41
 
@@ -26,37 +48,37 @@ describe CORS::Rules do
26
48
  rules = CORS::Rules.new { |r| r.required "method", // }
27
49
  errors = rules.validate({})
28
50
 
29
- errors.should eq({ "method" => [:required, rules.first] })
51
+ expect(errors).to eq({ "method" => [:required, rules.first] })
30
52
  end
31
53
 
32
54
  it "results in an error when the value does not match" do
33
55
  rules = CORS::Rules.new { |r| r.required "content-type", %r|image/jpe?g| }
34
56
  errors = rules.validate({ "content-type" => "image/png" })
35
57
 
36
- errors.should eq({ "content-type" => [:match, rules.first] })
58
+ expect(errors).to eq({ "content-type" => [:match, rules.first] })
37
59
  end
38
60
 
39
61
  it "can match a regexp" do
40
62
  rules = CORS::Rules.new { |r| r.required "content-type", %r|image/jpe?g| }
41
63
 
42
- rules.validate({ "content-type" => "image/jpeg" }).should be_empty
43
- rules.validate({ "content-type" => "image/jpg" }).should be_empty
44
- rules.validate({ "content-type" => "image/png" }).should_not be_empty
64
+ expect(rules.validate({ "content-type" => "image/jpeg" })).to be_empty
65
+ expect(rules.validate({ "content-type" => "image/jpg" })).to be_empty
66
+ expect(rules.validate({ "content-type" => "image/png" })).to_not be_empty
45
67
  end
46
68
 
47
69
  it "can match a literal string" do
48
70
  rules = CORS::Rules.new { |r| r.required "content-type", "image/jpeg" }
49
71
 
50
- rules.validate({ "content-type" => "image/jpeg" }).should be_empty
51
- rules.validate({ "content-type" => "image/jpg" }).should_not be_empty
72
+ expect(rules.validate({ "content-type" => "image/jpeg" })).to be_empty
73
+ expect(rules.validate({ "content-type" => "image/jpg" })).to_not be_empty
52
74
  end
53
75
 
54
76
  it "can match an array" do
55
77
  rules = CORS::Rules.new { |r| r.required "content-type", ["image/jpeg", "image/png"] }
56
78
 
57
- rules.validate({ "content-type" => "image/jpeg" }).should be_empty
58
- rules.validate({ "content-type" => "image/png" }).should be_empty
59
- rules.validate({ "content-type" => "image/jpg" }).should_not be_empty
79
+ expect(rules.validate({ "content-type" => "image/jpeg" })).to be_empty
80
+ expect(rules.validate({ "content-type" => "image/png" })).to be_empty
81
+ expect(rules.validate({ "content-type" => "image/jpg" })).to_not be_empty
60
82
  end
61
83
 
62
84
  it "can match a block" do
@@ -66,8 +88,8 @@ describe CORS::Rules do
66
88
  end
67
89
  end
68
90
 
69
- rules.validate({ "content-type" => "image/jpeg" }).should be_empty
70
- rules.validate({ "content-type" => "image/png" }).should_not be_empty
91
+ expect(rules.validate({ "content-type" => "image/jpeg" })).to be_empty
92
+ expect(rules.validate({ "content-type" => "image/png" })).to_not be_empty
71
93
  end
72
94
  end
73
95
 
@@ -76,14 +98,14 @@ describe CORS::Rules do
76
98
  rules = CORS::Rules.new { |r| r.optional "method", // }
77
99
  errors = rules.validate({})
78
100
 
79
- errors.should be_empty
101
+ expect(errors).to be_empty
80
102
  end
81
103
 
82
104
  it "results in an error when the value is present but does not match" do
83
105
  rules = CORS::Rules.new { |r| r.optional "content-type", %r|image/jpe?g| }
84
106
  errors = rules.validate({ "content-type" => "image/png" })
85
107
 
86
- errors.should eq({ "content-type" => [:match, rules.first] })
108
+ expect(errors).to eq({ "content-type" => [:match, rules.first] })
87
109
  end
88
110
  end
89
111
  end
metadata CHANGED
@@ -1,65 +1,65 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cors
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
5
- prerelease:
4
+ version: 1.0.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Kim Burgestrand
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-10-30 00:00:00.000000000 Z
11
+ date: 2019-08-08 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: multi_json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
14
27
  - !ruby/object:Gem::Dependency
15
28
  name: rspec
16
29
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
30
  requirements:
19
- - - ~>
31
+ - - ">="
20
32
  - !ruby/object:Gem::Version
21
- version: '2.0'
33
+ version: '0'
22
34
  type: :development
23
35
  prerelease: false
24
36
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
37
  requirements:
27
- - - ~>
38
+ - - ">="
28
39
  - !ruby/object:Gem::Version
29
- version: '2.0'
30
- description: ! 'Cross-originresourcesharing(CORS)isgreat;itallowsyourvisitorsto
31
-
32
- asynchronouslyuploadfilestoe.g.FilepickerorAmazonS3,withoutthe
33
-
34
- fileshavingtoround-tripthroughyourwebserver.Unfortunately,giving
35
-
36
- youruserscompletewriteaccesstoyouronlinestoragealsoexposesyouto
37
-
38
- maliciousintent.
39
-
40
-
41
- Tocombatharmfulusage,gooduploadservicesthatallowclient-side
42
-
43
- upload,supportamechanismthatallowsyoutovalidateandsignallupload
44
-
45
- requeststoyouronlinestorage.Byvalidatingeveryrequest,youcangive
46
-
47
- yourvisitorsaniceuploadexperience,whilekeepingthebadvisitorsat
40
+ version: '0'
41
+ description: |
42
+ Cross-origin resource sharing (CORS) is great; it allows your visitors to
43
+ asynchronously upload files to e.g. Filepicker or Amazon S3, without the
44
+ files having to round-trip through your web server. Unfortunately, giving
45
+ your users complete write access to your online storage also exposes you to
46
+ malicious intent.
48
47
 
48
+ To combat harmful usage, good upload services that allow client-side
49
+ upload, support a mechanism that allows you to validate and sign all upload
50
+ requests to your online storage. By validating every request, you can give
51
+ your visitors a nice upload experience, while keeping the bad visitors at
49
52
  bay.
50
53
 
51
-
52
- TheCORSgemcomeswithsupportfortheAmazonS3RESTAPI.
53
-
54
- '
54
+ The CORS gem comes with support for the Amazon S3 REST API.
55
55
  email:
56
56
  - kim@burgestrand.se
57
57
  executables: []
58
58
  extensions: []
59
59
  extra_rdoc_files: []
60
60
  files:
61
- - .gitignore
62
- - .rspec
61
+ - ".gitignore"
62
+ - ".rspec"
63
63
  - Gemfile
64
64
  - Gemfile.lock
65
65
  - README.md
@@ -68,38 +68,44 @@ files:
68
68
  - lib/cors.rb
69
69
  - lib/cors/policy.rb
70
70
  - lib/cors/policy/s3.rb
71
+ - lib/cors/policy/s3_post.rb
71
72
  - lib/cors/rules.rb
72
73
  - lib/cors/version.rb
73
- - spec/cors_spec.rb
74
+ - spec/policies/s3_post_spec.rb
74
75
  - spec/policies/s3_spec.rb
76
+ - spec/policy_spec.rb
75
77
  - spec/rules_spec.rb
76
78
  - spec/spec_helper.rb
77
79
  homepage: http://github.com/elabs/cors
78
80
  licenses: []
79
- post_install_message:
81
+ metadata: {}
82
+ post_install_message: |
83
+ [DEPRECATED] The CORS gem is deprecated and will not receive further updates.
84
+ The functionality of CORS is now provided by the ruby AWS SDK:
85
+
86
+ https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/PresignedPost.html
80
87
  rdoc_options: []
81
88
  require_paths:
82
89
  - lib
83
90
  required_ruby_version: !ruby/object:Gem::Requirement
84
- none: false
85
91
  requirements:
86
- - - ! '>='
92
+ - - ">="
87
93
  - !ruby/object:Gem::Version
88
94
  version: '0'
89
95
  required_rubygems_version: !ruby/object:Gem::Requirement
90
- none: false
91
96
  requirements:
92
- - - ! '>='
97
+ - - ">="
93
98
  - !ruby/object:Gem::Version
94
99
  version: '0'
95
100
  requirements: []
96
101
  rubyforge_project:
97
- rubygems_version: 1.8.24
102
+ rubygems_version: 2.7.6
98
103
  signing_key:
99
- specification_version: 3
104
+ specification_version: 4
100
105
  summary: CORS policy validation- and signing library for Amazon S3 REST API.
101
106
  test_files:
102
- - spec/cors_spec.rb
107
+ - spec/policies/s3_post_spec.rb
103
108
  - spec/policies/s3_spec.rb
109
+ - spec/policy_spec.rb
104
110
  - spec/rules_spec.rb
105
111
  - spec/spec_helper.rb