opensesame 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +11 -1
  3. data/app/controllers/open_sesame/sessions_controller.rb +6 -2
  4. data/lib/open_sesame.rb +8 -2
  5. data/lib/open_sesame/configuration.rb +23 -8
  6. data/lib/open_sesame/devise.rb +13 -0
  7. data/lib/open_sesame/engine.rb +12 -16
  8. data/lib/open_sesame/failure/devise_app.rb +1 -1
  9. data/lib/open_sesame/github_auth.rb +17 -1
  10. data/lib/open_sesame/github_warden.rb +6 -2
  11. data/lib/open_sesame/helpers/controller_helper.rb +1 -1
  12. data/lib/open_sesame/member.rb +52 -19
  13. data/lib/open_sesame/version.rb +1 -1
  14. data/spec/dummy/app/models/user.rb +8 -0
  15. data/spec/dummy/config/initializers/devise.rb +267 -0
  16. data/spec/dummy/config/initializers/opensesame.rb +5 -4
  17. data/spec/dummy/config/locales/devise.en.yml +59 -0
  18. data/spec/dummy/config/routes.rb +2 -0
  19. data/spec/dummy/db/development.sqlite3 +0 -0
  20. data/spec/dummy/db/migrate/20140410210424_devise_create_users.rb +42 -0
  21. data/spec/dummy/db/schema.rb +19 -1
  22. data/spec/dummy/db/test.sqlite3 +0 -0
  23. data/spec/dummy/log/development.log +153 -0
  24. data/spec/dummy/log/test.log +77170 -0
  25. data/spec/dummy/tmp/cache/assets/C72/560/sprockets%2F454956b6f70061da46ea7e27111c1008 +0 -0
  26. data/spec/dummy/tmp/cache/assets/C96/3A0/sprockets%2F97c9391b36c4982d0c9fc0807276627f +0 -0
  27. data/spec/dummy/tmp/cache/assets/CA9/460/sprockets%2F948e48dc820b40d8161dd1460b2064b9 +0 -0
  28. data/spec/dummy/tmp/cache/assets/CB9/D50/sprockets%2F2945a991966bdb26e54c2d48a63d6225 +0 -0
  29. data/spec/dummy/tmp/cache/assets/CFC/F00/sprockets%2F031f4282e0b852bc633f0bad24e56c63 +0 -0
  30. data/spec/dummy/tmp/cache/assets/D08/BA0/sprockets%2F796774ff7a0a9a7f394dd67d369c8693 +0 -0
  31. data/spec/dummy/tmp/cache/assets/D4C/C80/sprockets%2F3555b9b1ef17e63f54c7f2a819a2ce88 +0 -0
  32. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  33. data/spec/dummy/tmp/cache/assets/D60/A00/sprockets%2F47747aad6a9bcc1d57003331c30e6cfd +0 -0
  34. data/spec/dummy/tmp/cache/assets/D61/6B0/sprockets%2Faa0ef972a2d713f5b0096ead0e9a0681 +0 -0
  35. data/spec/dummy/tmp/cache/assets/D6D/F40/sprockets%2F071c809d0cdd0bbad45a1b9f8d718858 +0 -0
  36. data/spec/dummy/tmp/cache/assets/D9D/E40/sprockets%2F81ceef9ff2401a52fa3d5777afa0348b +0 -0
  37. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  38. data/spec/lib/open_sesame/configuration_spec.rb +9 -4
  39. data/spec/lib/open_sesame/github_warden_spec.rb +13 -8
  40. data/spec/lib/open_sesame/member_spec.rb +9 -25
  41. data/spec/lib/open_sesame/sessions_spec.rb +4 -5
  42. data/spec/spec_helper.rb +7 -5
  43. data/spec/support/capybara.rb +15 -11
  44. data/spec/support/request_helpers.rb +1 -1
  45. data/spec/support/vcr.rb +3 -2
  46. data/spec/vcr/1.9/member/retrieves_attributes_from_github.yml +491 -0
  47. data/spec/vcr/1.9/member/returns_nil_if_no_github_member_found.yml +185 -0
  48. data/spec/vcr/1.9/member/serialize_from_session_returns_member_from_given_member_id.yml +491 -0
  49. data/spec/vcr/1.9/member/serialize_into_session_returns_given_member_id_in_array.yml +491 -0
  50. data/spec/vcr/1.9/session/allows_auto_login.yml +491 -0
  51. data/spec/vcr/1.9/session/enforces_opensesame_login.yml +491 -0
  52. data/spec/vcr/1.9/session/skips_auto_login_if_just_logged_out.yml +491 -0
  53. data/spec/vcr/2.0/member/retrieves_attributes_from_github.yml +208 -0
  54. data/spec/vcr/2.0/member/returns_nil_if_no_github_member_found.yml +67 -0
  55. data/spec/vcr/2.0/member/serialize_from_session_returns_member_from_given_member_id.yml +208 -0
  56. data/spec/vcr/2.0/member/serialize_into_session_returns_given_member_id_in_array.yml +208 -0
  57. data/spec/vcr/2.0/session/allows_auto_login.yml +208 -0
  58. data/spec/vcr/2.0/session/enforces_opensesame_login.yml +208 -0
  59. data/spec/vcr/2.0/session/skips_auto_login_if_just_logged_out.yml +208 -0
  60. metadata +141 -81
  61. data/spec/vcr/member/retrieves_attributes_from_github.yml +0 -46
  62. data/spec/vcr/member/returns_nil_if_no_github_member_found.yml +0 -46
  63. data/spec/vcr/member/serialize_from_session_returns_member_from_given_member_id.yml +0 -89
  64. data/spec/vcr/member/serialize_into_session_returns_given_member_id_in_array.yml +0 -46
  65. data/spec/vcr/session/allows_auto_login.yml +0 -132
  66. data/spec/vcr/session/enforces_opensesame_login.yml +0 -132
  67. data/spec/vcr/session/skips_auto_login_if_just_logged_out.yml +0 -175
  68. data/spec/vcr/session/tries_auto_login_and_ends_up_on_opensesame_page_after_failure.yml +0 -46
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTk0MzdkMjYyNDgyY2YyYjIxNjE1MTlkN2JiNGYyNjU1NzZiMTI0Nw==
5
+ data.tar.gz: !binary |-
6
+ ZGE5OGMyYjkxZmIwYTkyN2Q2ZWNlNDdjZmQzZGZhMTBhNzQ2OTJlYQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ N2I3ZTc2ZmI1MjZjMThjZjFlMzVhMjk0MjBiMmVkMGM3Njk1MGI2Yzk3YjFh
10
+ NzliZWQ1MmU1YzUzMjZiYWVhOTlmYWE3Y2FlZDhjNjZhZDE3MTlmMGYxN2U1
11
+ YjQzYzRjMTJmNzEwZTVjMjA0OTM0MjA4MTNlNzVhNTNjODlkMTQ=
12
+ data.tar.gz: !binary |-
13
+ MDRhMGY1MGNkMTAyMDgzZGY2ZjdiYjBhMmE4YWJlOTlmMmNmNzIzNzRjZWZj
14
+ MzFiMzc3YmE0YTA2MThlOTQzZDRkZDU5NzhmNjhlNzNjMGU2ZjM0NWNlZDU3
15
+ ZmExNTAxZDk4Y2Q1M2QzZWIxZThlMmQ4M2I3YmM3ZThhNjdlYTc=
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # OpenSesame
2
2
 
3
+ [![Build Status](https://secure.travis-ci.org/rossta/opensesame.png)](http://travis-ci.org/rossta/opensesame)
4
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/rossta/opensesame)
5
+
3
6
  OpenSesame is a [Warden](https://github.com/hassox/warden) strategy for providing "walled garden" authentication for access to Rack-based applications via Omniauth. The intent is protect the visibility of your app from the outside world. For example, your company has internal apps and/or staging enviroments for multiple projects and you want something better than HTTP basic auth.
4
7
 
5
8
  Enter OpenSesame. To authenticate, OpenSesame currently uses Omniauth and the Github API to require that a user is both logged in to Github and a member of the Github organization for which OpenSesame is configured.
@@ -26,7 +29,7 @@ require 'opensesame'
26
29
 
27
30
  OpenSesame.configure do |config|
28
31
  config.enable Rails.env.staging?
29
- config.github ENV['GITHUB_APP_ID'], ENV['GITHUB_SECRET']
32
+ config.github ENV['GITHUB_APP_ID'], ENV['GITHUB_SECRET']
30
33
  config.organization 'challengepost'
31
34
  config.mounted_at '/opensesame'
32
35
  end
@@ -39,3 +42,10 @@ Mount OpenSesame in your Rails routes.rb:
39
42
 
40
43
  mount OpenSesame::Engine => OpenSesame.mount_prefix
41
44
  ```
45
+
46
+ Place the following into your appplication_contrrollerb.rb:
47
+
48
+ ```ruby
49
+ before_filter :authenticate_opensesame!
50
+ ```
51
+
@@ -7,8 +7,8 @@ module OpenSesame
7
7
  after_filter :clear_auto_attempt!, :only => :create
8
8
 
9
9
  def new
10
- if warden.message
11
- flash.now[:notice] = warden.message
10
+ if error_message
11
+ flash.now[:notice] = error_message
12
12
  end
13
13
  render :layout => 'open_sesame/application'
14
14
  end
@@ -29,6 +29,10 @@ module OpenSesame
29
29
 
30
30
  protected
31
31
 
32
+ def error_message
33
+ warden.message || env['omniauth.error'] || env['omniauth.error.type']
34
+ end
35
+
32
36
  def attempt_auto_authenticate
33
37
  return unless attempt_auto_access?
34
38
 
data/lib/open_sesame.rb CHANGED
@@ -19,15 +19,21 @@ module OpenSesame
19
19
 
20
20
  @to_configuration = Configuration::CONFIGURABLE_ATTRIBUTES + [:to => :configuration]
21
21
  delegate *@to_configuration
22
- delegate :enabled?, :to => :configuration
22
+ delegate :enabled?, :debug?, :to => :configuration
23
23
 
24
24
  mattr_accessor :configuration
25
25
  @@configuration = Configuration.new
26
26
 
27
27
  def configure(&block)
28
+ configuration.enable! # defaults to true
28
29
  yield configuration
29
30
  configuration
30
31
  end
32
+
33
+ def logger
34
+ @logger ||= defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
35
+ end
31
36
  end
32
37
 
33
- require "open_sesame/engine" if defined?(Rails)
38
+ require "open_sesame/engine" if defined?(Rails)
39
+ Opensesame = OpenSesame
@@ -3,8 +3,15 @@ module OpenSesame
3
3
  class ConfigurationError < RuntimeError; end
4
4
 
5
5
  class Configuration
6
- CONFIGURABLE_ATTRIBUTES = [:organization_name, :mount_prefix, :github_client,
7
- :enabled, :full_host, :auto_access_provider]
6
+ CONFIGURABLE_ATTRIBUTES = [
7
+ :organization_name,
8
+ :mount_prefix,
9
+ :github_application,
10
+ :enabled,
11
+ :debug,
12
+ :full_host,
13
+ :auto_access_provider
14
+ ]
8
15
  attr_accessor *CONFIGURABLE_ATTRIBUTES
9
16
 
10
17
  def mounted_at(mount_prefix)
@@ -16,7 +23,11 @@ module OpenSesame
16
23
  end
17
24
 
18
25
  def github(client_id, client_secret)
19
- self.github_client = { :id => client_id, :secret => client_secret }
26
+ self.github_application = { :client_id => client_id, :client_secret => client_secret }
27
+ end
28
+
29
+ def github_access_token(access_token)
30
+ self.github_application = { :access_token => access_token }
20
31
  end
21
32
 
22
33
  def organization(organization_name)
@@ -40,7 +51,11 @@ module OpenSesame
40
51
  end
41
52
 
42
53
  def enabled?
43
- self.enabled
54
+ !!self.enabled
55
+ end
56
+
57
+ def debug?
58
+ !!self.debug
44
59
  end
45
60
 
46
61
  def configure
@@ -52,12 +67,12 @@ module OpenSesame
52
67
  def valid?
53
68
  self.organization_name && self.organization_name.is_a?(String) &&
54
69
  self.mount_prefix && self.mount_prefix.is_a?(String) &&
55
- self.github_client.is_a?(Hash) &&
56
- [:id, :secret].all? { |key| self.github_client.keys.include?(key) }
70
+ self.github_application.is_a?(Hash) &&
71
+ [:client_id, :client_secret].all? { |key| self.github_application.keys.include?(key) }
57
72
  end
58
73
 
59
74
  def configured?
60
- [:organization_name, :mount_prefix, :github_client].any? { |required| send(required).present? }
75
+ [:organization_name, :mount_prefix, :github_application].any? { |required| send(required).present? }
61
76
  end
62
77
 
63
78
  def validate!
@@ -87,4 +102,4 @@ module OpenSesame
87
102
  end
88
103
 
89
104
  end
90
- end
105
+ end
@@ -0,0 +1,13 @@
1
+ Devise.setup do |config|
2
+ config.warden do |manager|
3
+ manager.default_strategies(:opensesame_github, :scope => :opensesame)
4
+ manager.serialize_into_session(:opensesame) { |member| member.login }
5
+ manager.serialize_from_session(:opensesame) { |login| OpenSesame::Member.find(login) }
6
+ end
7
+ end
8
+
9
+ Devise.add_mapping(
10
+ :opensesame,
11
+ class_name: 'OpenSesame::Member',
12
+ failure_app: OpenSesame::Failure::DeviseApp.new
13
+ )
@@ -21,25 +21,21 @@ module OpenSesame
21
21
  end
22
22
 
23
23
  initializer "opensesame.middleware", :after => :load_config_initializers do |app|
24
- require 'open_sesame/github_warden'
25
-
26
- app.config.middleware.use OpenSesame::GithubAuth,
27
- OpenSesame.github_client[:id],
28
- OpenSesame.github_client[:secret],
29
- :path_prefix => OpenSesame.mount_prefix
30
-
31
- if defined?(Devise)
32
- Devise.setup do |config|
33
- config.warden do |manager|
24
+ if OpenSesame.enabled?
25
+ require 'open_sesame/github_warden'
26
+ app.config.middleware.use OpenSesame::GithubAuth,
27
+ OpenSesame.github_application[:client_id],
28
+ OpenSesame.github_application[:client_secret],
29
+ :path_prefix => OpenSesame.mount_prefix
30
+
31
+ if defined?(Devise)
32
+ require 'open_sesame/devise'
33
+ else
34
+ app.config.middleware.use ::Warden::Manager do |manager|
34
35
  manager.default_strategies(:opensesame_github, :scope => :opensesame)
35
- manager.failure_app = OpenSesame::Failure::DeviseApp.new
36
+ manager.failure_app = OpenSesame::Failure::App.new
36
37
  end
37
38
  end
38
- else
39
- app.config.middleware.use ::Warden::Manager do |manager|
40
- manager.default_strategies(:opensesame_github, :scope => :opensesame)
41
- manager.failure_app = OpenSesame::Failure::App.new
42
- end
43
39
  end
44
40
 
45
41
  end
@@ -14,4 +14,4 @@ module OpenSesame
14
14
 
15
15
  end
16
16
  end
17
- end
17
+ end
@@ -5,5 +5,21 @@ module OpenSesame
5
5
  class GithubAuth < ::OmniAuth::Strategies::GitHub
6
6
  option :name, 'github'
7
7
  option :path_prefix, OpenSesame.mount_prefix
8
+ option :on_failure, OpenSesame::Failure::App.new
9
+
10
+ # overrides OmniAuth::Strategy#fail!
11
+ def fail!(message_key, exception = nil)
12
+ self.env['omniauth.error'] = exception
13
+ self.env['omniauth.error.type'] = message_key.to_sym
14
+ self.env['omniauth.error.strategy'] = self
15
+
16
+ if exception
17
+ log :error, "Authentication failure! #{message_key}: #{exception.class.to_s}, #{exception.message}"
18
+ else
19
+ log :error, "Authentication failure! #{message_key} encountered."
20
+ end
21
+
22
+ options.on_failure.call(self.env)
23
+ end
8
24
  end
9
- end
25
+ end
@@ -9,13 +9,17 @@ module OpenSesame
9
9
  end
10
10
 
11
11
  def authenticate!
12
- if member = OpenSesame::Member.find(auth_hash["uid"])
12
+ if member = OpenSesame::Member.find(github_login)
13
13
  success! member
14
14
  else
15
15
  fail 'Sorry, you do not have access'
16
16
  end
17
17
  end
18
18
 
19
+ def github_login
20
+ auth_hash['info']['nickname']
21
+ end
22
+
19
23
  def auth_hash
20
24
  request.env['omniauth.auth']
21
25
  end
@@ -23,4 +27,4 @@ module OpenSesame
23
27
  end
24
28
  end
25
29
 
26
- ::Warden::Strategies.add(:opensesame_github, OpenSesame::GithubWarden)
30
+ ::Warden::Strategies.add(:opensesame_github, OpenSesame::GithubWarden)
@@ -16,4 +16,4 @@ module OpenSesame
16
16
  end
17
17
 
18
18
  end
19
- end
19
+ end
@@ -8,51 +8,84 @@ module OpenSesame
8
8
  OpenSesame.organization_name
9
9
  end
10
10
 
11
- def self.find(member_id)
12
- return nil unless member_id.present?
13
- attributes = organization_members.detect { |member| member.id.to_s == member_id.to_s }
14
- return nil unless attributes.present?
15
- new(attributes)
11
+ def self.find(member_login)
12
+ return nil unless member_login.present?
13
+ return unless member?(member_login)
14
+ member = find_member(member_login) # Sawyer::Resource
15
+ return unless member # may have been an API error
16
+ members << member
17
+ new(member.attrs)
16
18
  end
17
19
 
18
- def self.organization_members
19
- github_api.organization_members(organization_name)
20
+ def self.find_member(member_login)
21
+ members.detect { |m| m.login == member_login } || begin
22
+ client.user(member_login)
23
+ rescue Octokit::Error => ek
24
+ OpenSesame.logger.info e
25
+ end
26
+ end
27
+
28
+ def self.member?(member_login)
29
+ member_logins.include?(member_login) || begin
30
+ client.organization_member?(organization_name, member_login)
31
+ rescue Octokit::ServerError => e
32
+ OpenSesame.logger.info e
33
+ end
34
+ end
35
+
36
+ # memoized list of accepted member
37
+ def self.members
38
+ @members ||= []
39
+ end
40
+
41
+ def self.member_logins
42
+ members.map(&:login)
20
43
  end
21
44
 
22
- def self.github_api
23
- @github_api ||= Octokit.new
45
+ def self.client
46
+ @client ||= begin
47
+ require "faraday-http-cache"
48
+ stack = Faraday::RackBuilder.new do |builder|
49
+ builder.response :logger, OpenSesame.logger
50
+ builder.use Faraday::HttpCache unless OpenSesame.debug?
51
+ builder.use Octokit::Response::RaiseError
52
+ builder.adapter Faraday.default_adapter
53
+ end
54
+ Octokit.middleware = stack
55
+ Octokit::Client.new(OpenSesame.github_application)
56
+ end
57
+ end
58
+
59
+ def self.reset
60
+ @members = nil
24
61
  end
25
62
 
26
63
  def self.lazy_attr_reader(*attrs)
27
64
  attrs.each do |attribute|
28
65
  class_eval do
29
66
  define_method(attribute) do
30
- @attributes[attribute.to_s] || @attributes[attribute] # allow string or symbol access
67
+ @attributes[attribute] || @attributes[attribute] # allow string or symbol access
31
68
  end
32
69
  end
33
70
  end
34
71
  end
35
72
 
36
73
  def self.serialize_into_session(member)
37
- [member.id]
74
+ [member.login]
38
75
  end
39
76
 
40
77
  def self.serialize_from_session(*args)
41
- id = args.shift
42
- find(id)
78
+ login = args.shift
79
+ find(login)
43
80
  end
44
81
 
45
82
  attr_accessor :attributes
46
- lazy_attr_reader :id, :login, :avatar_url, :gravatar_id, :url
83
+ lazy_attr_reader :id, :login, :email
47
84
 
48
85
  def initialize(attributes = {})
49
86
  @attributes = attributes
50
87
  end
51
88
 
52
- def id
53
- @attributes["id"]
54
- end
55
-
56
89
  def organization_name
57
90
  self.class.organization_name
58
91
  end
@@ -62,4 +95,4 @@ module OpenSesame
62
95
  end
63
96
 
64
97
  end
65
- end
98
+ end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module OpenSesame
3
- VERSION = "0.1.2"
3
+ VERSION = "0.2.0"
4
4
  end
@@ -0,0 +1,8 @@
1
+ class User < ActiveRecord::Base
2
+ if defined?(Devise)
3
+ devise :database_authenticatable, :registerable,
4
+ :recoverable, :rememberable, :trackable, :validatable
5
+ end
6
+ #
7
+ attr_accessible :email, :password, :password_confirmation, :remember_me
8
+ end
@@ -0,0 +1,267 @@
1
+ begin
2
+ require 'devise'
3
+ require 'devise/version'
4
+ Rails.logger.info "Loading Devise version #{Devise::VERSION}"
5
+
6
+ # Use this hook to configure devise mailer, warden hooks and so forth.
7
+ # Many of these configuration options can be set straight in your model.
8
+ Devise.setup do |config|
9
+ # The secret key used by Devise. Devise uses this key to generate
10
+ # random tokens. Changing this key will render invalid all existing
11
+ # confirmation, reset password and unlock tokens in the database.
12
+ if config.respond_to?(:secret_key=)
13
+ config.secret_key = '6085f5216b0ce333f6b83443853c4afa38f8aaa97f22460ff622ab43298fdb60201946abba17250ba5bed603bc100e0762f12e22d113a26d8a4a939bc301e90e'
14
+ end
15
+
16
+ # ==> Mailer Configuration
17
+ # Configure the e-mail address which will be shown in Devise::Mailer,
18
+ # note that it will be overwritten if you use your own mailer class
19
+ # with default "from" parameter.
20
+ config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
21
+
22
+ # Configure the class responsible to send e-mails.
23
+ # config.mailer = 'Devise::Mailer'
24
+
25
+ # ==> ORM configuration
26
+ # Load and configure the ORM. Supports :active_record (default) and
27
+ # :mongoid (bson_ext recommended) by default. Other ORMs may be
28
+ # available as additional gems.
29
+ require 'devise/orm/active_record'
30
+
31
+ # ==> Configuration for any authentication mechanism
32
+ # Configure which keys are used when authenticating a user. The default is
33
+ # just :email. You can configure it to use [:username, :subdomain], so for
34
+ # authenticating a user, both parameters are required. Remember that those
35
+ # parameters are used only when authenticating and not when retrieving from
36
+ # session. If you need permissions, you should implement that in a before filter.
37
+ # You can also supply a hash where the value is a boolean determining whether
38
+ # or not authentication should be aborted when the value is not present.
39
+ # config.authentication_keys = [ :email ]
40
+
41
+ # Configure parameters from the request object used for authentication. Each entry
42
+ # given should be a request method and it will automatically be passed to the
43
+ # find_for_authentication method and considered in your model lookup. For instance,
44
+ # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
45
+ # The same considerations mentioned for authentication_keys also apply to request_keys.
46
+ # config.request_keys = []
47
+
48
+ # Configure which authentication keys should be case-insensitive.
49
+ # These keys will be downcased upon creating or modifying a user and when used
50
+ # to authenticate or find a user. Default is :email.
51
+ config.case_insensitive_keys = [ :email ]
52
+
53
+ # Configure which authentication keys should have whitespace stripped.
54
+ # These keys will have whitespace before and after removed upon creating or
55
+ # modifying a user and when used to authenticate or find a user. Default is :email.
56
+ config.strip_whitespace_keys = [ :email ]
57
+
58
+ # Tell if authentication through request.params is enabled. True by default.
59
+ # It can be set to an array that will enable params authentication only for the
60
+ # given strategies, for example, `config.params_authenticatable = [:database]` will
61
+ # enable it only for database (email + password) authentication.
62
+ # config.params_authenticatable = true
63
+
64
+ # Tell if authentication through HTTP Auth is enabled. False by default.
65
+ # It can be set to an array that will enable http authentication only for the
66
+ # given strategies, for example, `config.http_authenticatable = [:database]` will
67
+ # enable it only for database authentication. The supported strategies are:
68
+ # :database = Support basic authentication with authentication key + password
69
+ # config.http_authenticatable = false
70
+
71
+ # If http headers should be returned for AJAX requests. True by default.
72
+ # config.http_authenticatable_on_xhr = true
73
+
74
+ # The realm used in Http Basic Authentication. 'Application' by default.
75
+ # config.http_authentication_realm = 'Application'
76
+
77
+ # It will change confirmation, password recovery and other workflows
78
+ # to behave the same regardless if the e-mail provided was right or wrong.
79
+ # Does not affect registerable.
80
+ # config.paranoid = true
81
+
82
+ # By default Devise will store the user in session. You can skip storage for
83
+ # particular strategies by setting this option.
84
+ # Notice that if you are skipping storage for all authentication paths, you
85
+ # may want to disable generating routes to Devise's sessions controller by
86
+ # passing skip: :sessions to `devise_for` in your config/routes.rb
87
+ config.skip_session_storage = [:http_auth]
88
+
89
+ # By default, Devise cleans up the CSRF token on authentication to
90
+ # avoid CSRF token fixation attacks. This means that, when using AJAX
91
+ # requests for sign in and sign up, you need to get a new CSRF token
92
+ # from the server. You can disable this option at your own risk.
93
+ # config.clean_up_csrf_token_on_authentication = true
94
+
95
+ # ==> Configuration for :database_authenticatable
96
+ # For bcrypt, this is the cost for hashing the password and defaults to 10. If
97
+ # using other encryptors, it sets how many times you want the password re-encrypted.
98
+ #
99
+ # Limiting the stretches to just one in testing will increase the performance of
100
+ # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
101
+ # a value less than 10 in other environments. Note that, for bcrypt (the default
102
+ # encryptor), the cost increases exponentially with the number of stretches (e.g.
103
+ # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
104
+ config.stretches = Rails.env.test? ? 1 : 10
105
+
106
+ # Setup a pepper to generate the encrypted password.
107
+ # config.pepper = 'cf4750f454ee89c4685aaa85c6966ee17e8ca8c9eeb9c46b4a231f168804681ac7299154de16812033660a610614c3d96dab4510d4242e55bc3ea0fd9d2922c4'
108
+
109
+ # ==> Configuration for :confirmable
110
+ # A period that the user is allowed to access the website even without
111
+ # confirming their account. For instance, if set to 2.days, the user will be
112
+ # able to access the website for two days without confirming their account,
113
+ # access will be blocked just in the third day. Default is 0.days, meaning
114
+ # the user cannot access the website without confirming their account.
115
+ # config.allow_unconfirmed_access_for = 2.days
116
+
117
+ # A period that the user is allowed to confirm their account before their
118
+ # token becomes invalid. For example, if set to 3.days, the user can confirm
119
+ # their account within 3 days after the mail was sent, but on the fourth day
120
+ # their account can't be confirmed with the token any more.
121
+ # Default is nil, meaning there is no restriction on how long a user can take
122
+ # before confirming their account.
123
+ # config.confirm_within = 3.days
124
+
125
+ # If true, requires any email changes to be confirmed (exactly the same way as
126
+ # initial account confirmation) to be applied. Requires additional unconfirmed_email
127
+ # db field (see migrations). Until confirmed, new email is stored in
128
+ # unconfirmed_email column, and copied to email column on successful confirmation.
129
+ config.reconfirmable = true
130
+
131
+ # Defines which key will be used when confirming an account
132
+ # config.confirmation_keys = [ :email ]
133
+
134
+ # ==> Configuration for :rememberable
135
+ # The time the user will be remembered without asking for credentials again.
136
+ # config.remember_for = 2.weeks
137
+
138
+ # If true, extends the user's remember period when remembered via cookie.
139
+ # config.extend_remember_period = false
140
+
141
+ # Options to be passed to the created cookie. For instance, you can set
142
+ # secure: true in order to force SSL only cookies.
143
+ # config.rememberable_options = {}
144
+
145
+ # ==> Configuration for :validatable
146
+ # Range for password length.
147
+ config.password_length = 8..128
148
+
149
+ # Email regex used to validate email formats. It simply asserts that
150
+ # one (and only one) @ exists in the given string. This is mainly
151
+ # to give user feedback and not to assert the e-mail validity.
152
+ # config.email_regexp = /\A[^@]+@[^@]+\z/
153
+
154
+ # ==> Configuration for :timeoutable
155
+ # The time you want to timeout the user session without activity. After this
156
+ # time the user will be asked for credentials again. Default is 30 minutes.
157
+ # config.timeout_in = 30.minutes
158
+
159
+ # If true, expires auth token on session timeout.
160
+ # config.expire_auth_token_on_timeout = false
161
+
162
+ # ==> Configuration for :lockable
163
+ # Defines which strategy will be used to lock an account.
164
+ # :failed_attempts = Locks an account after a number of failed attempts to sign in.
165
+ # :none = No lock strategy. You should handle locking by yourself.
166
+ # config.lock_strategy = :failed_attempts
167
+
168
+ # Defines which key will be used when locking and unlocking an account
169
+ # config.unlock_keys = [ :email ]
170
+
171
+ # Defines which strategy will be used to unlock an account.
172
+ # :email = Sends an unlock link to the user email
173
+ # :time = Re-enables login after a certain amount of time (see :unlock_in below)
174
+ # :both = Enables both strategies
175
+ # :none = No unlock strategy. You should handle unlocking by yourself.
176
+ # config.unlock_strategy = :both
177
+
178
+ # Number of authentication tries before locking an account if lock_strategy
179
+ # is failed attempts.
180
+ # config.maximum_attempts = 20
181
+
182
+ # Time interval to unlock the account if :time is enabled as unlock_strategy.
183
+ # config.unlock_in = 1.hour
184
+
185
+ # Warn on the last attempt before the account is locked.
186
+ # config.last_attempt_warning = false
187
+
188
+ # ==> Configuration for :recoverable
189
+ #
190
+ # Defines which key will be used when recovering the password for an account
191
+ # config.reset_password_keys = [ :email ]
192
+
193
+ # Time interval you can reset your password with a reset password key.
194
+ # Don't put a too small interval or your users won't have the time to
195
+ # change their passwords.
196
+ config.reset_password_within = 6.hours
197
+
198
+ # ==> Configuration for :encryptable
199
+ # Allow you to use another encryption algorithm besides bcrypt (default). You can use
200
+ # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
201
+ # :authlogic_sha512 (then you should set stretches above to 20 for default behavior)
202
+ # and :restful_authentication_sha1 (then you should set stretches to 10, and copy
203
+ # REST_AUTH_SITE_KEY to pepper).
204
+ #
205
+ # Require the `devise-encryptable` gem when using anything other than bcrypt
206
+ # config.encryptor = :sha512
207
+
208
+ # ==> Scopes configuration
209
+ # Turn scoped views on. Before rendering "sessions/new", it will first check for
210
+ # "users/sessions/new". It's turned off by default because it's slower if you
211
+ # are using only default views.
212
+ # config.scoped_views = false
213
+
214
+ # Configure the default scope given to Warden. By default it's the first
215
+ # devise role declared in your routes (usually :user).
216
+ # config.default_scope = :user
217
+
218
+ # Set this configuration to false if you want /users/sign_out to sign out
219
+ # only the current scope. By default, Devise signs out all scopes.
220
+ # config.sign_out_all_scopes = true
221
+
222
+ # ==> Navigation configuration
223
+ # Lists the formats that should be treated as navigational. Formats like
224
+ # :html, should redirect to the sign in page when the user does not have
225
+ # access, but formats like :xml or :json, should return 401.
226
+ #
227
+ # If you have any extra navigational formats, like :iphone or :mobile, you
228
+ # should add them to the navigational formats lists.
229
+ #
230
+ # The "*/*" below is required to match Internet Explorer requests.
231
+ # config.navigational_formats = ['*/*', :html]
232
+
233
+ # The default HTTP method used to sign out a resource. Default is :delete.
234
+ config.sign_out_via = :delete
235
+
236
+ # ==> OmniAuth
237
+ # Add a new OmniAuth provider. Check the wiki for more information on setting
238
+ # up on your models and hooks.
239
+ # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
240
+
241
+ # ==> Warden configuration
242
+ # If you want to use other strategies, that are not supported by Devise, or
243
+ # change the failure app, you can configure them inside the config.warden block.
244
+ #
245
+ # config.warden do |manager|
246
+ # manager.intercept_401 = false
247
+ # manager.default_strategies(scope: :user).unshift :some_external_strategy
248
+ # end
249
+
250
+ # ==> Mountable engine configurations
251
+ # When using Devise inside an engine, let's call it `MyEngine`, and this engine
252
+ # is mountable, there are some extra configurations to be taken into account.
253
+ # The following options are available, assuming the engine is mounted as:
254
+ #
255
+ # mount MyEngine, at: '/my_engine'
256
+ #
257
+ # The router that invoked `devise_for`, in the example above, would be:
258
+ # config.router_name = :my_engine
259
+ #
260
+ # When using omniauth, Devise cannot automatically set Omniauth path,
261
+ # so you need to do it manually. For the users scope, it would be:
262
+ # config.omniauth_path_prefix = '/my_engine/users/auth'
263
+ end
264
+ rescue LoadError
265
+
266
+ Rails.logger.info("Ignoring Devise")
267
+ end