api_authenticator 0.2.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 +7 -0
- data/.gitignore +22 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +123 -0
- data/Rakefile +7 -0
- data/api_authenticator.gemspec +25 -0
- data/lib/api_authenticator.rb +10 -0
- data/lib/api_authenticator/api_authenticator.rb +25 -0
- data/lib/api_authenticator/authenticated_request.rb +48 -0
- data/lib/api_authenticator/configuration.rb +35 -0
- data/lib/api_authenticator/errors.rb +36 -0
- data/lib/api_authenticator/version.rb +3 -0
- data/spec/api_authenticator_spec.rb +73 -0
- data/spec/authenticator_concern_spec.rb +69 -0
- data/spec/errors_spec.rb +17 -0
- data/spec/spec_helper.rb +8 -0
- metadata +121 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 321edb7c0d50d3e4b73771824e994e2a049242e80ec36edf5e7ab97ea64fb8fd
|
4
|
+
data.tar.gz: b3f867b93a93fb9295c3cbe28b04d46ccf809b0099a1fd96cd9eac5b343ec8f8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 887bc481a0eac05ca8527d7fd7e9ee7a0890f8f1907f05ef43727a1d7af7d61968d48c6eb22e59a24ddfee841be12a9369b436d03a90bb49ac7102cd17b9e211
|
7
|
+
data.tar.gz: 4e1b13ca8e25a1b986ad13868802ae04da105be95baa2914fbd53af98c6e1f2552b89ab2c85dcf15ae034dde5b25cf84921b3ea7084b1ce51905ad69fecfcb3e
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Austin Fonacier
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
# ApiAuthenticator
|
2
|
+
|
3
|
+
[](https://codeclimate.com/github/Spokeo/api_authenticator)
|
4
|
+
[](https://travis-ci.org/Spokeo/api_authenticator)
|
5
|
+
|
6
|
+
This gem will authenticate API requests using a slightly modified version HMAC-SHA1
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'api_authenticator'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install api_authenticator
|
21
|
+
|
22
|
+
## Authentication
|
23
|
+
|
24
|
+
This gem assumes headers being pass into the request.
|
25
|
+
The two headers are:
|
26
|
+
- API-Time
|
27
|
+
- API-Token
|
28
|
+
|
29
|
+
### API-Time
|
30
|
+
The API-Time is a String UTC representation of the current time of request.
|
31
|
+
|
32
|
+
For example:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
=> "2014-10-16 18:55:48 UTC"
|
36
|
+
```
|
37
|
+
|
38
|
+
### API-Token
|
39
|
+
The token passed in is a SHA256 of the time AND the request URL. The shared_secret_key is used as the encyrption key.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
digest = OpenSSL::Digest.new('sha256')
|
43
|
+
|
44
|
+
env['API-Token'] = OpenSSL::HMAC.hexdigest(digest, shared_secret_key, "#{DateTime.now.new_offset(0)}#{request.original_url}")
|
45
|
+
```
|
46
|
+
|
47
|
+
|
48
|
+
## Configuration
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
ApiAuthenticator.configure do |config|
|
52
|
+
config.shared_secret_keys = ["my_shared_token", "my_shared_token2"]
|
53
|
+
config.time_threshold = 2.hours
|
54
|
+
config.logger = Rails.logger
|
55
|
+
config.report_unauthenticated_requests = true
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
- shared_secret_keys: An Array of approved shared secret keys between the client and the server.
|
60
|
+
- time_threshold: The time threshold to allow requests. So for example the entry above will only allow requests from 2 hours before now and 2 hours in the future.
|
61
|
+
- logger: Your logger
|
62
|
+
- report_unauthenticated_requests: will throw some basic information into your logger.warn.
|
63
|
+
|
64
|
+
## Usage
|
65
|
+
There is a before_filter that is included in the gem. If not authenticated it will automatically render a status 401.
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
class ApiController
|
69
|
+
include ApiAuthenticator
|
70
|
+
|
71
|
+
before_filter :api_authenticator
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
Or you can use it without the before_filter.
|
76
|
+
Note here is that right now, if the request is not authenticated the gem with throw an exception. All exceptions inherit from ApiAuthentiactor::BaseError
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
class ApiController
|
80
|
+
def people
|
81
|
+
# Takes a Rails request object
|
82
|
+
begin
|
83
|
+
ApiAuthentiactor.authenticated_request?(request)
|
84
|
+
rescue ApiAuthenticator::InvalidTimeError => e
|
85
|
+
logger.error(e)
|
86
|
+
rescue ApiAuthenticator::InvalidTokenError => e
|
87
|
+
logger.error(e)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
|
94
|
+
## TODO:
|
95
|
+
- Set time intervals instead of explicity passing in the time.
|
96
|
+
|
97
|
+
## Running The Specs
|
98
|
+
|
99
|
+
Just run rake:
|
100
|
+
```
|
101
|
+
rake
|
102
|
+
```
|
103
|
+
|
104
|
+
## Upggrading from 0.1.0 to 0.2.0
|
105
|
+
|
106
|
+
The big change here is ApiAuthenticator now takes a list of shared secret keys. So where there was
|
107
|
+
```ruby
|
108
|
+
ApiAuthenticator.shared_secret_key = 'key1'
|
109
|
+
```
|
110
|
+
|
111
|
+
it now takes an array
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
ApiAuthenticator.shared_secret_keys = ['key1', 'key2']
|
115
|
+
```
|
116
|
+
|
117
|
+
## Contributing
|
118
|
+
|
119
|
+
1. Fork it ( https://github.com/[my-github-username]/api_authenticator/fork )
|
120
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
121
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
122
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
123
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'api_authenticator/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "api_authenticator"
|
8
|
+
spec.version = ApiAuthenticator::VERSION
|
9
|
+
spec.authors = ["Austin Fonacier"]
|
10
|
+
spec.email = ["austinrf@gmail.com"]
|
11
|
+
spec.summary = "This gem will authenticate API requests using a modified HMAC-SHA1"
|
12
|
+
spec.description = "This gem will authenticate API requests using a modified HMAC-SHA1"
|
13
|
+
spec.homepage = "https://github.com/Spokeo/api_authenticator"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency 'rspec', '~> 3.3.0'
|
24
|
+
spec.add_dependency "activesupport"
|
25
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'api_authenticator/configuration'
|
3
|
+
require 'api_authenticator/errors'
|
4
|
+
require 'api_authenticator/authenticated_request'
|
5
|
+
require 'api_authenticator/api_authenticator' if defined?(ActiveSupport)
|
6
|
+
require "api_authenticator/version"
|
7
|
+
|
8
|
+
module ApiAuthenticator
|
9
|
+
# Your code goes here...
|
10
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/concern'
|
3
|
+
require 'digest'
|
4
|
+
|
5
|
+
module ApiAuthenticator
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
# Before filter
|
9
|
+
def api_authenticator
|
10
|
+
begin
|
11
|
+
ApiAuthenticator.authenticated_request?(request)
|
12
|
+
rescue BaseError => e
|
13
|
+
report_unauthenticated_requests(e)
|
14
|
+
render( status: 401, nothing: true ) and return false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
# TODO: more stuff in here
|
21
|
+
def report_unauthenticated_requests(e)
|
22
|
+
ApiAuthenticator.logger.warn("failed request #{e.constructed_message}")
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'active_support/security_utils' if defined?(ActiveSupport)
|
3
|
+
|
4
|
+
module ApiAuthenticator
|
5
|
+
# authenticated_request?
|
6
|
+
#
|
7
|
+
# Returns: True or False
|
8
|
+
def self.authenticated_request?(request)
|
9
|
+
time = nil
|
10
|
+
token = request.headers['API-Token']
|
11
|
+
begin
|
12
|
+
time = DateTime.parse(request.headers['API-Time'])
|
13
|
+
rescue ArgumentError, TypeError
|
14
|
+
end
|
15
|
+
valid_api_time?(time)
|
16
|
+
valid_api_token?(request.original_url, time, token)
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def self.valid_api_time?(time)
|
22
|
+
return false if time.nil?
|
23
|
+
utc_now = DateTime.now.new_offset(0)
|
24
|
+
|
25
|
+
lower_threshold = utc_now - time_threshold
|
26
|
+
upper_threshold = utc_now + time_threshold
|
27
|
+
|
28
|
+
if time < lower_threshold || time > upper_threshold
|
29
|
+
raise InvalidTimeError.new(upper_threshold, lower_threshold, time)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.valid_api_token?(request_url, time, token)
|
34
|
+
digest = OpenSSL::Digest.new('sha256')
|
35
|
+
keys_and_tokens = []
|
36
|
+
shared_secret_keys.each do |secret_key|
|
37
|
+
expected_token = OpenSSL::HMAC.hexdigest(digest, secret_key, "#{time}#{request_url}")
|
38
|
+
if defined?(ActiveSupport)
|
39
|
+
return true if ActiveSupport::SecurityUtils.secure_compare(expected_token, token)
|
40
|
+
else
|
41
|
+
return true if expected_token == token
|
42
|
+
end
|
43
|
+
keys_and_tokens << [secret_key, token, expected_token]
|
44
|
+
end
|
45
|
+
|
46
|
+
raise InvalidTokenError.new(time, keys_and_tokens)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ApiAuthenticator
|
2
|
+
@@logger = nil
|
3
|
+
|
4
|
+
def self.configure
|
5
|
+
yield self
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.shared_secret_keys=(shared_secret_keys)
|
9
|
+
@@shared_secret_keys = shared_secret_keys
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.shared_secret_keys
|
13
|
+
@@shared_secret_keys
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.time_threshold=(time_threshold)
|
17
|
+
@@time_threshold = time_threshold
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.time_threshold
|
21
|
+
@@time_threshold
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.report_unauthenticated_requests=(report)
|
25
|
+
@@report_unauthenticated_requests = report || false
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.logger=(logger)
|
29
|
+
@@logger = logger || Logger.new($stdout)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.logger
|
33
|
+
@@logger || Logger.new($stdout)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ApiAuthenticator
|
2
|
+
class BaseError < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
class InvalidTimeError < BaseError
|
6
|
+
attr_reader :upper_threshold, :lower_threshold, :actual_time
|
7
|
+
|
8
|
+
def initialize(upper_threshold, lower_threshold, actual_time)
|
9
|
+
@upper_threshold = upper_threshold
|
10
|
+
@lower_threshold = lower_threshold
|
11
|
+
@actual_time = actual_time
|
12
|
+
end
|
13
|
+
|
14
|
+
def constructed_message
|
15
|
+
"Invalid Time Error: upper threshold: #{@upper_threshold} lower threshold: #{@lower_threshold} actual time: #{@actual_time}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class InvalidTokenError < BaseError
|
20
|
+
attr_reader :time, :keys_and_tokens
|
21
|
+
|
22
|
+
def initialize(time, keys_and_tokens)
|
23
|
+
@time = time
|
24
|
+
@keys_and_tokens = keys_and_tokens
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def constructed_message
|
29
|
+
message = ""
|
30
|
+
@keys_and_tokens.each do |key_and_token|
|
31
|
+
message << "Invalid Token Error Time: #{@time} Shared Key: #{key_and_token[0]} expected token: #{key_and_token[2]} actual token: #{key_and_token[1]}"
|
32
|
+
end
|
33
|
+
message
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
describe 'ApiAuthenticator' do
|
5
|
+
let :shared_key do
|
6
|
+
'asdf'
|
7
|
+
end
|
8
|
+
|
9
|
+
let :shared_key2 do
|
10
|
+
'fork123'
|
11
|
+
end
|
12
|
+
|
13
|
+
let :api_token do
|
14
|
+
digest = OpenSSL::Digest.new('sha256')
|
15
|
+
OpenSSL::HMAC.hexdigest(digest, shared_key, "#{DateTime.now.new_offset(0)}http://www.austinrocks.com/asdf")
|
16
|
+
end
|
17
|
+
|
18
|
+
let :valid_request do
|
19
|
+
time = DateTime.now.utc
|
20
|
+
double(:request, original_url: "http://www.austinrocks.com/asdf", headers: {"API-Time" => time.to_s, "API-Token" => api_token})
|
21
|
+
end
|
22
|
+
|
23
|
+
let :api_token2 do
|
24
|
+
digest = OpenSSL::Digest.new('sha256')
|
25
|
+
OpenSSL::HMAC.hexdigest(digest, shared_key2, "#{DateTime.now.new_offset(0)}http://www.austinrocks.com/asdf")
|
26
|
+
end
|
27
|
+
|
28
|
+
let :valid_request_shared_key2 do
|
29
|
+
time = DateTime.now.utc
|
30
|
+
double(:request, original_url: "http://www.austinrocks.com/asdf", headers: {"API-Time" => time.to_s, "API-Token" => api_token})
|
31
|
+
end
|
32
|
+
|
33
|
+
let :bad_time_request do
|
34
|
+
time = 6.years.from_now
|
35
|
+
double(:request, original_url: "http://www.austinrocks.com/asdf", headers: {"API-Time" => time.to_s, "API-Token" => api_token})
|
36
|
+
end
|
37
|
+
|
38
|
+
let :bad_token_request do
|
39
|
+
time = Time.now.utc
|
40
|
+
double(:request, original_url: "http://www.austinrocks.com/asdf", headers: {"API-Time" => time.to_s, "API-Token" => "AUSTIN LIVES IN YO TESTS"})
|
41
|
+
end
|
42
|
+
|
43
|
+
context "authenticated_request?" do
|
44
|
+
before :each do
|
45
|
+
ApiAuthenticator.configure do |config|
|
46
|
+
config.time_threshold = 2.hours
|
47
|
+
config.shared_secret_keys = [shared_key, shared_key2]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'valid_request' do
|
52
|
+
it "should not throw an exception" do
|
53
|
+
expect{ApiAuthenticator.authenticated_request?(valid_request)}.to_not raise_error
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not throw an exception with shared_key2" do
|
57
|
+
expect{ApiAuthenticator.authenticated_request?(valid_request_shared_key2)}.to_not raise_error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'invalid time' do
|
62
|
+
it "should raise InvalidTimeError" do
|
63
|
+
expect{ApiAuthenticator.authenticated_request?(bad_time_request)}.to raise_error(ApiAuthenticator::InvalidTimeError)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'bad api token' do
|
68
|
+
it "should raise InvalidTokenError" do
|
69
|
+
expect{ApiAuthenticator.authenticated_request?(bad_token_request)}.to raise_error(ApiAuthenticator::InvalidTokenError)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class TesterTemper
|
4
|
+
include ApiAuthenticator
|
5
|
+
|
6
|
+
attr_reader :request
|
7
|
+
|
8
|
+
def initialize(request)
|
9
|
+
@request = request
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "ApiAuthenticator Concern" do
|
14
|
+
before :each do
|
15
|
+
ApiAuthenticator.configure do |config|
|
16
|
+
config.time_threshold = 2.hours
|
17
|
+
config.shared_secret_keys = [shared_key]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
let :shared_key do
|
22
|
+
'asdf'
|
23
|
+
end
|
24
|
+
|
25
|
+
let :bad_time_request do
|
26
|
+
time = 6.years.from_now
|
27
|
+
double(:request, original_url: "http://www.austinrocks.com/asdf", headers: {"API-Time" => time.to_s, "API-Token" => Digest::SHA1.hexdigest("#{time}#{shared_key}")})
|
28
|
+
end
|
29
|
+
|
30
|
+
let :bad_token_request do
|
31
|
+
time = Time.now.utc
|
32
|
+
double(:request, original_url: "http://www.austinrocks.com/asdf", headers: {"API-Time" => time.to_s, "API-Token" => "AUSTIN LIVES IN YO TESTS"})
|
33
|
+
end
|
34
|
+
let :api_token do
|
35
|
+
digest = OpenSSL::Digest.new('sha256')
|
36
|
+
OpenSSL::HMAC.hexdigest(digest, shared_key, "#{DateTime.now.new_offset(0)}http://www.austinrocks.com/asdf")
|
37
|
+
end
|
38
|
+
|
39
|
+
let :valid_request do
|
40
|
+
time = DateTime.now.utc
|
41
|
+
double(:request, original_url: "http://www.austinrocks.com/asdf", headers: {"API-Time" => time.to_s, "API-Token" => api_token})
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "api_authenticator" do
|
45
|
+
context 'successful requests' do
|
46
|
+
it "should not return false if authenticated_request" do
|
47
|
+
temp_class = TesterTemper.new(valid_request)
|
48
|
+
# expect(temp_class).to receive(:render) { }
|
49
|
+
expect(temp_class.api_authenticator).to be_truthy
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'invalid token requests' do
|
54
|
+
it "should return false and render" do
|
55
|
+
temp_class = TesterTemper.new(bad_token_request)
|
56
|
+
expect(temp_class).to receive(:render) { }
|
57
|
+
expect(temp_class.api_authenticator).to be_falsey
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'invalid time requests' do
|
62
|
+
it "should return false and render" do
|
63
|
+
temp_class = TesterTemper.new(bad_time_request)
|
64
|
+
expect(temp_class).to receive(:render) { }
|
65
|
+
expect(temp_class.api_authenticator).to be_falsey
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/spec/errors_spec.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
describe 'ApiAuthenticator::Errors' do
|
5
|
+
describe "InvalidTokenError" do
|
6
|
+
it "should have a constructed_message" do
|
7
|
+
error = ApiAuthenticator::InvalidTokenError.new(DateTime.now.utc, [[DateTime.now.utc, 'foobar', 'yolo']])
|
8
|
+
expect(error.constructed_message).to match(/Invalid\sToken\sError/)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
describe "InvalidTimeError" do
|
12
|
+
it "should have a constructed_message" do
|
13
|
+
error = ApiAuthenticator::InvalidTimeError.new(DateTime.now.utc, DateTime.now.utc, DateTime.now.utc)
|
14
|
+
expect(error.constructed_message).to match(/Invalid\sTime\sError/)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: api_authenticator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Austin Fonacier
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-07-12 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.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '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.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.3.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: This gem will authenticate API requests using a modified HMAC-SHA1
|
70
|
+
email:
|
71
|
+
- austinrf@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- api_authenticator.gemspec
|
83
|
+
- lib/api_authenticator.rb
|
84
|
+
- lib/api_authenticator/api_authenticator.rb
|
85
|
+
- lib/api_authenticator/authenticated_request.rb
|
86
|
+
- lib/api_authenticator/configuration.rb
|
87
|
+
- lib/api_authenticator/errors.rb
|
88
|
+
- lib/api_authenticator/version.rb
|
89
|
+
- spec/api_authenticator_spec.rb
|
90
|
+
- spec/authenticator_concern_spec.rb
|
91
|
+
- spec/errors_spec.rb
|
92
|
+
- spec/spec_helper.rb
|
93
|
+
homepage: https://github.com/Spokeo/api_authenticator
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.7.3
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: This gem will authenticate API requests using a modified HMAC-SHA1
|
117
|
+
test_files:
|
118
|
+
- spec/api_authenticator_spec.rb
|
119
|
+
- spec/authenticator_concern_spec.rb
|
120
|
+
- spec/errors_spec.rb
|
121
|
+
- spec/spec_helper.rb
|