moguera-authentication 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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