moguera-authentication 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fc3dfe649673b10bebc29e516c4ce648b1dd04e1
4
+ data.tar.gz: 790de69338563c94b9a52eacef08b7c1d60297c1
5
+ SHA512:
6
+ metadata.gz: c3c1a8c8013d6e34740591ca912bb9bbdb8d72089f846b882d9b9dff569a94f6660c82c222a8471b0d3cebffe865a8d7bedbf14862b426a991175d60b0602416
7
+ data.tar.gz: ecc22756a412c60b51b0885f4e2a12c6bd43ea065da697b5baa320b730c211c338aea75a88d525ccfd3927854767667809cdcc4c6728f34e39e8261bdf5d0275
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ /.idea/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
4
+ gemfile:
5
+ - Gemfile
6
+ script:
7
+ - bundle exec rake spec
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in moguera-authentication.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'timecop'
8
+ gem 'pry'
9
+ gem 'pry-byebug'
10
+ gem 'simplecov'
11
+ gem 'simplecov-rcov'
12
+ gem 'coveralls'
13
+ end
14
+
15
+ group :development do
16
+ gem 'rest-client'
17
+ gem 'sinatra'
18
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 hiro-su
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,144 @@
1
+ # Moguera::Authentication
2
+
3
+ Simple REST API Authentication.
4
+
5
+ [![Build Status](https://travis-ci.org/moguera/moguera-authentication.svg)](https://travis-ci.org/moguera/moguera-authentication)
6
+ [![Coverage Status](https://coveralls.io/repos/moguera/moguera-authentication/badge.png?branch=master)](https://coveralls.io/r/moguera/moguera-authentication?branch=master)
7
+
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'moguera-authentication'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install moguera-authentication
24
+
25
+ ## Authentication Logic
26
+ Use paramas
27
+
28
+ - access_key
29
+ - secret_access_key
30
+ - request_pah
31
+ - request_method
32
+ - http_date
33
+ - content_type
34
+
35
+ ```ruby
36
+ string_to_isgn = access_key + request_path + request_method + http_date + conetnt_type
37
+ signature = Baes64.encode64(OpenSSL::HMAC.hexdigest(sha1, secret_access_key, string_to_sign)
38
+
39
+ Authorization header
40
+ Authorization: MOGUERA + " " + access_key + ":" + signature
41
+ ```
42
+
43
+ Server check
44
+
45
+ 1. Same request_token and server_token?
46
+ 2. Expired the request?
47
+
48
+ ## Usage
49
+
50
+ ### Server
51
+ sinatra sample
52
+
53
+ ```ruby
54
+ require 'sinatra'
55
+ require 'moguera/authentication'
56
+
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
+ )
71
+ 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
+ end
85
+ end
86
+ ```
87
+
88
+ ### Cilent
89
+ rest-client sample
90
+
91
+ ```ruby
92
+ require 'moguera/authentication'
93
+ require 'rest-client'
94
+ require 'time'
95
+ require 'json'
96
+ require 'uri'
97
+
98
+ url = ARGV[0]
99
+ abort "Usage: ruby #{__FILE__} http://localhost:4567/login" unless url
100
+
101
+ request_path = URI.parse(url).path
102
+ request_method = 'POST'
103
+ http_date = Time.now.httpdate
104
+ content_type = 'application/json'
105
+
106
+ request = Moguera::Authentication::Request.new(
107
+ access_key: 'apikey',
108
+ secret_access_key: 'secret',
109
+ request_path: request_path,
110
+ request_method: request_method,
111
+ http_date: http_date,
112
+ content_type: content_type
113
+ )
114
+
115
+ headers = {
116
+ Authorization: request.token,
117
+ content_type: content_type,
118
+ Date: http_date
119
+ }
120
+
121
+ payload = { key: 'value' }.to_json
122
+
123
+ begin
124
+ res = RestClient.post(url, payload, headers)
125
+ puts res.code
126
+ puts res.body
127
+ rescue => e
128
+ abort e.response
129
+ end
130
+ ```
131
+
132
+ ## Contributing
133
+
134
+ 1. Fork it ( https://github.com/[my-github-username]/moguera-authentication/fork )
135
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
136
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
137
+ 4. Push to the branch (`git push origin my-new-feature`)
138
+ 5. Create a new Pull Request
139
+
140
+ ## Copyright
141
+
142
+ Copyright (c) 2014 hiro-su.
143
+
144
+ MIT License
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ begin
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.fail_on_error = true
8
+ t.rspec_opts = '--format doc'
9
+ end
10
+
11
+ task :default => :spec
12
+ rescue LoadError
13
+ # no rspec available
14
+ end
@@ -0,0 +1,14 @@
1
+ module Moguera
2
+ class Authentication
3
+ class AuthenticationError < StandardError
4
+ attr_accessor :server_request
5
+ attr_accessor :request_token
6
+ end
7
+
8
+ class ParameterInvalid < StandardError
9
+ end
10
+
11
+ class BlockRequired < StandardError
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,56 @@
1
+ module Moguera
2
+ class Authentication
3
+ class Request
4
+ attr_accessor :token_prefix
5
+
6
+ def initialize(access_key:, secret_access_key:, request_path:, request_method:, http_date:, content_type:)
7
+ require 'time'
8
+ require 'openssl'
9
+ require 'base64'
10
+
11
+ @access_key = access_key
12
+ @secret_access_key = secret_access_key
13
+ @request_path = request_path
14
+ @request_method = request_method
15
+ @http_date = http_date
16
+ @content_type = content_type
17
+
18
+ @token_prefix = token_prefix || 'MOGUERA'
19
+
20
+ validate_parameter!
21
+ end
22
+
23
+ attr_reader :access_key, :secret_access_key, :request_path,
24
+ :request_method, :http_date, :content_type
25
+
26
+ def token
27
+ raise ParameterInvalid, 'Token prefix required.' if @token_prefix.nil?
28
+
29
+ @token_prefix + ' ' + @access_key + ':' + signature
30
+ end
31
+
32
+ private
33
+
34
+ def signature
35
+ sha1 = OpenSSL::Digest::SHA1.new
36
+ digest = OpenSSL::HMAC.hexdigest(sha1, @secret_access_key, string_to_sign)
37
+ Base64.encode64(digest).strip
38
+ end
39
+
40
+ def string_to_sign
41
+ @access_key + @request_path + @request_method + @http_date + @content_type
42
+ end
43
+
44
+ def validate_parameter!
45
+ errors = []
46
+ errors << 'Access Key' unless @access_key
47
+ errors << 'Secret Access Key' unless @secret_access_key
48
+ errors << 'Request Path' unless @request_path
49
+ errors << 'Date Header' unless @http_date
50
+ errors << 'Content-Type Header' unless @content_type
51
+
52
+ raise ParameterInvalid, 'Missing: ' + errors * ', ' unless errors.empty?
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,5 @@
1
+ module Moguera
2
+ class Authentication
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,78 @@
1
+ require 'moguera/authentication/version'
2
+ require 'moguera/authentication/request'
3
+ require 'moguera/authentication/exception'
4
+
5
+ module Moguera
6
+ class Authentication
7
+ attr_accessor :allow_time_interval
8
+
9
+ def initialize(request_token = nil)
10
+ raise AuthenticationError, 'Missing request token.' unless request_token
11
+
12
+ @request_token = request_token
13
+ @allow_time_interval = allow_time_interval || 600
14
+ end
15
+
16
+ def authenticate!(&block)
17
+ raise BlockRequired, 'Request token required.' unless block_given?
18
+
19
+ access_key = extract_access_key_from_token(token: @request_token)
20
+ server_request = block.call(access_key)
21
+
22
+ validate_token!(server_token: server_request.token, request_token: @request_token)
23
+ validate_time!(request_time: server_request.http_date)
24
+
25
+ server_request
26
+ rescue AuthenticationError => e
27
+ authentication_error = AuthenticationError.new(e.message)
28
+ authentication_error.request_token = @request_token
29
+ authentication_error.server_request = server_request if server_request
30
+ raise authentication_error
31
+ end
32
+
33
+ def authenticate(&block)
34
+ authenticate!(&block)
35
+
36
+ rescue AuthenticationError
37
+ false
38
+ end
39
+
40
+ private
41
+
42
+ def extract_access_key_from_token(token:)
43
+ begin
44
+ _, access_key_signature = token.split
45
+ access_key, _ = access_key_signature.split(':')
46
+ rescue
47
+ raise AuthenticationError, 'Invalid token.'
48
+ end
49
+
50
+ access_key
51
+ end
52
+
53
+ def validate_token!(server_token:, request_token:)
54
+ unless server_token == request_token
55
+ raise AuthenticationError, 'Mismatch token.'
56
+ end
57
+
58
+ true
59
+ end
60
+
61
+ def validate_time!(request_time:)
62
+ return true if @allow_time_interval.nil?
63
+
64
+ if @allow_time_interval <= 0
65
+ raise ParameterInvalid, 'Please input a positive value.'
66
+ end
67
+
68
+ rt = Time.parse(request_time).to_i
69
+ interval = (Time.now.to_i - rt).abs
70
+
71
+ if @allow_time_interval <= interval
72
+ raise AuthenticationError, 'Expired request.'
73
+ end
74
+
75
+ true
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'moguera/authentication/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "moguera-authentication"
8
+ spec.version = Moguera::Authentication::VERSION
9
+ spec.authors = ["hiro-su"]
10
+ spec.email = ["h.sugipon@gmail.com"]
11
+ spec.summary = %q{Simple REST API Authentication.}
12
+ spec.description = %q{Simple REST API Authentication.}
13
+ spec.homepage = "https://github.com/moguera/moguera-authentication"
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", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.1.0"
24
+ end
data/sample/client.rb ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), %w(.. lib)))
5
+
6
+ require 'moguera/authentication'
7
+ require 'rest-client'
8
+ require 'time'
9
+ require 'json'
10
+ require 'uri'
11
+
12
+ url = ARGV[0]
13
+ abort "Usage: ruby #{__FILE__} http://localhost:4567/login" unless url
14
+
15
+ request_path = URI.parse(url).path
16
+ request_method = 'POST'
17
+ http_date = Time.now.httpdate
18
+ content_type = 'application/json'
19
+
20
+ request = Moguera::Authentication::Request.new(
21
+ access_key: 'apikey',
22
+ secret_access_key: 'secret',
23
+ request_path: request_path,
24
+ request_method: request_method,
25
+ http_date: http_date,
26
+ content_type: content_type
27
+ )
28
+
29
+ headers = {
30
+ Authorization: request.token,
31
+ content_type: content_type,
32
+ Date: http_date
33
+ }
34
+
35
+ payload = { key: 'value' }.to_json
36
+
37
+ begin
38
+ res = RestClient.post(url, payload, headers)
39
+ puts res.code
40
+ puts res.body
41
+ rescue => e
42
+ abort e.response
43
+ end
data/sample/server.rb ADDED
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), %w(.. lib)))
5
+
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"
36
+ end
37
+ end
38
+
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'
43
+
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
53
+
54
+ halt 401, "401 Unauthorized" unless user
55
+ return user.access_key
56
+ end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ describe Moguera::Authentication::Request do
4
+ include_context 'prepare_auth'
5
+
6
+ subject {
7
+ Moguera::Authentication::Request.new(
8
+ access_key: access_key,
9
+ secret_access_key: secret_access_key,
10
+ request_path: request_path,
11
+ request_method: request_method,
12
+ http_date: http_date,
13
+ content_type: content_type
14
+ )
15
+ }
16
+
17
+ it 'should be set the token_prefix' do
18
+ subject.token_prefix = 'TEST'
19
+ expect(subject.token_prefix).to eq 'TEST'
20
+ end
21
+
22
+ it 'should be read the token_prefix' do
23
+ expect(subject.token_prefix).to eq 'MOGUERA'
24
+ end
25
+
26
+ it 'should be read the access_key' do
27
+ expect(subject.access_key).to eq access_key
28
+ end
29
+
30
+ it 'should be read the secret_access_key' do
31
+ expect(subject.secret_access_key).to eq secret_access_key
32
+ end
33
+
34
+ it 'should be read the request_path' do
35
+ expect(subject.request_path).to eq request_path
36
+ end
37
+
38
+ it 'should be read the request_method' do
39
+ expect(subject.request_method).to eq request_method
40
+ end
41
+
42
+ it 'should be read the http_date' do
43
+ expect(subject.http_date).to eq http_date
44
+ end
45
+
46
+ it 'should be read the content_type' do
47
+ expect(subject.content_type).to eq content_type
48
+ end
49
+
50
+ describe '#token' do
51
+ it 'should be display the signature token' do
52
+ expect(subject.token).to eq request_token
53
+ end
54
+ end
55
+
56
+ describe '#signature' do
57
+ it 'should be create the signature' do
58
+ _, access_key_signature = subject.token.split
59
+ _, signature = access_key_signature.split(':')
60
+
61
+ expect(subject.send(:signature)).to eq signature
62
+ end
63
+ end
64
+
65
+ describe '#string_to_sign' do
66
+ it 'should be create the string_to_sign' do
67
+ string_to_sign = access_key + request_path + request_method + http_date + content_type
68
+
69
+ expect(subject.send(:string_to_sign)).to eq string_to_sign
70
+ end
71
+ end
72
+
73
+ describe 'Invalid Parameter' do
74
+ describe 'request parameter is nil' do
75
+ it 'should be raise ParameterInvalid Exception' do
76
+ error = "Missing: Access Key, Secret Access Key, Request Path, Date Header, Content-Type Header"
77
+ expect {
78
+ Moguera::Authentication::Request.new(
79
+ access_key: nil,
80
+ secret_access_key: nil,
81
+ request_path: nil,
82
+ request_method: nil,
83
+ http_date: nil,
84
+ content_type: nil
85
+ )
86
+ }.to raise_error(Moguera::Authentication::ParameterInvalid, error)
87
+ end
88
+ end
89
+
90
+ describe 'token_prefix is nil' do
91
+ it 'should be raise ParameterInvalid Exception' do
92
+ subject.token_prefix = nil
93
+ expect {
94
+ subject.token
95
+ }.to raise_error(Moguera::Authentication::ParameterInvalid, 'Token prefix required.')
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,134 @@
1
+ require 'spec_helper'
2
+
3
+ describe Moguera::Authentication do
4
+ include_context "prepare_auth"
5
+
6
+ subject { Moguera::Authentication.new(request_token) }
7
+
8
+ it 'should be set allow_time_interval' do
9
+ subject.allow_time_interval = 300
10
+ expect(subject.allow_time_interval).to eq 300
11
+ end
12
+
13
+ it 'should be read allow_time_interval' do
14
+ # default 600s
15
+ expect(subject.allow_time_interval).to eq 600
16
+ end
17
+
18
+ describe "#authenticate!" do
19
+ it 'should be authenticate' do
20
+ user = subject.authenticate! do |request_key|
21
+ Moguera::Authentication::Request.new(
22
+ access_key: request_key,
23
+ secret_access_key: secret_access_key,
24
+ request_path: request_path,
25
+ request_method: request_method,
26
+ http_date: http_date,
27
+ content_type: content_type
28
+ )
29
+ end
30
+ expect(user.access_key).to eq access_key
31
+ end
32
+
33
+ describe 'Invalid token' do
34
+ it 'should be raise AuthenticationError with missing request token message' do
35
+ expect {
36
+ Moguera::Authentication.new
37
+ }.to raise_error(Moguera::Authentication::AuthenticationError, 'Missing request token.')
38
+ end
39
+
40
+ it 'should be raise AuthenticationError with invalid token message' do
41
+ expect {
42
+ Moguera::Authentication.new('invalid_token').authenticate! { request }
43
+ }.to raise_error(Moguera::Authentication::AuthenticationError, 'Invalid token.')
44
+ end
45
+
46
+ it 'should be raise AuthenticationError with mismatch token message' do
47
+ expect {
48
+ Moguera::Authentication.new('Mismatch token:signature').authenticate! { request }
49
+ }.to raise_error(Moguera::Authentication::AuthenticationError, 'Mismatch token.')
50
+ end
51
+ end
52
+ end
53
+
54
+ describe '#authenticate' do
55
+ it 'should be authenticate' do
56
+ user = subject.authenticate do |request_key|
57
+ Moguera::Authentication::Request.new(
58
+ access_key: request_key,
59
+ secret_access_key: secret_access_key,
60
+ request_path: request_path,
61
+ request_method: request_method,
62
+ http_date: http_date,
63
+ content_type: content_type
64
+ )
65
+ end
66
+ expect(user.access_key).to eq access_key
67
+ end
68
+
69
+ describe 'Invalid token' do
70
+ it 'should be return false' do
71
+ expect(
72
+ Moguera::Authentication.new('Mismatch token:signature').authenticate { request }
73
+ ).to eq false
74
+ end
75
+ end
76
+ end
77
+
78
+ describe '#extract_access_key_from_token' do
79
+ it 'should be return access_key' do
80
+ expect(
81
+ subject.send(:extract_access_key_from_token, token: 'TEST access_key:signature')
82
+ ).to eq 'access_key'
83
+ end
84
+
85
+ describe 'Invalid token' do
86
+ it 'should be raise AuthenticationError with invalid token message' do
87
+ expect {
88
+ subject.send(:extract_access_key_from_token, token: 'invalid_token')
89
+ }.to raise_error(Moguera::Authentication::AuthenticationError, 'Invalid token.')
90
+ end
91
+ end
92
+ end
93
+
94
+ describe '#validate_token!' do
95
+ it 'should be validate token' do
96
+ expect(
97
+ subject.send(:validate_token!, server_token: 'test_token', request_token: 'test_token')
98
+ ).to eq true
99
+ end
100
+
101
+ describe 'Mismatch token' do
102
+ it 'should be raise AuthenticationError with mismatch token message' do
103
+ expect {
104
+ subject.send(:validate_token!, server_token: 'test1_token', request_token: 'test2_token')
105
+ }.to raise_error(Moguera::Authentication::AuthenticationError, 'Mismatch token.')
106
+ end
107
+ end
108
+ end
109
+
110
+ describe '#validate_time!' do
111
+ it 'should be validate time' do
112
+ expect(
113
+ subject.send(:validate_time!, request_time: http_date)
114
+ ).to eq true
115
+ end
116
+
117
+ describe 'Invalid allow_time_interval' do
118
+ it 'should be raise ParameterInvalid' do
119
+ subject.allow_time_interval = -1
120
+ expect {
121
+ subject.send(:validate_time!, request_time: http_date)
122
+ }.to raise_error(Moguera::Authentication::ParameterInvalid, 'Please input a positive value.')
123
+ end
124
+ end
125
+
126
+ describe 'Expired request' do
127
+ it 'should be raise AuthenticationError' do
128
+ expect {
129
+ subject.send(:validate_time!, request_time: (Time.parse(http_date)-1000).httpdate)
130
+ }.to raise_error(Moguera::Authentication::AuthenticationError, 'Expired request.')
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,22 @@
1
+ RSpec.shared_context 'prepare_auth' do
2
+ let(:access_key) { 'apikey' }
3
+ let(:secret_access_key) { 'secret' }
4
+ let(:request_path) { 'path' }
5
+ let(:request_method) { 'POST' }
6
+ let(:content_type) { 'application/json' }
7
+ let(:now) { Timecop.freeze(Time.now) }
8
+ let(:http_date) { now.httpdate }
9
+ let(:request) {
10
+ Moguera::Authentication::Request.new(
11
+ access_key: access_key,
12
+ secret_access_key: secret_access_key,
13
+ request_path: request_path,
14
+ request_method: request_method,
15
+ http_date: http_date,
16
+ content_type: content_type
17
+ )
18
+ }
19
+ let(:request_token) {
20
+ request.token
21
+ }
22
+ end
@@ -0,0 +1,40 @@
1
+ require "bundler/setup"
2
+ Bundler.require :test
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), %w(.. lib)))
6
+
7
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
+ SimpleCov::Formatter::HTMLFormatter,
9
+ SimpleCov::Formatter::RcovFormatter,
10
+ Coveralls::SimpleCov::Formatter
11
+ ]
12
+ SimpleCov.start { add_filter 'spec' }
13
+
14
+ RSpec.configure do |config|
15
+
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
34
+
35
+ result
36
+ end
37
+ end
38
+
39
+ require 'moguera/authentication'
40
+ require 'shared_context'
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: moguera-authentication
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - hiro-su
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-23 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: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.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.1.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.1.0
55
+ description: Simple REST API Authentication.
56
+ email:
57
+ - h.sugipon@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".coveralls.yml"
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - lib/moguera/authentication.rb
71
+ - lib/moguera/authentication/exception.rb
72
+ - lib/moguera/authentication/request.rb
73
+ - lib/moguera/authentication/version.rb
74
+ - moguera-authentication.gemspec
75
+ - sample/client.rb
76
+ - sample/server.rb
77
+ - spec/authentication/request_spec.rb
78
+ - spec/authentication_spec.rb
79
+ - spec/shared_context.rb
80
+ - spec/spec_helper.rb
81
+ homepage: https://github.com/moguera/moguera-authentication
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.2.2
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Simple REST API Authentication.
105
+ test_files:
106
+ - spec/authentication/request_spec.rb
107
+ - spec/authentication_spec.rb
108
+ - spec/shared_context.rb
109
+ - spec/spec_helper.rb