omniauth-rightsignature 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.
@@ -0,0 +1,62 @@
1
+ module OmniAuth
2
+ class Builder < ::Rack::Builder
3
+ def initialize(app, &block)
4
+ @options = nil
5
+ if rack14?
6
+ super
7
+ else
8
+ @app = app
9
+ super(&block)
10
+ @ins << @app
11
+ end
12
+ end
13
+
14
+ def rack14?
15
+ Rack.release.split('.')[1].to_i >= 4
16
+ end
17
+
18
+ def on_failure(&block)
19
+ OmniAuth.config.on_failure = block
20
+ end
21
+
22
+ def before_options_phase(&block)
23
+ OmniAuth.config.before_options_phase = block
24
+ end
25
+
26
+ def before_request_phase(&block)
27
+ OmniAuth.config.before_request_phase = block
28
+ end
29
+
30
+ def before_callback_phase(&block)
31
+ OmniAuth.config.before_callback_phase = block
32
+ end
33
+
34
+ def configure(&block)
35
+ OmniAuth.configure(&block)
36
+ end
37
+
38
+ def options(options = false)
39
+ return @options || {} if options == false
40
+ @options = options
41
+ end
42
+
43
+ def provider(klass, *args, &block)
44
+ if klass.is_a?(Class)
45
+ middleware = klass
46
+ else
47
+ begin
48
+ middleware = OmniAuth::Strategies.const_get("#{OmniAuth::Utils.camelize(klass.to_s)}")
49
+ rescue NameError
50
+ raise(LoadError.new("Could not find matching strategy for #{klass.inspect}. You may need to install an additional gem (such as omniauth-#{klass})."))
51
+ end
52
+ end
53
+
54
+ args.last.is_a?(Hash) ? args.push(options.merge(args.pop)) : args.push(options)
55
+ use middleware, *args, &block
56
+ end
57
+
58
+ def call(env)
59
+ to_app.call(env)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,44 @@
1
+ module OmniAuth
2
+ # This simple Rack endpoint that serves as the default
3
+ # 'failure' mechanism for OmniAuth. If a strategy fails for
4
+ # any reason this endpoint will be invoked. The default behavior
5
+ # is to redirect to `/auth/failure` except in the case of
6
+ # a development `RACK_ENV`, in which case an exception will
7
+ # be raised.
8
+ class FailureEndpoint
9
+ attr_reader :env
10
+
11
+ def self.call(env)
12
+ new(env).call
13
+ end
14
+
15
+ def initialize(env)
16
+ @env = env
17
+ end
18
+
19
+ def call
20
+ raise_out! if OmniAuth.config.failure_raise_out_environments.include?(ENV['RACK_ENV'].to_s)
21
+ redirect_to_failure
22
+ end
23
+
24
+ def raise_out!
25
+ fail(env['omniauth.error'] || OmniAuth::Error.new(env['omniauth.error.type']))
26
+ end
27
+
28
+ def redirect_to_failure
29
+ message_key = env['omniauth.error.type']
30
+ new_path = "#{env['SCRIPT_NAME']}#{OmniAuth.config.path_prefix}/failure?message=#{message_key}#{origin_query_param}#{strategy_name_query_param}"
31
+ Rack::Response.new(['302 Moved'], 302, 'Location' => new_path).finish
32
+ end
33
+
34
+ def strategy_name_query_param
35
+ return '' unless env['omniauth.error.strategy']
36
+ "&strategy=#{env['omniauth.error.strategy'].name}"
37
+ end
38
+
39
+ def origin_query_param
40
+ return '' unless env['omniauth.origin']
41
+ "&origin=#{Rack::Utils.escape(env['omniauth.origin'])}"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,81 @@
1
+ body {
2
+ background: #ccc;
3
+ font-family: "Lucida Grande", "Lucida Sans", Helvetica, Arial, sans-serif;
4
+ }
5
+
6
+ h1 {
7
+ text-align: center;
8
+ margin: 30px auto 0px;
9
+ font-size: 18px;
10
+ padding: 10px 10px 15px;
11
+ background: #555;
12
+ color: white;
13
+ width: 320px;
14
+ border: 10px solid #444;
15
+ border-bottom: 0;
16
+ -moz-border-radius-topleft: 10px;
17
+ -moz-border-radius-topright: 10px;
18
+ -webkit-border-top-left-radius: 10px;
19
+ -webkit-border-top-right-radius: 10px;
20
+ border-top-left-radius: 10px;
21
+ border-top-right-radius: 10px;
22
+ }
23
+
24
+ h1, form {
25
+ -moz-box-shadow: 2px 2px 7px rgba(0,0,0,0.3);
26
+ -webkit-box-shadow: 2px 2px 7px rgba(0,0,0,0.3);
27
+ }
28
+
29
+ form {
30
+ background: white;
31
+ border: 10px solid #eee;
32
+ border-top: 0;
33
+ padding: 20px;
34
+ margin: 0px auto 40px;
35
+ width: 300px;
36
+ -moz-border-radius-bottomleft: 10px;
37
+ -moz-border-radius-bottomright: 10px;
38
+ -webkit-border-bottom-left-radius: 10px;
39
+ -webkit-border-bottom-right-radius: 10px;
40
+ border-bottom-left-radius: 10px;
41
+ border-bottom-right-radius: 10px;
42
+ }
43
+
44
+ label {
45
+ display: block;
46
+ font-weight: bold;
47
+ margin-bottom: 5px;
48
+ }
49
+
50
+ input {
51
+ font-size: 18px;
52
+ padding: 4px 8px;
53
+ display: block;
54
+ margin-bottom: 10px;
55
+ width: 280px;
56
+ }
57
+
58
+ input#identifier, input#openid_url {
59
+ background: url(http://openid.net/login-bg.gif) no-repeat;
60
+ background-position: 0 50%;
61
+ padding-left: 18px;
62
+ }
63
+
64
+ button {
65
+ font-size: 22px;
66
+ padding: 4px 8px;
67
+ display: block;
68
+ margin: 20px auto 0;
69
+ }
70
+
71
+ fieldset {
72
+ border: 1px solid #ccc;
73
+ border-left: 0;
74
+ border-right: 0;
75
+ padding: 10px 0;
76
+ }
77
+
78
+ fieldset input {
79
+ width: 260px;
80
+ font-size: 16px;
81
+ }
@@ -0,0 +1,111 @@
1
+ module OmniAuth
2
+ class Form # rubocop:disable ClassLength
3
+ DEFAULT_CSS = File.read(File.expand_path('../form.css', __FILE__))
4
+
5
+ attr_accessor :options
6
+
7
+ def initialize(options = {})
8
+ options[:title] ||= 'Authentication Info Required'
9
+ options[:header_info] ||= ''
10
+ self.options = options
11
+
12
+ @html = ''
13
+ @with_custom_button = false
14
+ @footer = nil
15
+ header(options[:title], options[:header_info])
16
+ end
17
+
18
+ def self.build(options = {}, &block)
19
+ form = OmniAuth::Form.new(options)
20
+ if block.arity > 0
21
+ yield form
22
+ else
23
+ form.instance_eval(&block)
24
+ end
25
+ form
26
+ end
27
+
28
+ def label_field(text, target)
29
+ @html << "\n<label for='#{target}'>#{text}:</label>"
30
+ self
31
+ end
32
+
33
+ def input_field(type, name)
34
+ @html << "\n<input type='#{type}' id='#{name}' name='#{name}'/>"
35
+ self
36
+ end
37
+
38
+ def text_field(label, name)
39
+ label_field(label, name)
40
+ input_field('text', name)
41
+ self
42
+ end
43
+
44
+ def password_field(label, name)
45
+ label_field(label, name)
46
+ input_field('password', name)
47
+ self
48
+ end
49
+
50
+ def button(text)
51
+ @with_custom_button = true
52
+ @html << "\n<button type='submit'>#{text}</button>"
53
+ end
54
+
55
+ def html(html)
56
+ @html << html
57
+ end
58
+
59
+ def fieldset(legend, options = {}, &block)
60
+ @html << "\n<fieldset#{" style='#{options[:style]}'" if options[:style]}#{" id='#{options[:id]}'" if options[:id]}>\n <legend>#{legend}</legend>\n"
61
+ instance_eval(&block)
62
+ @html << "\n</fieldset>"
63
+ self
64
+ end
65
+
66
+ def header(title, header_info)
67
+ @html << <<-HTML
68
+ <!DOCTYPE html>
69
+ <html>
70
+ <head>
71
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
72
+ <title>#{title}</title>
73
+ #{css}
74
+ #{header_info}
75
+ </head>
76
+ <body>
77
+ <h1>#{title}</h1>
78
+ <form method='post' #{"action='#{options[:url]}' " if options[:url]}noValidate='noValidate'>
79
+ HTML
80
+ self
81
+ end
82
+
83
+ def footer
84
+ return self if @footer
85
+ @html << "\n<button type='submit'>Connect</button>" unless @with_custom_button
86
+ @html << <<-HTML
87
+ </form>
88
+ </body>
89
+ </html>
90
+ HTML
91
+ @footer = true
92
+ self
93
+ end
94
+
95
+ def to_html
96
+ footer
97
+ @html
98
+ end
99
+
100
+ def to_response
101
+ footer
102
+ Rack::Response.new(@html, 200, 'content-type' => 'text/html').finish
103
+ end
104
+
105
+ protected
106
+
107
+ def css
108
+ "\n<style type='text/css'>#{OmniAuth.config.form_css}</style>"
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,5 @@
1
+ module OmniAuth
2
+ module Rightsignature
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,44 @@
1
+ # oa-oauth/lib/omniauth/strategies/rdio.rb
2
+ require 'omniauth-oauth'
3
+ require 'multi_json'
4
+
5
+ module OmniAuth
6
+ module Strategies
7
+ #
8
+ # Authenticate to RightSignature via OAuth and retrieve basic user information.
9
+ # Usage:
10
+ # use OmniAuth::Strategies::RightSignature, 'consumerkey', 'consumersecret'
11
+ #
12
+ class Rightsignature < OmniAuth::Strategies::OAuth
13
+ args [:consumer_key, :consumer_secret]
14
+ option :client_options, {
15
+ :site => 'https://rightsignature.com',
16
+ :request_token_path => '/oauth/request_token',
17
+ :access_token_path => '/oauth/access_token',
18
+ :authorize_url => 'https://rightsignature.com/oauth/authorize'
19
+ }
20
+ option :name, 'rightsignature'
21
+
22
+ #raise 'Error'
23
+ uid {access_token.params['user_id']}
24
+
25
+ info do
26
+ {
27
+ :name => raw_info['name'],
28
+ :email => raw_info['email']
29
+ }
30
+ end
31
+
32
+ extra do
33
+ {
34
+ 'raw_info' => raw_info
35
+ }
36
+ end
37
+
38
+ def raw_info
39
+ @raw_info ||= MultiJson.decode(access_token.get('https://rightsignature.com/api/users/user_details.json').body)
40
+
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,501 @@
1
+ require 'hashie/mash'
2
+
3
+ module OmniAuth
4
+ class NoSessionError < StandardError; end
5
+ # The Strategy is the base unit of OmniAuth's ability to
6
+ # wrangle multiple providers. Each strategy provided by
7
+ # OmniAuth includes this mixin to gain the default functionality
8
+ # necessary to be compatible with the OmniAuth library.
9
+ module Strategy
10
+ def self.included(base)
11
+ OmniAuth.strategies << base
12
+
13
+ base.extend ClassMethods
14
+ base.class_eval do
15
+ option :setup, false
16
+ option :skip_info, false
17
+ end
18
+ end
19
+
20
+ module ClassMethods
21
+ # Returns an inherited set of default options set at the class-level
22
+ # for each strategy.
23
+ def default_options
24
+ return @default_options if instance_variable_defined?(:@default_options) && @default_options
25
+ existing = superclass.respond_to?(:default_options) ? superclass.default_options : {}
26
+ @default_options = OmniAuth::Strategy::Options.new(existing)
27
+ end
28
+
29
+ # This allows for more declarative subclassing of strategies by allowing
30
+ # default options to be set using a simple configure call.
31
+ #
32
+ # @param options [Hash] If supplied, these will be the default options (deep-merged into the superclass's default options).
33
+ # @yield [Options] The options Mash that allows you to set your defaults as you'd like.
34
+ #
35
+ # @example Using a yield to configure the default options.
36
+ #
37
+ # class MyStrategy
38
+ # include OmniAuth::Strategy
39
+ #
40
+ # configure do |c|
41
+ # c.foo = 'bar'
42
+ # end
43
+ # end
44
+ #
45
+ # @example Using a hash to configure the default options.
46
+ #
47
+ # class MyStrategy
48
+ # include OmniAuth::Strategy
49
+ # configure foo: 'bar'
50
+ # end
51
+ def configure(options = nil)
52
+ if block_given?
53
+ yield default_options
54
+ else
55
+ default_options.deep_merge!(options)
56
+ end
57
+ end
58
+
59
+ # Directly declare a default option for your class. This is a useful from
60
+ # a documentation perspective as it provides a simple line-by-line analysis
61
+ # of the kinds of options your strategy provides by default.
62
+ #
63
+ # @param name [Symbol] The key of the default option in your configuration hash.
64
+ # @param value [Object] The value your object defaults to. Nil if not provided.
65
+ #
66
+ # @example
67
+ #
68
+ # class MyStrategy
69
+ # include OmniAuth::Strategy
70
+ #
71
+ # option :foo, 'bar'
72
+ # option
73
+ # end
74
+ def option(name, value = nil)
75
+ default_options[name] = value
76
+ end
77
+
78
+ # Sets (and retrieves) option key names for initializer arguments to be
79
+ # recorded as. This takes care of 90% of the use cases for overriding
80
+ # the initializer in OmniAuth Strategies.
81
+ def args(args = nil)
82
+ if args
83
+ @args = Array(args)
84
+ return
85
+ end
86
+ existing = superclass.respond_to?(:args) ? superclass.args : []
87
+ (instance_variable_defined?(:@args) && @args) || existing
88
+ end
89
+
90
+ %w(uid info extra credentials).each do |fetcher|
91
+ class_eval <<-RUBY
92
+ def #{fetcher}(&block)
93
+ return @#{fetcher}_proc unless block_given?
94
+ @#{fetcher}_proc = block
95
+ end
96
+
97
+ def #{fetcher}_stack(context)
98
+ compile_stack(self.ancestors, :#{fetcher}, context)
99
+ end
100
+ RUBY
101
+ end
102
+
103
+ def compile_stack(ancestors, method, context)
104
+ stack = ancestors.inject([]) do |a, ancestor|
105
+ a << context.instance_eval(&ancestor.send(method)) if ancestor.respond_to?(method) && ancestor.send(method)
106
+ a
107
+ end
108
+ stack.reverse!
109
+ end
110
+ end
111
+
112
+ attr_reader :app, :env, :options, :response
113
+
114
+ # Initializes the strategy by passing in the Rack endpoint,
115
+ # the unique URL segment name for this strategy, and any
116
+ # additional arguments. An `options` hash is automatically
117
+ # created from the last argument if it is a hash.
118
+ #
119
+ # @param app [Rack application] The application on which this middleware is applied.
120
+ #
121
+ # @overload new(app, options = {})
122
+ # If nothing but a hash is supplied, initialized with the supplied options
123
+ # overriding the strategy's default options via a deep merge.
124
+ # @overload new(app, *args, options = {})
125
+ # If the strategy has supplied custom arguments that it accepts, they may
126
+ # will be passed through and set to the appropriate values.
127
+ #
128
+ # @yield [Options] Yields options to block for further configuration.
129
+ def initialize(app, *args, &block) # rubocop:disable UnusedMethodArgument
130
+ @app = app
131
+ @env = nil
132
+ @options = self.class.default_options.dup
133
+
134
+ options.deep_merge!(args.pop) if args.last.is_a?(Hash)
135
+ options.name ||= self.class.to_s.split('::').last.downcase
136
+
137
+ self.class.args.each do |arg|
138
+ break if args.empty?
139
+ options[arg] = args.shift
140
+ end
141
+
142
+ # Make sure that all of the args have been dealt with, otherwise error out.
143
+ fail(ArgumentError.new("Received wrong number of arguments. #{args.inspect}")) unless args.empty?
144
+
145
+ yield options if block_given?
146
+ end
147
+
148
+ def inspect
149
+ "#<#{self.class}>"
150
+ end
151
+
152
+ # Direct access to the OmniAuth logger, automatically prefixed
153
+ # with this strategy's name.
154
+ #
155
+ # @example
156
+ # log :warn, "This is a warning."
157
+ def log(level, message)
158
+ OmniAuth.logger.send(level, "(#{name}) #{message}")
159
+ end
160
+
161
+ # Duplicates this instance and runs #call! on it.
162
+ # @param [Hash] The Rack environment.
163
+ def call(env)
164
+ dup.call!(env)
165
+ end
166
+
167
+ # The logic for dispatching any additional actions that need
168
+ # to be taken. For instance, calling the request phase if
169
+ # the request path is recognized.
170
+ #
171
+ # @param env [Hash] The Rack environment.
172
+ def call!(env) # rubocop:disable CyclomaticComplexity, PerceivedComplexity
173
+ unless env['rack.session']
174
+ error = OmniAuth::NoSessionError.new('You must provide a session to use OmniAuth.')
175
+ fail(error)
176
+ end
177
+
178
+ @env = env
179
+ @env['omniauth.strategy'] = self if on_auth_path?
180
+
181
+ return mock_call!(env) if OmniAuth.config.test_mode
182
+ return options_call if on_auth_path? && options_request?
183
+ return request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
184
+ return callback_call if on_callback_path?
185
+ return other_phase if respond_to?(:other_phase)
186
+ @app.call(env)
187
+ end
188
+
189
+ # Responds to an OPTIONS request.
190
+ def options_call
191
+ OmniAuth.config.before_options_phase.call(env) if OmniAuth.config.before_options_phase
192
+ verbs = OmniAuth.config.allowed_request_methods.collect(&:to_s).collect(&:upcase).join(', ')
193
+ [200, {'Allow' => verbs}, []]
194
+ end
195
+
196
+ # Performs the steps necessary to run the request phase of a strategy.
197
+ def request_call # rubocop:disable CyclomaticComplexity, MethodLength, PerceivedComplexity
198
+ setup_phase
199
+ log :info, 'Request phase initiated.'
200
+ # store query params from the request url, extracted in the callback_phase
201
+ session['omniauth.params'] = request.params
202
+ OmniAuth.config.before_request_phase.call(env) if OmniAuth.config.before_request_phase
203
+ if options.form.respond_to?(:call)
204
+ log :info, 'Rendering form from supplied Rack endpoint.'
205
+ options.form.call(env)
206
+ elsif options.form
207
+ log :info, 'Rendering form from underlying application.'
208
+ call_app!
209
+ else
210
+ if request.params['origin']
211
+ env['rack.session']['omniauth.origin'] = request.params['origin']
212
+ elsif env['HTTP_REFERER'] && !env['HTTP_REFERER'].match(/#{request_path}$/)
213
+ env['rack.session']['omniauth.origin'] = env['HTTP_REFERER']
214
+ end
215
+ request_phase
216
+ end
217
+ end
218
+
219
+ # Performs the steps necessary to run the callback phase of a strategy.
220
+ def callback_call
221
+ setup_phase
222
+ log :info, 'Callback phase initiated.'
223
+ @env['omniauth.origin'] = session.delete('omniauth.origin')
224
+ @env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
225
+ @env['omniauth.params'] = session.delete('omniauth.params') || {}
226
+ OmniAuth.config.before_callback_phase.call(@env) if OmniAuth.config.before_callback_phase
227
+ callback_phase
228
+ end
229
+
230
+ # Returns true if the environment recognizes either the
231
+ # request or callback path.
232
+ def on_auth_path?
233
+ on_request_path? || on_callback_path?
234
+ end
235
+
236
+ def on_request_path?
237
+ if options.request_path.respond_to?(:call)
238
+ options.request_path.call(env)
239
+ else
240
+ on_path?(request_path)
241
+ end
242
+ end
243
+
244
+ def on_callback_path?
245
+ on_path?(callback_path)
246
+ end
247
+
248
+ def on_path?(path)
249
+ current_path.casecmp(path) == 0
250
+ end
251
+
252
+ def options_request?
253
+ request.request_method == 'OPTIONS'
254
+ end
255
+
256
+ # This is called in lieu of the normal request process
257
+ # in the event that OmniAuth has been configured to be
258
+ # in test mode.
259
+ def mock_call!(*)
260
+ return mock_request_call if on_request_path?
261
+ return mock_callback_call if on_callback_path?
262
+ call_app!
263
+ end
264
+
265
+ def mock_request_call
266
+ setup_phase
267
+
268
+ session['omniauth.params'] = request.params
269
+ OmniAuth.config.before_request_phase.call(env) if OmniAuth.config.before_request_phase
270
+ if request.params['origin']
271
+ @env['rack.session']['omniauth.origin'] = request.params['origin']
272
+ elsif env['HTTP_REFERER'] && !env['HTTP_REFERER'].match(/#{request_path}$/)
273
+ @env['rack.session']['omniauth.origin'] = env['HTTP_REFERER']
274
+ end
275
+
276
+ redirect(callback_url)
277
+ end
278
+
279
+ def mock_callback_call
280
+ setup_phase
281
+ mocked_auth = OmniAuth.mock_auth_for(name.to_s)
282
+ if mocked_auth.is_a?(Symbol)
283
+ fail!(mocked_auth)
284
+ else
285
+ @env['omniauth.auth'] = mocked_auth
286
+ @env['omniauth.params'] = session.delete('omniauth.params') || {}
287
+ @env['omniauth.origin'] = session.delete('omniauth.origin')
288
+ @env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
289
+ OmniAuth.config.before_callback_phase.call(@env) if OmniAuth.config.before_callback_phase
290
+ call_app!
291
+ end
292
+ end
293
+
294
+ # The setup phase looks for the `:setup` option to exist and,
295
+ # if it is, will call either the Rack endpoint supplied to the
296
+ # `:setup` option or it will call out to the setup path of the
297
+ # underlying application. This will default to `/auth/:provider/setup`.
298
+ def setup_phase
299
+ if options[:setup].respond_to?(:call)
300
+ log :info, 'Setup endpoint detected, running now.'
301
+ options[:setup].call(env)
302
+ elsif options.setup?
303
+ log :info, 'Calling through to underlying application for setup.'
304
+ setup_env = env.merge('PATH_INFO' => setup_path, 'REQUEST_METHOD' => 'GET')
305
+ call_app!(setup_env)
306
+ end
307
+ end
308
+
309
+ # @abstract This method is called when the user is on the request path. You should
310
+ # perform any information gathering you need to be able to authenticate
311
+ # the user in this phase.
312
+ def request_phase
313
+ fail(NotImplementedError)
314
+ end
315
+
316
+ def uid
317
+ self.class.uid_stack(self).last
318
+ end
319
+
320
+ def info
321
+ merge_stack(self.class.info_stack(self))
322
+ end
323
+
324
+ def credentials
325
+ merge_stack(self.class.credentials_stack(self))
326
+ end
327
+
328
+ def extra
329
+ merge_stack(self.class.extra_stack(self))
330
+ end
331
+
332
+ def auth_hash
333
+ hash = AuthHash.new(:provider => name, :uid => uid)
334
+ hash.info = info unless skip_info?
335
+ hash.credentials = credentials if credentials
336
+ hash.extra = extra if extra
337
+ hash
338
+ end
339
+
340
+ # Determines whether or not user info should be retrieved. This
341
+ # allows some strategies to save a call to an external API service
342
+ # for existing users. You can use it either by setting the `:skip_info`
343
+ # to true or by setting `:skip_info` to a Proc that takes a uid and
344
+ # evaluates to true when you would like to skip info.
345
+ #
346
+ # @example
347
+ #
348
+ # use MyStrategy, :skip_info => lambda{|uid| User.find_by_uid(uid)}
349
+ def skip_info?
350
+ if options.skip_info?
351
+ if options.skip_info.respond_to?(:call)
352
+ return options.skip_info.call(uid)
353
+ else
354
+ return true
355
+ end
356
+ end
357
+ false
358
+ end
359
+
360
+ def callback_phase
361
+ env['omniauth.auth'] = auth_hash
362
+ call_app!
363
+ end
364
+
365
+ def path_prefix
366
+ options[:path_prefix] || OmniAuth.config.path_prefix
367
+ end
368
+
369
+ def custom_path(kind)
370
+ if options[kind].respond_to?(:call)
371
+ result = options[kind].call(env)
372
+ return nil unless result.is_a?(String)
373
+ result
374
+ else
375
+ options[kind]
376
+ end
377
+ end
378
+
379
+ def request_path
380
+ @request_path ||= options[:request_path].is_a?(String) ? options[:request_path] : "#{path_prefix}/#{name}"
381
+ end
382
+
383
+ def callback_path
384
+ @callback_path ||= begin
385
+ path = options[:callback_path] if options[:callback_path].is_a?(String)
386
+ path ||= current_path if options[:callback_path].respond_to?(:call) && options[:callback_path].call(env)
387
+ path ||= custom_path(:request_path)
388
+ path ||= "#{path_prefix}/#{name}/callback"
389
+ path
390
+ end
391
+ end
392
+
393
+ def setup_path
394
+ options[:setup_path] || "#{path_prefix}/#{name}/setup"
395
+ end
396
+
397
+ CURRENT_PATH_REGEX = /\/$/
398
+ EMPTY_STRING = ''.freeze
399
+ def current_path
400
+ @current_path ||= request.path_info.downcase.sub(CURRENT_PATH_REGEX, EMPTY_STRING)
401
+ end
402
+
403
+ def query_string
404
+ request.query_string.empty? ? '' : "?#{request.query_string}"
405
+ end
406
+
407
+ def call_app!(env = @env)
408
+ @app.call(env)
409
+ end
410
+
411
+ def full_host
412
+ case OmniAuth.config.full_host
413
+ when String
414
+ OmniAuth.config.full_host
415
+ when Proc
416
+ OmniAuth.config.full_host.call(env)
417
+ else
418
+ # in Rack 1.3.x, request.url explodes if scheme is nil
419
+ if request.scheme && request.url.match(URI::ABS_URI)
420
+ uri = URI.parse(request.url.gsub(/\?.*$/, ''))
421
+ uri.path = ''
422
+ # sometimes the url is actually showing http inside rails because the
423
+ # other layers (like nginx) have handled the ssl termination.
424
+ uri.scheme = 'https' if ssl? # rubocop:disable BlockNesting
425
+ uri.to_s
426
+ else ''
427
+ end
428
+ end
429
+ end
430
+
431
+ def callback_url
432
+ full_host + script_name + callback_path + query_string
433
+ end
434
+
435
+ def script_name
436
+ @env['SCRIPT_NAME'] || ''
437
+ end
438
+
439
+ def session
440
+ @env['rack.session']
441
+ end
442
+
443
+ def request
444
+ @request ||= Rack::Request.new(@env)
445
+ end
446
+
447
+ def name
448
+ options.name
449
+ end
450
+
451
+ def redirect(uri)
452
+ r = Rack::Response.new
453
+
454
+ if options[:iframe]
455
+ r.write("<script type='text/javascript' charset='utf-8'>top.location.href = '#{uri}';</script>")
456
+ else
457
+ r.write("Redirecting to #{uri}...")
458
+ r.redirect(uri)
459
+ end
460
+
461
+ r.finish
462
+ end
463
+
464
+ def user_info
465
+ {}
466
+ end
467
+
468
+ def fail!(message_key, exception = nil)
469
+ env['omniauth.error'] = exception
470
+ env['omniauth.error.type'] = message_key.to_sym
471
+ env['omniauth.error.strategy'] = self
472
+
473
+ if exception
474
+ log :error, "Authentication failure! #{message_key}: #{exception.class}, #{exception.message}"
475
+ else
476
+ log :error, "Authentication failure! #{message_key} encountered."
477
+ end
478
+
479
+ OmniAuth.config.on_failure.call(env)
480
+ end
481
+
482
+ class Options < Hashie::Mash; end
483
+
484
+ protected
485
+
486
+ def merge_stack(stack)
487
+ stack.inject({}) do |a, e|
488
+ a.merge!(e)
489
+ a
490
+ end
491
+ end
492
+
493
+ def ssl?
494
+ request.env['HTTPS'] == 'on' ||
495
+ request.env['HTTP_X_FORWARDED_SSL'] == 'on' ||
496
+ request.env['HTTP_X_FORWARDED_SCHEME'] == 'https' ||
497
+ (request.env['HTTP_X_FORWARDED_PROTO'] && request.env['HTTP_X_FORWARDED_PROTO'].split(',')[0] == 'https') ||
498
+ request.env['rack.url_scheme'] == 'https'
499
+ end
500
+ end
501
+ end