Giter Club home page Giter Club logo

clearance's Introduction

Clearance

Build Status Code Climate Documentation Quality Reviewed by Hound

Rails authentication with email & password.

Clearance is intended to be small, simple, and well-tested. It has opinionated defaults but is intended to be easy to override.

Please use GitHub Issues to report bugs. If you have a question about the library, please use the clearance tag on Stack Overflow. This tag is monitored by contributors.

Getting Started

Clearance is a Rails engine tested against Rails >= 6.1 and Ruby >= 3.0.0.

You can add it to your Gemfile with:

gem "clearance"

Run the bundle command to install it.

After you install Clearance, you need to run the generator:

rails generate clearance:install

The Clearance install generator:

  • Inserts Clearance::User into your User model
  • Inserts Clearance::Controller into your ApplicationController
  • Creates an initializer file to allow further configuration.
  • Creates a migration file that either create a users table or adds any necessary columns to the existing table.

Configure

Override any of these defaults in config/initializers/clearance.rb:

Clearance.configure do |config|
  config.allow_sign_up = true
  config.cookie_domain = ".example.com"
  config.cookie_expiration = lambda { |cookies| 1.year.from_now.utc }
  config.cookie_name = "remember_token"
  config.cookie_path = "/"
  config.routes = true
  config.httponly = true
  config.mailer_sender = "[email protected]"
  config.password_strategy = Clearance::PasswordStrategies::BCrypt
  config.redirect_url = "/"
  config.url_after_destroy = nil
  config.url_after_denied_access_when_signed_out = nil
  config.rotate_csrf_on_sign_in = true
  config.same_site = nil
  config.secure_cookie = false
  config.signed_cookie = false
  config.sign_in_guards = []
  config.user_model = "User"
  config.parent_controller = "ApplicationController"
  config.sign_in_on_password_reset = false
end

Use

Access Control

Use the require_login filter to control access to controller actions.

class ArticlesController < ApplicationController
  before_action :require_login

  def index
    current_user.articles
  end
end

Clearance also provides routing constraints that can be used to control access at the routing layer:

Blog::Application.routes.draw do
  constraints Clearance::Constraints::SignedIn.new { |user| user.admin? } do
    root to: "admin/dashboards#show", as: :admin_root
  end

  constraints Clearance::Constraints::SignedIn.new do
    root to: "dashboards#show", as: :signed_in_root
  end

  constraints Clearance::Constraints::SignedOut.new do
    root to: "marketing#index"
  end
end

Helper Methods

Use current_user, signed_in?, and signed_out? in controllers, views, and helpers. For example:

<% if signed_in? %>
  <%= current_user.email %>
  <%= button_to "Sign out", sign_out_path, method: :delete %>
<% else %>
  <%= link_to "Sign in", sign_in_path %>
<% end %>

Password Resets

When a user resets their password, Clearance delivers them an email. You should change the mailer_sender default, used in the email's "from" header:

Clearance.configure do |config|
  config.mailer_sender = "[email protected]"
end

Multiple Domain Support

You can support multiple domains, or other special domain configurations by optionally setting cookie_domain as a callable object. The first argument passed to the method is an ActionDispatch::Request object.

Clearance.configure do |config|
  config.cookie_domain = lambda { |request| request.host }
end

Integrating with Rack Applications

Clearance adds its session to the Rack environment hash so middleware and other Rack applications can interact with it:

class Bubblegum::Middleware
  def initialize(app)
    @app = app
  end

  def call(env)
    if env[:clearance].signed_in?
      env[:clearance].current_user.bubble_gum
    end

    @app.call(env)
  end
end

Overriding Clearance

Routes

See config/routes.rb for the default set of routes.

As of Clearance 1.5 it is recommended that you disable Clearance routes and take full control over routing and URL design. This ensures that your app's URL design won't be affected if the gem's routes and URL design are changed.

To disable the routes, change the routes configuration option to false:

Clearance.configure do |config|
  config.routes = false
end

You can optionally run rails generate clearance:routes to dump a copy of the default routes into your application for modification.

Controllers

See app/controllers/clearance for the default behavior. Many protected methods were extracted in these controllers in an attempt to make overrides and hooks simpler.

To override a Clearance controller, subclass it and update the routes to point to your new controller (see the "Routes" section).

class PasswordsController < Clearance::PasswordsController
class SessionsController < Clearance::SessionsController
class UsersController < Clearance::UsersController

Redirects

The post-action redirects in Clearance are simple methods which can be overridden one by one, or configured globally.

These "success" methods are called for signed in users, and redirect to Clearance.configuration.redirect_url (which is / by default):

  • passwords#url_after_update
  • sessions#url_after_create
  • sessions#url_for_signed_in_users
  • users#url_after_create
  • application#url_after_denied_access_when_signed_in

To override them all at once, change the global configuration of redirect_url. To change individual URLs, override the appropriate method in your subclassed controller.

These "failure" methods are called for signed out sessions:

  • application#url_after_denied_access_when_signed_out
  • sessions#url_after_destroy

You can override the appropriate method in your subclassed controller or you can set a configuration value for either of these URLs:

  • Clearance.configuration.url_after_denied_access_when_signed_out
  • Clearance.configuration.url_after_destroy

Both configurations default to nil and if not set will default to sign_in_url in sessions_controller.rb and authorization.rb for backwards compatibility.

Views

See app/views for the default behavior.

To override a view, create your own copy of it:

app/views/clearance_mailer/change_password.html.erb
app/views/passwords/create.html.erb
app/views/passwords/edit.html.erb
app/views/passwords/new.html.erb
app/views/sessions/_form.html.erb
app/views/sessions/new.html.erb
app/views/users/_form.html.erb
app/views/users/new.html.erb

You can use the Clearance views generator to copy the default views to your application for modification.

rails generate clearance:views

Layouts

By default, Clearance uses your application's default layout. If you would like to change the layout that Clearance uses when rendering its views, simply specify the layout in the config/application.rb

config.to_prepare do
  Clearance::PasswordsController.layout "my_passwords_layout"
  Clearance::SessionsController.layout "my_sessions_layout"
  Clearance::UsersController.layout "my_admin_layout"
end

Translations

All flash messages and email subject lines are stored in i18n translations. Override them like any other translation.

See config/locales/clearance.en.yml for the default behavior.

You can also install clearance-i18n for access to additional, user-contributed translations.

User Model

See lib/clearance/user.rb for the default behavior. You can override those methods as needed.

Note that there are some model-level validations (see above link for detail) which the Clearance::User module will add to the configured model class and which may conflict with or duplicate already present validations on the email and password attributes. Over-riding the email_optional? or skip_password_validation? methods to return true will disable those validations from being added.

Signed Cookies

By default, Clearance uses unsigned cookies. If you would like to use signed cookies you can do so by overriding the default in an initializer like so:

Clearance.configure do |config|
  # ... other overrides
  config.signed_cookie = true
end

If you are currently not using signed cookies but would like to migrate your users over to them without breaking current sessions, you can do so by passing in :migrate rather than true as so:

Clearance.configure do |config|
  # ... other overrides
  config.signed_cookie = :migrate
end

You can read more about signed cookies in Clearance and why they are a good idea in the pull request that added them.

Extending Sign In

By default, Clearance will sign in any user with valid credentials. If you need to support additional checks during the sign in process then you can use the SignInGuard stack. For example, using the SignInGuard stack, you could prevent suspended users from signing in, or require that users confirm their email address before accessing the site.

SignInGuards offer fine-grained control over the process of signing in a user. Each guard is run in order and hands the session off to the next guard in the stack.

A SignInGuard is an object that responds to call. It is initialized with a session and the current stack.

On success, a guard should call the next guard or return SuccessStatus.new if you don't want any subsequent guards to run.

On failure, a guard should call FailureStatus.new(failure_message). It can provide a message explaining the failure.

For convenience, a SignInGuard class has been provided and can be inherited from. The convenience class provides a few methods to help make writing guards simple: success, failure, next_guard, signed_in?, and current_user.

Here's an example custom guard to handle email confirmation:

Clearance.configure do |config|
  config.sign_in_guards = ["EmailConfirmationGuard"]
end
# app/guards/email_confirmation_guard.rb
class EmailConfirmationGuard < Clearance::SignInGuard
  def call
    if unconfirmed?
      failure("You must confirm your email address.")
    else
      next_guard
    end
  end

  def unconfirmed?
    signed_in? && !current_user.confirmed_at
  end
end

Testing

Fast Feature Specs

Clearance includes middleware that avoids wasting time spent visiting, loading, and submitting the sign in form. It instead signs in the designated user directly. The speed increase can be substantial.

Enable the Middleware in Test:

# config/environments/test.rb
MyRailsApp::Application.configure do
  # ...
  config.middleware.use Clearance::BackDoor
  # ...
end

Usage:

visit root_path(as: user)

Additionally, if User#to_param is overridden, you can pass a block in order to override the default behavior:

# config/environments/test.rb
MyRailsApp::Application.configure do
  # ...
  config.middleware.use Clearance::BackDoor do |username|
    Clearance.configuration.user_model.find_by(username: username)
  end
  # ...
end

Ready Made Feature Specs

If you're using RSpec, you can generate feature specs to help prevent regressions in Clearance's integration with your Rails app over time. These feature specs, will also require factory_bot_rails.

To Generate the clearance specs, run:

rails generate clearance:specs

Controller Test Helpers

To test controller actions that are protected by before_action :require_login, require Clearance's test helpers in your test suite.

For rspec, add the following line to your spec/rails_helper.rb or spec/spec_helper if rails_helper does not exist:

require "clearance/rspec"

For test-unit, add this line to your test/test_helper.rb:

require "clearance/test_unit"

Note for Rails 5: the default generated controller tests are now integration tests. You will need to use the backdoor middleware instead.

This will make Clearance::Controller methods work in your controllers during functional tests and provide access to helper methods like:

sign_in
sign_in_as(user)
sign_out

View and Helper Spec Helpers

Does the view or helper you're testing reference signed_in?, signed_out? or current_user? If you require 'clearance/rspec', you will have the following helpers available in your view specs:

sign_in
sign_in_as(user)

These will make the clearance view helpers work as expected by signing in either a new instance of your user model (sign_in) or the object you pass to sign_in_as. If you do not call one of these sign in helpers or otherwise set current_user in your view specs, your view will behave as if there is no current user: signed_in? will be false and signed_out? will be true.

Contributing

Please see CONTRIBUTING.md. Thank you, contributors!

Security

For security issues it's better to contact [email protected] (See https://thoughtbot.com/security)

License

Clearance is copyright © 2009 thoughtbot. It is free software, and may be redistributed under the terms specified in the LICENSE file.

clearance's People

Contributors

abunashir avatar calebhearth avatar danhodge avatar danielnolan avatar derekprior avatar eebs avatar eugenebolshakov avatar geoffharcourt avatar gnfisher avatar halogenandtoast avatar hardbap avatar harlow avatar imtayadeway avatar jessieay avatar jferris avatar joshuaclayton avatar jsteiner avatar kenyonj avatar matheusrich avatar mike-burns avatar mjankowski avatar mottinimauro avatar mxie avatar odlp avatar pedrosmmoreira avatar qrush avatar rmm5t avatar sej3506 avatar sikachu avatar technicalpickles avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clearance's Issues

Routes hack generates stack level too deep error

Using the Clearance engine with the ResourceController gem has led to some issues with routing; namely, a stack level too deep error. It's triggered once the clearance_features generator runs, but attempting to migrate, start a server, and run console also fail with the same issue.

Running this template ( http://gist.github.com/104454 ) will recreate the error. A quick monkey patch ( http://github.com/joshuaclayton/... ) to have Rails engines handle routes itself resolves the issue, but per the blog post on Engines ( http://giantrobots.thoughtbot.co... ), it doesn't sound like it's able to be fixed that way.

undefined method `rescue_responses' for ActionController::Base:Class

I just froze edge rails and now anytime I try to load the clearance gem I get the exception below. I just updated to 0.6.6 of clearance.

rake gems:unpack --trace
** Invoke gems:unpack (first_time)
** Invoke gems:install (first_time)
** Invoke gems:base (first_time)
** Execute gems:base
** Invoke environment (first_time)
** Execute environment
rake aborted!
undefined method rescue_responses' for ActionController::Base:Class /Library/Ruby/Gems/1.8/gems/thoughtbot-clearance-0.6.6/lib/clearance/extensions/rescue.rb:1 /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:ingem_original_require'
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in require' /PROJECT_PATH/vendor/rails/activeresource/lib/../../activesupport/lib/active_support/dependencies.rb:167:inrequire'
/PROJECT_PATH/vendor/rails/activeresource/lib/../../activesupport/lib/active_support/dependencies.rb:532:in new_constants_in' /PROJECT_PATH/vendor/rails/activeresource/lib/../../activesupport/lib/active_support/dependencies.rb:167:inrequire'
/Library/Ruby/Gems/1.8/gems/thoughtbot-clearance-0.6.6/lib/clearance.rb:2
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in gem_original_require' /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:inrequire'
/PROJECT_PATH/vendor/rails/activeresource/lib/../../activesupport/lib/active_support/dependencies.rb:167:in require' /PROJECT_PATH/vendor/rails/activeresource/lib/../../activesupport/lib/active_support/dependencies.rb:532:innew_constants_in'
/PROJECT_PATH/vendor/rails/activeresource/lib/../../activesupport/lib/active_support/dependencies.rb:167:in require' /PROJECT_PATH/config/../vendor/rails/railties/lib/rails/gem_dependency.rb:192:inload'
/PROJECT_PATH/config/../vendor/rails/railties/lib/initializer.rb:308:in load_gems' /PROJECT_PATH/config/../vendor/rails/railties/lib/initializer.rb:308:ineach'
/PROJECT_PATH/config/../vendor/rails/railties/lib/initializer.rb:308:in load_gems' /PROJECT_PATH/config/../vendor/rails/railties/lib/initializer.rb:161:inprocess'
/PROJECT_PATH/config/../vendor/rails/railties/lib/initializer.rb:110:in send' /PROJECT_PATH/config/../vendor/rails/railties/lib/initializer.rb:110:inrun'
/PROJECT_PATH/config/environment.rb:11
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in gem_original_require' /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:inrequire'
/PROJECT_PATH/vendor/rails/railties/lib/tasks/misc.rake:4
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:617:in call' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:617:inexecute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:612:in each' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:612:inexecute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:578:in invoke_with_call_chain' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/monitor.rb:242:insynchronize'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:571:in invoke_with_call_chain' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:564:ininvoke'
/PROJECT_PATH/vendor/rails/railties/lib/tasks/gems.rake:17
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:617:in call' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:617:inexecute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:612:in each' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:612:inexecute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:578:in invoke_with_call_chain' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/monitor.rb:242:insynchronize'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:571:in invoke_with_call_chain' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:588:ininvoke_prerequisites'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:585:in each' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:585:ininvoke_prerequisites'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:577:in invoke_with_call_chain' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/monitor.rb:242:insynchronize'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:571:in invoke_with_call_chain' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:588:ininvoke_prerequisites'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:585:in each' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:585:ininvoke_prerequisites'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:577:in invoke_with_call_chain' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/monitor.rb:242:insynchronize'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:571:in invoke_with_call_chain' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:564:ininvoke'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:2019:in invoke_task' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:1997:intop_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:1997:in each' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:1997:intop_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:2036:in standard_exception_handling' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:1991:intop_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:1970:in run' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:2036:instandard_exception_handling'
/Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake.rb:1967:in run' /Library/Ruby/Gems/1.8/gems/rake-0.8.3/bin/rake:31 /usr/bin/rake:19:inload'
/usr/bin/rake:19

Readme small mistake

Hi there,

Nothing serious but in the README,

config.gem "thoughtbot-clearance",
  :lib     => 'clearance',
  :source  => 'http://gemcutter.org',
  :version => '0.8.3'

should actually be:

config.gem "clearance",
  :lib     => 'clearance',
  :source  => 'http://gemcutter.org',
  :version => '0.8.3'

Thanks,
Marcelo

Minor spelling mistake

Really minor, but … in confirmations_controller and passwords_controller, it should be spelt “existent”, not “existant”.

flash key audit

app/controllers/clearance/confirmations_controller.rb
18: flash[:success] = "Confirmed email and signed in."

app/controllers/clearance/passwords_controller.rb
16: flash[:notice] = "You will receive an email within the next few minutes. " <<
20: flash.now[:notice] = "Unknown email"

app/controllers/clearance/sessions_controller.rb
15: flash.now[:notice] = "Bad email or password."
21: flash[:notice] = "Signed in successfully."
33: flash[:notice] = "You have been signed out."

app/controllers/clearance/users_controller.rb
16: flash[:notice] = "You will receive an email within the next few minutes. " <<

lib/clearance/authentication.rb
72: def deny_access(flash_message = nil, opts = {})
74: flash[:failure] = flash_message if flash_message

One could argue all of the sessions_controller keys could be either :failure or :success. I say bad email should be :failure, signed in should be :success, and signed out should be :success. Weigh in.

Shoulda Macros are not autoloaded (unless gem is unpacked)

The custom macros defined in #{gem_dir}/shoulda_macros/clearance.rb are not autoloaded unless the gem is unpacked (in a Rails app).

Running tests without unpacking the gem results in a NoMethodErrors — the order in which your tests are run will, of course, determine which method raises the error.

User can log in as another user if passwords are the same

To recreate, simple create two users with the same password and log both users in on the same day with the remember me option selected. Because the remember_me token is only encrypt("--#{Time.now.utc}--#{password}--") and neither of these values are unique the tokens will clash.

We actually had this problem occur on one of our servers....

url_after_create not working

Well i officially don't know why this isn't working, even after the wiki update for the wonky route that was screwing me up before....

class SessionsController < Clearance::SessionsController
  # ssl_required :new
  private
  def url_after_create
    some_wicked_path
  end
end

and in the routes i have
map.session 'session', :controller => 'sessions', :action => 'create'

I'm not sure why this isn't working. i thought this is all i had to do after i read the wiki entry under useage. One day when i was messing around with the Clearance_routes.rb file, it started to work, because i changed clearance_routes to routes and got rid of the extentions/routes.rb file... Just to see what would happen.

So i was excited when i saw this functionality work, but in a new 0.7.0 version of clearance gem, it doesn't work for me. thoughts?

Clearance routes loaded before app routes if ActiveSupport::Inflector.inflections is called

Just like the title says, Clearance routes are loaded before the app routes if ActiveSupport::Inflector.inflections is called. Issue occurs even if the block passed to #inflections is empty.

Clearly this is a problem in ActiveSupport or ActionPack (or both), but I'm stretching my knowledge of Rails internals, so maybe someone else can dig around and see what's what.

I'm running Rails 2.3.2 and Clearance 0.6.7.

Steps to reproduce:

  1. Create a fresh Rails 2.3.2 app

  2. Install Clearance like normal (add gem dependency to environment.rb, unpack to vendor/gems, script/generate clearance)

  3. rake db:migrate

  4. Open config/initializers/inflections.rb and change it to the following:

    # Be sure to restart your server when you modify this file.
    
    # Add new inflection rules using the following format 
    # (all these examples are active by default):
    ActiveSupport::Inflector.inflections do |inflect|
    #   inflect.plural /^(ox)$/i, '\1en'
    #   inflect.singular /^(ox)en/i, '\1'
    #   inflect.irregular 'person', 'people'
    #   inflect.uncountable %w( fish sheep )
    end
    
  5. Add a route to config/routes.rb

  6. rake routes ... the route added in step 5 will be at the bottom.

Chris

"remember me" feature always passes

I've noticed that the "remember me" sections of the feature tests seem to pass regardless of whether the checkbox is checked or not.

I can remove the

And %{I check "Remember me"} if remember

line from clearance_steps.rb and the tests still pass.

I haven't had a change yet to investigate, but currently the only step for clearing the session seems to be clearing the user_id. Not sure if this is enough or not.

ssl_required in Clearance Gem?

hi another issue i'd like to report, can i put clearance controllers into https://?

i tried simply adding

class SessionsController < Clearance::SessionsController
  ssl_required :new
end

into the controller but no dice. i didn't want to hack the gem yet either. wondering if it's possible?

make cleareance i18n aware

Hi,

it would be great to have clearance using the new rails i18n features. I’ve seen some messages are in English only in some places :

Flash[:notice] in controllers for example.

It sounds pretty reasonable to just add a translation enabled text, with english fallback :

from : flash[:notice] = ‘You have been logged out.’ to : flash[:notice] = I18n.t(:clearance_you_have_been_logged_out, :default => ‘You have been logged out.’)

Thanks ! Gravis

should_be_signed_in_as shouldn't look into the session

It should use the current_user public method.

def should_be_signed_in_as(&block)
  should "be signed in as #{block.bind(self).call}" do
    user = block.bind(self).call
    assert_not_nil user,
      "please pass a User. try: should_be_signed_in_as { @user }"
    assert_equal user, @controller.send(:current_user),
      "#{user.inspect} is not the current_user, " <<
      "which is #{@controller.send(:current_user).inspect}"
  end
end

Need to think about send versus calling it normally. Probably should be a public method but if anyone overrides it (like in BuyWithMe), they may accidentally make it protected or private, which will raise an error.

tests fail w/ DO_NOT_REPLY containing display name

environment.rb: DO_NOT_REPLY = ‘“Ricky Bobby” [email protected]

ClearanceMailerTest failures: A change password email should set its from address to DO_NOT_REPLY A confirmation email should set its from address to DO_NOT_REPLY

Because: email.from[0] == "shakeandbakewonderbread.com"

Possible solution: should “set its from address to DO_NOT_REPLY” do assert DO_NOT_REPLY =~ /#{@email.from0}/i end

Ping pong sessions for one user and multiple machines

Please pull this branch.
http://github.com/rmm5t/clearance/commits/fixing_ping_pong_sessions

This is in reference to the recent clearance google groups thread:
http://groups.google.com/group/thoughtbot-clearance/browse_thread/thread/d071ae84573e40ff

This includes:

  • Deprecated User#remember_me! for User#reset_remember_token!
  • Removed User#initialize_confirmation_token from before_save; added
    #generate_confirmation_token to before_create
  • Reset the remember_token on sign out instead of sign in

This also includes the "global sign out" feature. I stuck it in there simply because there was already a controller test that expected the sign out to reset the remember_token; it just wasn't testing it correctly before. Plus I'm partial to the feature. If it's a problem, it's easy to change. Just remove the call to reset_remember_token! in Clearance::Authentication::InstanceMethods#signout.

styles around forms

Evergreen-style. Need to think more about backwards-compatibility effects.

password_confirmation validation never fires

looks like password_confirmation validation is not fired when a password is present because of the password_required if conditional:

validates_presence_of     :password, :if => :password_required?
validates_confirmation_of :password, :if => :password_required?

should rather validate if password is not blank, versus password_required right?

Unit test example:

def test_password_confirmation_is_never_checked
  unimportant = {
    :email => "[email protected]",
    :email_confirmed => true
  }
  @user = User.new( unimportant.merge(:password => 'password',
                         :password_confirmation => 'not_password' ))
  assert @user.valid?
end

HAML support

It can be done in two ways:

  1. Create the corresponding haml templates from the erbs and basically accept an additional command-line argument from the user when generating views. So, for generating haml templates the command would become:
script/generate clearance_views haml

This would basically copy the files over from templates/haml/formtastic to the appropriate location in the application.

  1. Generate the haml templates from the corresponding erb templates on the fly by employing nifty html2haml.

Well, I have already implemented the first one as it is quite easy but my proclivity is towards the second one. I would like to take Dan's opinion on this one.

Allow HTTP authentication (for an API, etc)

Hi,

I needed to have HTTP authentication on current project using Clearance, and discovered Clearance does not provide it. I implemented it as following patch:

http://gist.github.com/159604

Does adding feature like this make sense to you?

(Note: I've tried to implement it directly to Clearance, but have not found an obvious way where to put the tests. I could not persuade AccountsControllerTest to have access to User or Factory(:email_confirmed_user) etc and had to give up.)

sign_in_as, sign_in, sign_out change

I propose we change the implementation of sign_in_as to stub current_user:

def sign_in_as(user)
@controller.class_eval { attr_accessor :current_user }
@controller.current_user = user
return user
end

We require that you pass it a user. We provide a second helper if you want to just use a typical user:

def sign_in
sign_in_as Factory(:email_confirmed_user)
end

This is better than the current implementation because it does not have to deal with the session.

"Unstubbing" it would allow it to go through the normal session/cookie/api_key checks, which is not the same as "signing out." Effectively forcing a signed out session means either ensuring that every means of finding a user won't find one (clearing the request's cookies/session/get data) or setting a stub that doesn't return a user:

def sign_out
@controller.class_eval { attr_accessor :current_user }
@controller.current_user = nil
end

Use a config file instead of HOST and DO_NOT_REPLY constants

I find it odd having to define constants in environment files as part of the config. I've updated my fork (samg/clearance) to use a config/clearance.yml file instead of HOST and DO_NOT_REPLY constants. This seems more in keeping with rails conventions, and more maintainable since it centralizes the engine's config.

All tests and features pass, and I've updated README.textile, and the generator README to reflect this configuration method.

(sorry for the pull request. missed that in the readme)

Shoulda macros deprecation

I'm proposing that we deprecate the following Shoulda macros in Clearance in the same style we deprecate Shoulda macros in Shoulda itself.

Please weigh in.

Deprecate for questionable usefulness:

should_be_signed_in_as { @user } should_be_signed_in_and_email_confirmed_as { @user } should_not_be_signed_in

Deprecate context macros because they add one level of indentation, are easy to miss visually, are easy to replace with sign_in_as, and they create obscure tests by moving the setup phase far away from the verification and exercise phase - Mystery Guest pattern

signed_in_user_context public_context

Deprecate because they are only used internally for Clearance's test suite:

should_create_user_successfully # this one also just makes me feel stupid typing it should_validate_confirmation_of # should be re-written and put in Shoulda

Deprecate because they are only used once or twice in Clearance's test suite and don't make sense to expose publicly:

should_display_a_password_update_form should_display_a_sign_up_form should_display_a_sign_in_form

Deprecate because they are helper methods for other deprecated macros:

should_validate_confirmation_is_not_blank should_validate_confirmation_is_not_bad bad_confirmation_options blank_confirmation_options assert_confirmation_error

factory_girl required during script/generate clearance

On a relatively new machine, I just installed clearance, and went to do script/generate clearance.

I received a stacktrace like this:

$ script/generate clearance
/gentoo/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- factory_girl (MissingSourceFile)
        from /gentoo/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:156:in `require'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:521:in `new_constants_in'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_srequire File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb")
upport/dependencies.rb:156:in `require'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/clearance-0.8.3/generators/clearance/clearance_generator.rb:3
        from /gentoo/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
        from /gentoo/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:156:in `require'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:521:in `new_constants_in'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:156:in `require'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/rails_generator/spec.rb:17:in `klass'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/rails_generator/lookup.rb:140:in `instance'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/rails_generator/scripts/../scripts.rb:31:in `run'
        from /gentoo/usr/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/commands/generate.rb:6
        from /gentoo/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
        from /gentoo/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from script/generate:3

Poking around, I found this code in the generator:

require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb")
require 'factory_girl'

It's actually kinda weird that a generator is requiring factory_girl, so maybe that line should be removed?

Default tests that send emails are failing in Rails 2.3.2

The default tests that send out emails are failing for me in Rails 2.3.2. I haven’t changed anything with them and I have this in my test environment file:

@@@config.action_mailer.delivery_method = :test@@@

Which I believe should be fine.

Here are the errors:

1) Failure:

test: a signed up user on POST to #create with correct email address should send the change your password email. (PasswordsControllerTest)
[vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_mailer/assertions.rb:20:in `assert_sent_email’
vendor/gems/thoughtbot-clearance-0.5.3/lib/clearance/test/functional/passwords_controller_test.rb:36:in`__bind_1237492650_839368’
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/context.rb:253:in `call’
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/context.rb:253:in`test: a signed up user on POST to #create with correct email address should send the change your password email. ’]:
No emails were sent.
is not true.

2) Failure:

test: a POST to #create with unconfirmed credentials should send the confirmation email. (SessionsControllerTest)
[vendor/gems/thoughtbot-clearance-0.5.3/lib/clearance/test/functional/sessions_controller_test.rb:33:in `__bind_1237492651_500559’
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/context.rb:253:in`call’
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/context.rb:253:in `test: a POST to #create with unconfirmed credentials should send the confirmation email. ’]:
expected to not be nil.

3) Failure:

test: The public Given valid attributes when creating a new user should send the confirmation email. (UsersControllerTest)
[vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_mailer/assertions.rb:20:in `assert_sent_email’
vendor/gems/thoughtbot-clearance-0.5.3/shoulda_macros/clearance.rb:93:in`__bind_1237492651_758022’
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/context.rb:253:in `call’
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/context.rb:253:in`test: The public Given valid attributes when creating a new user should send the confirmation email. ’]:
No emails were sent.
is not true.

Sign in and sign up using Open ID

I would love to have Open ID support for one of my apps.

  • A user should be able to sign up by providing his open ID provider and his open ID username.
  • A user should be able to sign in by providing his open ID identifier.

Would you plan to integrate this into Clearance or do you think this would rather be the scope of an add-on?

PublicCompanySecurityAudit module

optional module that does:

  • password minimum length (8)
  • password minimum number of non-alphanumeric characters (2)
  • password duplicate consecutive characters
  • password history (8)
  • password automatic change period of days (90)
  • password bad attempts (3)

Password Reset feature fails

’ve been unable to figure out why the following two scenarios fail on the same step:

Scenario: User signs up with invalid data

Scenario: User is signed up updated his password and types wrong confirmation

They both fail at:

Then I should see error messages

I’ve looked at the step and it seems that there is an issue with:

Then %{I should see “error(s)? prohibited”}

Where id does not seem to figure out that (s)? is a regular expression.

If I remove the (s)? the first scenario passes and if I add just a s the second scenario passes.

I generated my app with rails boost with the following script: http://www.railsboost.com/1139.rb

Clearance 0.5.3 Shoulda 2.10.1 webrat 0.4.3 nokogiri 1.2.3

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.