api_authenticator 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -0,0 +1,8 @@
1
+ nguage: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - 2.1.1
7
+ - 2.1.5
8
+ - jruby-19mode
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in api_authenticator.gemspec
4
+ gemspec
@@ -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.
@@ -0,0 +1,123 @@
1
+ # ApiAuthenticator
2
+
3
+ [![Code Climate](https://codeclimate.com/github/Spokeo/api_authenticator/badges/gpa.svg)](https://codeclimate.com/github/Spokeo/api_authenticator)
4
+ [![Build Status](https://travis-ci.org/Spokeo/api_authenticator.svg)](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
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+ task :default => :spec
6
+ task :test => :spec
7
+
@@ -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,3 @@
1
+ module ApiAuthenticator
2
+ VERSION = "0.2.1"
3
+ 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
@@ -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
@@ -0,0 +1,8 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+ require 'api_authenticator'
4
+ require 'digest'
5
+
6
+ RSpec.configure do |config|
7
+ end
8
+
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