diff --git a/README.md b/README.md index bdce3e7f8..94b38f4e9 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Override any of these defaults in `config/initializers/clearance.rb`: ```ruby Clearance.configure do |config| config.allow_sign_up = true + config.allow_password_reset = true config.cookie_domain = ".example.com" config.cookie_expiration = lambda { |cookies| 1.year.from_now.utc } config.cookie_name = "remember_token" diff --git a/app/views/sessions/_form.html.erb b/app/views/sessions/_form.html.erb index 31dc415ac..8fb2e9abe 100644 --- a/app/views/sessions/_form.html.erb +++ b/app/views/sessions/_form.html.erb @@ -17,6 +17,8 @@ <% if Clearance.configuration.allow_sign_up? %> <%= link_to t(".sign_up"), sign_up_path %> <% end %> - <%= link_to t(".forgot_password"), new_password_path %> + <% if Clearance.configuration.allow_password_reset? %> + <%= link_to t(".forgot_password"), new_password_path %> + <% end %> <% end %> diff --git a/config/routes.rb b/config/routes.rb index 700f7b3e0..08de03e34 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,9 +11,11 @@ resources :users, controller: 'clearance/users', only: Clearance.configuration.user_actions do - resource :password, - controller: 'clearance/passwords', - only: [:edit, :update] + if Clearance.configuration.allow_password_reset? + resource :password, + controller: 'clearance/passwords', + only: [:edit, :update] + end end get '/sign_in' => 'clearance/sessions#new', as: 'sign_in' diff --git a/lib/clearance/configuration.rb b/lib/clearance/configuration.rb index b5f21eeb3..61f0b3800 100644 --- a/lib/clearance/configuration.rb +++ b/lib/clearance/configuration.rb @@ -7,6 +7,13 @@ class Configuration # @return [Boolean] attr_writer :allow_sign_up + # Controls whether the password reset routes are enabled + # Defaults to `true`. Set to False to disable password reset routes + # The setting is ignored if routes are disabled. + # @param [Boolean] value + # @return [Boolean] + attr_writer :allow_password_reset + # The domain to use for the clearance remember token cookie. # Defaults to `nil`, which causes the cookie domain to default to the # domain of the request. For more, see @@ -145,6 +152,7 @@ class Configuration def initialize @allow_sign_up = true + @allow_password_reset = true @allowed_backdoor_environments = ["test", "ci", "development"] @cookie_domain = nil @cookie_expiration = ->(cookies) { 1.year.from_now.utc } @@ -195,6 +203,12 @@ def allow_sign_up? @allow_sign_up end + # Are the password reset routes enabled? + # @return [Boolean] + def allow_password_reset? + @allow_password_reset + end + # Specifies which controller actions are allowed for user resources. # This will be `[:create]` is `allow_sign_up` is true (the default), and # empty otherwise. diff --git a/spec/configuration_spec.rb b/spec/configuration_spec.rb index 446365023..c6436ece7 100644 --- a/spec/configuration_spec.rb +++ b/spec/configuration_spec.rb @@ -179,6 +179,21 @@ end end + describe "#allow_password_reset?" do + context "when allow_password_reset is configured to false" do + it "returns false" do + Clearance.configure { |config| config.allow_password_reset = false } + expect(Clearance.configuration.allow_password_reset?).to eq false + end + end + + context "when allow_sign_up has not been configured" do + it "returns true" do + expect(Clearance.configuration.allow_password_reset?).to eq true + end + end + end + describe "#user_actions" do context "when allow_sign_up is configured to false" do it "returns empty array" do diff --git a/spec/routing/clearance_routes_spec.rb b/spec/routing/clearance_routes_spec.rb index 960c1ba90..633824b95 100644 --- a/spec/routing/clearance_routes_spec.rb +++ b/spec/routing/clearance_routes_spec.rb @@ -62,4 +62,36 @@ expect(post: 'users').to be_routable end end + + context 'password reset disabled' do + around do |example| + Clearance.configure { |config| config.allow_password_reset = false } + Rails.application.reload_routes! + example.run + Clearance.configuration = Clearance::Configuration.new + Rails.application.reload_routes! + end + + it 'does not route password edit' do + user = create(:user) + expect(get: "users/#{user.id}/password/edit").not_to be_routable + end + + it 'does not route to clearance/passwords#update' do + user = create(:user) + expect(patch: "/users/#{user.id}/password").not_to be_routable + end + end + + context 'reset enabled' do + it 'does route password edit' do + user = create(:user) + expect(get: "users/#{user.id}/password/edit").to be_routable + end + + it 'does route to clearance/passwords#update' do + user = create(:user) + expect(patch: "/users/#{user.id}/password").to be_routable + end + end end