authenticate 0.1.0 → 0.2.0

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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/Gemfile +0 -4
  4. data/Gemfile.lock +0 -5
  5. data/README.md +149 -78
  6. data/app/controllers/authenticate/passwords_controller.rb +130 -0
  7. data/app/controllers/authenticate/sessions_controller.rb +46 -0
  8. data/app/controllers/authenticate/users_controller.rb +46 -0
  9. data/app/mailers/authenticate_mailer.rb +13 -0
  10. data/app/views/authenticate_mailer/change_password.html.erb +8 -0
  11. data/app/views/authenticate_mailer/change_password.text.erb +5 -0
  12. data/app/views/layouts/application.html.erb +25 -0
  13. data/app/views/passwords/edit.html.erb +20 -0
  14. data/app/views/passwords/new.html.erb +19 -0
  15. data/app/views/sessions/new.html.erb +28 -0
  16. data/app/views/users/new.html.erb +24 -0
  17. data/authenticate.gemspec +1 -2
  18. data/config/locales/authenticate.en.yml +57 -0
  19. data/config/routes.rb +14 -1
  20. data/lib/authenticate/callbacks/brute_force.rb +5 -9
  21. data/lib/authenticate/callbacks/lifetimed.rb +1 -0
  22. data/lib/authenticate/callbacks/timeoutable.rb +2 -1
  23. data/lib/authenticate/callbacks/trackable.rb +1 -3
  24. data/lib/authenticate/configuration.rb +94 -5
  25. data/lib/authenticate/controller.rb +69 -9
  26. data/lib/authenticate/debug.rb +1 -0
  27. data/lib/authenticate/engine.rb +4 -11
  28. data/lib/authenticate/model/brute_force.rb +22 -3
  29. data/lib/authenticate/model/db_password.rb +12 -7
  30. data/lib/authenticate/model/email.rb +8 -10
  31. data/lib/authenticate/model/password_reset.rb +76 -0
  32. data/lib/authenticate/model/timeoutable.rb +9 -3
  33. data/lib/authenticate/model/trackable.rb +1 -1
  34. data/lib/authenticate/model/username.rb +21 -8
  35. data/lib/authenticate/modules.rb +19 -1
  36. data/lib/authenticate/session.rb +3 -1
  37. data/lib/authenticate/user.rb +6 -1
  38. data/lib/authenticate/version.rb +1 -1
  39. data/lib/generators/authenticate/controllers/USAGE +12 -0
  40. data/lib/generators/authenticate/controllers/controllers_generator.rb +21 -0
  41. data/lib/generators/authenticate/install/USAGE +7 -0
  42. data/lib/generators/authenticate/install/install_generator.rb +140 -0
  43. data/lib/generators/authenticate/install/templates/authenticate.rb +22 -0
  44. data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_brute_force_to_users.rb +6 -0
  45. data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_password_reset_to_users.rb +7 -0
  46. data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_timeoutable_to_users.rb +5 -0
  47. data/lib/generators/authenticate/install/templates/db/migrate/add_authenticate_to_users.rb +21 -0
  48. data/lib/generators/authenticate/install/templates/db/migrate/create_users.rb +14 -0
  49. data/lib/generators/authenticate/install/templates/user.rb +3 -0
  50. data/lib/generators/authenticate/routes/USAGE +8 -0
  51. data/lib/generators/authenticate/routes/routes_generator.rb +32 -0
  52. data/lib/generators/authenticate/routes/templates/routes.rb +10 -0
  53. data/lib/generators/authenticate/views/USAGE +13 -0
  54. data/lib/generators/authenticate/views/views_generator.rb +21 -0
  55. data/spec/dummy/app/controllers/application_controller.rb +1 -0
  56. data/spec/dummy/config/initializers/authenticate.rb +12 -5
  57. data/spec/dummy/db/development.sqlite3 +0 -0
  58. data/spec/dummy/db/migrate/20160130192728_create_users.rb +18 -0
  59. data/spec/dummy/db/migrate/20160130192729_add_authenticate_brute_force_to_users.rb +6 -0
  60. data/spec/dummy/db/migrate/20160130192730_add_authenticate_timeoutable_to_users.rb +5 -0
  61. data/spec/dummy/db/migrate/20160130192731_add_authenticate_password_reset_to_users.rb +7 -0
  62. data/spec/dummy/db/schema.rb +14 -10
  63. data/spec/dummy/db/test.sqlite3 +0 -0
  64. data/spec/factories/users.rb +5 -8
  65. data/spec/model/brute_force_spec.rb +63 -0
  66. data/spec/model/session_spec.rb +4 -0
  67. data/spec/model/user_spec.rb +15 -5
  68. data/spec/spec_helper.rb +2 -1
  69. metadata +41 -9
  70. data/app/controllers/.keep +0 -0
  71. data/app/mailers/.keep +0 -0
  72. data/app/views/.keep +0 -0
  73. data/spec/dummy/db/migrate/20160120003910_create_users.rb +0 -18
@@ -0,0 +1,46 @@
1
+ class Authenticate::SessionsController < ApplicationController
2
+ before_action :redirect_signed_in_users, only: [:new]
3
+ skip_before_action :require_authentication, only: [:create, :new, :destroy], raise: false
4
+
5
+
6
+ def new
7
+ render template: 'sessions/new'
8
+ end
9
+
10
+ def create
11
+ @user = authenticate(params)
12
+ login(@user) do |status|
13
+ if status.success?
14
+ redirect_back_or url_after_create
15
+ else
16
+ flash.now.notice = status.message
17
+ render template: 'sessions/new', status: :unauthorized
18
+ end
19
+ end
20
+ end
21
+
22
+ def destroy
23
+ logout
24
+ redirect_to url_after_destroy
25
+ end
26
+
27
+ private
28
+
29
+ def redirect_signed_in_users
30
+ if authenticated?
31
+ redirect_to url_for_signed_in_users
32
+ end
33
+ end
34
+
35
+ def url_after_create
36
+ Authenticate.configuration.redirect_url
37
+ end
38
+
39
+ def url_after_destroy
40
+ sign_in_url
41
+ end
42
+
43
+ def url_for_signed_in_users
44
+ url_after_create
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ class Authenticate::UsersController < ApplicationController
2
+ before_action :redirect_signed_in_users, only: [:create, :new]
3
+ skip_before_action :require_authentication, only: [:create, :new], raise: false
4
+
5
+ def new
6
+ @user = user_from_params
7
+ render template: 'users/new'
8
+ end
9
+
10
+ def create
11
+ @user = user_from_params
12
+
13
+ if @user.save
14
+ login @user
15
+ redirect_back_or url_after_create
16
+ else
17
+ render template: 'users/new'
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def redirect_signed_in_users
24
+ if authenticated?
25
+ redirect_to Authenticate.configuration.redirect_url
26
+ end
27
+ end
28
+
29
+ def url_after_create
30
+ Authenticate.configuration.redirect_url
31
+ end
32
+
33
+ def user_from_params
34
+ email = user_params.delete(:email)
35
+ password = user_params.delete(:password)
36
+
37
+ Authenticate.configuration.user_model_class.new(user_params).tap do |user|
38
+ user.email = email
39
+ user.password = password
40
+ end
41
+ end
42
+
43
+ def user_params
44
+ params[:user] || Hash.new
45
+ end
46
+ end
@@ -0,0 +1,13 @@
1
+ class AuthenticateMailer < ActionMailer::Base
2
+ def change_password(user)
3
+ @user = user
4
+ mail(
5
+ from: Authenticate.configuration.mailer_sender,
6
+ to: @user.email,
7
+ subject: I18n.t(
8
+ :change_password,
9
+ scope: [:authenticate, :models, :authenticate_mailer]
10
+ ),
11
+ )
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ <p><%= t(".opening") %></p>
2
+
3
+ <p>
4
+ <%= link_to t(".link_text", default: "Change my password"),
5
+ edit_users_password_url(@user, token: @user.password_reset_token.html_safe) %>
6
+ </p>
7
+
8
+ <p><%= raw t(".closing") %></p>
@@ -0,0 +1,5 @@
1
+ <%= t(".opening") %></p>
2
+
3
+ <%= edit_users_password_url(@user, token: @user.password_reset_token.html_safe) %>
4
+
5
+ <%= raw t(".closing") %>
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <%= javascript_include_tag 'application' %>
5
+ <%= csrf_meta_tag %>
6
+ </head>
7
+ <body>
8
+ <div id="header">
9
+ <% if authenticated? -%>
10
+ <%= link_to t(".sign_out"), sign_out_path %>
11
+ <% else -%>
12
+ <%= link_to t(".sign_in"), sign_in_path %>
13
+ <% end -%>
14
+ </div>
15
+
16
+ <div id="flash">
17
+ <% flash.each do |key, value| -%>
18
+ <div id="flash_<%= key %>"><%=h value %></div>
19
+ <% end %>
20
+ </div>
21
+
22
+ <%= yield %>
23
+
24
+ </body>
25
+ </html>
@@ -0,0 +1,20 @@
1
+ <div id="authenticate" class="password-reset">
2
+ <h2><%= t(".title") %></h2>
3
+
4
+ <p><%= t(".description") %></p>
5
+
6
+ <%= form_for :password_reset,
7
+ url: users_password_path(@user, token: @user.password_reset_token),
8
+ html: { method: :put } do |form| %>
9
+
10
+ <div class="field">
11
+ <%= form.label :password %>
12
+ <%= form.password_field :password %>
13
+ </div>
14
+
15
+ <div class="actions">
16
+ <%= form.submit %>
17
+ </div>
18
+
19
+ <% end %>
20
+ </div>
@@ -0,0 +1,19 @@
1
+ <div id="authenticate" class="password-reset">
2
+ <h2><%= t(".title") %></h2>
3
+
4
+ <p><%= t(".description") %></p>
5
+
6
+ <%= form_for :password, url: passwords_path do |form| %>
7
+
8
+ <div class="field">
9
+ <%= form.label :email %>
10
+ <%= form.text_field :email, type: 'email' %>
11
+ </div>
12
+
13
+ <div class="actions">
14
+ <%= form.submit %>
15
+ </div>
16
+
17
+ <% end %>
18
+
19
+ </div>
@@ -0,0 +1,28 @@
1
+ <div id="authenticate" class="sign-in">
2
+ <h2><%= t(".title") %></h2>
3
+
4
+ <%= form_for :session, url: session_path do |form| %>
5
+
6
+ <div class="field">
7
+ <%= form.label :email %>
8
+ <%= form.text_field :email, type: 'email' %>
9
+ </div>
10
+
11
+ <div class="field">
12
+ <%= form.label :password %>
13
+ <%= form.password_field :password %>
14
+ </div>
15
+
16
+ <div class="actions">
17
+ <%= form.submit %>
18
+ </div>
19
+
20
+ <div class="links">
21
+ <% if Authenticate.configuration.allow_sign_up? %>
22
+ <%= link_to t(".sign_up"), sign_up_path %>
23
+ <% end %>
24
+ <%= link_to t(".forgot_password"), new_password_path %>
25
+ </div>
26
+ <% end %>
27
+
28
+ </div>
@@ -0,0 +1,24 @@
1
+ <div id="authenticate" class="sign-up">
2
+ <h2><%= t(".title") %></h2>
3
+
4
+ <%= form_for @user do |form| %>
5
+
6
+ <div class="field">
7
+ <%= form.label :email %>
8
+ <%= form.text_field :email, type: 'email' %>
9
+ </div>
10
+
11
+ <div class="field">
12
+ <%= form.label :password %>
13
+ <%= form.password_field :password %>
14
+ </div>
15
+
16
+ <div class="actions">
17
+ <%= form.submit %>
18
+ </div>
19
+
20
+ <div class="links">
21
+ <%= link_to t(".sign_in"), sign_in_path %>
22
+ </div>
23
+ <% end %>
24
+ </div>
data/authenticate.gemspec CHANGED
@@ -1,5 +1,4 @@
1
1
  $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
- # $:.push File.expand_path("../lib", __FILE__)
3
2
 
4
3
  require 'authenticate/version'
5
4
  require 'date'
@@ -29,10 +28,10 @@ Gem::Specification.new do |s|
29
28
  s.add_dependency 'email_validator', '~> 1.6'
30
29
  s.add_dependency 'rails', '>= 4.0', '< 5.1'
31
30
  s.add_development_dependency 'sqlite3'
32
- s.add_development_dependency 'rspec'
33
31
  s.add_development_dependency 'rspec-rails'
34
32
  # s.add_development_dependency 'capybara'
35
33
  s.add_development_dependency 'factory_girl_rails'
34
+ s.add_development_dependency 'pry'
36
35
 
37
36
  s.required_ruby_version = Gem::Requirement.new('>= 2.0')
38
37
  end
@@ -0,0 +1,57 @@
1
+ ---
2
+ en:
3
+ authenticate:
4
+ models:
5
+ authenticate_mailer:
6
+ change_password: Change your password
7
+ authenticate_mailer:
8
+ change_password:
9
+ closing: If you didn't request this, ignore this email. Your password has not been changed.
10
+ link_text: Change my password
11
+ opening: Someone has requested a link to change your password. You can do this through the link below.
12
+ flashes:
13
+ failure_after_create: Bad email or password.
14
+ failure_after_update: Password can't be blank.
15
+ failure_when_forbidden: Please double check the URL or try submitting the form again.
16
+ failure_when_not_signed_in: Please sign in to continue.
17
+ failure_token_expired: Your password change request has expired. Please click 'Forgot Password' and try again.
18
+ success_password_changed: Your password has been updated.
19
+ helpers:
20
+ label:
21
+ password:
22
+ email: Email address
23
+ password_reset:
24
+ password: Choose password
25
+ submit:
26
+ password:
27
+ submit: Reset password
28
+ password_reset:
29
+ submit: Save this password
30
+ session:
31
+ submit: Sign in
32
+ user:
33
+ create: Sign up
34
+ layouts:
35
+ application:
36
+ sign_in: Sign in
37
+ sign_out: Sign out
38
+ passwords:
39
+ create:
40
+ description: You will receive an email within the next few minutes. It
41
+ contains instructions for changing your password.
42
+ edit:
43
+ description: Your password can be reset. Choose a new password below.
44
+ title: Change your password
45
+ new:
46
+ description: To be emailed a link to reset your password, please enter your email address.
47
+ title: Reset your password?
48
+ sessions:
49
+ form:
50
+ forgot_password: Forgot password?
51
+ sign_up: Sign up
52
+ new:
53
+ title: Sign in
54
+ users:
55
+ new:
56
+ sign_in: Sign in
57
+ title: Sign up
data/config/routes.rb CHANGED
@@ -1,2 +1,15 @@
1
- Rails.application.routes.draw do
1
+ if Authenticate.configuration.routes_enabled?
2
+ Rails.application.routes.draw do
3
+ resource :session, controller: 'authenticate/sessions', only: [:create, :new, :destroy]
4
+ resources :passwords, controller: 'authenticate/passwords', only: [:new, :create]
5
+
6
+ user_actions = Authenticate.configuration.allow_sign_up? ? [:new, :create] : []
7
+ resource :users, controller: 'authenticate/users', only: user_actions do
8
+ resources :passwords, controller: 'authenticate/passwords', only: [:edit, :update]
9
+ end
10
+
11
+ get '/sign_up', to: 'authenticate/users#new', as: 'sign_up'
12
+ get '/sign_in', to: 'authenticate/sessions#new', as: 'sign_in'
13
+ get '/sign_out', to: 'authenticate/sessions#destroy', as: 'sign_out'
14
+ end
2
15
  end
@@ -3,26 +3,22 @@
3
3
  Authenticate.lifecycle.prepend_after_authentication name: 'brute force protection' do |user, session, options|
4
4
  include ActionView::Helpers::DateHelper
5
5
 
6
- # puts 'bf: about to check authentication'
7
- unless session.authenticated?
8
- # puts 'bf: session not authenticated'
9
-
6
+ unless session.authenticated? || Authenticate.configuration.max_consecutive_bad_logins_allowed.nil?
10
7
  user_credentials = User.credentials(session.request.params)
11
- # puts "brute force protection user_credentials: #{user_credentials}"
12
8
  user ||= User.find_by_credentials(user_credentials)
13
-
14
- # puts 'bf: looked up user by credentials, found:' + user.inspect
15
9
  if user
16
- # puts 'found user, about to register failed attempt'
17
10
  user.register_failed_login!
18
11
  user.save!
19
12
  end
20
13
  end
21
14
 
22
- if user && user.locked? && Authenticate.configuration.bad_login_lockout_period != nil
15
+ # if user is locked, and we allow a lockout period, then unlock the user if they've waited
16
+ # longer than the lockout period.
17
+ if user && !Authenticate.configuration.bad_login_lockout_period.nil? && user.locked?
23
18
  user.unlock! if user.lock_expires_at <= Time.now.utc
24
19
  end
25
20
 
21
+ # if the user is still locked, let them know how long they are locked for.
26
22
  if user && user.locked?
27
23
  remaining = time_ago_in_words(user.lock_expires_at)
28
24
  throw(:failure, "Your account is locked, will unlock in #{remaining.to_s}")
@@ -1,3 +1,4 @@
1
+ # Catch sessions that have been live for too long and kill them, forcing the user to reauthenticate.
1
2
  Authenticate.lifecycle.after_set_user name: 'lifetimed after set_user', except: :authentication do |user, session, options|
2
3
  if user && user.respond_to?(:max_session_timedout?)
3
4
  throw(:failure, "Your session has reached it's maximum allowed lifetime, you must log in again") if user.max_session_timedout?
@@ -1,3 +1,4 @@
1
+ # Update last_access_at on every authentication
1
2
  Authenticate.lifecycle.after_authentication name: 'timeoutable after authentication' do |user, session, options|
2
3
  if user && user.respond_to?(:last_access_at)
3
4
  user.last_access_at = Time.now.utc
@@ -5,8 +6,8 @@ Authenticate.lifecycle.after_authentication name: 'timeoutable after authenticat
5
6
  end
6
7
  end
7
8
 
9
+ # Fail users that have timed out. Otherwise update last_access_at.
8
10
  Authenticate.lifecycle.after_set_user name: 'timeoutable after set_user', except: :authentication do |user, session, options|
9
- puts "user.respond_to?(:timedout?) #{user.respond_to?(:timedout?).inspect}" if user
10
11
  if user && user.respond_to?(:timedout?)
11
12
  throw(:failure, 'Your session has expired') if user.timedout?
12
13
  user.last_access_at = Time.now.utc
@@ -1,6 +1,4 @@
1
- # After each sign in: ”update sign in time, sign in count and sign in IP.
2
- # This is only triggered when the user is explicitly set (with set_user)
3
- # and on authentication.
1
+ # Update all standard tracked stats at each authentication.
4
2
  Authenticate.lifecycle.after_authentication name: 'trackable' do |user, session, options|
5
3
  if user.respond_to?(:update_tracked_fields!)
6
4
  user.update_tracked_fields!(session.request)
@@ -34,8 +34,38 @@ module Authenticate
34
34
  # @return [String]
35
35
  attr_accessor :cookie_domain
36
36
 
37
- # Crypto used when authenticating and setting passwords.
38
- # Defaults to {Authenticate::Model::BCrypt}.
37
+ # Controls which paths the session token cookie is valid for.
38
+ # Defaults to `"/"` for the entire domain.
39
+ # For more, see [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.1.4).
40
+ # @return [String]
41
+ attr_accessor :cookie_path
42
+
43
+ # Controls the secure setting on the session cookie. Defaults to `false`.
44
+ # When set, the browser will only send the cookie to the server over HTTPS.
45
+ # If set to true over an insecure http (not https) connection, the cookie will not
46
+ # be usable and the user will not be successfully authenticated.
47
+ #
48
+ # You should set this value to true in live environments to prevent session hijacking.
49
+ #
50
+ # For more, see [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.2.5).
51
+ # @return [Boolean]
52
+ attr_accessor :secure_cookie
53
+
54
+ # Controls whether the HttpOnly flag should be set on the session cookie.
55
+ # Defaults to `false`. If `true`, the cookie will not be made available to JavaScript.
56
+ # For more see [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.2.6).
57
+ # @return [Boolean]
58
+ attr_accessor :cookie_http_only
59
+
60
+ # Controls the 'from' address for Authenticate emails.
61
+ # Defaults to reply@example.com.
62
+ # @return [String]
63
+ attr_accessor :mailer_sender
64
+
65
+ # Determines what crypto is used when authenticating and setting passwords.
66
+ # Defaults to {Authenticate::Model::BCrypt}. At the moment Bcrypt is the only
67
+ # option offered.
68
+ #
39
69
  # Crypto implementations must provide:
40
70
  # * match?(secret, encrypted)
41
71
  # * encrypt(secret)
@@ -74,35 +104,75 @@ module Authenticate
74
104
  # Available strategies:
75
105
  # :email - requires user have attribute :email
76
106
  # :username - requires user have attribute :username
107
+ #
77
108
  # Defaults to :email. To set to :username:
109
+ #
78
110
  # Configuration.configure do |config|
79
111
  # config.authentication_strategy = :username
80
112
  # end
81
113
  #
82
114
  # Or, you can plug in your own authentication class, eg:
115
+ #
83
116
  # Configuration.configure do |config|
84
117
  # config.authentication_strategy = MyFunkyAuthClass
85
118
  # end
119
+ #
86
120
  # @return [Symbol or Class]
87
121
  attr_accessor :authentication_strategy
88
122
 
123
+ # The default path Authenticate will redirect signed in users to.
124
+ # Defaults to `"/"`. This can often be overridden for specific scenarios by
125
+ # overriding controller methods that rely on it.
126
+ # @return [String]
127
+ attr_accessor :redirect_url
89
128
 
90
- # Enable debugging messages.
91
- # @private
129
+ # Controls whether the "sign up" route, allowing creation of users, is enabled.
130
+ # Defaults to `true`. Set to `false` to disable user creation routes.
131
+ # The setting is ignored if routes are disabled.
132
+ # @param [Boolean] value
92
133
  # @return [Boolean]
93
- attr_accessor :debug
134
+ attr_accessor :allow_sign_up
135
+
136
+
137
+ # Enable or disable Authenticate's built-in routes. Defaults to 'true',
138
+ # enabling Authenticate's built-in routes. Disable by setting to 'false'.
139
+ # If you disable the routes, your application is responsible for all routes.
140
+ # You can deploy a copy of Authenticate's routes with `rails generate authenticate:routes`,
141
+ # which will also set `config.routes = false`.
142
+ # @return [Boolean]
143
+ attr_accessor :routes
144
+
145
+ # The time period within which the password must be reset or the token expires.
146
+ # If set to nil, the password reset token does not expire.
147
+ # Defaults to `2.days`.
148
+ # @return [ActiveSupport::CoreExtensions::Numeric::Time]
149
+ attr_accessor :reset_password_within
94
150
 
95
151
  # An array of additional modules to load into the User module.
96
152
  # Defaults to an empty array.
97
153
  # @return [Array]
98
154
  attr_accessor :modules
99
155
 
156
+ # Enable debugging messages.
157
+ # @private
158
+ # @return [Boolean]
159
+ attr_accessor :debug
160
+
100
161
 
101
162
  def initialize
102
163
  # Defaults
103
164
  @debug = false
104
165
  @cookie_name = 'authenticate_session_token'
105
166
  @cookie_expiration = -> { 1.year.from_now.utc }
167
+ @cookie_domain = nil
168
+ @cookie_path = '/'
169
+ @secure_cookie = false
170
+ @cookie_http_only = false
171
+ @mailer_sender = 'reply@example.com'
172
+ @redirect_url = '/'
173
+ @allow_sign_up = true
174
+ @routes = true
175
+ @reset_password_within = 2.days
106
176
  @modules = []
107
177
  @user_model = '::User'
108
178
  @authentication_strategy = :email
@@ -112,12 +182,31 @@ module Authenticate
112
182
  @user_model_class ||= user_model.constantize
113
183
  end
114
184
 
185
+ # The name of foreign key parameter for the configured user model.
186
+ # This is derived from the `model_name` of the `user_model` setting.
187
+ # In the default configuration, this is `user_id`.
188
+ # @return [Symbol]
189
+ def user_id_parameter
190
+ "#{user_model_class.model_name.singular}_id".to_sym
191
+ end
192
+
193
+ # Is the user sign up route enabled?
194
+ # @return [Boolean]
195
+ def allow_sign_up?
196
+ @allow_sign_up
197
+ end
198
+
199
+ # @return [Boolean] are Authenticate's built-in routes enabled?
200
+ def routes_enabled?
201
+ @routes
202
+ end
115
203
 
116
204
  # List of symbols naming modules to load.
117
205
  def modules
118
206
  modules = @modules.dup # in case the user pushes any on
119
207
  modules << @authentication_strategy
120
208
  modules << :db_password
209
+ modules << :password_reset
121
210
  modules << :trackable # needs configuration
122
211
  modules << :timeoutable if @timeout_in
123
212
  modules << :lifetimed if @max_session_lifetime