http_signature 0.0.7 → 0.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 33793ff4276cb6c366f88d15abb0e38b69cdb468
4
- data.tar.gz: cde3efe53a20f5ef8a94c2ed21b9341300f4ed76
3
+ metadata.gz: 821df2c08e3f1d58e737250711d5d45d6baf561d
4
+ data.tar.gz: 3ee3456c48c461e7ae328b42f5c4808a7fe9cb9d
5
5
  SHA512:
6
- metadata.gz: 88cf8f428a7bafd0971b4e8d0650c8b9ee15c8f74794347afa7cdaed32da0462468f4a7f1471f1f4578886009801a822dcf990481d859dac5fa3e9b65e2e8630
7
- data.tar.gz: 516d8a279e8a340df3e2aae7e8b1bd313229dd8e8643c81bda7caea37e321d1e812e692afabe2b4535281c6c35970b2b62286ffdd07178fa5a57ca2c63d0c72f
6
+ metadata.gz: 75c29e3608b55604dcc9bbbcae30d8907e3b830b8001fc563f2c606a88f7f071e54470d56c28ee3d2d9406aa173445b176e1c1bfe9c02ca2c3994b1559b0fe9c
7
+ data.tar.gz: 73ec032a5fdf6813d1ac273aadf4b90d9f583c72e023299f62383c82f8ad92d17c72010b8571a9bb7d211c2781d9f477a901f89b6da3992bc5291159d298fed2
@@ -0,0 +1,5 @@
1
+ Metrics/LineLength:
2
+ Max: 100
3
+
4
+ Metrics/MethodLength:
5
+ Max: 15
data/README.md CHANGED
@@ -105,16 +105,46 @@ HTTPSignature.valid?(
105
105
  )
106
106
  ```
107
107
 
108
- ## Example usage with middleware
109
- ### Faraday middleware on outgoing requests
110
- Example of using it on an outgoing request.
108
+ ## Example usage
109
+ ### NET::HTTP
110
+ Example of using it with `NET::HTTP`. There's no real integration written so it's basically just
111
+ getting the request object's data and create the signature and adding it to the headers.
112
+
113
+ ```ruby
114
+ require 'net/http'
115
+ require 'http_signature'
116
+
117
+ uri = URI('http://example.com/hello')
118
+
119
+ Net::HTTP.start(uri.host, uri.port) do |http|
120
+ request = Net::HTTP::Get.new(uri)
121
+
122
+ signature = HTTPSignature.create(
123
+ url: request.uri,
124
+ method: request.method,
125
+ headers: request.each_header.map { |k, v| [k, v] }.to_h,
126
+ key: 'MYSECRETKEY',
127
+ key_id: 'KEY_1',
128
+ algorithm: 'hmac-sha256',
129
+ body: request.body ? request.body : ''
130
+ )
131
+
132
+ request['Signature'] = signature
133
+
134
+ response = http.request(request) # Net::HTTPResponse
135
+ end
136
+ ```
137
+
138
+ ### Faraday middleware
139
+ Example of using it with an outgoing faraday request. IMO, this is the smoothest usage.
140
+ Basically you set the keys and tell faraday to use the middleware.
141
+
111
142
  ```ruby
112
143
  require 'http_signature/faraday'
113
144
 
114
145
  HTTPSignature::Faraday.key = 'MySecureKey' # This should be long and random
115
146
  HTTPSignature::Faraday.key_id = 'key-1' # For the recipient to know which key to decrypt with
116
147
 
117
-
118
148
  # Tell faraday to use the middleware. Read more about it here: https://github.com/lostisland/faraday#advanced-middleware-usage
119
149
  Faraday.new('http://example.com') do |faraday|
120
150
  faraday.use(HTTPSignature::Faraday)
@@ -131,16 +161,18 @@ response = conn.get('/')
131
161
  ```
132
162
 
133
163
  ### Rack middleware for incoming requests
134
- I've written a quite sloppy but totally usable rack middleware that validates every incoming request.
164
+ I've written a quite sloppy but totally usable rack middleware that validates incoming requests.
135
165
 
136
- #### General rack application
166
+ #### General Rack application
137
167
  Sinatra for example
138
168
  ```ruby
139
169
  require 'http_signature/rack'
140
170
 
141
171
  HTTPSignature.config(keys: [{ id: 'key-1', value: 'MySecureKey' }])
142
- # You can exclude paths where you don't want to validate the signature:
143
- HTTPSignature::Rack.exclude_paths = ['/']
172
+ # You can exclude paths where you don't want to validate the signature, it's using
173
+ # regexp so you can use `*` and stuff like that. Just watch out so you don't exclude
174
+ # more paths than intended. Regexp can trick you when you least expect it 👻.
175
+ HTTPSignature::Rack.exclude_paths = ['/', '/hello/*']
144
176
 
145
177
  use HTTPSignature::Rack
146
178
  run MyApp
@@ -1,9 +1,10 @@
1
1
  lib = File.expand_path('../lib', __FILE__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'http_signature/version'
3
4
 
4
5
  Gem::Specification.new do |spec|
5
6
  spec.name = 'http_signature'
6
- spec.version = '0.0.7'
7
+ spec.version = HTTPSignature::VERSION
7
8
  spec.authors = ['Joel Larsson']
8
9
  spec.email = ['bolmaster2@gmail.com']
9
10
 
@@ -5,6 +5,8 @@ require 'securerandom'
5
5
  require 'base64'
6
6
  require 'uri'
7
7
 
8
+ # Implements signing of a request according to https://tools.ietf.org/html/draft-cavage-http-signatures
9
+ # specification.
8
10
  module HTTPSignature
9
11
  # Create signature based on the data sent in
10
12
  #
@@ -18,12 +20,10 @@ module HTTPSignature
18
20
  # @param method [Symbol] Request method, default is `:get`
19
21
  # @param algorithm [String] Algorithm to use when signing, check `supported_algorithms` for
20
22
  # @return [String] The signature header value to use in "Signature" header
21
- def self.create(url:, query_string_params: {}, body: '', headers: {}, key:,
22
- key_id: SecureRandom.hex(8),
23
- method: :get,
24
- algorithm: 'hmac-sha256'
23
+ def self.create(
24
+ url:, query_string_params: {}, body: '', headers: {}, key:, key_id: SecureRandom.hex(8),
25
+ method: :get, algorithm: 'hmac-sha256'
25
26
  )
26
-
27
27
  raise 'Unsupported algorithm :(' unless supported_algorithms.include?(algorithm)
28
28
 
29
29
  uri = URI(url)
@@ -32,12 +32,11 @@ module HTTPSignature
32
32
  headers = convert_headers(headers)
33
33
  query = create_query_string(uri, query_string_params)
34
34
 
35
- string_to_sign = create_signing_string(method: method, path: path,
36
- query: query, headers: headers)
37
-
38
- signature = sign(string_to_sign, key: key, algorithm: algorithm)
39
- create_signature_header(key_id: key_id, headers: headers, signature: signature,
40
- algorithm: algorithm)
35
+ sign_string = create_signing_string(method: method, path: path, query: query, headers: headers)
36
+ signature = sign(sign_string, key: key, algorithm: algorithm)
37
+ create_signature_header(
38
+ key_id: key_id, headers: headers, signature: signature, algorithm: algorithm
39
+ )
41
40
  end
42
41
 
43
42
  def self.sign(string, key:, algorithm:)
@@ -86,7 +85,7 @@ module HTTPSignature
86
85
  # @return [String]
87
86
  def self.create_signing_string(method:, path:, query:, headers:)
88
87
  [
89
- "(request-target): #{method.upcase} #{path}#{query}",
88
+ "(request-target): #{method.downcase} #{path}#{query}"
90
89
  ].concat(headers).join("\n")
91
90
  end
92
91
 
@@ -109,6 +108,7 @@ module HTTPSignature
109
108
  uri = URI(url)
110
109
  path = uri.path
111
110
  signature = headers.delete(:signature)
111
+ headers = add_digest(headers, body)
112
112
  headers = convert_headers(headers)
113
113
  query = create_query_string(uri, query_string_params)
114
114
 
@@ -141,11 +141,13 @@ module HTTPSignature
141
141
  # When query string params is also set on the url, append the params defined
142
142
  # in `query_string_params` and make a joint query string
143
143
  def self.create_query_string(uri, query_string_params)
144
- if uri.query || !query_string_params.empty?
145
- delimiter = uri.query.nil? ? '' : '&'
146
- '?' + (query_string_params.empty? ? '' : [uri.query.to_s, delimiter, URI.encode_www_form(query_string_params)].join)
147
- end
144
+ return if !uri.query && query_string_params.empty?
145
+
146
+ delimiter = uri.query.nil? || query_string_params.empty? ? '' : '&'
147
+
148
+ ['?', uri.query.to_s, delimiter, URI.encode_www_form(query_string_params)].join
148
149
  end
150
+
149
151
  # Convert a header hash into an array with header strings
150
152
  # { header: 'value'} -> ['header: value']
151
153
  def self.convert_headers(headers)
@@ -156,7 +158,6 @@ module HTTPSignature
156
158
 
157
159
  def self.add_digest(headers, body)
158
160
  headers[:digest] = create_digest(body) unless body.empty?
159
-
160
161
  headers
161
162
  end
162
163
 
@@ -165,9 +166,7 @@ module HTTPSignature
165
166
  end
166
167
 
167
168
  def self.key(id)
168
- key = @keys.select do |o|
169
- o[:id] == id
170
- end.first
169
+ key = @keys.select { |o| o[:id] == id }.first
171
170
 
172
171
  key&.dig(:value) || (raise "Key with id #{id} could not be found")
173
172
  end
@@ -21,8 +21,8 @@ class HTTPSignature::Faraday < Faraday::Middleware
21
21
  end
22
22
 
23
23
  # Choose which headers to sign
24
- filtered_headers = %w{ Host Date Digest }
25
- headers_to_sign = env[:request_headers].select { |k, v| filtered_headers.include?(k.to_s) }
24
+ filtered_headers = %w[Host Date Digest]
25
+ headers_to_sign = env[:request_headers].select { |k, _v| filtered_headers.include?(k.to_s) }
26
26
 
27
27
  signature = HTTPSignature.create(
28
28
  url: env[:url],
@@ -34,7 +34,7 @@ class HTTPSignature::Faraday < Faraday::Middleware
34
34
  body: body
35
35
  )
36
36
 
37
- env[:request_headers].merge!('Signature' => signature)
37
+ env[:request_headers]['Signature'] = signature
38
38
 
39
39
  @app.call(env)
40
40
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HTTPSignature
4
+ VERSION = '0.1.0'
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http_signature
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Larsson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-02 00:00:00.000000000 Z
11
+ date: 2018-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,6 +75,7 @@ extra_rdoc_files: []
75
75
  files:
76
76
  - ".circleci/config.yml"
77
77
  - ".gitignore"
78
+ - ".rubocop.yml"
78
79
  - ".ruby-version"
79
80
  - Gemfile
80
81
  - Gemfile.lock
@@ -84,6 +85,7 @@ files:
84
85
  - lib/http_signature.rb
85
86
  - lib/http_signature/faraday.rb
86
87
  - lib/http_signature/rack.rb
88
+ - lib/http_signature/version.rb
87
89
  homepage: https://github.com/bolmaster2/http-signature
88
90
  licenses:
89
91
  - MIT