clearance 1.8.0 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of clearance might be problematic. Click here for more details.

Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +24 -6
  4. data/.yardopts +6 -0
  5. data/Appraisals +12 -4
  6. data/CONTRIBUTING.md +4 -1
  7. data/Gemfile +2 -2
  8. data/Gemfile.lock +87 -85
  9. data/NEWS.md +672 -311
  10. data/README.md +185 -330
  11. data/app/controllers/clearance/passwords_controller.rb +25 -19
  12. data/app/controllers/clearance/sessions_controller.rb +17 -4
  13. data/app/controllers/clearance/users_controller.rb +10 -4
  14. data/app/mailers/clearance_mailer.rb +2 -3
  15. data/app/views/clearance_mailer/change_password.html.erb +6 -3
  16. data/app/views/clearance_mailer/change_password.text.erb +5 -0
  17. data/app/views/layouts/application.html.erb +2 -2
  18. data/app/views/passwords/create.html.erb +1 -1
  19. data/app/views/passwords/edit.html.erb +2 -2
  20. data/app/views/passwords/new.html.erb +2 -2
  21. data/app/views/sessions/_form.html.erb +2 -2
  22. data/app/views/sessions/new.html.erb +1 -1
  23. data/app/views/users/new.html.erb +2 -2
  24. data/bin/setup +6 -2
  25. data/config/locales/clearance.en.yml +6 -0
  26. data/db/migrate/20110111224543_create_clearance_users.rb +1 -1
  27. data/gemfiles/{rails3.2.gemfile → rails32.gemfile} +1 -1
  28. data/gemfiles/{rails4.0.gemfile → rails40.gemfile} +2 -2
  29. data/gemfiles/{rails4.1.gemfile → rails41.gemfile} +2 -2
  30. data/gemfiles/{rails4.2.gemfile → rails42.gemfile} +2 -2
  31. data/gemfiles/rails50.gemfile +19 -0
  32. data/lib/clearance/authentication.rb +52 -1
  33. data/lib/clearance/authorization.rb +47 -4
  34. data/lib/clearance/back_door.rb +1 -0
  35. data/lib/clearance/configuration.rb +127 -15
  36. data/lib/clearance/constraints/signed_in.rb +21 -0
  37. data/lib/clearance/constraints/signed_out.rb +12 -0
  38. data/lib/clearance/constraints.rb +12 -0
  39. data/lib/clearance/controller.rb +13 -0
  40. data/lib/clearance/default_sign_in_guard.rb +17 -0
  41. data/lib/clearance/engine.rb +24 -4
  42. data/lib/clearance/password_strategies/bcrypt.rb +9 -2
  43. data/lib/clearance/password_strategies/bcrypt_migration_from_sha1.rb +19 -0
  44. data/lib/clearance/password_strategies/blowfish.rb +17 -0
  45. data/lib/clearance/password_strategies/sha1.rb +17 -0
  46. data/lib/clearance/password_strategies.rb +13 -0
  47. data/lib/clearance/rack_session.rb +13 -0
  48. data/lib/clearance/rspec.rb +15 -4
  49. data/lib/clearance/session.rb +46 -1
  50. data/lib/clearance/session_status.rb +7 -0
  51. data/lib/clearance/sign_in_guard.rb +65 -0
  52. data/lib/clearance/test_unit.rb +3 -3
  53. data/lib/clearance/testing/controller_helpers.rb +44 -0
  54. data/lib/clearance/testing/deny_access_matcher.rb +35 -1
  55. data/lib/clearance/testing/helpers.rb +9 -25
  56. data/lib/clearance/testing/view_helpers.rb +32 -0
  57. data/lib/clearance/token.rb +7 -0
  58. data/lib/clearance/user.rb +159 -0
  59. data/lib/clearance/version.rb +1 -1
  60. data/lib/clearance.rb +2 -0
  61. data/lib/generators/clearance/install/install_generator.rb +13 -3
  62. data/lib/generators/clearance/install/templates/db/migrate/add_clearance_to_users.rb +3 -3
  63. data/lib/generators/clearance/install/templates/db/migrate/create_users.rb +2 -2
  64. data/lib/generators/clearance/routes/routes_generator.rb +23 -0
  65. data/lib/generators/clearance/routes/templates/routes.rb +7 -7
  66. data/lib/generators/clearance/specs/templates/features/clearance/user_signs_out_spec.rb.tt +1 -1
  67. data/lib/generators/clearance/specs/templates/features/clearance/visitor_resets_password_spec.rb.tt +12 -2
  68. data/lib/generators/clearance/specs/templates/features/clearance/visitor_signs_in_spec.rb.tt +1 -1
  69. data/lib/generators/clearance/specs/templates/features/clearance/visitor_signs_up_spec.rb.tt +1 -1
  70. data/lib/generators/clearance/specs/templates/features/clearance/visitor_updates_password_spec.rb.tt +1 -1
  71. data/spec/acceptance/clearance_installation_spec.rb +4 -1
  72. data/spec/app_templates/config/initializers/clearance.rb +2 -0
  73. data/spec/app_templates/testapp/app/controllers/home_controller.rb +5 -1
  74. data/spec/app_templates/testapp/config/initializers/action_mailer.rb +1 -3
  75. data/spec/clearance/controller_spec.rb +11 -0
  76. data/spec/clearance/rack_session_spec.rb +5 -5
  77. data/spec/clearance/testing/{helpers_spec.rb → controller_helpers_spec.rb} +12 -12
  78. data/spec/clearance/testing/view_helpers_spec.rb +37 -0
  79. data/spec/configuration_spec.rb +24 -0
  80. data/spec/controllers/apis_controller_spec.rb +6 -2
  81. data/spec/controllers/forgeries_controller_spec.rb +6 -1
  82. data/spec/controllers/passwords_controller_spec.rb +1 -11
  83. data/spec/controllers/permissions_controller_spec.rb +13 -3
  84. data/spec/controllers/sessions_controller_spec.rb +4 -4
  85. data/spec/dummy/app/controllers/application_controller.rb +5 -1
  86. data/spec/dummy/application.rb +4 -0
  87. data/spec/generators/clearance/install/install_generator_spec.rb +15 -3
  88. data/spec/generators/clearance/routes/routes_generator_spec.rb +5 -1
  89. data/spec/generators/clearance/views/views_generator_spec.rb +11 -10
  90. data/spec/helpers/helper_helpers_spec.rb +10 -0
  91. data/spec/mailers/clearance_mailer_spec.rb +13 -19
  92. data/spec/password_strategies/bcrypt_migration_from_sha1_spec.rb +6 -0
  93. data/spec/password_strategies/blowfish_spec.rb +6 -0
  94. data/spec/password_strategies/sha1_spec.rb +6 -0
  95. data/spec/spec_helper.rb +7 -0
  96. data/spec/support/generator_spec_helpers.rb +4 -0
  97. data/spec/support/http_method_shim.rb +23 -0
  98. data/spec/user_spec.rb +9 -0
  99. data/spec/views/view_helpers_spec.rb +10 -0
  100. metadata +19 -8
@@ -1,23 +1,94 @@
1
1
  module Clearance
2
2
  class Configuration
3
- attr_writer :allow_sign_up, :routes
4
-
5
- attr_accessor \
6
- :cookie_domain,
7
- :cookie_expiration,
8
- :cookie_name,
9
- :cookie_path,
10
- :httponly,
11
- :mailer_sender,
12
- :password_strategy,
13
- :redirect_url,
14
- :secure_cookie,
15
- :sign_in_guards,
16
- :user_model
3
+ # Controls whether the sign up route is enabled.
4
+ # Defaults to `true`. Set to `false` to disable user creation routes.
5
+ # The setting is ignored if routes are disabled.
6
+ # @param [Boolean] value
7
+ # @return [Boolean]
8
+ attr_writer :allow_sign_up
9
+
10
+ # The domain to use for the clearance remember token cookie.
11
+ # Defaults to `nil`, which causes the cookie domain to default to the
12
+ # domain of the request. For more, see
13
+ # [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.2.3).
14
+ # @return [String]
15
+ attr_accessor :cookie_domain
16
+
17
+ # A lambda called to set the remember token cookie expires attribute.
18
+ # The lambda accepts the collection of cookies as an argument which
19
+ # allows for changing the expiration according to those cookies.
20
+ # This could be used, for example, to set a session cookie unless
21
+ # a `remember_me` cookie was also present. By default, cookie expiration
22
+ # is one year. For more on cookie expiration see
23
+ # [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.2.1).
24
+ # @return [Lambda]
25
+ attr_accessor :cookie_expiration
26
+
27
+ # The name of Clearance's remember token cookie.
28
+ # Defaults to `remember_token`.
29
+ # @return [String]
30
+ attr_accessor :cookie_name
31
+
32
+ # Controls which paths the remember token cookie is valid for.
33
+ # Defaults to `"/"` for the entire domain. For more, see
34
+ # [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.1.4).
35
+ # @return [String]
36
+ attr_accessor :cookie_path
37
+
38
+ # Controls whether the HttpOnly flag should be set on the remember token
39
+ # cookie. Defaults to `false`. If `true`, the cookie will not be made
40
+ # available to JavaScript. For more see
41
+ # [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.2.6).
42
+ # @return [Boolean]
43
+ attr_accessor :httponly
44
+
45
+ # Controls the address the password reset email is sent from.
46
+ # Defaults to reply@example.com.
47
+ # @return [String]
48
+ attr_accessor :mailer_sender
49
+
50
+ # The password strategy to use when authenticating and setting passwords.
51
+ # Defaults to {Clearance::PasswordStrategies::BCrypt}.
52
+ # @return [Module #authenticated? #password=]
53
+ attr_accessor :password_strategy
54
+
55
+ # The default path Clearance will redirect signed in users to.
56
+ # Defaults to `"/"`. This can often be overridden for specific scenarios by
57
+ # overriding controller methods that rely on it.
58
+ # @return [String]
59
+ attr_accessor :redirect_url
60
+
61
+ # Set to `false` to disable Clearance's built-in routes.
62
+ # Defaults to `true`. When set to false, your app is responsible for all
63
+ # routes. You can dump a copy of Clearance's default routes with
64
+ # `rails generate clearance:routes`.
65
+ # @return [Boolean]
66
+ attr_writer :routes
67
+
68
+ # Controls the secure setting on the remember token cookie.
69
+ # Defaults to `false`. When set, the browser will only send the
70
+ # cookie to the server over HTTPS. You should set this value to true in
71
+ # live environments to prevent session hijacking. For more, see
72
+ # [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.2.5).
73
+ # @return [Boolean]
74
+ attr_accessor :secure_cookie
75
+
76
+ # The array of sign in guards to run when signing a user in.
77
+ # Defaults to an empty array. Sign in guards respond to `call` and are
78
+ # initialized with a session and the current stack. Each guard can decide
79
+ # to fail the sign in, yield to the next guard, or allow the sign in.
80
+ # @return [Array<#call>]
81
+ attr_accessor :sign_in_guards
82
+
83
+ # The ActiveRecord class that represents users in your application.
84
+ # Defualts to `::User`.
85
+ # @return [ActiveRecord::Base]
86
+ attr_accessor :user_model
17
87
 
18
88
  def initialize
19
89
  @allow_sign_up = true
20
90
  @cookie_expiration = ->(cookies) { 1.year.from_now.utc }
91
+ @cookie_domain = nil
21
92
  @cookie_path = '/'
22
93
  @cookie_name = "remember_token"
23
94
  @httponly = false
@@ -32,10 +103,16 @@ module Clearance
32
103
  @user_model ||= ::User
33
104
  end
34
105
 
106
+ # Is the user sign up route enabled?
107
+ # @return [Boolean]
35
108
  def allow_sign_up?
36
109
  @allow_sign_up
37
110
  end
38
111
 
112
+ # Specifies which controller actions are allowed for user resources.
113
+ # This will be `[:create]` is `allow_sign_up` is true (the default), and
114
+ # empty otherwise.
115
+ # @return [Array<Symbol>]
39
116
  def user_actions
40
117
  if allow_sign_up?
41
118
  [:create]
@@ -44,23 +121,58 @@ module Clearance
44
121
  end
45
122
  end
46
123
 
124
+ # The name of user parameter for the configured user model.
125
+ # This is derived from the `model_name` of the `user_model` setting.
126
+ # In the default configuration, this is `user`.
127
+ # @return [Symbol]
128
+ def user_parameter
129
+ user_model.model_name.singular.to_sym
130
+ end
131
+
132
+ # The name of foreign key parameter for the configured user model.
133
+ # This is derived from the `model_name` of the `user_model` setting.
134
+ # In the default configuration, this is `user_id`.
135
+ # @return [Symbol]
47
136
  def user_id_parameter
48
- "#{user_model.model_name.singular}_id".to_sym
137
+ "#{user_parameter}_id".to_sym
49
138
  end
50
139
 
140
+ # @return [Boolean] are Clearance's built-in routes enabled?
51
141
  def routes_enabled?
52
142
  @routes
53
143
  end
144
+
145
+ # Reloads the clearance user model class.
146
+ # This is called from the Clearance engine to reload the configured
147
+ # user class during each request while in development mode, but only once
148
+ # in production.
149
+ #
150
+ # @api private
151
+ def reload_user_model
152
+ if @user_model.present?
153
+ @user_model = @user_model.to_s.constantize
154
+ end
155
+ end
54
156
  end
55
157
 
158
+ # @return [Clearance::Configuration] Clearance's current configuration
56
159
  def self.configuration
57
160
  @configuration ||= Configuration.new
58
161
  end
59
162
 
163
+ # Set Clearance's configuration
164
+ # @param config [Clearance::Configuration]
60
165
  def self.configuration=(config)
61
166
  @configuration = config
62
167
  end
63
168
 
169
+ # Modify Clearance's current configuration
170
+ # @yieldparam [Clearance::Configuration] config current Clearance config
171
+ # ```
172
+ # Clearance.configure do |config|
173
+ # config.routes = false
174
+ # end
175
+ # ```
64
176
  def self.configure
65
177
  yield configuration
66
178
  end
@@ -1,5 +1,22 @@
1
1
  module Clearance
2
2
  module Constraints
3
+ # Can be applied to make a set of routes visible only to users that are
4
+ # signed in.
5
+ #
6
+ # # config/routes.rb
7
+ # constraints Clearance::Constraints::SignedIn.new do
8
+ # resources :posts
9
+ # end
10
+ #
11
+ # In the example above, requests to `/posts` from users that are not signed
12
+ # in will result in a 404. You can make additional assertions about the user
13
+ # by passing a block. For instance, if you want to require that the
14
+ # signed-in user be an admin:
15
+ #
16
+ # # config/routes.rb
17
+ # constraints Clearance::Constraints::SignedIn.new { |user| user.admin? } do
18
+ # resources :posts
19
+ # end
3
20
  class SignedIn
4
21
  def initialize(&block)
5
22
  @block = block || lambda { |user| true }
@@ -12,18 +29,22 @@ module Clearance
12
29
 
13
30
  private
14
31
 
32
+ # @api private
15
33
  def clearance_session
16
34
  @request.env[:clearance]
17
35
  end
18
36
 
37
+ # @api private
19
38
  def current_user
20
39
  clearance_session.current_user
21
40
  end
22
41
 
42
+ # @api private
23
43
  def current_user_fulfills_additional_requirements?
24
44
  @block.call current_user
25
45
  end
26
46
 
47
+ # @api private
27
48
  def signed_in?
28
49
  clearance_session.present? && clearance_session.signed_in?
29
50
  end
@@ -1,5 +1,15 @@
1
1
  module Clearance
2
2
  module Constraints
3
+ # Can be applied to make a set of routes visible only to users that are
4
+ # signed out.
5
+ #
6
+ # # config/routes.rb
7
+ # constraints Clearance::Constraints::SignedOut.new do
8
+ # resources :registrations, only: [:new, :create]
9
+ # end
10
+ #
11
+ # In the example above, requests to `/registrations/new` from users that are
12
+ # signed in will result in a 404.
3
13
  class SignedOut
4
14
  def matches?(request)
5
15
  @request = request
@@ -8,10 +18,12 @@ module Clearance
8
18
 
9
19
  private
10
20
 
21
+ # @api private
11
22
  def clearance_session
12
23
  @request.env[:clearance]
13
24
  end
14
25
 
26
+ # @api private
15
27
  def missing_session?
16
28
  clearance_session.nil?
17
29
  end
@@ -1,2 +1,14 @@
1
1
  require 'clearance/constraints/signed_in'
2
2
  require 'clearance/constraints/signed_out'
3
+
4
+ module Clearance
5
+ # Clearance provides Rails routing constraints that can control access and the
6
+ # visibility of routes at the routing layer. The {Constraints::SignedIn}
7
+ # constraint can be used to make routes visible only to signed in users. The
8
+ # {Constraints::SignedOut} constraint can be used to make routes visible only
9
+ # to signed out users.
10
+ #
11
+ # @see http://guides.rubyonrails.org/routing.html#advanced-constraints
12
+ module Constraints
13
+ end
14
+ end
@@ -2,6 +2,19 @@ require 'clearance/authentication'
2
2
  require 'clearance/authorization'
3
3
 
4
4
  module Clearance
5
+ # Adds clearance controller helpers to the controller it is mixed into.
6
+ #
7
+ # This exposes clearance controller and helper methods such as `current_user`.
8
+ # See {Authentication} and {Authorization} documentation for complete
9
+ # documentation on the methods.
10
+ #
11
+ # The `clearance:install` generator automatically adds this mixin to
12
+ # `ApplicationController`, which is the recommended configuration.
13
+ #
14
+ # class ApplicationController < ApplicationController
15
+ # include Clearance::Controller
16
+ # end
17
+ #
5
18
  module Controller
6
19
  extend ActiveSupport::Concern
7
20
 
@@ -1,5 +1,14 @@
1
1
  module Clearance
2
+ # Runs as the base {SignInGuard} for all requests, regardless of configured
3
+ # {Configuration#sign_in_guards}.
2
4
  class DefaultSignInGuard < SignInGuard
5
+ # Runs the default sign in guard.
6
+ #
7
+ # If there is a value set in the clearance session object, then the guard
8
+ # returns {SuccessStatus}. Otherwise, it returns {FailureStatus} with the
9
+ # message returned by {#default_failure_message}.
10
+ #
11
+ # @return [SuccessStatus, FailureStatus]
3
12
  def call
4
13
  if session.signed_in?
5
14
  success
@@ -8,6 +17,14 @@ module Clearance
8
17
  end
9
18
  end
10
19
 
20
+ # The default failure message pulled from the i18n framework.
21
+ #
22
+ # Will use the value returned from the following i18n keys, in this order:
23
+ #
24
+ # * `clearance.controllers.sessions.bad_email_or_password`
25
+ # * `flashes.failure_after_create`
26
+ #
27
+ # @return [String]
11
28
  def default_failure_message
12
29
  I18n.t(
13
30
  :bad_email_or_password,
@@ -1,12 +1,32 @@
1
- require 'clearance'
2
- require 'rails'
1
+ require "clearance"
2
+ require "rails"
3
3
 
4
4
  module Clearance
5
+ # Makes Clearance behavior available to Rails apps on initialization. By using
6
+ # a Rails Engine rather than a Railtie, Clearance can automatically expose its
7
+ # own routes and views to the hosting application.
8
+ #
9
+ # Requiring `clearance` (likely by having it in your `Gemfile`) will
10
+ # automatically require the engine. You can opt-out of Clearance's internal
11
+ # routes by using {Configuration#routes=}. You can override the Clearance
12
+ # views by running `rails generate clearance:views`.
13
+ #
14
+ # In addition to providing routes and views, the Clearance engine:
15
+ #
16
+ # * Ensures `password` and `token` parameters are filtered out of Rails logs.
17
+ # * Mounts the {RackSession} middleware in the appropriate location
18
+ # * Reloads classes referenced in your {Configuration} on every request in
19
+ # development mode.
20
+ #
5
21
  class Engine < Rails::Engine
6
- initializer 'clearance.filter' do |app|
22
+ initializer "clearance.filter" do |app|
7
23
  app.config.filter_parameters += [:password, :token]
8
24
  end
9
25
 
10
- config.app_middleware.insert_after ActionDispatch::ParamsParser, Clearance::RackSession
26
+ config.app_middleware.use(Clearance::RackSession)
27
+
28
+ config.to_prepare do
29
+ Clearance.configuration.reload_user_model
30
+ end
11
31
  end
12
32
  end
@@ -1,10 +1,14 @@
1
1
  module Clearance
2
2
  module PasswordStrategies
3
+ # Uses BCrypt to authenticate users and store encrypted passwords.
4
+ #
5
+ # The BCrypt cost (the measure of how many key expansion iterations BCrypt
6
+ # will perform) is automatically set to the minimum allowed value when
7
+ # Rails is operating in the test environment and the default cost in all
8
+ # other envionments. This provides a speed boost in tests.
3
9
  module BCrypt
4
10
  require 'bcrypt'
5
11
 
6
- extend ActiveSupport::Concern
7
-
8
12
  def authenticated?(password)
9
13
  if encrypted_password.present?
10
14
  ::BCrypt::Password.new(encrypted_password) == password
@@ -21,10 +25,12 @@ module Clearance
21
25
 
22
26
  private
23
27
 
28
+ # @api private
24
29
  def encrypt(password)
25
30
  ::BCrypt::Password.create(password, cost: cost)
26
31
  end
27
32
 
33
+ # @api private
28
34
  def cost
29
35
  if test_environment?
30
36
  ::BCrypt::Engine::MIN_COST
@@ -33,6 +39,7 @@ module Clearance
33
39
  end
34
40
  end
35
41
 
42
+ # @api private
36
43
  def test_environment?
37
44
  defined?(::Rails) && ::Rails.env.test?
38
45
  end
@@ -1,6 +1,15 @@
1
1
  module Clearance
2
2
  module PasswordStrategies
3
+ # @deprecated Use {BCrypt} or `clearance-deprecated_password_strategies` gem
3
4
  module BCryptMigrationFromSHA1
5
+ DEPRECATION_MESSAGE = "[DEPRECATION] The BCryptMigrationFromSha1 " \
6
+ "password strategy has been deprecated and will be removed from " \
7
+ "Clearance 2.0. BCrypt is the only officially supported strategy, " \
8
+ "though you are free to provide your own. To continue using this " \
9
+ "strategy, add clearance-deprecated_password_strategies to your " \
10
+ "Gemfile."
11
+
12
+ # @api private
4
13
  class BCryptUser
5
14
  include Clearance::PasswordStrategies::BCrypt
6
15
 
@@ -11,6 +20,7 @@ module Clearance
11
20
  delegate :encrypted_password, :encrypted_password=, to: :@user
12
21
  end
13
22
 
23
+ # @api private
14
24
  class SHA1User
15
25
  include Clearance::PasswordStrategies::SHA1
16
26
 
@@ -21,17 +31,24 @@ module Clearance
21
31
  delegate :salt, :salt=, :encrypted_password, :encrypted_password=, to: :@user
22
32
  end
23
33
 
34
+ # @deprecated Use {BCrypt} or `clearance-deprecated_password_strategies`
35
+ # gem
24
36
  def authenticated?(password)
37
+ warn "#{Kernel.caller.first}: #{DEPRECATION_MESSAGE}"
25
38
  authenticated_with_sha1?(password) || authenticated_with_bcrypt?(password)
26
39
  end
27
40
 
41
+ # @deprecated Use {BCrypt} or `clearance-deprecated_password_strategies`
42
+ # gem
28
43
  def password=(new_password)
44
+ warn "#{Kernel.caller.first}: #{DEPRECATION_MESSAGE}"
29
45
  @password = new_password
30
46
  BCryptUser.new(self).password = new_password
31
47
  end
32
48
 
33
49
  private
34
50
 
51
+ # @api private
35
52
  def authenticated_with_bcrypt?(password)
36
53
  begin
37
54
  BCryptUser.new(self).authenticated? password
@@ -40,6 +57,7 @@ module Clearance
40
57
  end
41
58
  end
42
59
 
60
+ # @api private
43
61
  def authenticated_with_sha1?(password)
44
62
  if sha1_password?
45
63
  if SHA1User.new(self).authenticated? password
@@ -50,6 +68,7 @@ module Clearance
50
68
  end
51
69
  end
52
70
 
71
+ # @api private
53
72
  def sha1_password?
54
73
  self.encrypted_password =~ /^[a-f0-9]{40}$/
55
74
  end
@@ -3,12 +3,25 @@ require 'base64'
3
3
 
4
4
  module Clearance
5
5
  module PasswordStrategies
6
+ # @deprecated Use {BCrypt} or `clearance-deprecated_password_strategies` gem
6
7
  module Blowfish
8
+ DEPRECATION_MESSAGE = "[DEPRECATION] The Blowfish password strategy " \
9
+ "has been deprecated and will be removed from Clearance 2.0. BCrypt " \
10
+ "is the only officially supported strategy, though you are free to " \
11
+ "provide your own. To continue using this strategy add " \
12
+ "clearance-deprecated_password_strategies to your Gemfile."
13
+
14
+ # @deprecated Use {BCrypt} or `clearance-deprecated_password_strategies`
15
+ # gem
7
16
  def authenticated?(password)
17
+ warn "#{Kernel.caller.first}: #{DEPRECATION_MESSAGE}"
8
18
  encrypted_password == encrypt(password)
9
19
  end
10
20
 
21
+ # @deprecated Use {BCrypt} or `clearance-deprecated_password_strategies`
22
+ # gem
11
23
  def password=(new_password)
24
+ warn "#{Kernel.caller.first}: #{DEPRECATION_MESSAGE}"
12
25
  @password = new_password
13
26
  initialize_salt_if_necessary
14
27
 
@@ -19,10 +32,12 @@ module Clearance
19
32
 
20
33
  protected
21
34
 
35
+ # @api private
22
36
  def encrypt(string)
23
37
  generate_hash("--#{salt}--#{string}--")
24
38
  end
25
39
 
40
+ # @api private
26
41
  def generate_hash(string)
27
42
  cipher = OpenSSL::Cipher::Cipher.new('bf-cbc').encrypt
28
43
  cipher.key = Digest::SHA256.digest(salt)
@@ -30,12 +45,14 @@ module Clearance
30
45
  Base64.encode64(hash).encode('utf-8')
31
46
  end
32
47
 
48
+ # @api private
33
49
  def initialize_salt_if_necessary
34
50
  if salt.blank?
35
51
  self.salt = generate_salt
36
52
  end
37
53
  end
38
54
 
55
+ # @api private
39
56
  def generate_salt
40
57
  Base64.encode64(SecureRandom.hex(20)).encode('utf-8')
41
58
  end
@@ -1,15 +1,28 @@
1
1
  module Clearance
2
2
  module PasswordStrategies
3
+ # @deprecated Use {BCrypt} or `clearance-deprecated_password_strategies` gem
3
4
  module SHA1
4
5
  require 'digest/sha1'
5
6
 
7
+ DEPRECATION_MESSAGE = "[DEPRECATION] The SHA1 password strategy " \
8
+ "has been deprecated and will be removed from Clearance 2.0. BCrypt " \
9
+ "is the only officially supported strategy, though you are free to " \
10
+ "provide your own. To continue using this strategy add " \
11
+ "clearance-deprecated_password_strategies to your Gemfile."
12
+
6
13
  extend ActiveSupport::Concern
7
14
 
15
+ # @deprecated Use {BCrypt} or `clearance-deprecated_password_strategies`
16
+ # gem
8
17
  def authenticated?(password)
18
+ warn "#{Kernel.caller.first}: #{DEPRECATION_MESSAGE}"
9
19
  encrypted_password == encrypt(password)
10
20
  end
11
21
 
22
+ # @deprecated Use {BCrypt} or `clearance-deprecated_password_strategies`
23
+ # gem
12
24
  def password=(new_password)
25
+ warn "#{Kernel.caller.first}: #{DEPRECATION_MESSAGE}"
13
26
  @password = new_password
14
27
  initialize_salt_if_necessary
15
28
 
@@ -20,20 +33,24 @@ module Clearance
20
33
 
21
34
  private
22
35
 
36
+ # @api private
23
37
  def encrypt(string)
24
38
  generate_hash "--#{salt}--#{string}--"
25
39
  end
26
40
 
41
+ # @api private
27
42
  def generate_hash(string)
28
43
  Digest::SHA1.hexdigest(string).encode 'UTF-8'
29
44
  end
30
45
 
46
+ # @api private
31
47
  def initialize_salt_if_necessary
32
48
  if salt.blank?
33
49
  self.salt = generate_salt
34
50
  end
35
51
  end
36
52
 
53
+ # @api private
37
54
  def generate_salt
38
55
  SecureRandom.hex(20).encode('UTF-8')
39
56
  end
@@ -1,4 +1,17 @@
1
1
  module Clearance
2
+ # Control how users are authenticated and how passwords are stored.
3
+ #
4
+ # The default password strategy is {Clearance::PasswordStrategies::BCrypt},
5
+ # but this can be overridden in {Clearance::Configuration}.
6
+ #
7
+ # You can supply your own password strategy by implementing a module that
8
+ # responds to the proper interface methods. Once this module is configured as
9
+ # your password strategy, Clearance will mix it into your Clearance User
10
+ # class. Thus, your module can access any methods or attributes on User.
11
+ #
12
+ # Password strategies need to respond to `authenticated?(password)` and
13
+ # `password=(new_password)`. For an example of how to implement these methods,
14
+ # see {Clearance::PasswordStrategies::BCrypt}.
2
15
  module PasswordStrategies
3
16
  autoload :BCrypt, 'clearance/password_strategies/bcrypt'
4
17
  autoload :BCryptMigrationFromSHA1,
@@ -1,9 +1,22 @@
1
1
  module Clearance
2
+ # Rack middleware that manages the Clearance {Session}. This middleware is
3
+ # automatically mounted by the Clearance {Engine}.
4
+ #
5
+ # * maintains the session cookie specified by your {Configuration}.
6
+ # * exposes previously cookied sessions to Clearance and your app at
7
+ # `request.env[:clearance]`, which {Authentication#current_user} pulls the
8
+ # user from.
9
+ #
10
+ # @see Session
11
+ # @see Configuration#cookie_name
12
+ #
2
13
  class RackSession
3
14
  def initialize(app)
4
15
  @app = app
5
16
  end
6
17
 
18
+ # Reads previously existing sessions from a cookie and maintains the cookie
19
+ # on each response.
7
20
  def call(env)
8
21
  session = Clearance::Session.new(env)
9
22
  env[:clearance] = session
@@ -1,8 +1,19 @@
1
- require 'rspec/rails'
2
- require 'clearance/testing/deny_access_matcher'
3
- require 'clearance/testing/helpers'
1
+ require "rspec/rails"
2
+ require "clearance/testing/deny_access_matcher"
3
+ require "clearance/testing/controller_helpers"
4
+ require "clearance/testing/view_helpers"
4
5
 
5
6
  RSpec.configure do |config|
6
7
  config.include Clearance::Testing::Matchers, type: :controller
7
- config.include Clearance::Testing::Helpers, type: :controller
8
+ config.include Clearance::Testing::ControllerHelpers, type: :controller
9
+ config.include Clearance::Testing::ViewHelpers, type: :view
10
+ config.include Clearance::Testing::ViewHelpers, type: :helper
11
+
12
+ config.before(:each, type: :view) do
13
+ view.extend Clearance::Testing::ViewHelpers::CurrentUser
14
+ end
15
+
16
+ config.before(:each, type: :helper) do
17
+ view.extend Clearance::Testing::ViewHelpers::CurrentUser
18
+ end
8
19
  end