moguera-authentication 0.0.1 → 0.1.0

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: fc3dfe649673b10bebc29e516c4ce648b1dd04e1
4
- data.tar.gz: 790de69338563c94b9a52eacef08b7c1d60297c1
3
+ metadata.gz: 4a415434847e3c2da2b68fb069c7d8f16c809c12
4
+ data.tar.gz: e2e77493353453c4dfa7e75a6a5fbebdb8a1624e
5
5
  SHA512:
6
- metadata.gz: c3c1a8c8013d6e34740591ca912bb9bbdb8d72089f846b882d9b9dff569a94f6660c82c222a8471b0d3cebffe865a8d7bedbf14862b426a991175d60b0602416
7
- data.tar.gz: ecc22756a412c60b51b0885f4e2a12c6bd43ea065da697b5baa320b730c211c338aea75a88d525ccfd3927854767667809cdcc4c6728f34e39e8261bdf5d0275
6
+ metadata.gz: c84d5bb23da6f68959d0b287837933a707a518cc28da365f5f72ed9f50d7694fef8d1b86b7d956d95b9f3f2c1f96d21384163027a7732613daae72df8a3f8b67
7
+ data.tar.gz: 5a042e0029fe21897f1b7094dec81dbc9a12f355263a312476b79b23bc70161e342bbddd1055548f11bceaedc4c417899ef90c4a324f2d6887d184628d0dddc8
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.5
3
+ - 2.1
4
4
  gemfile:
5
5
  - Gemfile
6
6
  script:
data/Gemfile CHANGED
@@ -10,6 +10,7 @@ group :test do
10
10
  gem 'simplecov'
11
11
  gem 'simplecov-rcov'
12
12
  gem 'coveralls'
13
+ gem 'rack-test'
13
14
  end
14
15
 
15
16
  group :development do
data/README.md CHANGED
@@ -5,6 +5,9 @@ Simple REST API Authentication.
5
5
  [![Build Status](https://travis-ci.org/moguera/moguera-authentication.svg)](https://travis-ci.org/moguera/moguera-authentication)
6
6
  [![Coverage Status](https://coveralls.io/repos/moguera/moguera-authentication/badge.png?branch=master)](https://coveralls.io/r/moguera/moguera-authentication?branch=master)
7
7
 
8
+ ## Requirements
9
+
10
+ Ruby 2.1+
8
11
 
9
12
  ## Installation
10
13
 
@@ -48,45 +51,73 @@ Server check
48
51
  ## Usage
49
52
 
50
53
  ### Server
51
- sinatra sample
54
+ A Rack middleware inserts a Moguera Authentication.
55
+
56
+ example config.ru
52
57
 
53
58
  ```ruby
54
- require 'sinatra'
55
- require 'moguera/authentication'
59
+ require 'rack/moguera_authentication'
60
+ require 'server'
61
+ require 'json'
62
+
63
+ map '/' do
64
+ run Public
65
+ end
66
+
67
+ map '/login' do
68
+ # Add Rack::MogueraAuthentication somewhere in your rack stack
69
+ use Rack::MogueraAuthentication do |request_access_key|
70
+
71
+ # Search a secret_access_key by a request_access_key
72
+ # # example credential.json
73
+ # #=> {"user01":"secret"}
74
+ file = File.join(File.expand_path(File.dirname(__FILE__)),'credential.json')
75
+ user = JSON.parse(File.open(file, &:read))
76
+ user[key]
77
+ end
78
+
79
+ run Private
80
+ end
81
+ ```
82
+
83
+ example server.rb
84
+
85
+ ```ruby
86
+ require 'sinatra/base'
87
+
88
+ class Public < Sinatra::Base
89
+ post '/hello' do
90
+ [200, {"Content-Type"=>"text/plain"}, ["Hello World!"]]
91
+ end
92
+ end
56
93
 
57
- post '/login' do
58
- begin
59
- request_token = Moguera::Authentication.new(request.env['HTTP_AUTHORIZATION'])
60
- user = request_token.authenticate! do |key|
61
- key_to_secret = 'secret'
62
-
63
- Moguera::Authentication::Request.new(
64
- access_key: key,
65
- secret_access_key: key_to_secret,
66
- request_path: request.env['REQUEST_PATH'],
67
- content_type: request.content_type,
68
- http_date: request.env['HTTP_DATE'],
69
- request_method: request.request_method
70
- )
94
+ class Private < Sinatra::Base
95
+ post '/hello' do
96
+ validate_user!
97
+ [200, {"Content-Type"=>"text/plain"}, ["Hello #{env['moguera.user'].access_key}!"]]
98
+ end
99
+
100
+ private
101
+
102
+ def validate_user!
103
+ if e = env['moguera.error']
104
+ $stderr.puts e.message
105
+ case e
106
+ when Moguera::Authentication::ParameterInvalid
107
+ halt 400, "400 Bad Request: #{e.message}\n"
108
+ when Moguera::Authentication::AuthenticationError
109
+ halt 401, "401 Unauthorized: #{e.message}\n"
110
+ else
111
+ halt 500, "500 Internal Server Error\n"
112
+ end
71
113
  end
72
- return user.access_key
73
- rescue Moguera::Authentication::ParameterInvalid => e
74
- halt 400, "400 Bad Request: #{e.message}\n"
75
- rescue Moguera::Authentication::AuthenticationError => e
76
- params = %w(
77
- token access_key secret_access_key http_date
78
- request_method request_path content_type
79
- )
80
- msg = ["request_tooken: #{e.request_token}"]
81
- msg << params.map {|k| "server_#{k}: #{e.server_request.send(k)}" }
82
- logger.error msg * "\n"
83
- halt 401, "401 Unauthorized: #{e.message}\n"
84
114
  end
85
115
  end
86
116
  ```
87
117
 
88
118
  ### Cilent
89
- rest-client sample
119
+
120
+ example rest-client
90
121
 
91
122
  ```ruby
92
123
  require 'moguera/authentication'
@@ -99,18 +130,20 @@ url = ARGV[0]
99
130
  abort "Usage: ruby #{__FILE__} http://localhost:4567/login" unless url
100
131
 
101
132
  request_path = URI.parse(url).path
102
- request_method = 'POST'
133
+ request_path = '/' if request_path.empty?
103
134
  http_date = Time.now.httpdate
104
135
  content_type = 'application/json'
105
136
 
106
- request = Moguera::Authentication::Request.new(
107
- access_key: 'apikey',
137
+ params = {
138
+ access_key: 'user01',
108
139
  secret_access_key: 'secret',
109
140
  request_path: request_path,
110
- request_method: request_method,
111
- http_date: http_date,
112
- content_type: content_type
113
- )
141
+ request_method: 'POST',
142
+ content_type: content_type,
143
+ http_date: http_date
144
+ }
145
+
146
+ request = Moguera::Authentication::Request.new(params)
114
147
 
115
148
  headers = {
116
149
  Authorization: request.token,
@@ -118,17 +151,32 @@ headers = {
118
151
  Date: http_date
119
152
  }
120
153
 
121
- payload = { key: 'value' }.to_json
122
-
123
154
  begin
124
- res = RestClient.post(url, payload, headers)
125
- puts res.code
155
+ res = RestClient.post(url, {key:'value'}.to_json, headers)
126
156
  puts res.body
127
157
  rescue => e
128
- abort e.response
158
+ puts e.message
129
159
  end
130
160
  ```
131
161
 
162
+ ### Quick Run
163
+
164
+ server
165
+
166
+ ```
167
+ $ rackup sample/config.ru
168
+ ```
169
+
170
+ client
171
+
172
+ ```
173
+ $ sample/client.rb http://localhost:9292/hello
174
+ Hello World!
175
+
176
+ $ sample/client.rb http://localhost:9292/login/hello
177
+ Hello user01!
178
+ ```
179
+
132
180
  ## Contributing
133
181
 
134
182
  1. Fork it ( https://github.com/[my-github-username]/moguera-authentication/fork )
@@ -1,5 +1,5 @@
1
1
  module Moguera
2
2
  class Authentication
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -0,0 +1,50 @@
1
+ require 'moguera/authentication'
2
+
3
+ module Rack
4
+ # A Rack middleware inserts a Moguera Authentication.
5
+ #
6
+ # @example config.ru
7
+ # # Add Rack::MogueraAuthentication somewhere in your rack stack
8
+ # use Rack::MogueraAuthentication do |request_access_key|
9
+ #
10
+ # # Search a secret_access_key by a request_access_key
11
+ # key_to_secret(request_access_key)
12
+ # end
13
+ class MogueraAuthentication
14
+ def initialize(app, &block)
15
+ @app = app
16
+ @secret_block = block
17
+ end
18
+
19
+ def call(env)
20
+ begin
21
+ request_token = Moguera::Authentication.new(env['HTTP_AUTHORIZATION'])
22
+ user = request_token.authenticate! do |key|
23
+ secret = @secret_block.call(key)
24
+ params = build_parameter(key, secret, env)
25
+
26
+ Moguera::Authentication::Request.new(params)
27
+ end
28
+
29
+ env['moguera.user'] = user
30
+ rescue => e
31
+ env['moguera.error'] = e
32
+ end
33
+
34
+ @app.call(env)
35
+ end
36
+
37
+ private
38
+
39
+ def build_parameter(key, secret, env)
40
+ {
41
+ access_key: key,
42
+ secret_access_key: secret,
43
+ request_path: env['PATH_INFO'],
44
+ request_method: env['REQUEST_METHOD'],
45
+ content_type: env['CONTENT_TYPE'],
46
+ http_date: env['HTTP_DATE']
47
+ }
48
+ end
49
+ end
50
+ end
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.7"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "rspec", "~> 3.1.0"
24
+ spec.add_development_dependency "rack", "~> 1.5"
24
25
  end
data/sample/client.rb CHANGED
@@ -13,18 +13,20 @@ url = ARGV[0]
13
13
  abort "Usage: ruby #{__FILE__} http://localhost:4567/login" unless url
14
14
 
15
15
  request_path = URI.parse(url).path
16
- request_method = 'POST'
16
+ request_path = '/' if request_path.empty?
17
17
  http_date = Time.now.httpdate
18
18
  content_type = 'application/json'
19
19
 
20
- request = Moguera::Authentication::Request.new(
21
- access_key: 'apikey',
20
+ params = {
21
+ access_key: 'user01',
22
22
  secret_access_key: 'secret',
23
23
  request_path: request_path,
24
- request_method: request_method,
25
- http_date: http_date,
26
- content_type: content_type
27
- )
24
+ request_method: 'POST',
25
+ content_type: content_type,
26
+ http_date: http_date
27
+ }
28
+
29
+ request = Moguera::Authentication::Request.new(params)
28
30
 
29
31
  headers = {
30
32
  Authorization: request.token,
@@ -32,12 +34,9 @@ headers = {
32
34
  Date: http_date
33
35
  }
34
36
 
35
- payload = { key: 'value' }.to_json
36
-
37
37
  begin
38
- res = RestClient.post(url, payload, headers)
39
- puts res.code
38
+ res = RestClient.post(url, {key:'value'}.to_json, headers)
40
39
  puts res.body
41
40
  rescue => e
42
- abort e.response
41
+ puts e.response
43
42
  end
data/sample/config.ru ADDED
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), %w(.. lib)))
3
+
4
+ require 'rack/moguera_authentication'
5
+ require 'server'
6
+ require 'json'
7
+
8
+ map '/' do
9
+ run Public
10
+ end
11
+
12
+ map '/login' do
13
+ use Rack::MogueraAuthentication do |key|
14
+ file = File.join(File.expand_path(File.dirname(__FILE__)), 'credential.json')
15
+ user = JSON.parse(File.open(file, &:read))
16
+ user[key]
17
+ end
18
+
19
+ run Private
20
+ end
@@ -0,0 +1,3 @@
1
+ {
2
+ "user01": "secret"
3
+ }
data/sample/server.rb CHANGED
@@ -1,56 +1,30 @@
1
- #!/usr/bin/env ruby
2
- #
3
- $LOAD_PATH.unshift(File.dirname(__FILE__))
4
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), %w(.. lib)))
1
+ require 'sinatra/base'
5
2
 
6
- require 'sinatra'
7
- require 'moguera/authentication'
8
-
9
- post '/login' do
10
- begin
11
- request_token = Moguera::Authentication.new(request.env['HTTP_AUTHORIZATION'])
12
- user = request_token.authenticate! do |key|
13
- key_to_secret = 'secret'
14
-
15
- Moguera::Authentication::Request.new(
16
- access_key: key,
17
- secret_access_key: key_to_secret,
18
- request_path: request.env['REQUEST_PATH'],
19
- content_type: request.content_type,
20
- http_date: request.env['HTTP_DATE'],
21
- request_method: request.request_method
22
- )
23
- end
24
- return user.access_key
25
- rescue Moguera::Authentication::ParameterInvalid => e
26
- halt 400, "400 Bad Request: #{e.message}\n"
27
- rescue Moguera::Authentication::AuthenticationError => e
28
- params = %w(
29
- token access_key secret_access_key http_date
30
- request_method request_path content_type
31
- )
32
- msg = ["request_tooken: #{e.request_token}"]
33
- msg << params.map {|k| "server_#{k}: #{e.server_request.send(k)}" }
34
- logger.error msg * "\n"
35
- halt 401, "401 Unauthorized: #{e.message}\n"
3
+ class Public < Sinatra::Base
4
+ post '/hello' do
5
+ [200, {"Content-Type"=>"text/plain"}, ["Hello World!"]]
36
6
  end
37
7
  end
38
8
 
39
- post '/login2' do
40
- request_token = Moguera::Authentication.new(request.env['HTTP_AUTHORIZATION'])
41
- user = request_token.authenticate do |key|
42
- key_to_secret = 'secret'
9
+ class Private < Sinatra::Base
10
+ post '/hello' do
11
+ validate_user!
12
+ [200, {"Content-Type"=>"text/plain"}, ["Hello #{env['moguera.user'].access_key}!"]]
13
+ end
43
14
 
44
- Moguera::Authentication::Request.new(
45
- access_key: key,
46
- secret_access_key: key_to_secret,
47
- request_path: request.env['REQUEST_PATH'],
48
- content_type: request.content_type,
49
- http_date: request.env['HTTP_DATE'],
50
- request_method: request.request_method
51
- )
52
- end
15
+ private
53
16
 
54
- halt 401, "401 Unauthorized" unless user
55
- return user.access_key
17
+ def validate_user!
18
+ if e = env['moguera.error']
19
+ $stderr.puts e.message
20
+ case e
21
+ when Moguera::Authentication::ParameterInvalid
22
+ halt 400, "400 Bad Request: #{e.message}\n"
23
+ when Moguera::Authentication::AuthenticationError
24
+ halt 401, "401 Unauthorized: #{e.message}\n"
25
+ else
26
+ halt 500, "500 Internal Server Error\n"
27
+ end
28
+ end
29
+ end
56
30
  end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rack::MogueraAuthentication do
4
+ include_context "prepare_auth"
5
+
6
+ include TestApplicationHelper
7
+ include Rack::Test::Methods
8
+
9
+ let(:test_app) { TestApplicationHelper::TestApplication.new }
10
+ let(:header) {
11
+ {
12
+ 'HTTP_AUTHORIZATION' => request_token,
13
+ 'CONTENT_TYPE' => content_type,
14
+ 'HTTP_DATE' => http_date
15
+ }
16
+ }
17
+
18
+ describe "POST /path" do
19
+ let(:app) { Rack::MogueraAuthentication.new(test_app) { 'secret' } }
20
+
21
+ it 'should be return 200 OK' do
22
+ post request_path, {}, header
23
+
24
+ expect(last_response.status).to eq 200
25
+ expect(last_response.body).to eq 'test'
26
+
27
+ expect(last_request.env['moguera.user'].token).to eq request_token
28
+ expect(last_request.env['moguera.user'].token_prefix).to eq 'MOGUERA'
29
+ expect(last_request.env['moguera.user'].access_key).to eq access_key
30
+ expect(last_request.env['moguera.user'].secret_access_key).to eq secret_access_key
31
+ expect(last_request.env['moguera.user'].http_date).to eq http_date
32
+ expect(last_request.env['moguera.user'].request_method).to eq request_method
33
+ expect(last_request.env['moguera.user'].request_path).to eq request_path
34
+ expect(last_request.env['moguera.user'].content_type).to eq content_type
35
+
36
+ end
37
+
38
+ describe 'Invalid secret_access_key' do
39
+ let(:app) { Rack::MogueraAuthentication.new(test_app) { 'invalid' } }
40
+
41
+ it "should be exists AuthenticationError in env['moguera.error']" do
42
+ post request_path, {}, header
43
+
44
+ expect(last_response.status).to eq 200
45
+ expect(last_response.body).to eq 'test'
46
+
47
+ expect(last_request.env['moguera.error'].class).to eq Moguera::Authentication::AuthenticationError
48
+ expect(last_request.env['moguera.error'].message).to eq 'Mismatch token.'
49
+ expect(last_request.env['moguera.error'].request_token).to eq request_token
50
+ expect(last_request.env['moguera.error'].server_request.access_key).to eq access_key
51
+ expect(last_request.env['moguera.error'].server_request.secret_access_key).to eq 'invalid'
52
+ end
53
+ end
54
+
55
+ describe 'Invalid header parameter' do
56
+ let(:app) { Rack::MogueraAuthentication.new(test_app) { 'invalid' } }
57
+
58
+ it "should be exists ParameterInvalid in env['moguera.error']" do
59
+ header.delete('HTTP_DATE')
60
+ post request_path, {}, header
61
+
62
+ expect(last_response.status).to eq 200
63
+ expect(last_response.body).to eq 'test'
64
+
65
+ expect(last_request.env['moguera.error'].class).to eq Moguera::Authentication::ParameterInvalid
66
+ expect(last_request.env['moguera.error'].message).to eq 'Missing: Date Header'
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,7 +1,7 @@
1
1
  RSpec.shared_context 'prepare_auth' do
2
2
  let(:access_key) { 'apikey' }
3
3
  let(:secret_access_key) { 'secret' }
4
- let(:request_path) { 'path' }
4
+ let(:request_path) { '/path' }
5
5
  let(:request_method) { 'POST' }
6
6
  let(:content_type) { 'application/json' }
7
7
  let(:now) { Timecop.freeze(Time.now) }
data/spec/spec_helper.rb CHANGED
@@ -11,30 +11,16 @@ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
11
11
  ]
12
12
  SimpleCov.start { add_filter 'spec' }
13
13
 
14
- RSpec.configure do |config|
14
+ require 'rack/moguera_authentication'
15
+ require 'moguera/authentication'
16
+ require 'shared_context'
15
17
 
16
- # Captures the output for analysis later
17
- #
18
- # @example Capture `$stderr`
19
- #
20
- # output = capture(:stderr) { $stderr.puts "this is captured" }
21
- #
22
- # @param [Symbol] stream `:stdout` or `:stderr`
23
- # @yield The block to capture stdout/stderr for.
24
- # @return [String] The contents of $stdout or $stderr
25
- def capture(stream)
26
- begin
27
- stream = stream.to_s
28
- eval "$#{stream} = StringIO.new"
29
- yield
30
- result = eval("$#{stream}").string
31
- ensure
32
- eval("$#{stream} = #{stream.upcase}")
33
- end
18
+ module TestApplicationHelper
19
+ extend self
34
20
 
35
- result
21
+ class TestApplication
22
+ def call(env)
23
+ [200, {"Content-Type" => "text/plain"}, ["test"]]
24
+ end
36
25
  end
37
26
  end
38
-
39
- require 'moguera/authentication'
40
- require 'shared_context'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moguera-authentication
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hiro-su
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-23 00:00:00.000000000 Z
11
+ date: 2014-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 3.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.5'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.5'
55
69
  description: Simple REST API Authentication.
56
70
  email:
57
71
  - h.sugipon@gmail.com
@@ -71,11 +85,15 @@ files:
71
85
  - lib/moguera/authentication/exception.rb
72
86
  - lib/moguera/authentication/request.rb
73
87
  - lib/moguera/authentication/version.rb
88
+ - lib/rack/moguera_authentication.rb
74
89
  - moguera-authentication.gemspec
75
90
  - sample/client.rb
91
+ - sample/config.ru
92
+ - sample/credential.json
76
93
  - sample/server.rb
94
+ - spec/authentication/authentication_spec.rb
77
95
  - spec/authentication/request_spec.rb
78
- - spec/authentication_spec.rb
96
+ - spec/rack/moguera_authentication_spec.rb
79
97
  - spec/shared_context.rb
80
98
  - spec/spec_helper.rb
81
99
  homepage: https://github.com/moguera/moguera-authentication
@@ -103,7 +121,8 @@ signing_key:
103
121
  specification_version: 4
104
122
  summary: Simple REST API Authentication.
105
123
  test_files:
124
+ - spec/authentication/authentication_spec.rb
106
125
  - spec/authentication/request_spec.rb
107
- - spec/authentication_spec.rb
126
+ - spec/rack/moguera_authentication_spec.rb
108
127
  - spec/shared_context.rb
109
128
  - spec/spec_helper.rb