basic_api_auth 1.0.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 +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +38 -0
- data/Rakefile +1 -0
- data/basic_api_auth.gemspec +27 -0
- data/lib/basic_api_auth.rb +28 -0
- data/lib/basic_api_auth/railtie.rb +9 -0
- data/lib/basic_api_auth/version.rb +3 -0
- data/lib/hashkey_generator.rb +26 -0
- data/spec/lib/basic_api_auth_spec.rb +28 -0
- data/spec/lib/hashkey_generator_spec.rb +31 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/factories.rb +6 -0
- metadata +147 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c2f5c819cc5ce307afaf1537c08808d57574318b
|
4
|
+
data.tar.gz: 6ea12981c89456c47e5dd086929db7128bb359a2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d39a71f5775fc97ee72321c5df225b09c1efd074a63f4871711132b409909939280d87c5854cd2d432944202c378f0e18e3439646b0ea2232edbbeecf25bdc5c
|
7
|
+
data.tar.gz: 17ec5e84914e841bc463469e2270d51488c9bc74983865d62d526ea6c611140cb712a85637f0a9afebe22bd399fe74bf04df910615417f803eaedf7ac207d790
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Gautam Naroji
|
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,38 @@
|
|
1
|
+
# BasicApiAuth
|
2
|
+
A basic SHA1 hashkey based authentication implementation.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Add this line to your application's Gemfile:
|
7
|
+
|
8
|
+
gem 'basic_api_auth'
|
9
|
+
|
10
|
+
And then execute:
|
11
|
+
|
12
|
+
$ bundle
|
13
|
+
|
14
|
+
Or install it yourself as:
|
15
|
+
|
16
|
+
$ gem install basic_api_auth
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
create a yml file with an authentication key as follows:
|
21
|
+
in config/basic_api_auth_key.yml
|
22
|
+
api_key: 'API-KEY-HERE'
|
23
|
+
|
24
|
+
## Generation of Hashkey
|
25
|
+
The hashkey sent to the api call should be generated by following these steps
|
26
|
+
1. Order all the parameters of the cal in alphabetic order of its keys
|
27
|
+
2. Convert them into a string representation such that, if the hash is of type {name: 'snarf'} then its string representation would be "name=snarf"
|
28
|
+
3. Append the api key given to you to the string after adding a "&" so the resulting string will become "name=snarf&API-KEY-HERE"
|
29
|
+
4. Use SHA1 to generate a hashkey from the resulting string
|
30
|
+
5. Append the generated hashkey as a paramter of the API call
|
31
|
+
|
32
|
+
## Contributing
|
33
|
+
|
34
|
+
1. Fork it ( http://github.com/<my-github-username>/basic_api_auth/fork )
|
35
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
36
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
37
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
38
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'basic_api_auth/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "basic_api_auth"
|
8
|
+
spec.version = BasicApiAuth::VERSION
|
9
|
+
spec.authors = ["Gautam Naroji"]
|
10
|
+
spec.email = ["gautam@appyantra.com"]
|
11
|
+
spec.summary = %q{Basic authentication for simple API implementations}
|
12
|
+
spec.description = %q{SHA1 Hashkey based authentication for simple API engine}
|
13
|
+
spec.homepage = ""
|
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_dependency "rack"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "json"
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "basic_api_auth/version"
|
2
|
+
require "hashkey_generator"
|
3
|
+
require 'basic_api_auth/railtie' if defined?(Rails)
|
4
|
+
|
5
|
+
module BasicApiAuth
|
6
|
+
class Middleware
|
7
|
+
include HashkeyGenerator
|
8
|
+
@@authenticity_error = [401, {"Content-Type" => "text/plain"}, ['{ "message": "Authentication Failed" }']]
|
9
|
+
@@hashkey_requirement_error = [401, {"Content-Type" => "text/plain"}, ['{ "message": "Hashkey is required for authentication" }']]
|
10
|
+
|
11
|
+
def initialize(app, api_key)
|
12
|
+
@app = app
|
13
|
+
@api_key = api_key
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
@params = Rack::Request.new(env).params
|
18
|
+
@hashkey = @params.delete('hashkey')
|
19
|
+
return @@hashkey_requirement_error unless @hashkey
|
20
|
+
return @@authenticity_error unless authenticate_hashkey
|
21
|
+
@app.call(env)
|
22
|
+
end
|
23
|
+
|
24
|
+
def authenticate_hashkey
|
25
|
+
@hashkey == generate_hashkey_for(@params, @api_key)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module BasicApiAuth
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
initializer "basic_api_auth_railtie.configure_rails_initialization" do |config|
|
4
|
+
api_key = YAML.load_file("#{Rails.root}/config/basic_api_auth_key.yml")["api_key"].to_s
|
5
|
+
config.middleware.use BasicApiAuth::Middleware, api_key
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module HashkeyGenerator
|
4
|
+
# create a string representation of passed hash, which can be encoded in a URL
|
5
|
+
def concat_params(params)
|
6
|
+
result = ""
|
7
|
+
return result if params.empty?
|
8
|
+
params.map{|key,val| result += "#{key}=#{val}&" unless val.nil? or val == ''}
|
9
|
+
result.chomp!('&')
|
10
|
+
end
|
11
|
+
|
12
|
+
# sort the parameters in alphabetical order of keys
|
13
|
+
def sort_params(params)
|
14
|
+
Hash[params.sort]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Generate a hashkey using SHA1 for a provided API key
|
18
|
+
# List of parameters
|
19
|
+
# *params : a list of parameters as a hash, that needs to be used for hashkey generation
|
20
|
+
# *api_key: a unique API key provided to you for authenticating the API calls
|
21
|
+
def generate_hashkey_for(params, api_key)
|
22
|
+
sorted_params = sort_params(params)
|
23
|
+
params_string = concat_params(sorted_params)
|
24
|
+
Digest::SHA1.hexdigest "#{params_string}&#{api_key}"
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
RSpec.describe BasicApiAuth, :type => :module do
|
2
|
+
let(:app) {
|
3
|
+
Rack::Builder.new do
|
4
|
+
use BasicApiAuth::Middleware, "snaf-test"
|
5
|
+
run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Testing Basic APi Auth!"]] }
|
6
|
+
end
|
7
|
+
}
|
8
|
+
|
9
|
+
describe BasicApiAuth::Middleware do
|
10
|
+
|
11
|
+
it "is successful if passed hashkey is correct" do
|
12
|
+
response = Rack::MockRequest.new(app).get('/api/snarf_test?hashkey=350d806c45699b4db9bdf0113505f0bac07526a6¶m_a=snarf')
|
13
|
+
response.status.should == 200
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns 401 if hashkey authentication fails" do
|
17
|
+
response = Rack::MockRequest.new(app).get('/api/test?hashkey=failedkey¶m_a=snarf')
|
18
|
+
response.status.should == 401
|
19
|
+
JSON.parse(response.body).should == { "message" => "Authentication Failed" }
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns 401 - hashkey required, if hashkey is not passed" do
|
23
|
+
response = Rack::MockRequest.new(app).get('/api/test?param_a=snarf')
|
24
|
+
response.status.should == 401
|
25
|
+
JSON.parse(response.body).should == { "message" => "Hashkey is required for authentication" }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
RSpec.describe HashkeyGenerator, :type => :module do
|
2
|
+
|
3
|
+
let(:generator_class) { class HashkeyGeneratorTest; extend HashkeyGenerator; end }
|
4
|
+
|
5
|
+
context "#concat_params" do
|
6
|
+
let(:params) { { operation: :add, operand_a: 1, operand_b: 2 } }
|
7
|
+
let(:expectation) { "operation=add&operand_a=1&operand_b=2" }
|
8
|
+
|
9
|
+
it "can concat a hash parameters into a string representation" do
|
10
|
+
expect(generator_class.concat_params(params)).to eq expectation
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns empty string is empty params hash ispassed" do
|
14
|
+
expect(generator_class.concat_params({})).to eq ""
|
15
|
+
end
|
16
|
+
|
17
|
+
it "omits hash key-pairs that have empty or nil values" do
|
18
|
+
expect(generator_class.concat_params({a: nil, b: '', c: 12})).to eq "c=12"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "#sort_params" do
|
23
|
+
let(:params) { { operation: :add, operand_a: 1, operand_b: 2 } }
|
24
|
+
let(:expectation) { { operand_a: 1, operand_b: 2, operation: :add } }
|
25
|
+
|
26
|
+
it "sorts a hash in alphabetical order of its keys" do
|
27
|
+
expect(generator_class.sort_params(params)).to eq expectation
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rack/mock'
|
2
|
+
require 'json'
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
Dir[File.expand_path("../../lib/*.rb", __FILE__)].each { |f| require f }
|
6
|
+
Dir[File.expand_path("../support/*.rb", __FILE__)].each { |f| require f }
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.mock_with :rspec
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: basic_api_auth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gautam Naroji
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: json
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: SHA1 Hashkey based authentication for simple API engine
|
98
|
+
email:
|
99
|
+
- gautam@appyantra.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- .rspec
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- basic_api_auth.gemspec
|
111
|
+
- lib/basic_api_auth.rb
|
112
|
+
- lib/basic_api_auth/railtie.rb
|
113
|
+
- lib/basic_api_auth/version.rb
|
114
|
+
- lib/hashkey_generator.rb
|
115
|
+
- spec/lib/basic_api_auth_spec.rb
|
116
|
+
- spec/lib/hashkey_generator_spec.rb
|
117
|
+
- spec/spec_helper.rb
|
118
|
+
- spec/support/factories.rb
|
119
|
+
homepage: ''
|
120
|
+
licenses:
|
121
|
+
- MIT
|
122
|
+
metadata: {}
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 2.2.2
|
140
|
+
signing_key:
|
141
|
+
specification_version: 4
|
142
|
+
summary: Basic authentication for simple API implementations
|
143
|
+
test_files:
|
144
|
+
- spec/lib/basic_api_auth_spec.rb
|
145
|
+
- spec/lib/hashkey_generator_spec.rb
|
146
|
+
- spec/spec_helper.rb
|
147
|
+
- spec/support/factories.rb
|