cognac 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d86971bb20a88cf6d836ee65efce4386553cf6c0
4
- data.tar.gz: c41738a6e82b804746588401eb22afff221a8d86
3
+ metadata.gz: 69e426ccc7c2a724b60027cf34434b191c1eadc8
4
+ data.tar.gz: d2a161c47f4b9d9af11dc8aaa02f698a4b3d8a10
5
5
  SHA512:
6
- metadata.gz: f4640a5c398bd1f4f76b6ce9944aa67cf181e9c1d96b5b21432e3ec14df452fe7b7a2a7112e3ee31a63294f8c662ebdf1c94f13cf33e8076ce71639ae14494cc
7
- data.tar.gz: 6d39d5d12e8a0f2fd48274fd7551307d84e3b9814290cd5867bd7997a9a0adb907069015ee791a3ac6a248961fbaf46ece7933142ce9095924b6264eb782cdf0
6
+ metadata.gz: 2cff56b051bf47e4c84c5d7be25a404dc60801fda1e45d3988ea4fa7c55ae29dd52d3bf716073038d6bb79f8786b89247e34ce9f3394e32b20ed58e0d37d48f9
7
+ data.tar.gz: 41c06c0c4252e30948b327ac9efbcca69c6765d65b548b4ec0bba05cfd436b5f61b410cda1d62ec506e55b9afabfb5a177cd34a6253cb984f7fb82f1bffdeefb
@@ -1 +1 @@
1
- 2.2.2
1
+ 2.2.3
@@ -0,0 +1,35 @@
1
+
2
+ == Version 0.1.3 (July 1, 2015)
3
+
4
+ Old Interface
5
+
6
+ file_name = Cognac::CloudFile.generate(params[:filename])
7
+ resource_end_point = Cognac::CloudFile.resource_end_point(ENV["AWS_S3_BUCKET"], file_name)
8
+
9
+ New Interface
10
+
11
+ file = Cognac::CloudFile.new(params[:filename], bucket)
12
+ resource_end_point = file.resource_end_point
13
+
14
+ == In Progress
15
+
16
+ Old Interface
17
+
18
+ options = Cognac::Signature.generate_options_for_build_s3_upload_url(ENV["AWS_S3_BUCKET"], file_name, params[:content_type])
19
+ url = Cognac::Signature.build_s3_upload_url(resource_end_point, ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"], options)
20
+
21
+ New Interface
22
+
23
+ url = Cognac::CloudFile.upload_url(ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"], params[:content_type])
24
+
25
+ == Combining the Two
26
+
27
+ file = Cognac::CloudFile.new(params[:filename], bucket)
28
+
29
+ resource_end_point = file.resource_end_point
30
+ url = file.upload_url(ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"], params[:content_type])
31
+
32
+ render :json => {put_url: url, file_url: resource_end_point}
33
+
34
+
35
+ Separate the configuration values for object properties.
data/README.md CHANGED
@@ -24,26 +24,37 @@ Or install it yourself as:
24
24
 
25
25
  ## Dependencies
26
26
 
27
- Ruby 2.2.2
27
+ Ruby 2.2.3
28
28
  ActiveSupport 4.2.3
29
29
 
30
30
  ## Usage
31
31
 
32
+ Configure the AWS credentials in config/initializers/aws.rb:
33
+
34
+ ```ruby
35
+ Cognac.configuration do |config|
36
+ config.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
37
+ config.aws_access_key = ENV['AWS_ACCESS_KEY_ID']
38
+ config.aws_s3_bucket = ENV['AWS_S3_BUCKET']
39
+ end
40
+ ```
41
+
32
42
  You can use this gem in your Rails controller like this:
33
43
 
34
44
  ```ruby
35
45
  def generate_signed_s3_url
36
- # To avoid file collision, we prepend string to the file_name
37
- file_name = Cognac::CloudFile.generate(params[:filename])
38
- resource_end_point = Cognac::CloudFile.resource_end_point(ENV["AWS_S3_BUCKET"], file_name)
39
-
40
- options = Cognac::Signature.generate_options_for_build_s3_upload_url(ENV["AWS_S3_BUCKET"], file_name, params[:content_type])
41
- url = Cognac::Signature.build_s3_upload_url(resource_end_point, ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"], options)
46
+ cloud_file = Cognac::CloudFile.new(params[:filename])
47
+ resource_end_point = cloud_file.resource_end_point
48
+
49
+ options = Cognac::Signature.generate_options_for_build_s3_upload_url(cloud_file.name, params[:content_type])
50
+ url = Cognac::Signature.build_s3_upload_url(resource_end_point, options)
42
51
 
43
- render :json => {:put_url => url, :file_url => resource_end_point}
52
+ render :json => {put_url: url, file_url: resource_end_point}
44
53
  end
45
54
  ```
46
55
 
56
+ For a sample Rails project that shows how to use this gem, check out: https://github.com/bparanj/s3-cors-upload-rails
57
+
47
58
  ## Development
48
59
 
49
60
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -55,12 +66,12 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
55
66
  Run the tests:
56
67
 
57
68
  ```sh
58
- $ruby -rminitest/pride test/cognac_test.rb
69
+ $ruby -rminitest/pride test/cloud_file_test.rb --verbose
70
+ $ruby -rminitest/pride test/signature_test.rb --verbose
59
71
  ```
60
72
 
61
73
  Bug reports and pull requests are welcome on Bitbucket at https://bitbucket.org/bparanj/cognac.
62
74
 
63
75
  ## License
64
76
 
65
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
66
-
77
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -19,7 +19,10 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
+ spec.required_ruby_version = '>= 2.2.2'
23
+
22
24
  spec.add_dependency 'activesupport', '~> 4.2'
25
+ spec.add_dependency 'lyon', "~> 0.1"
23
26
 
24
27
  spec.add_development_dependency "bundler", "~> 1.10"
25
28
  spec.add_development_dependency "rake", "~> 10.0"
@@ -1,78 +1,13 @@
1
+ require "cognac/cloud_file"
2
+ require "cognac/signature"
1
3
  require "cognac/version"
2
- require 'active_support/core_ext/numeric/time'
3
- require "erb"
4
+ require 'lyon'
4
5
 
5
6
  module Cognac
6
-
7
- class CloudFile
8
- def self.generate(file_name)
9
- "#{SecureRandom.hex(4).to_s}_#{file_name}"
10
- end
11
-
12
- def self.resource_end_point(bucket, file_name)
13
- "http://#{bucket}.s3.amazonaws.com/#{file_name}"
14
- end
15
- end
16
-
17
- # AWS Signature Version 2 : http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
18
- class Signature
19
- NEW_LINE = "\n"
20
-
21
- def self.build_string_to_sign(options = {})
22
- options = {
23
- http_verb: "PUT",
24
- content_md5: nil,
25
- content_type: nil,
26
- date: an_hour_from_now,
27
- amz_headers: [],
28
- resource: ""
29
- }.merge(options)
7
+ extend Lyon::Configuration
30
8
 
31
- add_new_line(options[:http_verb]) +
32
- add_new_line(options[:content_md5]) +
33
- add_new_line(options[:content_type]) +
34
- add_new_line(options[:date]) +
35
- (options[:amz_headers].any? ? (options[:amz_headers].join(NEW_LINE) + NEW_LINE) : "") +
36
- options[:resource]
37
- end
38
-
39
- def self.build_s3_rest_signature(secret_access_key, options = {})
40
- s = build_string_to_sign(options).force_encoding("UTF-8")
41
- Base64.encode64(OpenSSL::HMAC.digest("sha1", secret_access_key, s)).strip
42
- end
43
-
44
- def self.build_s3_upload_url(end_point, aws_access_key, secret_access_key, signature_options = {})
45
- signature = encoded_signature(secret_access_key, signature_options)
46
- expires = expiration(signature_options)
47
- "#{end_point}?AWSAccessKeyId=#{aws_access_key}&Expires=#{expires}&Signature=#{signature}"
48
- end
49
-
50
- def self.generate_options_for_build_s3_upload_url(bucket, file_name, content_type)
51
- {
52
- http_verb: "PUT",
53
- date: 1.hours.from_now.to_i,
54
- resource: "/#{bucket}/#{file_name}",
55
- content_type: content_type
56
- }
57
- end
58
-
59
- private
60
-
61
- def self.add_new_line(option)
62
- option.to_s + NEW_LINE
63
- end
64
-
65
- def self.an_hour_from_now
66
- 1.hours.from_now.rfc822
67
- end
68
-
69
- def self.encoded_signature(secret_access_key, signature_options)
70
- ERB::Util.url_encode(build_s3_rest_signature(secret_access_key, signature_options))
71
- end
72
-
73
- def self.expiration(signature_options)
74
- signature_options[:date] || an_hour_from_now
75
- end
76
-
77
- end
9
+ # Amazon Credentials
10
+ define_setting :secret_access_key
11
+ define_setting :aws_access_key
12
+ define_setting :aws_s3_bucket
78
13
  end
@@ -0,0 +1,22 @@
1
+ require 'securerandom'
2
+
3
+ module Cognac
4
+ class CloudFile
5
+
6
+ def initialize(file_name)
7
+ @file_name = file_name
8
+ end
9
+
10
+ # To avoid file collision, we prepend random string to the file_name
11
+ def name
12
+ "#{SecureRandom.hex(4).to_s}_#{@file_name}"
13
+ end
14
+
15
+ def resource_end_point
16
+ raise 'AWS_S3_BUCKET Environment variable is not intialized. Refer README.md at https://bitbucket.org/bparanj/cognac' if Cognac.aws_s3_bucket.nil?
17
+ "http://#{Cognac.aws_s3_bucket}.s3.amazonaws.com/#{name}"
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,109 @@
1
+ require 'active_support/core_ext/numeric/time'
2
+ require "erb"
3
+
4
+ module Cognac
5
+
6
+ # file = Cognac::CloudFile.new(params[:filename], bucket)
7
+ #
8
+ # resource_end_point = file.resource_end_point
9
+ # url = file.upload_url(ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"], params[:content_type])
10
+
11
+ # 1. Create cloudfile
12
+ # 2. Generate end point
13
+ # 3. Generate upload url
14
+
15
+ # Input
16
+ # - file_name
17
+ # - bucket
18
+ # - access_key_id
19
+ # - secret_access_key
20
+ # - content_type
21
+ #
22
+ # Output
23
+ # - Signed S3 Upload URL
24
+
25
+ # build_s3_upload_url (access_key, secret_access_key)
26
+ # - Encode signature
27
+ # - build s3 rest signature (secret_access_key)
28
+ # - build_string_to_sign (options)
29
+ # - base encode hmac digest (string to sign, secret_access_key)
30
+ # - End point
31
+
32
+ # AWS Signature Version 2 : http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
33
+ class Signature
34
+ NEW_LINE = "\n"
35
+ SECURE_HASH_ALGORITHM = "sha1"
36
+ BLANK_STRING = ""
37
+ UTF8_ENCODING = "UTF-8"
38
+ HTTP_PUT = "PUT"
39
+
40
+ def initialize(options = {})
41
+ @secret_access_key = Cognac.secret_access_key
42
+ @aws_access_key = Cognac.aws_access_key
43
+ @options = options
44
+ @default = {
45
+ http_verb: HTTP_PUT,
46
+ content_md5: nil,
47
+ content_type: nil,
48
+ date: an_hour_from_now,
49
+ amz_headers: [],
50
+ resource: BLANK_STRING
51
+ }
52
+ end
53
+
54
+ # This is called in the controller
55
+ def build_s3_upload_url(end_point)
56
+ "#{end_point}?AWSAccessKeyId=#{@aws_access_key}&Expires=#{expiration}&Signature=#{encoded_signature}"
57
+ end
58
+
59
+ def encoded_signature
60
+ ERB::Util.url_encode(build_s3_rest_signature)
61
+ end
62
+
63
+ def build_s3_rest_signature
64
+ string_to_sign = build_string_to_sign(@options).force_encoding(UTF8_ENCODING)
65
+ base_encoded_hmac_digest(string_to_sign)
66
+ end
67
+
68
+ def build_string_to_sign(options = {})
69
+ o = @default.merge(options)
70
+
71
+ add_new_line(o[:http_verb]) +
72
+ add_new_line(o[:content_md5]) +
73
+ add_new_line(o[:content_type]) +
74
+ add_new_line(o[:date]) +
75
+ (o[:amz_headers].any? ? (o[:amz_headers].join(NEW_LINE) + NEW_LINE) : BLANK_STRING) +
76
+ o[:resource]
77
+ end
78
+
79
+ def base_encoded_hmac_digest(string_to_sign)
80
+ Base64.encode64(OpenSSL::HMAC.digest(SECURE_HASH_ALGORITHM, @secret_access_key, string_to_sign)).strip
81
+ end
82
+
83
+ # This is called in the controller and passed in to the build_s3_upload_url method as a parameter
84
+ # Hide this method
85
+ def generate_options_for_build_s3_upload_url(file_name, content_type)
86
+ {
87
+ http_verb: HTTP_PUT,
88
+ date: 1.hours.from_now.to_i,
89
+ resource: "/#{Cognac.aws_s3_bucket}/#{file_name}",
90
+ content_type: content_type
91
+ }
92
+ end
93
+
94
+ private
95
+
96
+ def add_new_line(option)
97
+ option.to_s + NEW_LINE
98
+ end
99
+
100
+ def an_hour_from_now
101
+ 1.hours.from_now.rfc822
102
+ end
103
+
104
+ def expiration
105
+ @options[:date] || an_hour_from_now
106
+ end
107
+
108
+ end
109
+ end
@@ -1,3 +1,3 @@
1
1
  module Cognac
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,24 @@
1
+ 1. Hide methods that are not used in the controller.
2
+
3
+ 2.
4
+
5
+ # file = Cognac::CloudFile.new(params[:filename], bucket)
6
+ #
7
+ # resource_end_point = file.resource_end_point
8
+ # url = file.upload_url(ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"], params[:content_type])
9
+
10
+ # 1. Create cloudfile
11
+ # 2. Generate end point
12
+ # 3. Generate upload url
13
+
14
+ 3. Use the latest version of Cognac gem with S3 uploader.
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cognac
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bala Paranj
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-07-01 00:00:00.000000000 Z
11
+ date: 2015-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: lyon
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -79,6 +93,7 @@ files:
79
93
  - ".ruby-gemset"
80
94
  - ".ruby-version"
81
95
  - ".travis.yml"
96
+ - CHANGELOG.md
82
97
  - Gemfile
83
98
  - LICENSE.txt
84
99
  - README.md
@@ -87,7 +102,10 @@ files:
87
102
  - bin/setup
88
103
  - cognac.gemspec
89
104
  - lib/cognac.rb
105
+ - lib/cognac/cloud_file.rb
106
+ - lib/cognac/signature.rb
90
107
  - lib/cognac/version.rb
108
+ - todo.txt
91
109
  homepage: http://www.rubyplus.com
92
110
  licenses:
93
111
  - MIT
@@ -100,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
118
  requirements:
101
119
  - - ">="
102
120
  - !ruby/object:Gem::Version
103
- version: '0'
121
+ version: 2.2.2
104
122
  required_rubygems_version: !ruby/object:Gem::Requirement
105
123
  requirements:
106
124
  - - ">="