api_signature 0.1.0 → 0.1.1

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: e907dd2adc3e3558f0f5fc7a00131ccac6d71aac
4
- data.tar.gz: 7db50a3800bc9c2e77eea7d7a543a1054d40073c
3
+ metadata.gz: 6b3f7f58448cc08c412e475bd5967b8af6cfb972
4
+ data.tar.gz: 13783e19a83c42cdbc744036a44065f6deb7a56c
5
5
  SHA512:
6
- metadata.gz: 527fd053ef63b32c5ce09cfa0e020c7dbc9a125e52b8332703e4bc2b20380e44557e6e51f30fbc64565238236daef9db38716f738c49c23fb2e05bcadece8fb1
7
- data.tar.gz: fb6449eb2de6530c14175f8faa775ba0a62466ac8581714255b9f62134d007525a3cc9f3aef62ad2d65402aea39f9f569e13dc748c7c4277fc4a2872e455356b
6
+ metadata.gz: 73189d7c54d5bef421df7d7f195bc8e2c708e2b5d67e85ee4151e35a02f34165db50420c836e0ee7ab2199f5e2adc5223146ba1560e6767867c1b1b7b1534e07
7
+ data.tar.gz: 1f61c800c0be84c0874807188774118ba332b57a92dca59b5116244131a9ebdd15cb505fbda2363da87c9662a00019db676f36f68bb21d2874f6a5b2db3e7875
data/README.md CHANGED
@@ -114,6 +114,67 @@ ApiSignature.setup do |config|
114
114
  end
115
115
  ```
116
116
 
117
+ ## Testing
118
+
119
+ In your `rails_helper.rb`:
120
+
121
+ ```ruby
122
+ require 'api_signature/spec_support/helper'
123
+
124
+ RSpec.configure do |config|
125
+ config.include ApiSignature::SpecSupport::Helper, type: :controller
126
+ end
127
+ ```
128
+
129
+ This will enable the following methods in controller tests:
130
+
131
+ * get_with_signature(client, action_name, params = {})
132
+ * post_with_signature(client, action_name, params = {})
133
+ * put_with_signature(client, action_name, params = {})
134
+ * patch_with_signature(client, action_name, params = {})
135
+ * delete_with_signature(client, action_name, params = {})
136
+
137
+ `client` object should respond to `#api_key` and `#api_secret`
138
+
139
+ Example usage:
140
+
141
+ ```ruby
142
+ RSpec.describe Api::V1::OrdersController do
143
+ let(:client) { FactoryBot.create(:client) }
144
+ # or any object, that responds to #api_key and #api_secret
145
+ # let(:client) { OpenStruct.new(api_key: 'some_key', api_secret: 'some_api_secret') }
146
+
147
+ it 'should filter orders by state' do
148
+ get_with_signature client, :index, state: :paid
149
+
150
+ expect(last_response.status).to eq 200
151
+ expect(last_response.body).to have_node(:orders)
152
+ expect(last_response.body).to have_node(:state).with('paid')
153
+ end
154
+
155
+ let(:order_attributes) { FactoryBot.attributes_for(:order) }
156
+
157
+ it 'should create new order' do
158
+ post_with_signature client, :create, order: order_attributes
159
+ end
160
+ end
161
+ ```
162
+
163
+ For nested resources path can be specified explicitly using `path` parameter:
164
+
165
+ ```ruby
166
+ # path: /api/v1/orders/:order_id/comments
167
+
168
+ RSpec.describe Api::V1::CommentsController do
169
+ let(:client) { OpenStruct.new(api_key: 'some_key', api_secret: 'some_api_secret') }
170
+ let(:order) { FactoryBot.create(:order) }
171
+
172
+ it 'should update comment for order' do
173
+ put_with_signature client, :update, path: { order_id: order.id }, comment: { content: 'Some value' }
174
+ end
175
+ end
176
+ ```
177
+
117
178
  ## Development
118
179
 
119
180
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -28,5 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency 'rspec', '~> 3.0'
29
29
 
30
30
  spec.add_dependency 'activesupport', '>= 4.0'
31
- spec.add_dependency 'rack', '~> 2.0', '>= 2.0.5'
31
+ spec.add_dependency 'rack', '>= 2.0'
32
32
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApiSignature
4
+ module SpecSupport
5
+ class HeadersBuilder
6
+ attr_reader :access_key, :secret, :http_method, :path
7
+
8
+ def initialize(access_key, secret, http_method, path)
9
+ @access_key = access_key
10
+ @secret = secret
11
+ @http_method = http_method
12
+ @path = path
13
+ end
14
+
15
+ def headers
16
+ {
17
+ 'HTTP_X_ACCESS_KEY' => access_key,
18
+ 'HTTP_X_TIMESTAMP' => options[:timestamp],
19
+ 'HTTP_X_SIGNATURE' => generator.generate_signature(secret)
20
+ }
21
+ end
22
+
23
+ private
24
+
25
+ def generator
26
+ @generator ||= ::ApiSignature::Generator.new(options)
27
+ end
28
+
29
+ def options
30
+ @options ||= {
31
+ request_method: http_method.to_s.upcase,
32
+ path: path,
33
+ access_key: access_key,
34
+ timestamp: Time.zone.now.to_i
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'api_signature/spec_support/path_builder'
4
+ require 'api_signature/spec_support/headers_builder'
5
+
6
+ module ApiSignature
7
+ module SpecSupport
8
+ module Helper
9
+ include Rack::Test::Methods
10
+
11
+ def app
12
+ Rails.app_class
13
+ end
14
+
15
+ def get_with_signature(client, *args)
16
+ with_signature(:get, client.api_key, client.api_secret, *args)
17
+ end
18
+
19
+ def post_with_signature(client, *args)
20
+ with_signature(:post, client.api_key, client.api_secret, *args)
21
+ end
22
+
23
+ def put_with_signature(client, *args)
24
+ with_signature(:put, client.api_key, client.api_secret, *args)
25
+ end
26
+
27
+ alias patch_with_signature put_with_signature
28
+
29
+ def delete_with_signature(client, *args)
30
+ with_signature(:delete, client.api_key, client.api_secret, *args)
31
+ end
32
+
33
+ private
34
+
35
+ def with_signature(http_method, api_key, secret, action_name, params = {})
36
+ path = PathBuilder.new(controller, action_name, params).path
37
+ headers = HeadersBuilder.new(api_key, secret, http_method, path).headers
38
+
39
+ send(http_method, path, params, headers)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApiSignature
4
+ module SpecSupport
5
+ class PathBuilder
6
+ attr_reader :controller, :action_name, :params
7
+
8
+ PRIMARY_KEYS = [:id, :token].freeze
9
+
10
+ def initialize(controller, action_name, params = {})
11
+ @controller = controller
12
+ @action_name = action_name
13
+ @params = params
14
+ end
15
+
16
+ def path
17
+ if params[:path].present?
18
+ hash = params.delete(:path)
19
+ url_options.merge!(hash)
20
+ params.merge!(hash)
21
+ end
22
+
23
+ controller.url_for(url_options)
24
+ end
25
+
26
+ private
27
+
28
+ def url_options
29
+ @url_options ||= {
30
+ action: action_name,
31
+ controller: controller.controller_path,
32
+ only_path: true
33
+ }.merge(key_options || {})
34
+ end
35
+
36
+ def key_options
37
+ key = (params.keys.map(&:to_sym) & PRIMARY_KEYS).first
38
+ { key => params[key] } if params[key].present?
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApiSignature
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_signature
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Galeta
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-06-22 00:00:00.000000000 Z
12
+ date: 2018-06-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -105,22 +105,16 @@ dependencies:
105
105
  name: rack
106
106
  requirement: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '2.0'
111
108
  - - ">="
112
109
  - !ruby/object:Gem::Version
113
- version: 2.0.5
110
+ version: '2.0'
114
111
  type: :runtime
115
112
  prerelease: false
116
113
  version_requirements: !ruby/object:Gem::Requirement
117
114
  requirements:
118
- - - "~>"
119
- - !ruby/object:Gem::Version
120
- version: '2.0'
121
115
  - - ">="
122
116
  - !ruby/object:Gem::Version
123
- version: 2.0.5
117
+ version: '2.0'
124
118
  description:
125
119
  email:
126
120
  - igor.malinovskiy@netfix.xyz
@@ -144,6 +138,9 @@ files:
144
138
  - lib/api_signature/builder.rb
145
139
  - lib/api_signature/generator.rb
146
140
  - lib/api_signature/request.rb
141
+ - lib/api_signature/spec_support/headers_builder.rb
142
+ - lib/api_signature/spec_support/helper.rb
143
+ - lib/api_signature/spec_support/path_builder.rb
147
144
  - lib/api_signature/validator.rb
148
145
  - lib/api_signature/version.rb
149
146
  homepage: https://github.com/psyipm/api_signature
@@ -166,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
163
  version: '0'
167
164
  requirements: []
168
165
  rubyforge_project:
169
- rubygems_version: 2.5.2
166
+ rubygems_version: 2.6.14.1
170
167
  signing_key:
171
168
  specification_version: 4
172
169
  summary: Sign API requests with HMAC signature