omniauth-traity 0.0.1 → 0.0.2
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 +4 -4
- data/Rakefile +7 -1
- data/lib/omniauth/strategies/traity.rb +98 -4
- data/lib/omniauth/traity/version.rb +1 -1
- data/omniauth-traity.gemspec +3 -3
- data/test/helper.rb +56 -0
- data/test/support/shared_examples.rb +85 -0
- data/test/test.rb +366 -0
- metadata +33 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e93400a5155ab46696b64b80a8b70e2be1b9cc88
|
4
|
+
data.tar.gz: bfcce00d2df7fb5b9531ed1457c4b6aab4275c6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c4b2dc843847d44d5567980db101c91ea832038f9faaa307f88a66795db3a8ffeb57647743a72335d7641c37cd3624a3657ac3bed5f3c17d0df9cafdf9076f9
|
7
|
+
data.tar.gz: 3a1cefa42c625dc9842057f50d9090a40b4cfad8810fe83ab9b2ade6ba15bd0593bd9e62c7db0b2d3407c826cb9260fe2207cf1035d9c5c855785a6736014ff6
|
data/Rakefile
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
-
require 'omniauth'
|
2
|
-
require '
|
1
|
+
require 'omniauth/strategies/oauth2'
|
2
|
+
require 'base64'
|
3
3
|
|
4
4
|
module OmniAuth
|
5
5
|
module Strategies
|
6
6
|
class Traity < OmniAuth::Strategies::OAuth2
|
7
|
+
class NoAuthorizationCodeError < StandardError; end
|
8
|
+
|
9
|
+
DEFAULT_SCOPE = 'email'
|
10
|
+
|
7
11
|
option :fields, [:name, :email]
|
8
12
|
option :uid_field, :id
|
9
13
|
|
@@ -13,6 +17,12 @@ module OmniAuth
|
|
13
17
|
token_url: 'oauth/token'
|
14
18
|
}
|
15
19
|
|
20
|
+
option :token_params, {
|
21
|
+
:parse => :query
|
22
|
+
}
|
23
|
+
|
24
|
+
option :authorize_options, [:scope, :display]
|
25
|
+
|
16
26
|
uid { raw_info['id'] }
|
17
27
|
|
18
28
|
info do
|
@@ -24,13 +34,43 @@ module OmniAuth
|
|
24
34
|
'cover_picture' => raw_info['cover_picture'],
|
25
35
|
'gender' => raw_info['gender'],
|
26
36
|
'location' => raw_info['location'],
|
27
|
-
'reputation' => raw_info['reputation'],
|
37
|
+
'reputation' => (raw_info['reputation'] || 0),
|
28
38
|
'email_verified' => (raw_info['verified'] || {}).has_key?('email')
|
29
39
|
})
|
30
40
|
end
|
31
41
|
|
42
|
+
def callback_url
|
43
|
+
options[:callback_url] || super
|
44
|
+
end
|
45
|
+
|
46
|
+
def callback_phase
|
47
|
+
with_authorization_code! do
|
48
|
+
super
|
49
|
+
end
|
50
|
+
rescue NoAuthorizationCodeError => e
|
51
|
+
fail!(:no_authorization_code, e)
|
52
|
+
end
|
53
|
+
|
54
|
+
def authorize_params
|
55
|
+
super.tap do |params|
|
56
|
+
%w[display scope].each do |v|
|
57
|
+
if request.params[v]
|
58
|
+
params[v.to_sym] = request.params[v]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
params[:scope] ||= DEFAULT_SCOPE
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
32
66
|
def raw_info
|
33
|
-
@raw_info ||= access_token.get('1.0/me').parsed || {}
|
67
|
+
@raw_info ||= access_token.get('1.0/me', info_options).parsed || {}
|
68
|
+
end
|
69
|
+
|
70
|
+
def info_options
|
71
|
+
params = {:appsecret_proof => appsecret_proof}
|
72
|
+
params.merge!({:locale => options[:locale]}) if options[:locale]
|
73
|
+
{ :params => params }
|
34
74
|
end
|
35
75
|
|
36
76
|
def prune!(hash)
|
@@ -39,6 +79,60 @@ module OmniAuth
|
|
39
79
|
value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
40
80
|
end
|
41
81
|
end
|
82
|
+
|
83
|
+
def appsecret_proof
|
84
|
+
@appsecret_proof ||= OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, client.secret, access_token.token)
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
def signed_request_from_cookie
|
89
|
+
@signed_request_from_cookie ||= raw_signed_request_from_cookie && parse_signed_request(raw_signed_request_from_cookie)
|
90
|
+
end
|
91
|
+
|
92
|
+
def raw_signed_request_from_cookie
|
93
|
+
request.cookies["tsr_#{client.id}"]
|
94
|
+
end
|
95
|
+
|
96
|
+
def with_authorization_code!
|
97
|
+
if request.params.key?('code')
|
98
|
+
yield
|
99
|
+
elsif code_from_signed_request = signed_request_from_cookie && signed_request_from_cookie['code']
|
100
|
+
request.params['code'] = code_from_signed_request
|
101
|
+
@authorization_code_from_signed_request_in_cookie = true
|
102
|
+
original_provider_ignores_state = options.provider_ignores_state
|
103
|
+
options.provider_ignores_state = true
|
104
|
+
begin
|
105
|
+
yield
|
106
|
+
ensure
|
107
|
+
request.params.delete('code')
|
108
|
+
@authorization_code_from_signed_request_in_cookie = false
|
109
|
+
options.provider_ignores_state = original_provider_ignores_state
|
110
|
+
end
|
111
|
+
else
|
112
|
+
raise NoAuthorizationCodeError, 'must pass either a `code` (via URL or by an `fbsr_XXX` signed request cookie)'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def parse_signed_request(value)
|
117
|
+
signature, encoded_payload = value.split('.')
|
118
|
+
return if signature.nil?
|
119
|
+
|
120
|
+
decoded_hex_signature = base64_decode_url(signature)
|
121
|
+
decoded_payload = MultiJson.decode(base64_decode_url(encoded_payload))
|
122
|
+
|
123
|
+
if valid_signature?(client.secret, decoded_hex_signature, encoded_payload)
|
124
|
+
decoded_payload
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def valid_signature?(secret, signature, payload)
|
129
|
+
Digest::SHA256.hexdigest("#{payload}-#{secret}") == signature
|
130
|
+
end
|
131
|
+
|
132
|
+
def base64_decode_url(value)
|
133
|
+
value += '=' * (4 - value.size.modulo(4))
|
134
|
+
Base64.decode64(value.tr('-_', '+/'))
|
135
|
+
end
|
42
136
|
end
|
43
137
|
end
|
44
138
|
end
|
data/omniauth-traity.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.add_runtime_dependency 'omniauth-oauth2', '~> 1.2'
|
21
21
|
|
22
|
-
spec.add_development_dependency "
|
23
|
-
spec.add_development_dependency
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency 'minitest'
|
24
|
+
spec.add_development_dependency 'mocha'
|
24
25
|
end
|
25
|
-
|
data/test/helper.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'mocha/setup'
|
4
|
+
require 'omniauth/strategies/traity'
|
5
|
+
|
6
|
+
OmniAuth.config.test_mode = true
|
7
|
+
|
8
|
+
module BlockTestHelper
|
9
|
+
def test(name, &blk)
|
10
|
+
method_name = "test_#{name.gsub(/\s+/, '_')}"
|
11
|
+
raise "Method already defined: #{method_name}" if instance_methods.include?(method_name.to_sym)
|
12
|
+
define_method method_name, &blk
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module CustomAssertions
|
17
|
+
def assert_has_key(key, hash, msg = nil)
|
18
|
+
msg = message(msg) { "Expected #{hash.inspect} to have key #{key.inspect}" }
|
19
|
+
assert hash.has_key?(key), msg
|
20
|
+
end
|
21
|
+
|
22
|
+
def refute_has_key(key, hash, msg = nil)
|
23
|
+
msg = message(msg) { "Expected #{hash.inspect} not to have key #{key.inspect}" }
|
24
|
+
refute hash.has_key?(key), msg
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class TestCase < Minitest::Test
|
29
|
+
extend BlockTestHelper
|
30
|
+
include CustomAssertions
|
31
|
+
end
|
32
|
+
|
33
|
+
class StrategyTestCase < TestCase
|
34
|
+
def setup
|
35
|
+
@request = stub('Request')
|
36
|
+
@request.stubs(:params).returns({})
|
37
|
+
@request.stubs(:cookies).returns({})
|
38
|
+
@request.stubs(:env).returns({})
|
39
|
+
@request.stubs(:scheme).returns({})
|
40
|
+
@request.stubs(:ssl?).returns(false)
|
41
|
+
|
42
|
+
@client_id = '123'
|
43
|
+
@client_secret = '53cr3tz'
|
44
|
+
end
|
45
|
+
|
46
|
+
def strategy
|
47
|
+
@strategy ||= begin
|
48
|
+
args = [@client_id, @client_secret, @options].compact
|
49
|
+
OmniAuth::Strategies::Traity.new(nil, *args).tap do |strategy|
|
50
|
+
strategy.stubs(:request).returns(@request)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
Dir[File.expand_path('../support/**/*', __FILE__)].each &method(:require)
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# NOTE it would be useful if this lived in omniauth-oauth2 eventually
|
2
|
+
module OAuth2StrategyTests
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
include ClientTests
|
6
|
+
include AuthorizeParamsTests
|
7
|
+
include CSRFAuthorizeParamsTests
|
8
|
+
include TokenParamsTests
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClientTests
|
13
|
+
extend BlockTestHelper
|
14
|
+
|
15
|
+
test 'should be initialized with symbolized client_options' do
|
16
|
+
@options = { :client_options => { 'authorize_url' => 'https://example.com' } }
|
17
|
+
assert_equal 'https://example.com', strategy.client.options[:authorize_url]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module AuthorizeParamsTests
|
22
|
+
extend BlockTestHelper
|
23
|
+
|
24
|
+
test 'should include any authorize params passed in the :authorize_params option' do
|
25
|
+
@options = { :authorize_params => { :foo => 'bar', :baz => 'zip' } }
|
26
|
+
assert_equal 'bar', strategy.authorize_params['foo']
|
27
|
+
assert_equal 'zip', strategy.authorize_params['baz']
|
28
|
+
end
|
29
|
+
|
30
|
+
test 'should include top-level options that are marked as :authorize_options' do
|
31
|
+
@options = { :authorize_options => [:scope, :foo], :scope => 'bar', :foo => 'baz' }
|
32
|
+
assert_equal 'bar', strategy.authorize_params['scope']
|
33
|
+
assert_equal 'baz', strategy.authorize_params['foo']
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'should exclude top-level options that are not passed' do
|
37
|
+
@options = { :authorize_options => [:bar] }
|
38
|
+
refute_has_key :bar, strategy.authorize_params
|
39
|
+
refute_has_key 'bar', strategy.authorize_params
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module CSRFAuthorizeParamsTests
|
44
|
+
extend BlockTestHelper
|
45
|
+
|
46
|
+
test 'should store random state in the session when none is present in authorize or request params' do
|
47
|
+
assert_includes strategy.authorize_params.keys, 'state'
|
48
|
+
refute_empty strategy.authorize_params['state']
|
49
|
+
refute_empty strategy.session['omniauth.state']
|
50
|
+
assert_equal strategy.authorize_params['state'], strategy.session['omniauth.state']
|
51
|
+
end
|
52
|
+
|
53
|
+
test 'should not store state in the session when present in authorize params vs. a random one' do
|
54
|
+
@options = { :authorize_params => { :state => 'bar' } }
|
55
|
+
refute_empty strategy.authorize_params['state']
|
56
|
+
refute_equal 'bar', strategy.authorize_params[:state]
|
57
|
+
refute_empty strategy.session['omniauth.state']
|
58
|
+
refute_equal 'bar', strategy.session['omniauth.state']
|
59
|
+
end
|
60
|
+
|
61
|
+
test 'should not store state in the session when present in request params vs. a random one' do
|
62
|
+
@request.stubs(:params).returns({ 'state' => 'foo' })
|
63
|
+
refute_empty strategy.authorize_params['state']
|
64
|
+
refute_equal 'foo', strategy.authorize_params[:state]
|
65
|
+
refute_empty strategy.session['omniauth.state']
|
66
|
+
refute_equal 'foo', strategy.session['omniauth.state']
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
module TokenParamsTests
|
71
|
+
extend BlockTestHelper
|
72
|
+
|
73
|
+
test 'should include any authorize params passed in the :token_params option' do
|
74
|
+
@options = { :token_params => { :foo => 'bar', :baz => 'zip' } }
|
75
|
+
assert_equal 'bar', strategy.token_params['foo']
|
76
|
+
assert_equal 'zip', strategy.token_params['baz']
|
77
|
+
end
|
78
|
+
|
79
|
+
test 'should include top-level options that are marked as :token_options' do
|
80
|
+
@options = { :token_options => [:scope, :foo], :scope => 'bar', :foo => 'baz' }
|
81
|
+
assert_equal 'bar', strategy.token_params['scope']
|
82
|
+
assert_equal 'baz', strategy.token_params['foo']
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/test/test.rb
ADDED
@@ -0,0 +1,366 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'omniauth-traity'
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
|
6
|
+
class StrategyTest < StrategyTestCase
|
7
|
+
include OAuth2StrategyTests
|
8
|
+
end
|
9
|
+
|
10
|
+
class ClientTest < StrategyTestCase
|
11
|
+
test 'has correct Traity site' do
|
12
|
+
assert_equal 'https://api.traity.com/', strategy.client.site
|
13
|
+
end
|
14
|
+
|
15
|
+
test 'has correct authorize url' do
|
16
|
+
assert_equal 'https://traity.com/oauth/dialog', strategy.client.options[:authorize_url]
|
17
|
+
end
|
18
|
+
|
19
|
+
test 'has correct token url with versioning' do
|
20
|
+
@options = {:client_options => {:site => 'https://api.traity.com/1.0'}}
|
21
|
+
assert_equal 'oauth/token', strategy.client.options[:token_url]
|
22
|
+
assert_equal 'https://api.traity.com/1.0/oauth/token', strategy.client.token_url
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class CallbackUrlTest < StrategyTestCase
|
27
|
+
test "returns the default callback url" do
|
28
|
+
url_base = 'http://auth.request.com'
|
29
|
+
@request.stubs(:url).returns("#{url_base}/some/page")
|
30
|
+
strategy.stubs(:script_name).returns('') # as not to depend on Rack env
|
31
|
+
assert_equal "#{url_base}/auth/traity/callback", strategy.callback_url
|
32
|
+
end
|
33
|
+
|
34
|
+
test "returns path from callback_path option" do
|
35
|
+
@options = { :callback_path => "/auth/traity/done"}
|
36
|
+
url_base = 'http://auth.request.com'
|
37
|
+
@request.stubs(:url).returns("#{url_base}/page/path")
|
38
|
+
strategy.stubs(:script_name).returns('') # as not to depend on Rack env
|
39
|
+
assert_equal "#{url_base}/auth/traity/done", strategy.callback_url
|
40
|
+
end
|
41
|
+
|
42
|
+
test "returns url from callback_url option" do
|
43
|
+
url = 'https://auth.myapp.com/auth/traity/callback'
|
44
|
+
@options = { :callback_url => url }
|
45
|
+
assert_equal url, strategy.callback_url
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
class AuthorizeParamsTest < StrategyTestCase
|
51
|
+
test 'includes default scope for email' do
|
52
|
+
assert strategy.authorize_params.is_a?(Hash)
|
53
|
+
assert_equal 'email', strategy.authorize_params[:scope]
|
54
|
+
end
|
55
|
+
|
56
|
+
test 'includes display parameter from request when present' do
|
57
|
+
@request.stubs(:params).returns({ 'display' => 'touch' })
|
58
|
+
assert strategy.authorize_params.is_a?(Hash)
|
59
|
+
assert_equal 'touch', strategy.authorize_params[:display]
|
60
|
+
end
|
61
|
+
|
62
|
+
test 'overrides default scope with parameter passed from request' do
|
63
|
+
@request.stubs(:params).returns({ 'scope' => 'email' })
|
64
|
+
assert strategy.authorize_params.is_a?(Hash)
|
65
|
+
assert_equal 'email', strategy.authorize_params[:scope]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class TokenParamsTest < StrategyTestCase
|
70
|
+
test 'has correct parse strategy' do
|
71
|
+
assert_equal :query, strategy.token_params[:parse]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class UidTest < StrategyTestCase
|
76
|
+
def setup
|
77
|
+
super
|
78
|
+
strategy.stubs(:raw_info).returns({ 'id' => '123' })
|
79
|
+
end
|
80
|
+
|
81
|
+
test 'returns the id from raw_info' do
|
82
|
+
assert_equal '123', strategy.uid
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
class InfoTestOptionalDataPresent < StrategyTestCase
|
88
|
+
def setup
|
89
|
+
super
|
90
|
+
@raw_info ||= { 'name' => 'Sergio Leone' }
|
91
|
+
strategy.stubs(:raw_info).returns(@raw_info)
|
92
|
+
end
|
93
|
+
|
94
|
+
test 'returns the name' do
|
95
|
+
assert_equal 'Sergio Leone', strategy.info['name']
|
96
|
+
end
|
97
|
+
|
98
|
+
test 'returns the email' do
|
99
|
+
@raw_info['email'] = 'sergio@leone.com'
|
100
|
+
assert_equal 'sergio@leone.com', strategy.info['email']
|
101
|
+
end
|
102
|
+
|
103
|
+
test 'returns the bio' do
|
104
|
+
@raw_info['bio'] = 'Amazing western director'
|
105
|
+
assert_equal 'Amazing western director', strategy.info['bio']
|
106
|
+
end
|
107
|
+
|
108
|
+
test 'returns the traity avatar url' do
|
109
|
+
@raw_info['picture'] = 'http://assets.com/userimage'
|
110
|
+
assert_equal 'http://assets.com/userimage', strategy.info['picture']
|
111
|
+
end
|
112
|
+
|
113
|
+
test 'returns the traity cover picture' do
|
114
|
+
@raw_info['cover_picture'] = 'http://assets.com/coverpicture'
|
115
|
+
assert_equal 'http://assets.com/coverpicture', strategy.info['cover_picture']
|
116
|
+
end
|
117
|
+
|
118
|
+
test 'returns the gender' do
|
119
|
+
@raw_info['gender'] = 'Male'
|
120
|
+
assert_equal 'Male', strategy.info['gender']
|
121
|
+
end
|
122
|
+
|
123
|
+
test 'returns the location as location' do
|
124
|
+
@raw_info['location'] = "Italy"
|
125
|
+
assert_equal "Italy", strategy.info['location']
|
126
|
+
end
|
127
|
+
|
128
|
+
test 'returns the reputation' do
|
129
|
+
@raw_info['reputation'] = 4.3
|
130
|
+
assert_equal 4.3, strategy.info['reputation']
|
131
|
+
end
|
132
|
+
|
133
|
+
test 'returns true if the email is verified' do
|
134
|
+
@raw_info['verified'] = { 'email' => Time.now }
|
135
|
+
assert_equal true, strategy.info['email_verified']
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class InfoTestOptionalDataNotPresent < StrategyTestCase
|
140
|
+
def setup
|
141
|
+
super
|
142
|
+
@raw_info ||= { 'name' => 'Sergio Leone' }
|
143
|
+
strategy.stubs(:raw_info).returns(@raw_info)
|
144
|
+
end
|
145
|
+
|
146
|
+
test 'has no bio key' do
|
147
|
+
refute_has_key 'bio', strategy.info
|
148
|
+
end
|
149
|
+
|
150
|
+
test 'has no picture key' do
|
151
|
+
refute_has_key 'picture', strategy.info
|
152
|
+
end
|
153
|
+
|
154
|
+
test 'has no cover_picture key' do
|
155
|
+
refute_has_key 'cover_picture', strategy.info
|
156
|
+
end
|
157
|
+
|
158
|
+
test 'has no gender key' do
|
159
|
+
refute_has_key 'gender', strategy.info
|
160
|
+
end
|
161
|
+
|
162
|
+
test 'has no location key' do
|
163
|
+
refute_has_key 'location', strategy.info
|
164
|
+
end
|
165
|
+
|
166
|
+
test 'has no reputation' do
|
167
|
+
assert_equal 0, strategy.info['reputation']
|
168
|
+
end
|
169
|
+
|
170
|
+
test 'has email verified as false' do
|
171
|
+
assert_equal false, strategy.info['email_verified']
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
class RawInfoTest < StrategyTestCase
|
176
|
+
def setup
|
177
|
+
super
|
178
|
+
@access_token = stub('OAuth2::AccessToken')
|
179
|
+
@appsecret_proof = 'appsecret_proof'
|
180
|
+
@options = {:appsecret_proof => @appsecret_proof}
|
181
|
+
end
|
182
|
+
|
183
|
+
test 'performs a GET to https://api.traity.com/1.0/me' do
|
184
|
+
strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
|
185
|
+
strategy.stubs(:access_token).returns(@access_token)
|
186
|
+
params = {:params => @options}
|
187
|
+
@access_token.expects(:get).with('1.0/me', params).returns(stub_everything('OAuth2::Response'))
|
188
|
+
strategy.raw_info
|
189
|
+
end
|
190
|
+
|
191
|
+
test 'performs a GET to https://api.traity.com/1.0/me with locale' do
|
192
|
+
@options.merge!({ :locale => 'cs_CZ' })
|
193
|
+
strategy.stubs(:access_token).returns(@access_token)
|
194
|
+
strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
|
195
|
+
params = {:params => @options}
|
196
|
+
@access_token.expects(:get).with('1.0/me', params).returns(stub_everything('OAuth2::Response'))
|
197
|
+
strategy.raw_info
|
198
|
+
end
|
199
|
+
|
200
|
+
test 'returns a Hash' do
|
201
|
+
strategy.stubs(:access_token).returns(@access_token)
|
202
|
+
strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
|
203
|
+
raw_response = stub('Faraday::Response')
|
204
|
+
raw_response.stubs(:body).returns('{ "ohai": "thar" }')
|
205
|
+
raw_response.stubs(:status).returns(200)
|
206
|
+
raw_response.stubs(:headers).returns({'Content-Type' => 'application/json' })
|
207
|
+
oauth2_response = OAuth2::Response.new(raw_response)
|
208
|
+
params = {:params => @options}
|
209
|
+
@access_token.stubs(:get).with('1.0/me', params).returns(oauth2_response)
|
210
|
+
assert_kind_of Hash, strategy.raw_info
|
211
|
+
assert_equal 'thar', strategy.raw_info['ohai']
|
212
|
+
end
|
213
|
+
|
214
|
+
test 'returns an empty hash when the response is false' do
|
215
|
+
strategy.stubs(:access_token).returns(@access_token)
|
216
|
+
strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
|
217
|
+
oauth2_response = stub('OAuth2::Response', :parsed => false)
|
218
|
+
params = {:params => @options}
|
219
|
+
@access_token.stubs(:get).with('1.0/me', params).returns(oauth2_response)
|
220
|
+
assert_kind_of Hash, strategy.raw_info
|
221
|
+
assert_equal({}, strategy.raw_info)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
class CredentialsTest < StrategyTestCase
|
227
|
+
def setup
|
228
|
+
super
|
229
|
+
@access_token = stub('OAuth2::AccessToken')
|
230
|
+
@access_token.stubs(:token)
|
231
|
+
@access_token.stubs(:expires?)
|
232
|
+
@access_token.stubs(:expires_at)
|
233
|
+
@access_token.stubs(:refresh_token)
|
234
|
+
strategy.stubs(:access_token).returns(@access_token)
|
235
|
+
end
|
236
|
+
|
237
|
+
test 'returns a Hash' do
|
238
|
+
assert_kind_of Hash, strategy.credentials
|
239
|
+
end
|
240
|
+
|
241
|
+
test 'returns the token' do
|
242
|
+
@access_token.stubs(:token).returns('123')
|
243
|
+
assert_equal '123', strategy.credentials['token']
|
244
|
+
end
|
245
|
+
|
246
|
+
test 'returns the expiry status' do
|
247
|
+
@access_token.stubs(:expires?).returns(true)
|
248
|
+
assert strategy.credentials['expires']
|
249
|
+
|
250
|
+
@access_token.stubs(:expires?).returns(false)
|
251
|
+
refute strategy.credentials['expires']
|
252
|
+
end
|
253
|
+
|
254
|
+
test 'returns the refresh token and expiry time when expiring' do
|
255
|
+
ten_mins_from_now = (Time.now + 600).to_i
|
256
|
+
@access_token.stubs(:expires?).returns(true)
|
257
|
+
@access_token.stubs(:refresh_token).returns('321')
|
258
|
+
@access_token.stubs(:expires_at).returns(ten_mins_from_now)
|
259
|
+
assert_equal '321', strategy.credentials['refresh_token']
|
260
|
+
assert_equal ten_mins_from_now, strategy.credentials['expires_at']
|
261
|
+
end
|
262
|
+
|
263
|
+
test 'does not return the refresh token when test is nil and expiring' do
|
264
|
+
@access_token.stubs(:expires?).returns(true)
|
265
|
+
@access_token.stubs(:refresh_token).returns(nil)
|
266
|
+
assert_nil strategy.credentials['refresh_token']
|
267
|
+
refute_has_key 'refresh_token', strategy.credentials
|
268
|
+
end
|
269
|
+
|
270
|
+
test 'does not return the refresh token when not expiring' do
|
271
|
+
@access_token.stubs(:expires?).returns(false)
|
272
|
+
@access_token.stubs(:refresh_token).returns('XXX')
|
273
|
+
assert_nil strategy.credentials['refresh_token']
|
274
|
+
refute_has_key 'refresh_token', strategy.credentials
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
module SignedRequestHelpers
|
279
|
+
def signed_request(payload, secret)
|
280
|
+
encoded_payload = base64_encode_url(MultiJson.encode(payload))
|
281
|
+
encoded_signature = base64_encode_url(signature(encoded_payload, secret))
|
282
|
+
[encoded_signature, encoded_payload].join('.')
|
283
|
+
end
|
284
|
+
|
285
|
+
def base64_encode_url(value)
|
286
|
+
Base64.encode64(value).tr('+/', '-_').gsub(/\n/, '')
|
287
|
+
end
|
288
|
+
|
289
|
+
def signature(payload, secret)
|
290
|
+
Digest::SHA256.hexdigest("#{payload}-#{secret}")
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
module SignedRequestTests
|
295
|
+
class TestCase < StrategyTestCase
|
296
|
+
include SignedRequestHelpers
|
297
|
+
end
|
298
|
+
|
299
|
+
class CookieAndParamNotPresentTest < TestCase
|
300
|
+
test 'is nil' do
|
301
|
+
assert_nil strategy.send(:signed_request_from_cookie)
|
302
|
+
end
|
303
|
+
|
304
|
+
test 'throws an error on calling build_access_token' do
|
305
|
+
assert_raises(OmniAuth::Strategies::Traity::NoAuthorizationCodeError) { strategy.send(:with_authorization_code!) {} }
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
class CookiePresentTest < TestCase
|
310
|
+
def setup(algo = nil)
|
311
|
+
super()
|
312
|
+
@payload = {
|
313
|
+
'code' => 'm4c0d3z',
|
314
|
+
'issued_at' => Time.now.to_i,
|
315
|
+
'user_id' => '123456'
|
316
|
+
}
|
317
|
+
|
318
|
+
@request.stubs(:cookies).returns({"tsr_#{@client_id}" => signed_request(@payload, @client_secret)})
|
319
|
+
end
|
320
|
+
|
321
|
+
test 'parses the access code out from the cookie' do
|
322
|
+
assert_equal @payload, strategy.send(:signed_request_from_cookie)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
class EmptySignedRequestTest < TestCase
|
327
|
+
def setup
|
328
|
+
super
|
329
|
+
@request.stubs(:params).returns({'signed_request' => ''})
|
330
|
+
end
|
331
|
+
|
332
|
+
test 'empty param' do
|
333
|
+
assert_equal nil, strategy.send(:signed_request_from_cookie)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
class MissingCodeInParamsRequestTest < TestCase
|
338
|
+
def setup
|
339
|
+
super
|
340
|
+
@request.stubs(:params).returns({})
|
341
|
+
end
|
342
|
+
|
343
|
+
test 'calls fail! when a code is not included in the params' do
|
344
|
+
strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(OmniAuth::Strategies::Traity::NoAuthorizationCodeError))
|
345
|
+
strategy.callback_phase
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
class MissingCodeInCookieRequestTest < TestCase
|
350
|
+
def setup(algo = nil)
|
351
|
+
super()
|
352
|
+
@payload = {
|
353
|
+
'code' => nil,
|
354
|
+
'issued_at' => Time.now.to_i,
|
355
|
+
'user_id' => '123456'
|
356
|
+
}
|
357
|
+
|
358
|
+
@request.stubs(:cookies).returns({"tsr_#{@client_id}" => signed_request(@payload, @client_secret)})
|
359
|
+
end
|
360
|
+
|
361
|
+
test 'calls fail! when a code is not included in the cookie' do
|
362
|
+
strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(OmniAuth::Strategies::Traity::NoAuthorizationCodeError))
|
363
|
+
strategy.callback_phase
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniauth-traity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Javi Velasco
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: omniauth-oauth2
|
@@ -25,33 +25,47 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mocha
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
68
|
+
version: '0'
|
55
69
|
description:
|
56
70
|
email:
|
57
71
|
- javi@traity.com
|
@@ -70,6 +84,9 @@ files:
|
|
70
84
|
- lib/omniauth/traity.rb
|
71
85
|
- lib/omniauth/traity/version.rb
|
72
86
|
- omniauth-traity.gemspec
|
87
|
+
- test/helper.rb
|
88
|
+
- test/support/shared_examples.rb
|
89
|
+
- test/test.rb
|
73
90
|
homepage: ''
|
74
91
|
licenses:
|
75
92
|
- MIT
|
@@ -94,4 +111,7 @@ rubygems_version: 2.2.2
|
|
94
111
|
signing_key:
|
95
112
|
specification_version: 4
|
96
113
|
summary: Traity OAuth2 Strategy for OmniAuth
|
97
|
-
test_files:
|
114
|
+
test_files:
|
115
|
+
- test/helper.rb
|
116
|
+
- test/support/shared_examples.rb
|
117
|
+
- test/test.rb
|