omniauth-rightsignature 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/omniauth/form.rb DELETED
@@ -1,111 +0,0 @@
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
@@ -1,501 +0,0 @@
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