s3_sig_gen 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ad0e1959ce6143a46a32e0b342c73f959d415df0
4
+ data.tar.gz: cdd125035c1f648bda4c0598755f707724e7360d
5
+ SHA512:
6
+ metadata.gz: 18779f361c4dca704852497b623d99a30f833c778b19ea0525c281794e9175fe12168df71cc1b93b06d7911669488aa251b6557ac5c69845ba3d88e29b137be6
7
+ data.tar.gz: a31a70ca14aa63648b3919b5d3475435c14a43a9db29928f863794618911bb73e9a4ee9408387e8583f5f0345d9b2c594163684900a79acd49ebeade6ddf7307
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3
3
+ Exclude:
4
+ - "**/*.gemspec"
5
+
6
+ Metrics/LineLength:
7
+ Max: 145
8
+
9
+ Style/FrozenStringLiteralComment:
10
+ EnforcedStyle: never
11
+
12
+ Style/IndentationConsistency:
13
+ EnforcedStyle: rails
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in s3_sig_gen.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Michael Diakonov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,66 @@
1
+ # S3SigGen
2
+
3
+ Authenticate requests for browser based direct uploads to AWS S3.
4
+
5
+ [Direct upload to AWS S3](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html)
6
+
7
+ ## Installation
8
+
9
+ ```ruby
10
+ gem 's3_sig_gen', :git => 'git@github.com:diakonovm/s3_sig_gen.git'
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ruby
16
+ s3_sig_gen = S3SigGen::Generator.new do |g|
17
+ g.aws_access_key_id = ENV["AWS_ACCESS_KEY_ID"]
18
+ g.aws_secret_access_key = ENV["AWS_SECRET_ACCESS_KEY"]
19
+ g.region = "us-east-1"
20
+ g.bucket = "sample-bucket"
21
+ g.key = "sample_key"
22
+ g.acl = "public-read"
23
+ end
24
+ @signature = s3_sig_gen.signature
25
+ ```
26
+ or
27
+
28
+ ```ruby
29
+ options = {
30
+ aws_access_key_id: ENV["AWS_ACCESS_KEY_ID"],
31
+ aws_secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
32
+ region: 'us-east-1',
33
+ bucket: 'sample-bucket',
34
+ key: 'sample_key',
35
+ acl: 'public-read'
36
+ }
37
+ s3_sig_gen = S3SigGen::Generator.new(options)
38
+ @signature = s3_sig_gen.signature
39
+ ```
40
+
41
+ ``` html
42
+ <!-- views/photos/new.html.erb -->
43
+
44
+ <form action="https://asdf.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
45
+ <input type="hidden" name="key" value="<%= @signature["key"] %>" />
46
+ <input type="hidden" name="acl" value="<%= @signature["acl"] %>" />
47
+ <!-- <input type="hidden" name="x-amz-server-side-encryption" value="AES256" /> -->
48
+ <input type="hidden" name="success_action_status" value="<%= @signature["success_action_status"] %>" />
49
+ <input type="hidden" name="X-Amz-Credential" value="<%= @signature["x-amz-credential"] %>" />
50
+ <input type="hidden" name="X-Amz-Algorithm" value="<%= @signature["x-amz-algorithm"] %>" />
51
+ <input type="hidden" name="X-Amz-Date" value="<%= @signature["x-amz-date"] %>" />
52
+ <input type="hidden" name="Policy" value="<%= @signature["policy"] %>" />
53
+ <input type="hidden" name="X-Amz-Signature" value="<%= @signature["x-amz-signature"] %>" />
54
+ File:
55
+ <input type="file" name="file" /> <br />
56
+ <input type="submit" name="submit" value="upload"/>
57
+ </form>
58
+ ```
59
+
60
+ ## Contributing
61
+
62
+ Bug reports and pull requests are welcome on GitHub at https://github.com/diakonovm/s3_sig_gen.
63
+
64
+ ## License
65
+
66
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 's3_sig_gen'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require 'pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,2 @@
1
+ require 's3_sig_gen/version'
2
+ require 's3_sig_gen/generator'
@@ -0,0 +1,82 @@
1
+ require 'base64'
2
+ require 'json'
3
+ require 'openssl'
4
+ require 'open-uri'
5
+ require 'time'
6
+
7
+ module S3SigGen
8
+ class Generator
9
+ attr_accessor :aws_access_key_id, :aws_secret_access_key, :region, :bucket, :key, :acl, :server_side_encryption
10
+
11
+ def initialize options = {}
12
+ @aws_access_key_id = options[:aws_access_key_id]
13
+ @aws_secret_access_key = options[:aws_secret_access_key]
14
+ @region = options[:region] || 'us-east-1'
15
+ @bucket = options[:bucket]
16
+ @key = options[:key]
17
+ @acl = options[:acl] || 'public-read'
18
+ @server_side_encryption = options[:server_side_encryption] || false
19
+
20
+ yield self if block_given?
21
+ end
22
+
23
+ def signature
24
+ build_signature
25
+ end
26
+
27
+ private
28
+
29
+ def build_signature
30
+ unencoded_policy = {}
31
+ unencoded_policy['expiration'] = expiration
32
+ unencoded_policy['conditions'] = []
33
+ unencoded_policy['conditions'] << { 'acl': @acl }
34
+ unencoded_policy['conditions'] << { 'bucket': @bucket }
35
+ unencoded_policy['conditions'] << { 'key': @key }
36
+ unencoded_policy['conditions'] << { 'success_action_status': '200' }
37
+ unencoded_policy['conditions'] << { 'x-amz-algorithm': 'AWS4-HMAC-SHA256' }
38
+ unencoded_policy['conditions'] << { 'x-amz-credential': x_amz_credential }
39
+ unencoded_policy['conditions'] << { 'x-amz-date': x_amz_date }
40
+ unencoded_policy['conditions'] << { 'x-amz-server-side-encryption': 'AES256' } if @server_side_encryption
41
+
42
+ base64_encoded_policy = base64_encode unencoded_policy.to_json
43
+ signed_policy = sign_policy base64_encoded_policy
44
+
45
+ signature = {}
46
+ signature['acl'] = unencoded_policy['conditions'][0][:acl]
47
+ signature['key'] = unencoded_policy['conditions'][2][:key]
48
+ signature['success_action_status'] = unencoded_policy['conditions'][3][:success_action_status]
49
+ signature['policy'] = base64_encoded_policy.to_s
50
+ signature['x-amz-algorithm'] = unencoded_policy['conditions'][4]['x-amz-algorithm'.to_sym]
51
+ signature['x-amz-credential'] = unencoded_policy['conditions'][5]['x-amz-credential'.to_sym]
52
+ signature['x-amz-date'] = unencoded_policy['conditions'][6]['x-amz-date'.to_sym]
53
+ signature['x-amz-server-side-encryption'] = unencoded_policy['conditions'][7]['x-amz-server-side-encryption'.to_sym] if @server_side_encryption
54
+ signature['x-amz-signature'] = signed_policy
55
+ signature
56
+ end
57
+
58
+ def expiration
59
+ (Time.now + (5 * 60 * 1000)).utc.iso8601.to_s
60
+ end
61
+
62
+ def x_amz_credential
63
+ "#{@aws_access_key_id}/#{Date.today.to_s.delete('-')}/#{@region}/s3/aws4_request"
64
+ end
65
+
66
+ def x_amz_date
67
+ "#{Date.today.to_s.delete('-')}T000000Z"
68
+ end
69
+
70
+ def base64_encode string
71
+ Base64.strict_encode64 string
72
+ end
73
+
74
+ def sign_policy policy
75
+ signing_key = OpenSSL::HMAC.digest('sha256', "AWS4#{@aws_secret_access_key}", Date.today.to_s.delete('-'))
76
+ signing_key = OpenSSL::HMAC.digest('sha256', signing_key, @region)
77
+ signing_key = OpenSSL::HMAC.digest('sha256', signing_key, 's3')
78
+ signing_key = OpenSSL::HMAC.digest('sha256', signing_key, 'aws4_request')
79
+ OpenSSL::HMAC.hexdigest('sha256', signing_key, policy)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,3 @@
1
+ module S3SigGen
2
+ VERSION = '0.2.0'.freeze
3
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 's3_sig_gen/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "s3_sig_gen"
8
+ spec.version = S3SigGen::VERSION
9
+ spec.authors = ["Michael Diakonov"]
10
+ spec.email = ["diakonov.m@gmail.com"]
11
+ spec.homepage = ""
12
+ spec.summary = %q{AWS Version 4 signatures for authenticated HTTP POST uploads to AWS S3}
13
+ spec.description = %q{}
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.15"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_development_dependency "rubocop", '~> 0.47.0', '< 0.49'
28
+
29
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: s3_sig_gen
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Diakonov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-09-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.47.0
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '0.49'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: 0.47.0
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.49'
75
+ description: ''
76
+ email:
77
+ - diakonov.m@gmail.com
78
+ executables: []
79
+ extensions: []
80
+ extra_rdoc_files: []
81
+ files:
82
+ - ".gitignore"
83
+ - ".rspec"
84
+ - ".rubocop.yml"
85
+ - Gemfile
86
+ - LICENSE.txt
87
+ - README.md
88
+ - Rakefile
89
+ - bin/console
90
+ - bin/setup
91
+ - lib/s3_sig_gen.rb
92
+ - lib/s3_sig_gen/generator.rb
93
+ - lib/s3_sig_gen/version.rb
94
+ - s3_sig_gen.gemspec
95
+ homepage: ''
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 2.6.8
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: AWS Version 4 signatures for authenticated HTTP POST uploads to AWS S3
119
+ test_files: []