From 33e2e7e6c6a1e5c950c59f60d91c9fa0b39524bc Mon Sep 17 00:00:00 2001 From: Dan Croak Date: Sat, 23 Feb 2013 22:01:31 -0800 Subject: [PATCH 1/4] Rename Authentication, User to Controller, Model --- README.md | 6 +++--- lib/clearance.rb | 4 ++-- lib/clearance/back_door.rb | 2 +- .../{authentication.rb => controller.rb} | 2 +- lib/clearance/{user.rb => model.rb} | 8 +++++--- .../app/controllers/application_controller.rb | 2 +- .../clearance/install/install_generator.rb | 4 ++-- .../clearance/install/templates/user.rb | 2 +- spec/controllers/denies_controller_spec.rb | 3 ++- spec/controllers/flashes_controller_spec.rb | 2 +- spec/controllers/forgeries_controller_spec.rb | 3 ++- .../models/bcrypt_migration_from_sha1_spec.rb | 1 - spec/models/password_strategies_spec.rb | 4 ++-- spec/models/user_spec.rb | 20 +++++++------------ spec/support/clearance.rb | 4 ++-- 15 files changed, 32 insertions(+), 35 deletions(-) rename lib/clearance/{authentication.rb => controller.rb} (98%) rename lib/clearance/{user.rb => model.rb} (93%) diff --git a/README.md b/README.md index 8f16260a1..abfce05ce 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,8 @@ Make sure the development database exists. Then, run the generator: The generator: -* inserts Clearance::User into your User model -* inserts Clearance::Authentication into your ApplicationController +* inserts `Clearance::Model` into your `User` model +* inserts `Clearance::Controller` into your `ApplicationController` * creates a migration that either creates a users table or adds only missing columns @@ -327,7 +327,7 @@ For example, in `spec/support/clearance.rb` or `test/test_helper.rb`: require 'clearance/testing' -This will make `Clearance::Authentication` methods work in your controllers +This will make `Clearance::Controller` methods work in your controllers during functional tests and provide access to helper methods like: sign_in diff --git a/lib/clearance.rb b/lib/clearance.rb index bc8e47b00..b6b581dc8 100644 --- a/lib/clearance.rb +++ b/lib/clearance.rb @@ -2,8 +2,8 @@ require 'clearance/session' require 'clearance/rack_session' require 'clearance/back_door' -require 'clearance/authentication' -require 'clearance/user' +require 'clearance/controller' +require 'clearance/model' require 'clearance/engine' require 'clearance/password_strategies' require 'clearance/constraints' diff --git a/lib/clearance/back_door.rb b/lib/clearance/back_door.rb index 2a22f6bb8..a104194aa 100644 --- a/lib/clearance/back_door.rb +++ b/lib/clearance/back_door.rb @@ -34,7 +34,7 @@ def sign_in_through_the_back_door(env) user_id = params['as'] if user_id.present? - user = ::User.find(user_id) + user = Clearance.configuration.user_model.find(user_id) env[:clearance].sign_in(user) end end diff --git a/lib/clearance/authentication.rb b/lib/clearance/controller.rb similarity index 98% rename from lib/clearance/authentication.rb rename to lib/clearance/controller.rb index 7c8254ca0..d26224ac9 100644 --- a/lib/clearance/authentication.rb +++ b/lib/clearance/controller.rb @@ -1,5 +1,5 @@ module Clearance - module Authentication + module Controller extend ActiveSupport::Concern included do diff --git a/lib/clearance/user.rb b/lib/clearance/model.rb similarity index 93% rename from lib/clearance/user.rb rename to lib/clearance/model.rb index c98b77c70..85d4def6b 100644 --- a/lib/clearance/user.rb +++ b/lib/clearance/model.rb @@ -2,7 +2,7 @@ require 'email_validator' module Clearance - module User + module Model extend ActiveSupport::Concern included do @@ -11,8 +11,10 @@ module User include Validations include Callbacks - include (Clearance.configuration.password_strategy || - Clearance::PasswordStrategies::BCrypt) + include ( + Clearance.configuration.password_strategy || + Clearance::PasswordStrategies::BCrypt + ) end module ClassMethods diff --git a/lib/clearance/testing/app/controllers/application_controller.rb b/lib/clearance/testing/app/controllers/application_controller.rb index e4f6216c1..aacdf8397 100644 --- a/lib/clearance/testing/app/controllers/application_controller.rb +++ b/lib/clearance/testing/app/controllers/application_controller.rb @@ -1,5 +1,5 @@ class ApplicationController < ActionController::Base - include Clearance::Authentication + include Clearance::Controller def show render :text => '', :layout => 'application' diff --git a/lib/generators/clearance/install/install_generator.rb b/lib/generators/clearance/install/install_generator.rb index 8fa2ae0d2..963c71645 100644 --- a/lib/generators/clearance/install/install_generator.rb +++ b/lib/generators/clearance/install/install_generator.rb @@ -15,13 +15,13 @@ def inject_clearance_into_application_controller inject_into( ApplicationController, 'app/controllers/application_controller.rb', - 'include Clearance::Authentication' + 'include Clearance::Controller' ) end def create_or_inject_clearance_into_user_model if File.exists? 'app/models/user.rb' - inject_into User, 'app/models/user.rb', 'include Clearance::User' + inject_into User, 'app/models/user.rb', 'include Clearance::Model' else copy_file 'user.rb', 'app/models/user.rb' end diff --git a/lib/generators/clearance/install/templates/user.rb b/lib/generators/clearance/install/templates/user.rb index 6d077a175..7559c4ba4 100644 --- a/lib/generators/clearance/install/templates/user.rb +++ b/lib/generators/clearance/install/templates/user.rb @@ -1,3 +1,3 @@ class User < ActiveRecord::Base - include Clearance::User + include Clearance::Model end diff --git a/spec/controllers/denies_controller_spec.rb b/spec/controllers/denies_controller_spec.rb index f54a0703f..00e863e3f 100644 --- a/spec/controllers/denies_controller_spec.rb +++ b/spec/controllers/denies_controller_spec.rb @@ -1,7 +1,8 @@ require 'spec_helper' class DeniesController < ActionController::Base - include Clearance::Authentication + include Clearance::Controller + before_filter :authorize, :only => :show def new diff --git a/spec/controllers/flashes_controller_spec.rb b/spec/controllers/flashes_controller_spec.rb index c74424ecb..76b3cb34e 100644 --- a/spec/controllers/flashes_controller_spec.rb +++ b/spec/controllers/flashes_controller_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' class FlashesController < ActionController::Base - include Clearance::Authentication + include Clearance::Controller def set_flash flash[:notice] = params[:message] diff --git a/spec/controllers/forgeries_controller_spec.rb b/spec/controllers/forgeries_controller_spec.rb index 12cf2ec06..f68dc6390 100644 --- a/spec/controllers/forgeries_controller_spec.rb +++ b/spec/controllers/forgeries_controller_spec.rb @@ -1,7 +1,8 @@ require 'spec_helper' class ForgeriesController < ActionController::Base - include Clearance::Authentication + include Clearance::Controller + protect_from_forgery before_filter :authorize diff --git a/spec/models/bcrypt_migration_from_sha1_spec.rb b/spec/models/bcrypt_migration_from_sha1_spec.rb index 38f05b3ea..cd5af07cd 100644 --- a/spec/models/bcrypt_migration_from_sha1_spec.rb +++ b/spec/models/bcrypt_migration_from_sha1_spec.rb @@ -30,7 +30,6 @@ it 'sets the pasword on the subject' do subject.password.should be_present end - end describe '#authenticated?' do diff --git a/spec/models/password_strategies_spec.rb b/spec/models/password_strategies_spec.rb index ad95fa615..690dc48e4 100644 --- a/spec/models/password_strategies_spec.rb +++ b/spec/models/password_strategies_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Clearance::User do +describe Clearance::Model do subject do class UniquenessValidator < ActiveModel::Validator def validate(record) @@ -15,7 +15,7 @@ def validate(record) def self.before_validation(*args); end def self.before_create(*args); end - include Clearance::User + include Clearance::Model end.new end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 329827ec3..066c24bcb 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -33,33 +33,28 @@ end it 'is authenticated with correct email and password' do - (Clearance.configuration.user_model.authenticate(@user.email, @password)). - should be + User.authenticate(@user.email, @password).should be @user.should be_authenticated(@password) end it 'is authenticated with correct uppercased email and correct password' do - (Clearance.configuration.user_model.authenticate(@user.email.upcase, @password)). - should be + User.authenticate(@user.email.upcase, @password).should be @user.should be_authenticated(@password) end it 'is authenticated with incorrect credentials' do - (Clearance.configuration.user_model.authenticate(@user.email, 'bad_password')). - should_not be + User.authenticate(@user.email, 'bad_password').should_not be @user.should_not be_authenticated('bad password') end it 'is retrieved via a case-insensitive search' do - (Clearance.configuration.user_model.find_by_normalized_email(@user.email.upcase)). - should be - @user + User.find_by_normalized_email(@user.email.upcase).should eq @user end end describe 'when resetting authentication with reset_remember_token!' do before do - @user = create(:user) + @user = create(:user) @user.remember_token = 'old-token' @user.reset_remember_token! end @@ -145,6 +140,7 @@ describe 'a user with an optional email' do before do @user = User.new + class << @user def email_optional? true @@ -185,9 +181,7 @@ def password_optional? let(:email) { 'Jo hn.Do e @exa mp le.c om' } it 'downcases the address and strips spaces' do - (Clearance.configuration.user_model.normalize_email(email)). - should be - 'john.doe@example.com' + User.normalize_email(email).should eq 'john.doe@example.com' end end diff --git a/spec/support/clearance.rb b/spec/support/clearance.rb index 1fa6c89e7..fb4eced6a 100644 --- a/spec/support/clearance.rb +++ b/spec/support/clearance.rb @@ -4,11 +4,11 @@ end class ApplicationController < ActionController::Base - include Clearance::Authentication + include Clearance::Controller end class User < ActiveRecord::Base - include Clearance::User + include Clearance::Model end module Clearance From 7c3bffd209524c06947931fd819d80d37c983d41 Mon Sep 17 00:00:00 2001 From: Dan Croak Date: Sun, 24 Feb 2013 22:12:32 -0800 Subject: [PATCH 2/4] Apply Greg's feedback from review --- lib/clearance/model.rb | 2 +- spec/models/user_spec.rb | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/clearance/model.rb b/lib/clearance/model.rb index 85d4def6b..7f300b4f7 100644 --- a/lib/clearance/model.rb +++ b/lib/clearance/model.rb @@ -11,7 +11,7 @@ module Model include Validations include Callbacks - include ( + include( Clearance.configuration.password_strategy || Clearance::PasswordStrategies::BCrypt ) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 066c24bcb..c85bf1430 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -33,22 +33,22 @@ end it 'is authenticated with correct email and password' do - User.authenticate(@user.email, @password).should be + User.authenticate(@user.email, @password).should be(true) @user.should be_authenticated(@password) end it 'is authenticated with correct uppercased email and correct password' do - User.authenticate(@user.email.upcase, @password).should be + User.authenticate(@user.email.upcase, @password).should be(true) @user.should be_authenticated(@password) end it 'is authenticated with incorrect credentials' do - User.authenticate(@user.email, 'bad_password').should_not be + User.authenticate(@user.email, 'bad_password').should be(false) @user.should_not be_authenticated('bad password') end it 'is retrieved via a case-insensitive search' do - User.find_by_normalized_email(@user.email.upcase).should eq @user + User.find_by_normalized_email(@user.email.upcase).should eq(@user) end end From c536948e14197f05eba9ba1d856166ae2369951e Mon Sep 17 00:00:00 2001 From: Dan Croak Date: Sat, 2 Mar 2013 10:13:00 -0800 Subject: [PATCH 3/4] Revert to Clearance::User --- README.md | 2 +- lib/clearance.rb | 2 +- lib/clearance/{model.rb => user.rb} | 2 +- lib/generators/clearance/install/install_generator.rb | 2 +- lib/generators/clearance/install/templates/user.rb | 2 +- spec/models/password_strategies_spec.rb | 4 ++-- spec/support/clearance.rb | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) rename lib/clearance/{model.rb => user.rb} (99%) diff --git a/README.md b/README.md index abfce05ce..44b2e12a9 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Make sure the development database exists. Then, run the generator: The generator: -* inserts `Clearance::Model` into your `User` model +* inserts `Clearance::User` into your `User` model * inserts `Clearance::Controller` into your `ApplicationController` * creates a migration that either creates a users table or adds only missing columns diff --git a/lib/clearance.rb b/lib/clearance.rb index b6b581dc8..8b1a8b431 100644 --- a/lib/clearance.rb +++ b/lib/clearance.rb @@ -3,7 +3,7 @@ require 'clearance/rack_session' require 'clearance/back_door' require 'clearance/controller' -require 'clearance/model' +require 'clearance/user' require 'clearance/engine' require 'clearance/password_strategies' require 'clearance/constraints' diff --git a/lib/clearance/model.rb b/lib/clearance/user.rb similarity index 99% rename from lib/clearance/model.rb rename to lib/clearance/user.rb index 7f300b4f7..63b468f01 100644 --- a/lib/clearance/model.rb +++ b/lib/clearance/user.rb @@ -2,7 +2,7 @@ require 'email_validator' module Clearance - module Model + module User extend ActiveSupport::Concern included do diff --git a/lib/generators/clearance/install/install_generator.rb b/lib/generators/clearance/install/install_generator.rb index 963c71645..9d2cae6c6 100644 --- a/lib/generators/clearance/install/install_generator.rb +++ b/lib/generators/clearance/install/install_generator.rb @@ -21,7 +21,7 @@ def inject_clearance_into_application_controller def create_or_inject_clearance_into_user_model if File.exists? 'app/models/user.rb' - inject_into User, 'app/models/user.rb', 'include Clearance::Model' + inject_into User, 'app/models/user.rb', 'include Clearance::User' else copy_file 'user.rb', 'app/models/user.rb' end diff --git a/lib/generators/clearance/install/templates/user.rb b/lib/generators/clearance/install/templates/user.rb index 7559c4ba4..6d077a175 100644 --- a/lib/generators/clearance/install/templates/user.rb +++ b/lib/generators/clearance/install/templates/user.rb @@ -1,3 +1,3 @@ class User < ActiveRecord::Base - include Clearance::Model + include Clearance::User end diff --git a/spec/models/password_strategies_spec.rb b/spec/models/password_strategies_spec.rb index 690dc48e4..ad95fa615 100644 --- a/spec/models/password_strategies_spec.rb +++ b/spec/models/password_strategies_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Clearance::Model do +describe Clearance::User do subject do class UniquenessValidator < ActiveModel::Validator def validate(record) @@ -15,7 +15,7 @@ def validate(record) def self.before_validation(*args); end def self.before_create(*args); end - include Clearance::Model + include Clearance::User end.new end diff --git a/spec/support/clearance.rb b/spec/support/clearance.rb index fb4eced6a..225c549e3 100644 --- a/spec/support/clearance.rb +++ b/spec/support/clearance.rb @@ -8,7 +8,7 @@ class ApplicationController < ActionController::Base end class User < ActiveRecord::Base - include Clearance::Model + include Clearance::User end module Clearance From 2ae5a1a76689407d7965f2d9857b2cd699cc904d Mon Sep 17 00:00:00 2001 From: Dan Croak Date: Sat, 2 Mar 2013 10:33:27 -0800 Subject: [PATCH 4/4] Split Clearance::{Authentication,Authorization} --- Gemfile.lock | 2 +- gemfiles/3.0.20.gemfile.lock | 2 +- gemfiles/3.1.11.gemfile.lock | 2 +- gemfiles/3.2.12.gemfile.lock | 2 +- lib/clearance/authentication.rb | 60 ++++++++++++++++++ lib/clearance/authorization.rb | 62 +++++++++++++++++++ lib/clearance/controller.rb | 104 ++------------------------------ spec/models/user_spec.rb | 6 +- 8 files changed, 134 insertions(+), 106 deletions(-) create mode 100644 lib/clearance/authentication.rb create mode 100644 lib/clearance/authorization.rb diff --git a/Gemfile.lock b/Gemfile.lock index f70e6d5ba..758b95ee4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - clearance (1.0.0.rc4) + clearance (1.0.0.rc5) bcrypt-ruby email_validator rails (>= 3.0) diff --git a/gemfiles/3.0.20.gemfile.lock b/gemfiles/3.0.20.gemfile.lock index 2c90e7e86..c6975522d 100644 --- a/gemfiles/3.0.20.gemfile.lock +++ b/gemfiles/3.0.20.gemfile.lock @@ -1,7 +1,7 @@ PATH remote: /Users/croaky/dev/clearance specs: - clearance (1.0.0.rc4) + clearance (1.0.0.rc5) bcrypt-ruby email_validator rails (>= 3.0) diff --git a/gemfiles/3.1.11.gemfile.lock b/gemfiles/3.1.11.gemfile.lock index 0e22ddc5e..4f4f72994 100644 --- a/gemfiles/3.1.11.gemfile.lock +++ b/gemfiles/3.1.11.gemfile.lock @@ -1,7 +1,7 @@ PATH remote: /Users/croaky/dev/clearance specs: - clearance (1.0.0.rc4) + clearance (1.0.0.rc5) bcrypt-ruby email_validator rails (>= 3.0) diff --git a/gemfiles/3.2.12.gemfile.lock b/gemfiles/3.2.12.gemfile.lock index 13c5a2de4..3a1ac7dbd 100644 --- a/gemfiles/3.2.12.gemfile.lock +++ b/gemfiles/3.2.12.gemfile.lock @@ -1,7 +1,7 @@ PATH remote: /Users/croaky/dev/clearance specs: - clearance (1.0.0.rc4) + clearance (1.0.0.rc5) bcrypt-ruby email_validator rails (>= 3.0) diff --git a/lib/clearance/authentication.rb b/lib/clearance/authentication.rb new file mode 100644 index 000000000..15856e7bf --- /dev/null +++ b/lib/clearance/authentication.rb @@ -0,0 +1,60 @@ +module Clearance + module Authentication + extend ActiveSupport::Concern + + included do + helper_method :current_user, :signed_in?, :signed_out? + hide_action( + :current_user, + :current_user=, + :sign_in, + :sign_out, + :signed_in?, + :signed_out? + ) + end + + def authenticate(params) + Clearance.configuration.user_model.authenticate( + params[:session][:email], params[:session][:password] + ) + end + + def current_user + clearance_session.current_user + end + + def current_user=(user) + clearance_session.sign_in user + end + + def sign_in(user) + clearance_session.sign_in user + end + + def sign_out + clearance_session.sign_out + end + + def signed_in? + clearance_session.signed_in? + end + + def signed_out? + !signed_in? + end + + # CSRF protection in Rails >= 3.0.4 + # http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails + def handle_unverified_request + super + sign_out + end + + protected + + def clearance_session + request.env[:clearance] + end + end +end diff --git a/lib/clearance/authorization.rb b/lib/clearance/authorization.rb new file mode 100644 index 000000000..775b9bca5 --- /dev/null +++ b/lib/clearance/authorization.rb @@ -0,0 +1,62 @@ +module Clearance + module Authorization + extend ActiveSupport::Concern + + included do + hide_action :authorize, :deny_access + end + + def authorize + unless signed_in? + deny_access + end + end + + def deny_access(flash_message = nil) + store_location + + if flash_message + flash[:notice] = flash_message + end + + if signed_in? + redirect_to url_after_denied_access_when_signed_in + else + redirect_to url_after_denied_access_when_signed_out + end + end + + protected + + def clear_return_to + session[:return_to] = nil + end + + def store_location + if request.get? + session[:return_to] = request.fullpath + end + end + + def redirect_back_or(default) + redirect_to(return_to || default) + clear_return_to + end + + def redirect_to_root + redirect_to('/') + end + + def return_to + session[:return_to] || params[:return_to] + end + + def url_after_denied_access_when_signed_in + '/' + end + + def url_after_denied_access_when_signed_out + sign_in_url + end + end +end diff --git a/lib/clearance/controller.rb b/lib/clearance/controller.rb index d26224ac9..d5df22d00 100644 --- a/lib/clearance/controller.rb +++ b/lib/clearance/controller.rb @@ -1,105 +1,11 @@ +require 'clearance/authentication' +require 'clearance/authorization' + module Clearance module Controller extend ActiveSupport::Concern - included do - helper_method :current_user, :signed_in?, :signed_out? - hide_action :authorize, :current_user, :current_user=, :deny_access, - :sign_in, :sign_out, :signed_in?, :signed_out? - end - - def authenticate(params) - Clearance.configuration.user_model.authenticate( - params[:session][:email], params[:session][:password] - ) - end - - def authorize - unless signed_in? - deny_access - end - end - - def current_user - clearance_session.current_user - end - - def current_user=(user) - clearance_session.sign_in user - end - - def deny_access(flash_message = nil) - store_location - - if flash_message - flash[:notice] = flash_message - end - - if signed_in? - redirect_to url_after_denied_access_when_signed_in - else - redirect_to url_after_denied_access_when_signed_out - end - end - - def sign_in(user) - clearance_session.sign_in user - end - - def sign_out - clearance_session.sign_out - end - - def signed_in? - clearance_session.signed_in? - end - - def signed_out? - !signed_in? - end - - # CSRF protection in Rails >= 3.0.4 - # http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails - def handle_unverified_request - super - sign_out - end - - protected - - def clear_return_to - session[:return_to] = nil - end - - def clearance_session - request.env[:clearance] - end - - def store_location - if request.get? - session[:return_to] = request.fullpath - end - end - - def redirect_back_or(default) - redirect_to(return_to || default) - clear_return_to - end - - def redirect_to_root - redirect_to('/') - end - - def return_to - session[:return_to] || params[:return_to] - end - - def url_after_denied_access_when_signed_in - '/' - end - - def url_after_denied_access_when_signed_out - sign_in_url - end + include Clearance::Authentication + include Clearance::Authorization end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index c85bf1430..b7323b0d3 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -33,17 +33,17 @@ end it 'is authenticated with correct email and password' do - User.authenticate(@user.email, @password).should be(true) + User.authenticate(@user.email, @password).should eq(@user) @user.should be_authenticated(@password) end it 'is authenticated with correct uppercased email and correct password' do - User.authenticate(@user.email.upcase, @password).should be(true) + User.authenticate(@user.email.upcase, @password).should eq(@user) @user.should be_authenticated(@password) end it 'is authenticated with incorrect credentials' do - User.authenticate(@user.email, 'bad_password').should be(false) + User.authenticate(@user.email, 'bad_password').should be_nil @user.should_not be_authenticated('bad password') end