diff options
author | Stefan Wintermeyer <stefan.wintermeyer@amooma.de> | 2012-12-17 12:01:45 +0100 |
---|---|---|
committer | Stefan Wintermeyer <stefan.wintermeyer@amooma.de> | 2012-12-17 12:01:45 +0100 |
commit | b80bd744ad873f6fc43018bc4bfb90677de167bd (patch) | |
tree | 072c4b0e33d442528555b82c415f5e7a1712b2b0 /lib/generators/nifty/authentication/templates | |
parent | 3e706c2025ecc5523e81ad649639ef2ff75e7bac (diff) |
Start of GS5.
Diffstat (limited to 'lib/generators/nifty/authentication/templates')
26 files changed, 870 insertions, 0 deletions
diff --git a/lib/generators/nifty/authentication/templates/authlogic_session.rb b/lib/generators/nifty/authentication/templates/authlogic_session.rb new file mode 100644 index 0000000..676cfd0 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/authlogic_session.rb @@ -0,0 +1,2 @@ +class <%= session_class_name %> < Authlogic::Session::Base +end diff --git a/lib/generators/nifty/authentication/templates/controller_authentication.rb b/lib/generators/nifty/authentication/templates/controller_authentication.rb new file mode 100644 index 0000000..6d34ab0 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/controller_authentication.rb @@ -0,0 +1,60 @@ +# This module is included in your application controller which makes +# several methods available to all controllers and views. Here's a +# common example you might add to your application layout file. +# +# <%% if logged_in? %> +# Welcome <%%= current_<%= user_singular_name %>.username %>. +# <%%= link_to "Edit profile", edit_current_<%= user_singular_name %>_path %> or +# <%%= link_to "Log out", logout_path %> +# <%% else %> +# <%%= link_to "Sign up", signup_path %> or +# <%%= link_to "log in", login_path %>. +# <%% end %> +# +# You can also restrict unregistered users from accessing a controller using +# a before filter. For example. +# +# before_filter :login_required, :except => [:index, :show] +module ControllerAuthentication + def self.included(controller) + controller.send :helper_method, :current_<%= user_singular_name %>, :logged_in?, :redirect_to_target_or_default + end + +<%- if options[:authlogic] -%> + def current_<%= session_singular_name %> + return @current_<%= session_singular_name %> if defined?(@current_<%= session_singular_name %>) + @current_<%= session_singular_name %> = <%= session_class_name %>.find + end + + def current_<%= user_singular_name %> + return @current_<%= user_singular_name %> if defined?(@current_<%= user_singular_name %>) + @current_<%= user_singular_name %> = current_<%= session_singular_name %> && current_<%= session_singular_name %>.record + end +<%- else -%> + def current_<%= user_singular_name %> + @current_<%= user_singular_name %> ||= <%= user_class_name %>.find(session[:<%= user_singular_name %>_id]) if session[:<%= user_singular_name %>_id] + end +<%- end -%> + + def logged_in? + current_<%= user_singular_name %> + end + + def login_required + unless logged_in? + store_target_location + redirect_to login_url, :alert => "You must first log in or sign up before accessing this page." + end + end + + def redirect_to_target_or_default(default, *args) + redirect_to(session[:return_to] || default, *args) + session[:return_to] = nil + end + + private + + def store_target_location + session[:return_to] = request.url + end +end diff --git a/lib/generators/nifty/authentication/templates/fixtures.yml b/lib/generators/nifty/authentication/templates/fixtures.yml new file mode 100644 index 0000000..c52532b --- /dev/null +++ b/lib/generators/nifty/authentication/templates/fixtures.yml @@ -0,0 +1,24 @@ +# password: "secret" +foo: + username: foo + email: foo@example.com +<%- if options[:authlogic] -%> + persistence_token: d5ddba13ed4408ea2b0a12ab18ed2d2eda086279736bdc121ca726a11f1e4b99217d9c534c2cc4ebb22729349c8c5fdbe1529e1f2c3c5859c62ef4dd9feea25c + crypted_password: 3d16c326648cccafe3d4b4cb024475c381dda92f430dfedf6f933e1f61203bacb6bae2437849bdb43b06be335e23790e4aa03902b3c28c3bbbbe27d501e521f3 + password_salt: n6z_wtpWoIsHgQb5IcFd +<%- else -%> + password_hash: 3488f5f7efecab14b91eb96169e5e1ee518a569f + password_salt: bef65e058905c379436d80d1a32e7374b139e7b0 +<%- end -%> + +bar: + username: bar + email: bar@example.com +<%- if options[:authlogic] -%> + persistence_token: 19e074bd7cb506ab3e7e53e41f24f0ab3221c8cb68111f4c1aa43965114ad734233979a50a9463537487cdca18c279ac91c4bc83693d589625d446493322394c + crypted_password: 3bc9f4113ca645a186765df3d31a9352d0067bf2304ba0cdd6b08a7f3d58c6668ab1762fa3e76aef466ea2ff188399d8e6c40244fa59312bb4112292dac9f7f0 + password_salt: UiAh9ejabnKRxqsiK0xO +<%- else -%> + password_hash: 3488f5f7efecab14b91eb96169e5e1ee518a569f + password_salt: bef65e058905c379436d80d1a32e7374b139e7b0 +<%- end -%> diff --git a/lib/generators/nifty/authentication/templates/migration.rb b/lib/generators/nifty/authentication/templates/migration.rb new file mode 100644 index 0000000..c945df3 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/migration.rb @@ -0,0 +1,20 @@ +class Create<%= user_plural_class_name %> < ActiveRecord::Migration + def self.up + create_table :<%= user_plural_name %> do |t| + t.string :username + t.string :email + <%- if options[:authlogic] -%> + t.string :persistence_token + t.string :crypted_password + <%- else -%> + t.string :password_hash + <%- end -%> + t.string :password_salt + t.timestamps + end + end + + def self.down + drop_table :<%= user_plural_name %> + end +end diff --git a/lib/generators/nifty/authentication/templates/sessions_controller.rb b/lib/generators/nifty/authentication/templates/sessions_controller.rb new file mode 100644 index 0000000..65e77c1 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/sessions_controller.rb @@ -0,0 +1,41 @@ +class <%= session_plural_class_name %>Controller < ApplicationController +<%- if options[:authlogic] -%> + def new + @<%= session_singular_name %> = <%= session_class_name %>.new + end + + def create + @<%= session_singular_name %> = <%= session_class_name %>.new(params[:<%= session_singular_name %>]) + if @<%= session_singular_name %>.save + redirect_to_target_or_default root_url, :notice => "Logged in successfully." + else + render :new + end + end + + def destroy + @<%= session_singular_name %> = <%= session_class_name %>.find + @<%= session_singular_name %>.destroy + redirect_to root_url, :notice => "You have been logged out." + end +<%- else -%> + def new + end + + def create + <%= user_singular_name %> = <%= user_class_name %>.authenticate(params[:login], params[:password]) + if <%= user_singular_name %> + session[:<%= user_singular_name %>_id] = <%= user_singular_name %>.id + redirect_to_target_or_default root_url, :notice => "Logged in successfully." + else + flash.now[:alert] = "Invalid login or password." + render :new + end + end + + def destroy + session[:<%= user_singular_name %>_id] = nil + redirect_to root_url, :notice => "You have been logged out." + end +<%- end -%> +end diff --git a/lib/generators/nifty/authentication/templates/sessions_helper.rb b/lib/generators/nifty/authentication/templates/sessions_helper.rb new file mode 100644 index 0000000..0958537 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/sessions_helper.rb @@ -0,0 +1,2 @@ +module <%= session_plural_class_name %>Helper +end diff --git a/lib/generators/nifty/authentication/templates/tests/rspec/sessions_controller.rb b/lib/generators/nifty/authentication/templates/tests/rspec/sessions_controller.rb new file mode 100644 index 0000000..e0953cc --- /dev/null +++ b/lib/generators/nifty/authentication/templates/tests/rspec/sessions_controller.rb @@ -0,0 +1,39 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe <%= session_plural_class_name %>Controller do + fixtures :all + render_views + + it "new action should render new template" do + get :new + response.should render_template(:new) + end + +<%- if options[:authlogic] -%> + it "create action should render new template when authentication is invalid" do + post :create, :<%= session_singular_name %> => { :username => "foo", :password => "badpassword" } + response.should render_template(:new) + <%= session_class_name %>.find.should be_nil + end + + it "create action should redirect when authentication is valid" do + post :create, :<%= session_singular_name %> => { :username => "foo", :password => "secret" } + response.should redirect_to(root_url) + <%= session_class_name %>.find.<%= user_singular_name %>.should == <%= user_plural_name %>(:foo) + end +<%- else -%> + it "create action should render new template when authentication is invalid" do + <%= user_class_name %>.stubs(:authenticate).returns(nil) + post :create + response.should render_template(:new) + session['<%= user_singular_name %>_id'].should be_nil + end + + it "create action should redirect when authentication is valid" do + <%= user_class_name %>.stubs(:authenticate).returns(<%= user_class_name %>.first) + post :create + response.should redirect_to(root_url) + session['<%= user_singular_name %>_id'].should == <%= user_class_name %>.first.id + end +<%- end -%> +end diff --git a/lib/generators/nifty/authentication/templates/tests/rspec/user.rb b/lib/generators/nifty/authentication/templates/tests/rspec/user.rb new file mode 100644 index 0000000..a3f7e92 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/tests/rspec/user.rb @@ -0,0 +1,83 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe <%= user_class_name %> do +<%- unless options[:authlogic] -%> + def new_<%= user_singular_name %>(attributes = {}) + attributes[:username] ||= 'foo' + attributes[:email] ||= 'foo@example.com' + attributes[:password] ||= 'abc123' + attributes[:password_confirmation] ||= attributes[:password] + <%= user_class_name %>.new(attributes) + end + + before(:each) do + <%= user_class_name %>.delete_all + end + + it "should be valid" do + new_<%= user_singular_name %>.should be_valid + end + + it "should require username" do + new_<%= user_singular_name %>(:username => '').should have(1).error_on(:username) + end + + it "should require password" do + new_<%= user_singular_name %>(:password => '').should have(1).error_on(:password) + end + + it "should require well formed email" do + new_<%= user_singular_name %>(:email => 'foo@bar@example.com').should have(1).error_on(:email) + end + + it "should validate uniqueness of email" do + new_<%= user_singular_name %>(:email => 'bar@example.com').save! + new_<%= user_singular_name %>(:email => 'bar@example.com').should have(1).error_on(:email) + end + + it "should validate uniqueness of username" do + new_<%= user_singular_name %>(:username => 'uniquename').save! + new_<%= user_singular_name %>(:username => 'uniquename').should have(1).error_on(:username) + end + + it "should not allow odd characters in username" do + new_<%= user_singular_name %>(:username => 'odd ^&(@)').should have(1).error_on(:username) + end + + it "should validate password is longer than 3 characters" do + new_<%= user_singular_name %>(:password => 'bad').should have(1).error_on(:password) + end + + it "should require matching password confirmation" do + new_<%= user_singular_name %>(:password_confirmation => 'nonmatching').should have(1).error_on(:password) + end + + it "should generate password hash and salt on create" do + <%= user_singular_name %> = new_<%= user_singular_name %> + <%= user_singular_name %>.save! + <%= user_singular_name %>.password_hash.should_not be_nil + <%= user_singular_name %>.password_salt.should_not be_nil + end + + it "should authenticate by username" do + <%= user_singular_name %> = new_<%= user_singular_name %>(:username => 'foobar', :password => 'secret') + <%= user_singular_name %>.save! + <%= user_class_name %>.authenticate('foobar', 'secret').should == <%= user_singular_name %> + end + + it "should authenticate by email" do + <%= user_singular_name %> = new_<%= user_singular_name %>(:email => 'foo@bar.com', :password => 'secret') + <%= user_singular_name %>.save! + <%= user_class_name %>.authenticate('foo@bar.com', 'secret').should == <%= user_singular_name %> + end + + it "should not authenticate bad username" do + <%= user_class_name %>.authenticate('nonexisting', 'secret').should be_nil + end + + it "should not authenticate bad password" do + new_<%= user_singular_name %>(:username => 'foobar', :password => 'secret').save! + <%= user_class_name %>.authenticate('foobar', 'badpassword').should be_nil + end +<%- end -%> +end diff --git a/lib/generators/nifty/authentication/templates/tests/rspec/users_controller.rb b/lib/generators/nifty/authentication/templates/tests/rspec/users_controller.rb new file mode 100644 index 0000000..60bcff9 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/tests/rspec/users_controller.rb @@ -0,0 +1,56 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe <%= user_plural_class_name %>Controller do + fixtures :all + render_views + + it "new action should render new template" do + get :new + response.should render_template(:new) + end + + it "create action should render new template when model is invalid" do + <%= user_class_name %>.any_instance.stubs(:valid?).returns(false) + post :create + response.should render_template(:new) + end + + it "create action should redirect when model is valid" do + <%= user_class_name %>.any_instance.stubs(:valid?).returns(true) + post :create + response.should redirect_to(root_url) + <%- unless options[:authlogic] -%> + session['<%= user_singular_name %>_id'].should == assigns['<%= user_singular_name %>'].id + <%- end -%> + end + + it "edit action should redirect when not logged in" do + get :edit, :id => "ignored" + response.should redirect_to(login_url) + end + + it "edit action should render edit template" do + @controller.stubs(:current_<%= user_singular_name %>).returns(<%= user_class_name %>.first) + get :edit, :id => "ignored" + response.should render_template(:edit) + end + + it "update action should redirect when not logged in" do + put :update, :id => "ignored" + response.should redirect_to(login_url) + end + + it "update action should render edit template when <%= user_singular_name %> is invalid" do + @controller.stubs(:current_<%= user_singular_name %>).returns(<%= user_class_name %>.first) + <%= user_class_name %>.any_instance.stubs(:valid?).returns(false) + put :update, :id => "ignored" + response.should render_template(:edit) + end + + it "update action should redirect when <%= user_singular_name %> is valid" do + @controller.stubs(:current_<%= user_singular_name %>).returns(<%= user_class_name %>.first) + <%= user_class_name %>.any_instance.stubs(:valid?).returns(true) + put :update, :id => "ignored" + response.should redirect_to(root_url) + end +end diff --git a/lib/generators/nifty/authentication/templates/tests/shoulda/sessions_controller.rb b/lib/generators/nifty/authentication/templates/tests/shoulda/sessions_controller.rb new file mode 100644 index 0000000..e2f9005 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/tests/shoulda/sessions_controller.rb @@ -0,0 +1,40 @@ +require 'test_helper' + +class <%= session_plural_class_name %>ControllerTest < ActionController::TestCase + context "new action" do + should "render new template" do + get :new + assert_template 'new' + end + end + + context "create action" do + <%- if options[:authlogic] -%> + should "render new template when authentication is invalid" do + post :create, :<%= session_singular_name %> => { :username => "foo", :password => "badpassword" } + assert_template 'new' + assert_nil <%= session_class_name %>.find + end + + should "redirect when authentication is valid" do + post :create, :<%= session_singular_name %> => { :username => "foo", :password => "secret" } + assert_redirected_to root_url + assert_equal <%= user_plural_name %>(:foo), <%= session_class_name %>.find.<%= user_singular_name %> + end + <%- else -%> + should "render new template when authentication is invalid" do + <%= user_class_name %>.stubs(:authenticate).returns(nil) + post :create + assert_template 'new' + assert_nil session['<%= user_singular_name %>_id'] + end + + should "redirect when authentication is valid" do + <%= user_class_name %>.stubs(:authenticate).returns(<%= user_class_name %>.first) + post :create + assert_redirected_to root_url + assert_equal <%= user_class_name %>.first.id, session['<%= user_singular_name %>_id'] + end + <%- end -%> + end +end diff --git a/lib/generators/nifty/authentication/templates/tests/shoulda/user.rb b/lib/generators/nifty/authentication/templates/tests/shoulda/user.rb new file mode 100644 index 0000000..beb8bf4 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/tests/shoulda/user.rb @@ -0,0 +1,85 @@ +require 'test_helper' + +class <%= user_class_name %>Test < ActiveSupport::TestCase +<%- unless options[:authlogic] -%> + def new_<%= user_singular_name %>(attributes = {}) + attributes[:username] ||= 'foo' + attributes[:email] ||= 'foo@example.com' + attributes[:password] ||= 'abc123' + attributes[:password_confirmation] ||= attributes[:password] + <%= user_singular_name %> = <%= user_class_name %>.new(attributes) + <%= user_singular_name %>.valid? # run validations + <%= user_singular_name %> + end + + def setup + <%= user_class_name %>.delete_all + end + + should "be valid" do + assert new_<%= user_singular_name %>.valid? + end + + should "require username" do + assert_equal ["can't be blank"], new_<%= user_singular_name %>(:username => '').errors[:username] + end + + should "require password" do + assert_equal ["can't be blank"], new_<%= user_singular_name %>(:password => '').errors[:password] + end + + should "require well formed email" do + assert_equal ["is invalid"], new_<%= user_singular_name %>(:email => 'foo@bar@example.com').errors[:email] + end + + should "validate uniqueness of email" do + new_<%= user_singular_name %>(:email => 'bar@example.com').save! + assert_equal ["has already been taken"], new_<%= user_singular_name %>(:email => 'bar@example.com').errors[:email] + end + + should "validate uniqueness of username" do + new_<%= user_singular_name %>(:username => 'uniquename').save! + assert_equal ["has already been taken"], new_<%= user_singular_name %>(:username => 'uniquename').errors[:username] + end + + should "not allow odd characters in username" do + assert_equal ["should only contain letters, numbers, or .-_@"], new_<%= user_singular_name %>(:username => 'odd ^&(@)').errors[:username] + end + + should "validate password is longer than 3 characters" do + assert_equal ["is too short (minimum is 4 characters)"], new_<%= user_singular_name %>(:password => 'bad').errors[:password] + end + + should "require matching password confirmation" do + assert_equal ["doesn't match confirmation"], new_<%= user_singular_name %>(:password_confirmation => 'nonmatching').errors[:password] + end + + should "generate password hash and salt on create" do + <%= user_singular_name %> = new_<%= user_singular_name %> + <%= user_singular_name %>.save! + assert <%= user_singular_name %>.password_hash + assert <%= user_singular_name %>.password_salt + end + + should "authenticate by username" do + <%= user_singular_name %> = new_<%= user_singular_name %>(:username => 'foobar', :password => 'secret') + <%= user_singular_name %>.save! + assert_equal <%= user_singular_name %>, <%= user_class_name %>.authenticate('foobar', 'secret') + end + + should "authenticate by email" do + <%= user_singular_name %> = new_<%= user_singular_name %>(:email => 'foo@bar.com', :password => 'secret') + <%= user_singular_name %>.save! + assert_equal <%= user_singular_name %>, <%= user_class_name %>.authenticate('foo@bar.com', 'secret') + end + + should "not authenticate bad username" do + assert_nil <%= user_class_name %>.authenticate('nonexisting', 'secret') + end + + should "not authenticate bad password" do + new_<%= user_singular_name %>(:username => 'foobar', :password => 'secret').save! + assert_nil <%= user_class_name %>.authenticate('foobar', 'badpassword') + end +<%- end -%> +end diff --git a/lib/generators/nifty/authentication/templates/tests/shoulda/users_controller.rb b/lib/generators/nifty/authentication/templates/tests/shoulda/users_controller.rb new file mode 100644 index 0000000..1728329 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/tests/shoulda/users_controller.rb @@ -0,0 +1,61 @@ +require 'test_helper' + +class <%= user_plural_class_name %>ControllerTest < ActionController::TestCase + context "new action" do + should "render new template" do + get :new + assert_template 'new' + end + end + + context "create action" do + should "render new template when <%= user_singular_name %> is invalid" do + <%= user_class_name %>.any_instance.stubs(:valid?).returns(false) + post :create + assert_template 'new' + end + + should "redirect when <%= user_singular_name %> is valid" do + <%= user_class_name %>.any_instance.stubs(:valid?).returns(true) + post :create + assert_redirected_to root_url + <%- unless options[:authlogic] -%> + assert_equal assigns['<%= user_singular_name %>'].id, session['<%= user_singular_name %>_id'] + <%- end -%> + end + end + + context "edit action" do + should "redirect when not logged in" do + get :edit, :id => "ignored" + assert_redirected_to login_url + end + + should "render edit template" do + @controller.stubs(:current_<%= user_singular_name %>).returns(<%= user_class_name %>.first) + get :edit, :id => "ignored" + assert_template 'edit' + end + end + + context "update action" do + should "redirect when not logged in" do + put :update, :id => "ignored" + assert_redirected_to login_url + end + + should "render edit template when <%= user_singular_name %> is invalid" do + @controller.stubs(:current_<%= user_singular_name %>).returns(<%= user_class_name %>.first) + <%= user_class_name %>.any_instance.stubs(:valid?).returns(false) + put :update, :id => "ignored" + assert_template 'edit' + end + + should "redirect when <%= user_singular_name %> is valid" do + @controller.stubs(:current_<%= user_singular_name %>).returns(<%= user_class_name %>.first) + <%= user_class_name %>.any_instance.stubs(:valid?).returns(true) + put :update, :id => "ignored" + assert_redirected_to root_url + end + end +end diff --git a/lib/generators/nifty/authentication/templates/tests/testunit/sessions_controller.rb b/lib/generators/nifty/authentication/templates/tests/testunit/sessions_controller.rb new file mode 100644 index 0000000..fe2a65b --- /dev/null +++ b/lib/generators/nifty/authentication/templates/tests/testunit/sessions_controller.rb @@ -0,0 +1,36 @@ +require 'test_helper' + +class <%= session_plural_class_name %>ControllerTest < ActionController::TestCase + def test_new + get :new + assert_template 'new' + end + +<%- if options[:authlogic] -%> + def test_create_invalid + post :create, :<%= session_singular_name %> => { :username => "foo", :password => "badpassword" } + assert_template 'new' + assert_nil <%= session_class_name %>.find + end + + def test_create_valid + post :create, :<%= session_singular_name %> => { :username => "foo", :password => "secret" } + assert_redirected_to root_url + assert_equal <%= user_plural_name %>(:foo), <%= session_class_name %>.find.<%= user_singular_name %> + end +<%- else -%> + def test_create_invalid + <%= user_class_name %>.stubs(:authenticate).returns(nil) + post :create + assert_template 'new' + assert_nil session['<%= user_singular_name %>_id'] + end + + def test_create_valid + <%= user_class_name %>.stubs(:authenticate).returns(<%= user_class_name %>.first) + post :create + assert_redirected_to root_url + assert_equal <%= user_class_name %>.first.id, session['<%= user_singular_name %>_id'] + end +<%- end -%> +end diff --git a/lib/generators/nifty/authentication/templates/tests/testunit/user.rb b/lib/generators/nifty/authentication/templates/tests/testunit/user.rb new file mode 100644 index 0000000..c036cf1 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/tests/testunit/user.rb @@ -0,0 +1,88 @@ +require 'test_helper' + +class <%= user_class_name %>Test < ActiveSupport::TestCase +<%- unless options[:authlogic] -%> + def new_<%= user_singular_name %>(attributes = {}) + attributes[:username] ||= 'foo' + attributes[:email] ||= 'foo@example.com' + attributes[:password] ||= 'abc123' + attributes[:password_confirmation] ||= attributes[:password] + <%= user_singular_name %> = <%= user_class_name %>.new(attributes) + <%= user_singular_name %>.valid? # run validations + <%= user_singular_name %> + end + + def setup + <%= user_class_name %>.delete_all + end + + def test_valid + assert new_<%= user_singular_name %>.valid? + end + + def test_require_username + assert_equal ["can't be blank"], new_<%= user_singular_name %>(:username => '').errors[:username] + end + + def test_require_password + assert_equal ["can't be blank"], new_<%= user_singular_name %>(:password => '').errors[:password] + end + + def test_require_well_formed_email + assert_equal ["is invalid"], new_<%= user_singular_name %>(:email => 'foo@bar@example.com').errors[:email] + end + + def test_validate_uniqueness_of_email + new_<%= user_singular_name %>(:email => 'bar@example.com').save! + assert_equal ["has already been taken"], new_<%= user_singular_name %>(:email => 'bar@example.com').errors[:email] + end + + def test_validate_uniqueness_of_username + new_<%= user_singular_name %>(:username => 'uniquename').save! + assert_equal ["has already been taken"], new_<%= user_singular_name %>(:username => 'uniquename').errors[:username] + end + + def test_validate_odd_characters_in_username + assert_equal ["should only contain letters, numbers, or .-_@"], new_<%= user_singular_name %>(:username => 'odd ^&(@)').errors[:username] + end + + def test_validate_password_length + assert_equal ["is too short (minimum is 4 characters)"], new_<%= user_singular_name %>(:password => 'bad').errors[:password] + end + + def test_require_matching_password_confirmation + assert_equal ["doesn't match confirmation"], new_<%= user_singular_name %>(:password_confirmation => 'nonmatching').errors[:password] + end + + def test_generate_password_hash_and_salt_on_create + <%= user_singular_name %> = new_<%= user_singular_name %> + <%= user_singular_name %>.save! + assert <%= user_singular_name %>.password_hash + assert <%= user_singular_name %>.password_salt + end + + def test_authenticate_by_username + <%= user_class_name %>.delete_all + <%= user_singular_name %> = new_<%= user_singular_name %>(:username => 'foobar', :password => 'secret') + <%= user_singular_name %>.save! + assert_equal <%= user_singular_name %>, <%= user_class_name %>.authenticate('foobar', 'secret') + end + + def test_authenticate_by_email + <%= user_class_name %>.delete_all + <%= user_singular_name %> = new_<%= user_singular_name %>(:email => 'foo@bar.com', :password => 'secret') + <%= user_singular_name %>.save! + assert_equal <%= user_singular_name %>, <%= user_class_name %>.authenticate('foo@bar.com', 'secret') + end + + def test_authenticate_bad_username + assert_nil <%= user_class_name %>.authenticate('nonexisting', 'secret') + end + + def test_authenticate_bad_password + <%= user_class_name %>.delete_all + new_<%= user_singular_name %>(:username => 'foobar', :password => 'secret').save! + assert_nil <%= user_class_name %>.authenticate('foobar', 'badpassword') + end +<%- end -%> +end diff --git a/lib/generators/nifty/authentication/templates/tests/testunit/users_controller.rb b/lib/generators/nifty/authentication/templates/tests/testunit/users_controller.rb new file mode 100644 index 0000000..ef8a3f7 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/tests/testunit/users_controller.rb @@ -0,0 +1,53 @@ +require 'test_helper' + +class <%= user_plural_class_name %>ControllerTest < ActionController::TestCase + def test_new + get :new + assert_template 'new' + end + + def test_create_invalid + <%= user_class_name %>.any_instance.stubs(:valid?).returns(false) + post :create + assert_template 'new' + end + + def test_create_valid + <%= user_class_name %>.any_instance.stubs(:valid?).returns(true) + post :create + assert_redirected_to root_url + <%- unless options[:authlogic] -%> + assert_equal assigns['<%= user_singular_name %>'].id, session['<%= user_singular_name %>_id'] + <%- end -%> + end + + def test_edit_without_user + get :edit, :id => "ignored" + assert_redirected_to login_url + end + + def test_edit + @controller.stubs(:current_<%= user_singular_name %>).returns(<%= user_class_name %>.first) + get :edit, :id => "ignored" + assert_template 'edit' + end + + def test_update_without_user + put :update, :id => "ignored" + assert_redirected_to login_url + end + + def test_update_invalid + @controller.stubs(:current_<%= user_singular_name %>).returns(<%= user_class_name %>.first) + <%= user_class_name %>.any_instance.stubs(:valid?).returns(false) + put :update, :id => "ignored" + assert_template 'edit' + end + + def test_update_valid + @controller.stubs(:current_<%= user_singular_name %>).returns(<%= user_class_name %>.first) + <%= user_class_name %>.any_instance.stubs(:valid?).returns(true) + put :update, :id => "ignored" + assert_redirected_to root_url + end +end diff --git a/lib/generators/nifty/authentication/templates/user.rb b/lib/generators/nifty/authentication/templates/user.rb new file mode 100644 index 0000000..ec18524 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/user.rb @@ -0,0 +1,38 @@ +class <%= user_class_name %> < ActiveRecord::Base +<%- if options[:authlogic] -%> + acts_as_authentic +<%- else -%> + # new columns need to be added here to be writable through mass assignment + attr_accessible :username, :email, :password, :password_confirmation + + attr_accessor :password + before_save :prepare_password + + validates_presence_of :username + validates_uniqueness_of :username, :email, :allow_blank => true + validates_format_of :username, :with => /^[-\w\._@]+$/i, :allow_blank => true, :message => "should only contain letters, numbers, or .-_@" + validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i + validates_presence_of :password, :on => :create + validates_confirmation_of :password + validates_length_of :password, :minimum => 4, :allow_blank => true + + # login can be either username or email address + def self.authenticate(login, pass) + <%= user_singular_name %> = find_by_username(login) || find_by_email(login) + return <%= user_singular_name %> if <%= user_singular_name %> && <%= user_singular_name %>.password_hash == <%= user_singular_name %>.encrypt_password(pass) + end + + def encrypt_password(pass) + BCrypt::Engine.hash_secret(pass, password_salt) + end + + private + + def prepare_password + unless password.blank? + self.password_salt = BCrypt::Engine.generate_salt + self.password_hash = encrypt_password(password) + end + end +<%- end -%> +end diff --git a/lib/generators/nifty/authentication/templates/users_controller.rb b/lib/generators/nifty/authentication/templates/users_controller.rb new file mode 100644 index 0000000..2faed00 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/users_controller.rb @@ -0,0 +1,32 @@ +class <%= user_plural_class_name %>Controller < ApplicationController + before_filter :login_required, :except => [:new, :create] + + def new + @<%= user_singular_name %> = <%= user_class_name %>.new + end + + def create + @<%= user_singular_name %> = <%= user_class_name %>.new(params[:<%= user_singular_name %>]) + if @<%= user_singular_name %>.save + <%- unless options[:authlogic] -%> + session[:<%= user_singular_name %>_id] = @<%= user_singular_name %>.id + <%- end -%> + redirect_to root_url, :notice => "Thank you for signing up! You are now logged in." + else + render :new + end + end + + def edit + @<%= user_singular_name %> = current_<%= user_singular_name %> + end + + def update + @<%= user_singular_name %> = current_<%= user_singular_name %> + if @<%= user_singular_name %>.update_attributes(params[:<%= user_singular_name %>]) + redirect_to root_url, :notice => "Your profile has been updated." + else + render :edit + end + end +end diff --git a/lib/generators/nifty/authentication/templates/users_helper.rb b/lib/generators/nifty/authentication/templates/users_helper.rb new file mode 100644 index 0000000..7eb9040 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/users_helper.rb @@ -0,0 +1,2 @@ +module <%= user_plural_class_name %>Helper +end diff --git a/lib/generators/nifty/authentication/templates/views/erb/_form.html.erb b/lib/generators/nifty/authentication/templates/views/erb/_form.html.erb new file mode 100644 index 0000000..4e1c47d --- /dev/null +++ b/lib/generators/nifty/authentication/templates/views/erb/_form.html.erb @@ -0,0 +1,20 @@ +<%%= form_for @<%= user_singular_name %> do |f| %> + <%%= f.error_messages %> + <div class="field"> + <%%= f.label :username %> + <%%= f.text_field :username %> + </div> + <div class="field"> + <%%= f.label :email, "Email Address" %> + <%%= f.text_field :email %> + </div> + <div class="field"> + <%%= f.label :password %> + <%%= f.password_field :password %> + </div> + <div class="field"> + <%%= f.label :password_confirmation, "Confirm Password" %> + <%%= f.password_field :password_confirmation %> + </div> + <div class="actions"><%%= f.submit (@<%= user_singular_name %>.new_record? ? "Sign up" : "Update") %></div> +<%% end %> diff --git a/lib/generators/nifty/authentication/templates/views/erb/edit.html.erb b/lib/generators/nifty/authentication/templates/views/erb/edit.html.erb new file mode 100644 index 0000000..75de67e --- /dev/null +++ b/lib/generators/nifty/authentication/templates/views/erb/edit.html.erb @@ -0,0 +1,3 @@ +<%% title "Update Profile" %> + +<%%= render "form" %> diff --git a/lib/generators/nifty/authentication/templates/views/erb/login.html.erb b/lib/generators/nifty/authentication/templates/views/erb/login.html.erb new file mode 100644 index 0000000..1cbc428 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/views/erb/login.html.erb @@ -0,0 +1,30 @@ +<%% title "Log in" %> + +<p>Don't have an account? <%%= link_to "Sign up!", signup_path %></p> + +<%- if options[:authlogic] -%> +<%%= form_for @<%= session_singular_name %> do |f| %> + <%%= f.error_messages %> + <div class="field"> + <%%= f.label :username %> + <%%= f.text_field :username %> + </div> + <div class="field"> + <%%= f.label :password %> + <%%= f.password_field :password %> + </div> + <div class="actions"><%%= f.submit "Log in" %></div> +<%% end %> +<%- else -%> +<%%= form_tag <%= session_plural_name %>_path do %> + <div class="field"> + <%%= label_tag :login, "Username or Email Address" %> + <%%= text_field_tag :login, params[:login] %> + </div> + <div class="field"> + <%%= label_tag :password %> + <%%= password_field_tag :password %> + </div> + <div class="actions"><%%= submit_tag "Log in" %></div> +<%% end %> +<%- end -%> diff --git a/lib/generators/nifty/authentication/templates/views/erb/signup.html.erb b/lib/generators/nifty/authentication/templates/views/erb/signup.html.erb new file mode 100644 index 0000000..6f282b5 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/views/erb/signup.html.erb @@ -0,0 +1,5 @@ +<%% title "Sign up" %> + +<p>Already have an account? <%%= link_to "Log in", login_path %>.</p> + +<%%= render "form" %> diff --git a/lib/generators/nifty/authentication/templates/views/haml/_form.html.haml b/lib/generators/nifty/authentication/templates/views/haml/_form.html.haml new file mode 100644 index 0000000..992ee9c --- /dev/null +++ b/lib/generators/nifty/authentication/templates/views/haml/_form.html.haml @@ -0,0 +1,16 @@ += form_for @<%= user_singular_name %> do |f| + = f.error_messages + .field + = f.label :username + = f.text_field :username + .field + = f.label :email, "Email Address" + = f.text_field :email + .field + = f.label :password + = f.password_field :password + .field + = f.label :password_confirmation, "Confirm Password" + = f.password_field :password_confirmation + .actions + = f.submit (@<%= user_singular_name %>.new_record? ? "Sign up" : "Update") diff --git a/lib/generators/nifty/authentication/templates/views/haml/edit.html.haml b/lib/generators/nifty/authentication/templates/views/haml/edit.html.haml new file mode 100644 index 0000000..4b43a3b --- /dev/null +++ b/lib/generators/nifty/authentication/templates/views/haml/edit.html.haml @@ -0,0 +1,3 @@ +- title "Sign up" + += render "form" diff --git a/lib/generators/nifty/authentication/templates/views/haml/login.html.haml b/lib/generators/nifty/authentication/templates/views/haml/login.html.haml new file mode 100644 index 0000000..22fc95b --- /dev/null +++ b/lib/generators/nifty/authentication/templates/views/haml/login.html.haml @@ -0,0 +1,26 @@ +- title "Log in" + +%p== Don't have an account? #{link_to "Sign up!", signup_path} + +<%- if options[:authlogic] -%> += form_for @<%= session_singular_name %> do |f| + = f.error_messages + .field + = f.label :username + = f.text_field :username + .field + = f.label :password + = f.password_field :password + .actions + = f.submit "Log in" +<%- else -%> +- form_tag <%= session_plural_name %>_path do + .field + = label_tag :login, "Username or Email Address" + = text_field_tag :login, params[:login] + .field + = label_tag :password + = password_field_tag :password + .actions + = submit_tag "Log in" +<%- end -%> diff --git a/lib/generators/nifty/authentication/templates/views/haml/signup.html.haml b/lib/generators/nifty/authentication/templates/views/haml/signup.html.haml new file mode 100644 index 0000000..dc75c13 --- /dev/null +++ b/lib/generators/nifty/authentication/templates/views/haml/signup.html.haml @@ -0,0 +1,5 @@ +- title "Sign up" + +%p== Already have an account? #{link_to "Log in", login_path}. + += render "form" |