omniauth-irm_health 0.0.1.pre.snapshot

Sign up to get free protection for your applications and to get access to all the features.
data/example/config.ru ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler/setup'
2
+ require 'omniauth-irm_health'
3
+ require './app.rb'
4
+
5
+ use Rack::Session::Cookie, :secret => 'abc123'
6
+
7
+ use OmniAuth::Builder do
8
+ provider :facebook, ENV['APP_ID'], ENV['APP_SECRET'], :scope => 'email'
9
+ end
10
+
11
+ run Sinatra::Application
@@ -0,0 +1 @@
1
+ require 'omniauth/irm_health'
@@ -0,0 +1,2 @@
1
+ require 'omniauth/irm_health/version'
2
+ require 'omniauth/strategies/irm_health'
@@ -0,0 +1,5 @@
1
+ module OmniAuth
2
+ module IrmHealth
3
+ VERSION = "0.0.1-snapshot"
4
+ end
5
+ end
@@ -0,0 +1,206 @@
1
+ require 'omniauth/strategies/oauth2'
2
+ require 'base64'
3
+ require 'openssl'
4
+ require 'rack/utils'
5
+ require 'uri'
6
+
7
+ module OmniAuth
8
+ module Strategies
9
+ class IrmHealth < OmniAuth::Strategies::OAuth2
10
+ class NoAuthorizationCodeError < StandardError; end
11
+ class UnknownSignatureAlgorithmError < NotImplementedError; end
12
+
13
+
14
+ OPHIES_BASE_URL = 'https://ophies.irm.kr'
15
+ BASE_SCOPE_URL = OPHIES_BASE_URL # 'http://auth.irm.kr' # FIXME to https
16
+ BASE_SCOPES = %w[email profile study series instance docset]
17
+ DEFAULT_SCOPE = 'email'
18
+ DEFAULT_ACCESS_TYPE = 'offline'
19
+
20
+ option :name, 'irm_health'
21
+
22
+ option :authorize_options, [:scope, :access_type, :state]
23
+
24
+ option :client_options, {
25
+ :site => BASE_SCOPE_URL,
26
+ :authorize_url => '/auth/oauth2/auth',
27
+ :token_url => '/auth/oauth2/token'
28
+ }
29
+
30
+ # from google oauth2
31
+ # def authorize_params
32
+ # super.tab do |params|
33
+ # options[:authorize_options].each do |k|
34
+ # params[k] = request.params[k.to_s] unless [nil, ''].include? request.params[k.to_s]
35
+ # end
36
+ # end
37
+ #
38
+ # raw_scope = params[:scope] || DEFAULT_SCOPE # email
39
+ # scope_list = raw_scope.split(" ").map {|item| item.split(",")}.flatten
40
+ # scope_list.map! { |s| s =~ /^http?:\/\// || BASE_SCOPES.include?(s) ? s : "#{BASE_SCOPE_URL}#{s}" }
41
+ # params[:scope] = scope_list.join(" ")
42
+ # params[:access_type] = 'offline' if params[:access_type].nil?
43
+ #
44
+ # session['omniauth.state'] = params[:state] if params[:state]
45
+ #
46
+ # end
47
+
48
+ # auth hash schema
49
+ #
50
+ # https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema
51
+
52
+ uid { raw_info['uid'] } # uid required
53
+
54
+ info do # info required
55
+ prune!({
56
+ # name
57
+ # first_name
58
+ # last_name
59
+ # location
60
+ # description
61
+ # image
62
+ # phone
63
+ # urls: { study: https://ophies.irm.kr/v1/studies }
64
+ 'name' => raw_info['username'],
65
+ 'email' => raw_info['email'],
66
+ 'urls' => raw_info['urls']
67
+ # study: "https://ophies.irm.kr/v1/studies",
68
+ # series: "https://ophies.irm.kr/v1/series",
69
+ # instance: "https://ophies.irm.kr/v1/instances",
70
+ # patients: "https://ophies.irm.kr/v1/patients",
71
+ # docsets: "https://ophies.irm.kr/v1/docsets"
72
+ })
73
+ end
74
+
75
+
76
+ # credentials do # if other than those of oauth2
77
+ #
78
+ # end
79
+
80
+ # no extra for irm_health
81
+ extra do # provider specific info
82
+ hash = {}
83
+ hash['raw_info'] = raw_info unless skip_info?
84
+ prune! hash
85
+ end
86
+
87
+ def raw_info
88
+ @raw_info ||= access_token.get('/me').parsed
89
+ end
90
+
91
+ def info_options
92
+ params = {:appsecret_proof => appsecret_proof}
93
+ params.merge!({:fields => options[:info_fields]}) if options[:info_fields]
94
+ params.merge!({:locale => options[:locale]}) if options[:locale]
95
+
96
+ { :params => params }
97
+ end
98
+
99
+ def callback_phase
100
+ with_authorization_code! do
101
+ super
102
+ end
103
+ rescue NoAuthorizationCodeError => e
104
+ fail!(:no_authorization_code, e)
105
+ rescue UnknownSignatureAlgorithmError => e
106
+ fail!(:unknown_signature_algoruthm, e)
107
+ end
108
+
109
+ def callback_url
110
+ "#{OPHIES_BASE_URL}/auth/oauth2/irm_health/callback"
111
+ end
112
+
113
+ # def access_token_options
114
+ # options.access_token_options.inject({}) { |h,(k,v)| h[k.to_sym] = v; h }
115
+ # end
116
+
117
+ # You can pass +display+, +scope+, or +auth_type+ params to the auth request, if you need to set them dynamically.
118
+ # You can also set these options in the OmniAuth config :authorize_params option.
119
+ #
120
+ # For example: /auth/facebook?display=popup
121
+ def authorize_params
122
+ super.tap do |params|
123
+ BASE_SCOPES.each do |v|
124
+ if request.params[v]
125
+ params[v.to_sym] = request.params[v]
126
+ end
127
+ end
128
+
129
+ params[:scope] ||= DEFAULT_SCOPE
130
+ params[:access_type] = DEFAULT_ACCESS_TYPE if params[:access_type].nil?
131
+ session['omniauth.state'] = params[:state] if params[:state]
132
+ end
133
+ end
134
+
135
+
136
+ protected
137
+
138
+
139
+ private
140
+
141
+ # Picks the authorization code in order, from:
142
+ #
143
+ # 1. The request 'code' param (manual callback from standard server-side flow)
144
+ # 2. A signed request from cookie (passed from the client during the client-side flow)
145
+ def with_authorization_code!
146
+ if request.params.key?('code')
147
+ yield
148
+ else
149
+ raise NoAuthorizationCodeError, 'must pass a `code`'
150
+ end
151
+ end
152
+
153
+ def prune!(hash)
154
+ hash.delete_if do |_, value|
155
+ prune!(value) if value.is_a?(Hash)
156
+ value.nil? || (value.respond_to?(:empty?) && value.empty?)
157
+ end
158
+ end
159
+
160
+ # def parse_signed_request(value)
161
+ # signature, encoded_payload = value.split('.')
162
+ # return if signature.nil?
163
+ #
164
+ # decoded_hex_signature = base64_decode_url(signature)
165
+ # decoded_payload = MultiJson.decode(base64_decode_url(encoded_payload))
166
+ #
167
+ # unless decoded_payload['algorithm'] == 'HMAC-SHA256'
168
+ # raise UnknownSignatureAlgorithmError, "unknown algorithm: #{decoded_payload['algorithm']}"
169
+ # end
170
+ #
171
+ # if valid_signature?(client.secret, decoded_hex_signature, encoded_payload)
172
+ # decoded_payload
173
+ # end
174
+ # end
175
+
176
+ def valid_signature?(secret, signature, payload, algorithm = OpenSSL::Digest::SHA256.new)
177
+ OpenSSL::HMAC.digest(algorithm, secret, payload) == signature
178
+ end
179
+
180
+ def base64_decode_url(value)
181
+ value += '=' * (4 - value.size.modulo(4))
182
+ Base64.decode64(value.tr('-_', '+/'))
183
+ end
184
+
185
+ # def image_url(uid, options)
186
+ # uri_class = options[:secure_image_url] ? URI::HTTPS : URI::HTTP
187
+ # url = uri_class.build({:host => 'graph.facebook.com', :path => "/#{uid}/picture"})
188
+ #
189
+ # query = if options[:image_size].is_a?(String)
190
+ # { :type => options[:image_size] }
191
+ # elsif options[:image_size].is_a?(Hash)
192
+ # options[:image_size]
193
+ # end
194
+ # url.query = Rack::Utils.build_query(query) if query
195
+ #
196
+ # url.to_s
197
+ # end
198
+
199
+ def appsecret_proof
200
+ @appsecret_proof ||= OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, client.secret, access_token.token)
201
+ end
202
+
203
+
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'omniauth/irm_health/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'omniauth-irm_health'
7
+ s.version = OmniAuth::IrmHealth::VERSION
8
+ s.authors = ['Youngjoon Choi']
9
+ s.email = ['ejoonie@irm.kr']
10
+ s.summary = 'Irm Health OAuth2 Strategy for OmniAuth'
11
+ s.homepage = 'https://github.com/ejoonie-irm/omniauth-irm_health'
12
+ s.license = 'MIT'
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
17
+ s.require_paths = ['lib']
18
+
19
+ s.add_runtime_dependency 'omniauth-oauth2' #, '~> 1.1'
20
+
21
+ s.add_development_dependency 'minitest'
22
+ s.add_development_dependency 'mocha'
23
+ s.add_development_dependency 'rake'
24
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,60 @@
1
+ require 'bundler/setup'
2
+ require 'minitest/autorun'
3
+ require 'mocha/setup'
4
+ require 'omniauth/strategies/irm_health'
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
+ IRM_AUTH_BASE_URL = 'https://ophies.irm.kr'
35
+ IRM_OPHIES_BASE_URL = 'https://ophies.irm.kr'
36
+
37
+ def setup
38
+
39
+ @request = stubs('Request')
40
+ @request.stubs(:params).returns({})
41
+ # @request.stubs(:cookies).returns({})
42
+ @request.stubs(:env).returns({})
43
+ @request.stubs(:scheme).returns({})
44
+ @request.stubs(:ssl?).returns(false)
45
+
46
+ @client_id = '123'
47
+ @client_secret = '53cr3tz'
48
+ end
49
+
50
+ def strategy
51
+ @strategy ||= begin
52
+ args = [@client_id, @client_secret, @options].compact
53
+ OmniAuth::Strategies::IrmHealth.new(nil, *args).tap do |strategy|
54
+ strategy.stubs(:request).returns(@request)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ 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,485 @@
1
+ require 'helper'
2
+ require 'omniauth-irm_health'
3
+ require 'openssl'
4
+ require 'base64'
5
+
6
+ class StrategyTest < StrategyTestCase
7
+ include OAuth2StrategyTests
8
+ end
9
+
10
+ class ClientTest < StrategyTestCase
11
+ test 'has correct IrmHealth(Ophies) site' do
12
+ assert_equal IRM_AUTH_BASE_URL, strategy.client.site
13
+ end
14
+
15
+ test 'has correct authorize url' do
16
+ assert_equal '/auth/oauth2/auth', strategy.client.options[:authorize_url]
17
+ end
18
+
19
+ test 'has correct token url' do
20
+ assert_equal '/auth/oauth2/token', strategy.client.options[:token_url]
21
+ end
22
+ end
23
+
24
+ class CallbackUrlTest < StrategyTestCase
25
+ test "returns the default callback url" do
26
+ url_base = IRM_OPHIES_BASE_URL
27
+ callback_url = "#{IRM_OPHIES_BASE_URL}/auth/oauth2/irm_health/callback"
28
+
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 callback_url, strategy.callback_url
32
+ end
33
+
34
+ # test "returns path from callback_path option" do
35
+ # @options = { :callback_path => "/auth/FB/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/FB/done", strategy.callback_url
40
+ # end
41
+
42
+ # test "returns url from callback_url option" do
43
+ # url = 'https://auth.myapp.com/auth/fb/callback'
44
+ # @options = { :callback_url => url }
45
+ # assert_equal url, strategy.callback_url
46
+ # end
47
+ end
48
+
49
+ class AuthorizeParamsTest < StrategyTestCase
50
+ test 'includes default scope for email' do
51
+ assert strategy.authorize_params.is_a?(Hash)
52
+ assert_equal 'email', strategy.authorize_params[:scope]
53
+ end
54
+
55
+ test 'includes default access type as offline' do
56
+ assert strategy.authorize_params.is_a? Hash
57
+ assert_equal 'offline', strategy.authorize_params[:access_type]
58
+ end
59
+
60
+ # test 'includes display parameter from request when present' do
61
+ # @request.stubs(:params).returns({ 'display' => 'touch' })
62
+ # assert strategy.authorize_params.is_a?(Hash)
63
+ # assert_equal 'touch', strategy.authorize_params[:display]
64
+ # end
65
+
66
+ # test 'includes auth_type parameter from request when present' do
67
+ # @request.stubs(:params).returns({ 'auth_type' => 'reauthenticate' })
68
+ # assert strategy.authorize_params.is_a?(Hash)
69
+ # assert_equal 'reauthenticate', strategy.authorize_params[:auth_type]
70
+ # end
71
+
72
+ # test 'overrides default scope with parameter passed from request' do
73
+ # @request.stubs(:params).returns({ 'scope' => 'email' })
74
+ # assert strategy.authorize_params.is_a?(Hash)
75
+ # assert_equal 'email', strategy.authorize_params[:scope]
76
+ # end
77
+ end
78
+
79
+ # N/A
80
+ # class TokenParamsTest < StrategyTestCase
81
+ # test 'has correct parse strategy' do
82
+ # assert_equal :query, strategy.token_params[:parse]
83
+ # end
84
+ # end
85
+
86
+ # N/A
87
+ # class AccessTokenOptionsTest < StrategyTestCase
88
+ # test 'has correct param name by default' do
89
+ # assert_equal 'access_token', strategy.access_token_options[:param_name]
90
+ # end
91
+ #
92
+ # test 'has correct header format by default' do
93
+ # assert_equal 'OAuth %s', strategy.access_token_options[:header_format]
94
+ # end
95
+ # end
96
+
97
+ class UidTest < StrategyTestCase
98
+ def setup
99
+ super
100
+ strategy.stubs(:raw_info).returns({ 'uid' => '123' })
101
+ end
102
+
103
+ test 'returns the id from raw_info' do
104
+ assert_equal '123', strategy.uid
105
+ end
106
+ end
107
+
108
+ class InfoTest < StrategyTestCase
109
+ test 'contains username and email' do
110
+ strategy.stubs(:raw_info).returns({ username: 'user01', email: 'test01@irm.kr'})
111
+ end
112
+
113
+
114
+ # test 'returns the secure facebook avatar url when `secure_image_url` option is specified' do
115
+ # @options = { :secure_image_url => true }
116
+ # raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
117
+ # strategy.stubs(:raw_info).returns(raw_info)
118
+ # assert_equal 'https://graph.facebook.com/321/picture', strategy.info['image']
119
+ # end
120
+
121
+ # test 'returns the image with size specified in the `image_size` option' do
122
+ # @options = { :image_size => 'normal' }
123
+ # raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
124
+ # strategy.stubs(:raw_info).returns(raw_info)
125
+ # assert_equal 'http://graph.facebook.com/321/picture?type=normal', strategy.info['image']
126
+ # end
127
+ #
128
+ # test 'returns the image with width and height specified in the `image_size` option' do
129
+ # @options = { :image_size => { :width => 123, :height => 987 } }
130
+ # raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
131
+ # strategy.stubs(:raw_info).returns(raw_info)
132
+ # assert_match 'width=123', strategy.info['image']
133
+ # assert_match 'height=987', strategy.info['image']
134
+ # assert_match 'http://graph.facebook.com/321/picture?', strategy.info['image']
135
+ # end
136
+ end
137
+
138
+ class InfoTestOptionalDataPresent < StrategyTestCase
139
+ def setup
140
+ super
141
+ @raw_info ||= { 'username' => 'Fred Smith' }
142
+ strategy.stubs(:raw_info).returns(@raw_info)
143
+ end
144
+
145
+ test 'returns the username' do
146
+ assert_equal 'Fred Smith', strategy.info['name']
147
+ end
148
+
149
+ test 'returns the email' do
150
+ @raw_info['email'] = 'test01@irm.kr'
151
+ assert_equal 'test01@irm.kr', strategy.info['email']
152
+ end
153
+
154
+ # test 'returns the username as nickname' do
155
+ # @raw_info['username'] = 'fredsmith'
156
+ # assert_equal 'fredsmith', strategy.info['nickname']
157
+ # end
158
+
159
+ # test 'returns the first name' do
160
+ # @raw_info['first_name'] = 'Fred'
161
+ # assert_equal 'Fred', strategy.info['first_name']
162
+ # end
163
+ #
164
+ # test 'returns the last name' do
165
+ # @raw_info['last_name'] = 'Smith'
166
+ # assert_equal 'Smith', strategy.info['last_name']
167
+ # end
168
+ #
169
+ # test 'returns the location name as location' do
170
+ # @raw_info['location'] = { 'id' => '104022926303756', 'name' => 'Palo Alto, California' }
171
+ # assert_equal 'Palo Alto, California', strategy.info['location']
172
+ # end
173
+ #
174
+ # test 'returns bio as description' do
175
+ # @raw_info['bio'] = 'I am great'
176
+ # assert_equal 'I am great', strategy.info['description']
177
+ # end
178
+ #
179
+ # test 'returns the facebook avatar url' do
180
+ # @raw_info['id'] = '321'
181
+ # assert_equal 'http://graph.facebook.com/321/picture', strategy.info['image']
182
+ # end
183
+ #
184
+ # test 'returns the Facebook link as the Facebook url' do
185
+ # @raw_info['link'] = 'http://www.facebook.com/fredsmith'
186
+ # assert_kind_of Hash, strategy.info['urls']
187
+ # assert_equal 'http://www.facebook.com/fredsmith', strategy.info['urls']['Facebook']
188
+ # end
189
+ #
190
+ # test 'returns website url' do
191
+ # @raw_info['website'] = 'https://my-wonderful-site.com'
192
+ # assert_kind_of Hash, strategy.info['urls']
193
+ # assert_equal 'https://my-wonderful-site.com', strategy.info['urls']['Website']
194
+ # end
195
+ #
196
+ # test 'return both Facebook link and website urls' do
197
+ # @raw_info['link'] = 'http://www.facebook.com/fredsmith'
198
+ # @raw_info['website'] = 'https://my-wonderful-site.com'
199
+ # assert_kind_of Hash, strategy.info['urls']
200
+ # assert_equal 'http://www.facebook.com/fredsmith', strategy.info['urls']['Facebook']
201
+ # assert_equal 'https://my-wonderful-site.com', strategy.info['urls']['Website']
202
+ # end
203
+ #
204
+ # test 'returns the positive verified status' do
205
+ # @raw_info['verified'] = true
206
+ # assert strategy.info['verified']
207
+ # end
208
+ #
209
+ # test 'returns the negative verified status' do
210
+ # @raw_info['verified'] = false
211
+ # refute strategy.info['verified']
212
+ # end
213
+ end
214
+
215
+ class InfoTestOptionalDataNotPresent < StrategyTestCase
216
+ def setup
217
+ super
218
+ @raw_info ||= { 'name' => 'Fred Smith' }
219
+ strategy.stubs(:raw_info).returns(@raw_info)
220
+ end
221
+
222
+ test 'has no email key' do
223
+ refute_has_key 'email', strategy.info
224
+ end
225
+
226
+ test 'has no nickname key' do
227
+ refute_has_key 'nickname', strategy.info
228
+ end
229
+
230
+ test 'has no first name key' do
231
+ refute_has_key 'first_name', strategy.info
232
+ end
233
+
234
+ test 'has no last name key' do
235
+ refute_has_key 'last_name', strategy.info
236
+ end
237
+
238
+ test 'has no location key' do
239
+ refute_has_key 'location', strategy.info
240
+ end
241
+
242
+ test 'has no description key' do
243
+ refute_has_key 'description', strategy.info
244
+ end
245
+
246
+ test 'has no urls' do
247
+ refute_has_key 'urls', strategy.info
248
+ end
249
+
250
+ test 'has no verified key' do
251
+ refute_has_key 'verified', strategy.info
252
+ end
253
+ end
254
+
255
+ class RawInfoTest < StrategyTestCase
256
+ def setup
257
+ super
258
+ @access_token = stub('OAuth2::AccessToken')
259
+ @appsecret_proof = 'appsecret_proof'
260
+ @options = {:appsecret_proof => @appsecret_proof}
261
+ end
262
+
263
+ test "performs a GET to IRM_AUTH_BASE_URL/me" do
264
+ strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
265
+ strategy.stubs(:access_token).returns(@access_token)
266
+ # params = {:params => @options}
267
+ # @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response'))
268
+ @access_token.expects(:get).with('/me').returns(stub_everything('OAuth2::Response'))
269
+ strategy.raw_info
270
+ end
271
+
272
+ # test 'performs a GET to https://graph.facebook.com/me with locale' do
273
+ # @options.merge!({ :locale => 'cs_CZ' })
274
+ # strategy.stubs(:access_token).returns(@access_token)
275
+ # strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
276
+ # params = {:params => @options}
277
+ # @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response'))
278
+ # strategy.raw_info
279
+ # end
280
+ #
281
+ # test 'performs a GET to https://graph.facebook.com/me with info_fields' do
282
+ # @options.merge!({:info_fields => 'about'})
283
+ # strategy.stubs(:access_token).returns(@access_token)
284
+ # strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
285
+ # params = {:params => {:appsecret_proof => @appsecret_proof, :fields => 'about'}}
286
+ # @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response'))
287
+ # strategy.raw_info
288
+ # end
289
+
290
+ test 'returns a Hash' do
291
+ strategy.stubs(:access_token).returns(@access_token)
292
+ strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
293
+ raw_response = stub('Faraday::Response')
294
+ raw_response.stubs(:body).returns('{ "ohai": "thar" }')
295
+ raw_response.stubs(:status).returns(200)
296
+ raw_response.stubs(:headers).returns({'Content-Type' => 'application/json' })
297
+ oauth2_response = OAuth2::Response.new(raw_response)
298
+ # params = {:params => @options}
299
+ @access_token.stubs(:get).with('/me').returns(oauth2_response)
300
+ assert_kind_of Hash, strategy.raw_info
301
+ assert_equal 'thar', strategy.raw_info['ohai']
302
+ end
303
+
304
+ test 'returns an empty hash when the response is false' do
305
+ strategy.stubs(:access_token).returns(@access_token)
306
+ strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
307
+ oauth2_response = stub('OAuth2::Response', :parsed => false)
308
+ # params = {:params => @options}
309
+ @access_token.stubs(:get).with('/me').returns(oauth2_response)
310
+ assert_kind_of Hash, strategy.raw_info
311
+ assert_equal({}, strategy.raw_info)
312
+ end
313
+
314
+ test 'should not include raw_info in extras hash when skip_info is specified' do
315
+ @options = { :skip_info => true }
316
+ strategy.stubs(:raw_info).returns({:foo => 'bar' })
317
+ refute_has_key 'raw_info', strategy.extra
318
+ end
319
+ end
320
+
321
+ class CredentialsTest < StrategyTestCase
322
+ def setup
323
+ super
324
+ @access_token = stub('OAuth2::AccessToken')
325
+ @access_token.stubs(:token)
326
+ @access_token.stubs(:expires?)
327
+ @access_token.stubs(:expires_at)
328
+ @access_token.stubs(:refresh_token)
329
+ strategy.stubs(:access_token).returns(@access_token)
330
+ end
331
+
332
+ test 'returns a Hash' do
333
+ assert_kind_of Hash, strategy.credentials
334
+ end
335
+
336
+ test 'returns the token' do
337
+ @access_token.stubs(:token).returns('123')
338
+ assert_equal '123', strategy.credentials['token']
339
+ end
340
+
341
+ test 'returns the expiry status' do
342
+ @access_token.stubs(:expires?).returns(true)
343
+ assert strategy.credentials['expires']
344
+
345
+ @access_token.stubs(:expires?).returns(false)
346
+ refute strategy.credentials['expires']
347
+ end
348
+
349
+ test 'returns the refresh token and expiry time when expiring' do
350
+ ten_mins_from_now = (Time.now + 600).to_i
351
+ @access_token.stubs(:expires?).returns(true)
352
+ @access_token.stubs(:refresh_token).returns('321')
353
+ @access_token.stubs(:expires_at).returns(ten_mins_from_now)
354
+ assert_equal '321', strategy.credentials['refresh_token']
355
+ assert_equal ten_mins_from_now, strategy.credentials['expires_at']
356
+ end
357
+
358
+ test 'does not return the refresh token when test is nil and expiring' do
359
+ @access_token.stubs(:expires?).returns(true)
360
+ @access_token.stubs(:refresh_token).returns(nil)
361
+ assert_nil strategy.credentials['refresh_token']
362
+ refute_has_key 'refresh_token', strategy.credentials
363
+ end
364
+
365
+ test 'does not return the refresh token when not expiring' do
366
+ @access_token.stubs(:expires?).returns(false)
367
+ @access_token.stubs(:refresh_token).returns('XXX')
368
+ assert_nil strategy.credentials['refresh_token']
369
+ refute_has_key 'refresh_token', strategy.credentials
370
+ end
371
+ end
372
+
373
+ class ExtraTest < StrategyTestCase
374
+ def setup
375
+ super
376
+ @raw_info = { 'name' => 'Fred Smith' }
377
+ strategy.stubs(:raw_info).returns(@raw_info)
378
+ end
379
+
380
+ test 'extra is not empty' do
381
+ refute_empty(strategy.extra)
382
+ end
383
+
384
+ test 'contains raw info' do
385
+ assert_has_key "raw_info", strategy.extra
386
+ assert_equal({ 'raw_info' => @raw_info }, strategy.extra)
387
+ end
388
+ end
389
+
390
+ # module SignedRequestHelpers
391
+ # def signed_request(payload, secret)
392
+ # encoded_payload = base64_encode_url(MultiJson.encode(payload))
393
+ # encoded_signature = base64_encode_url(signature(encoded_payload, secret))
394
+ # [encoded_signature, encoded_payload].join('.')
395
+ # end
396
+ #
397
+ # def base64_encode_url(value)
398
+ # Base64.encode64(value).tr('+/', '-_').gsub(/\n/, '')
399
+ # end
400
+ #
401
+ # def signature(payload, secret, algorithm = OpenSSL::Digest::SHA256.new)
402
+ # OpenSSL::HMAC.digest(algorithm, secret, payload)
403
+ # end
404
+ # end
405
+
406
+ module SignedRequestTests
407
+ # class TestCase < StrategyTestCase
408
+ # include SignedRequestHelpers
409
+ # end
410
+
411
+ # class CookieAndParamNotPresentTest < TestCase
412
+ # test 'is nil' do
413
+ # assert_nil strategy.send(:signed_request_from_cookie)
414
+ # end
415
+ #
416
+ # test 'throws an error on calling build_access_token' do
417
+ # assert_raises(OmniAuth::Strategies::IrmHealth::NoAuthorizationCodeError) { strategy.send(:with_authorization_code!) {} }
418
+ # end
419
+ # end
420
+
421
+ # class CookiePresentTest < TestCase
422
+ # def setup(algo = nil)
423
+ # super()
424
+ # @payload = {
425
+ # 'algorithm' => algo || 'HMAC-SHA256',
426
+ # 'code' => 'm4c0d3z',
427
+ # 'issued_at' => Time.now.to_i,
428
+ # 'user_id' => '123456'
429
+ # }
430
+ #
431
+ # @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload, @client_secret)})
432
+ # end
433
+ #
434
+ # test 'parses the access code out from the cookie' do
435
+ # assert_equal @payload, strategy.send(:signed_request_from_cookie)
436
+ # end
437
+ #
438
+ # test 'throws an error if the algorithm is unknown' do
439
+ # setup('UNKNOWN-ALGO')
440
+ # assert_equal "unknown algorithm: UNKNOWN-ALGO", assert_raises(OmniAuth::Strategies::IrmHealth::UnknownSignatureAlgorithmError) { strategy.send(:signed_request_from_cookie) }.message
441
+ # end
442
+ # end
443
+
444
+ # class EmptySignedRequestTest < TestCase
445
+ # def setup
446
+ # super
447
+ # @request.stubs(:params).returns({'signed_request' => ''})
448
+ # end
449
+ #
450
+ # test 'empty param' do
451
+ # assert_equal nil, strategy.send(:signed_request_from_cookie)
452
+ # end
453
+ # end
454
+
455
+ # class MissingCodeInParamsRequestTest < TestCase
456
+ # def setup
457
+ # super
458
+ # @request.stubs(:params).returns({})
459
+ # end
460
+ #
461
+ # test 'calls fail! when a code is not included in the params' do
462
+ # strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(Exception))
463
+ # strategy.callback_phase
464
+ # end
465
+ # end
466
+
467
+ # class MissingCodeInCookieRequestTest < TestCase
468
+ # def setup(algo = nil)
469
+ # super()
470
+ # @payload = {
471
+ # 'algorithm' => algo || 'HMAC-SHA256',
472
+ # 'code' => nil,
473
+ # 'issued_at' => Time.now.to_i,
474
+ # 'user_id' => '123456'
475
+ # }
476
+ #
477
+ # @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload, @client_secret)})
478
+ # end
479
+ #
480
+ # test 'calls fail! when a code is not included in the cookie' do
481
+ # strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(Exception))
482
+ # strategy.callback_phase
483
+ # end
484
+ # end
485
+ end