api_signature 0.1.0 → 0.1.1
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 +4 -4
- data/README.md +61 -0
- data/api_signature.gemspec +1 -1
- data/lib/api_signature/spec_support/headers_builder.rb +39 -0
- data/lib/api_signature/spec_support/helper.rb +43 -0
- data/lib/api_signature/spec_support/path_builder.rb +42 -0
- data/lib/api_signature/version.rb +1 -1
- metadata +8 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b3f7f58448cc08c412e475bd5967b8af6cfb972
|
4
|
+
data.tar.gz: 13783e19a83c42cdbc744036a44065f6deb7a56c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
data/api_signature.gemspec
CHANGED
@@ -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
|
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.
|
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-
|
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
|
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
|
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.
|
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
|