moguera-authentication 0.0.1 → 0.1.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 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