restful_authentication 1.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/CHANGELOG +68 -0
  2. data/LICENSE +20 -0
  3. data/README.textile +232 -0
  4. data/Rakefile +54 -0
  5. data/TODO +15 -0
  6. data/generators/authenticated/USAGE +1 -0
  7. data/generators/authenticated/authenticated_generator.rb +493 -0
  8. data/generators/authenticated/lib/insert_routes.rb +69 -0
  9. data/generators/authenticated/templates/_model_partial.html.erb +8 -0
  10. data/generators/authenticated/templates/activation.erb +3 -0
  11. data/generators/authenticated/templates/authenticated_system.rb +189 -0
  12. data/generators/authenticated/templates/authenticated_test_helper.rb +12 -0
  13. data/generators/authenticated/templates/controller.rb +43 -0
  14. data/generators/authenticated/templates/features/accounts.feature +67 -0
  15. data/generators/authenticated/templates/features/sessions.feature +77 -0
  16. data/generators/authenticated/templates/features/step_definitions/ra_env.rb +7 -0
  17. data/generators/authenticated/templates/features/step_definitions/user_steps.rb +31 -0
  18. data/generators/authenticated/templates/helper.rb +2 -0
  19. data/generators/authenticated/templates/login.html.erb +14 -0
  20. data/generators/authenticated/templates/machinist_spec.rb +5 -0
  21. data/generators/authenticated/templates/machinist_test.rb +5 -0
  22. data/generators/authenticated/templates/mailer.rb +25 -0
  23. data/generators/authenticated/templates/migration.rb +24 -0
  24. data/generators/authenticated/templates/model.rb +83 -0
  25. data/generators/authenticated/templates/model_controller.rb +96 -0
  26. data/generators/authenticated/templates/model_helper.rb +93 -0
  27. data/generators/authenticated/templates/model_helper_spec.rb +157 -0
  28. data/generators/authenticated/templates/observer.rb +11 -0
  29. data/generators/authenticated/templates/signup.html.erb +19 -0
  30. data/generators/authenticated/templates/signup_notification.erb +8 -0
  31. data/generators/authenticated/templates/site_keys.rb +38 -0
  32. data/generators/authenticated/templates/spec/blueprints/user.rb +13 -0
  33. data/generators/authenticated/templates/spec/controllers/access_control_spec.rb +89 -0
  34. data/generators/authenticated/templates/spec/controllers/authenticated_system_spec.rb +107 -0
  35. data/generators/authenticated/templates/spec/controllers/sessions_controller_spec.rb +138 -0
  36. data/generators/authenticated/templates/spec/controllers/users_controller_spec.rb +197 -0
  37. data/generators/authenticated/templates/spec/fixtures/users.yml +60 -0
  38. data/generators/authenticated/templates/spec/helpers/users_helper_spec.rb +141 -0
  39. data/generators/authenticated/templates/spec/models/user_spec.rb +298 -0
  40. data/generators/authenticated/templates/tasks/auth.rake +33 -0
  41. data/generators/authenticated/templates/test/functional_test.rb +84 -0
  42. data/generators/authenticated/templates/test/mailer_test.rb +31 -0
  43. data/generators/authenticated/templates/test/model_functional_test.rb +91 -0
  44. data/generators/authenticated/templates/test/unit_test.rb +177 -0
  45. data/lib/authentication.rb +40 -0
  46. data/lib/authentication/by_cookie_token.rb +82 -0
  47. data/lib/authentication/by_password.rb +64 -0
  48. data/lib/authorization.rb +14 -0
  49. data/lib/authorization/aasm_roles.rb +64 -0
  50. data/lib/authorization/stateful_roles.rb +64 -0
  51. data/lib/restful_authentication.rb +6 -0
  52. data/lib/trustification.rb +14 -0
  53. data/lib/trustification/email_validation.rb +20 -0
  54. data/notes/AccessControl.txt +2 -0
  55. data/notes/Authentication.txt +5 -0
  56. data/notes/Authorization.txt +154 -0
  57. data/notes/RailsPlugins.txt +78 -0
  58. data/notes/SecurityFramework.graffle +0 -0
  59. data/notes/SecurityFramework.png +0 -0
  60. data/notes/SecurityPatterns.txt +163 -0
  61. data/notes/Tradeoffs.txt +126 -0
  62. data/notes/Trustification.txt +49 -0
  63. data/restful_authentication.gemspec +32 -0
  64. metadata +128 -0
@@ -0,0 +1,7 @@
1
+ begin
2
+ ApplicationController.send(:public, :logged_in?, :current_<%= file_name %>, :authorized?)
3
+ rescue NameError => e
4
+ puts "An exception occurred: #{e}"
5
+ puts 'Did you forget to move "include AuthenticatedSystem" from sessions_controller.rb to application_controller.rb?'
6
+ exit!
7
+ end
@@ -0,0 +1,31 @@
1
+ Given /^I am not logged in$/ do
2
+ visit '/logout'
3
+ end
4
+
5
+ Given /^I am logged in$/ do
6
+ <%= file_name %> = <%= class_name %>.make
7
+ visit '/login'
8
+ fill_in 'login', :with => <%= file_name %>.login
9
+ fill_in 'password', :with => <%= file_name %>.password
10
+ click_button 'Log in'
11
+ end
12
+
13
+ Then /^I should not be logged in$/ do
14
+ controller.current_<%= file_name %>.should be_nil
15
+ end
16
+
17
+ Then /^I should be logged in$/ do
18
+ controller.current_<%= file_name %>.should_not be_nil
19
+ end
20
+
21
+ Given /^someone with the login "([^\"]*)" already exists$/ do |login|
22
+ <%= class_name %>.make(:login => login)
23
+ end
24
+
25
+ Then /^I should have a remember token$/ do
26
+ controller.current_<%= file_name %>.remember_token.should_not be_nil
27
+ end
28
+
29
+ Then /^I should not have a remember token$/ do
30
+ controller.current_<%= file_name %>.remember_token.should be_nil
31
+ end
@@ -0,0 +1,2 @@
1
+ module <%= controller_class_name %>Helper
2
+ end
@@ -0,0 +1,14 @@
1
+ <h1>Log In</h1>
2
+
3
+ <%% form_tag <%= controller_routing_name %>_path do -%>
4
+ <p><%%= label_tag 'login' %><br />
5
+ <%%= text_field_tag 'login', @login %></p>
6
+
7
+ <p><%%= label_tag 'password' %><br/>
8
+ <%%= password_field_tag 'password', nil %></p>
9
+
10
+ <p><%%= label_tag 'remember_me', 'Remember me' %>
11
+ <%%= check_box_tag 'remember_me', '1', @remember_me %></p>
12
+
13
+ <p><%%= submit_tag 'Log in' %></p>
14
+ <%% end -%>
@@ -0,0 +1,5 @@
1
+ require 'machinist/active_record'
2
+ require 'sham'
3
+ require 'faker'
4
+
5
+ Dir["#{RAILS_ROOT}/spec/blueprints/*.rb"].each { |f| require f }
@@ -0,0 +1,5 @@
1
+ require 'machinist/active_record'
2
+ require 'sham'
3
+ require 'faker'
4
+
5
+ Dir["#{RAILS_ROOT}/test/blueprints/*.rb"].each { |f| require f }
@@ -0,0 +1,25 @@
1
+ class <%= class_name %>Mailer < ActionMailer::Base
2
+ def signup_notification(<%= file_name %>)
3
+ setup_email(<%= file_name %>)
4
+ @subject += 'Please activate your new account'
5
+ <% if options[:include_activation] %>
6
+ @body[:url] = "http://YOURSITE/activate/#{<%= file_name %>.activation_code}"
7
+ <% else %>
8
+ @body[:url] = "http://YOURSITE/login/" <% end %>
9
+ end
10
+
11
+ def activation(<%= file_name %>)
12
+ setup_email(<%= file_name %>)
13
+ @subject += 'Your account has been activated!'
14
+ @body[:url] = "http://YOURSITE/"
15
+ end
16
+
17
+ protected
18
+ def setup_email(<%= file_name %>)
19
+ @recipients = "#{<%= file_name %>.email}"
20
+ @from = "ADMINEMAIL"
21
+ @subject = "[YOURSITE] "
22
+ @sent_on = Time.now
23
+ @body[:<%= file_name %>] = <%= file_name %>
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= table_name %>, :force => true do |t|
4
+ t.string :login, :crypted_password, :salt, :remember_token, :limit => 40
5
+ t.datetime :remember_token_expires_at
6
+ t.string :name, :limit => 100, :default => '', :null => true
7
+ t.string :email, :limit => 100
8
+ <% if options[:include_activation] -%>
9
+ t.string :activation_code, :limit => 40
10
+ t.datetime :activated_at
11
+ <% end -%>
12
+ <% if options[:stateful] -%>
13
+ t.string :state, :null => :no, :default => 'passive'
14
+ t.datetime :deleted_at
15
+ <% end -%>
16
+ t.timestamps
17
+ end
18
+ add_index :<%= table_name %>, :login, :unique => true
19
+ end
20
+
21
+ def self.down
22
+ drop_table :<%= table_name %>
23
+ end
24
+ end
@@ -0,0 +1,83 @@
1
+ require 'digest/sha1'
2
+
3
+ class <%= class_name %> < ActiveRecord::Base
4
+ include Authentication
5
+ include Authentication::ByPassword
6
+ include Authentication::ByCookieToken
7
+ <% if options[:aasm] -%>
8
+ include Authorization::AasmRoles
9
+ <% elsif options[:stateful] -%>
10
+ include Authorization::StatefulRoles<% end %>
11
+ validates_presence_of :login
12
+ validates_length_of :login, :within => 3..40
13
+ validates_uniqueness_of :login
14
+ validates_format_of :login, :with => Authentication.login_regex, :message => Authentication.bad_login_message
15
+
16
+ validates_format_of :name, :with => Authentication.name_regex, :message => Authentication.bad_name_message, :allow_nil => true
17
+ validates_length_of :name, :maximum => 100
18
+
19
+ validates_presence_of :email
20
+ validates_length_of :email, :within => 6..100 #r@a.wk
21
+ validates_uniqueness_of :email
22
+ validates_format_of :email, :with => Authentication.email_regex, :message => Authentication.bad_email_message
23
+
24
+ <% if options[:include_activation] && !options[:stateful] %>before_create :make_activation_code <% end %>
25
+
26
+ # HACK HACK HACK -- how to do attr_accessible from here?
27
+ # prevents a user from submitting a crafted form that bypasses activation
28
+ # anything else you want your user to change should be added here.
29
+ attr_accessible :login, :email, :name, :password, :password_confirmation
30
+
31
+ <% if options[:include_activation] && !options[:stateful] %>
32
+ # Activates the user in the database.
33
+ def activate!
34
+ @activated = true
35
+ self.activated_at = Time.now.utc
36
+ self.activation_code = nil
37
+ save(false)
38
+ end
39
+
40
+ # Returns true if the user has just been activated.
41
+ def recently_activated?
42
+ @activated
43
+ end
44
+
45
+ def active?
46
+ # the existence of an activation code means they have not activated yet
47
+ activation_code.nil?
48
+ end<% end %>
49
+
50
+ # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
51
+ #
52
+ # uff. this is really an authorization, not authentication routine.
53
+ # We really need a Dispatch Chain here or something.
54
+ # This will also let us return a human error message.
55
+ #
56
+ def self.authenticate(login, password)
57
+ return nil if login.blank? || password.blank?
58
+ u = <% if options[:stateful] %>find_in_state :first, :active, :conditions => {:login => login.downcase}<%
59
+ elsif options[:include_activation] %>find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login]<%
60
+ else %>find_by_login(login.downcase)<% end %> # need to get the salt
61
+ u && u.authenticated?(password) ? u : nil
62
+ end
63
+
64
+ def login=(value)
65
+ write_attribute :login, (value ? value.downcase : nil)
66
+ end
67
+
68
+ def email=(value)
69
+ write_attribute :email, (value ? value.downcase : nil)
70
+ end
71
+
72
+ protected
73
+
74
+ <% if options[:include_activation] -%>
75
+ def make_activation_code
76
+ <% if options[:stateful] -%>
77
+ self.deleted_at = nil
78
+ <% end -%>
79
+ self.activation_code = self.class.make_token
80
+ end
81
+ <% end %>
82
+
83
+ end
@@ -0,0 +1,96 @@
1
+ class <%= model_controller_class_name %>Controller < ApplicationController
2
+ # Be sure to include AuthenticationSystem in Application Controller instead
3
+ include AuthenticatedSystem
4
+ <% if options[:stateful] %>
5
+ # Protect these actions behind an admin login
6
+ # before_filter :admin_required, :only => [:suspend, :unsuspend, :destroy, :purge]
7
+ before_filter :find_<%= file_name %>, :only => [:suspend, :unsuspend, :destroy, :purge]
8
+ <% end %>
9
+
10
+ # render new.html.erb
11
+ def new
12
+ @<%= file_name %> = <%= class_name %>.new
13
+ end
14
+
15
+ def create
16
+ logout_keeping_session!
17
+ @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>])
18
+ <% if options[:stateful] -%>
19
+ @<%= file_name %>.register! if @<%= file_name %> && @<%= file_name %>.valid?
20
+ success = @<%= file_name %> && @<%= file_name %>.valid?
21
+ <% else -%>
22
+ success = @<%= file_name %> && @<%= file_name %>.save
23
+ <% end -%>
24
+ if success && @<%= file_name %>.errors.empty?
25
+ <% if !options[:include_activation] -%>
26
+ # Protects against session fixation attacks, causes request forgery
27
+ # protection if visitor resubmits an earlier form using back
28
+ # button. Uncomment if you understand the tradeoffs.
29
+ # reset session
30
+ self.current_<%= file_name %> = @<%= file_name %> # !! now logged in
31
+ <% end -%>redirect_back_or_default('/')
32
+ <% if options[:include_activation] -%>
33
+ flash[:notice] = "Thanks for signing up! We're sending you an email with your activation code."
34
+ <% else -%>
35
+ flash[:notice] = "Thanks for signing up!"
36
+ <% end -%>
37
+ else
38
+ <% if options[:include_activation] -%>
39
+ flash[:error] = "We couldn't set up that account, sorry. Please try again, or contact an admin (link is above)."
40
+ <% else -%>
41
+ flash[:error] = "We couldn't create your account, sorry."
42
+ <% end -%>
43
+ render :action => 'new'
44
+ end
45
+ end
46
+
47
+ <% if options[:include_activation] -%>
48
+ def activate
49
+ logout_keeping_session!
50
+ <%= file_name %> = <%= class_name %>.find_by_activation_code(params[:activation_code]) unless params[:activation_code].blank?
51
+ case
52
+ when (!params[:activation_code].blank?) && <%= file_name %> && !<%= file_name %>.active?
53
+ <%= file_name %>.activate!
54
+ flash[:notice] = "Signup complete! Please sign in to continue."
55
+ redirect_to '/login'
56
+ when params[:activation_code].blank?
57
+ flash[:error] = "The activation code was missing. Please follow the URL from your email."
58
+ redirect_back_or_default('/')
59
+ else
60
+ flash[:error] = "We couldn't find a <%= file_name %> with that activation code -- check your email? Or maybe you've already activated -- try signing in."
61
+ redirect_back_or_default('/')
62
+ end
63
+ end
64
+ <% end -%>
65
+
66
+ <% if options[:stateful] -%>
67
+ def suspend
68
+ @<%= file_name %>.suspend!
69
+ redirect_to <%= model_controller_routing_name %>_path
70
+ end
71
+
72
+ def unsuspend
73
+ @<%= file_name %>.unsuspend!
74
+ redirect_to <%= model_controller_routing_name %>_path
75
+ end
76
+
77
+ def destroy
78
+ @<%= file_name %>.delete!
79
+ redirect_to <%= model_controller_routing_name %>_path
80
+ end
81
+
82
+ def purge
83
+ @<%= file_name %>.destroy
84
+ redirect_to <%= model_controller_routing_name %>_path
85
+ end
86
+
87
+ # There's no page here to update or destroy a <%= file_name %>. If you add those, be
88
+ # smart -- make sure you check that the visitor is authorized to do so, that they
89
+ # supply their old password along with a new one to update it, etc.
90
+
91
+ protected
92
+ def find_<%= file_name %>
93
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
94
+ end
95
+ <% end -%>
96
+ end
@@ -0,0 +1,93 @@
1
+ module <%= model_controller_class_name %>Helper
2
+
3
+ #
4
+ # Use this to wrap view elements that the user can't access.
5
+ # !! Note: this is an *interface*, not *security* feature !!
6
+ # You need to do all access control at the controller level.
7
+ #
8
+ # Example:
9
+ # <%%= if_authorized?(:index, User) do link_to('List all users', users_path) end %> |
10
+ # <%%= if_authorized?(:edit, @user) do link_to('Edit this user', edit_user_path) end %> |
11
+ # <%%= if_authorized?(:destroy, @user) do link_to 'Destroy', @user, :confirm => 'Are you sure?', :method => :delete end %>
12
+ #
13
+ #
14
+ def if_authorized?(action, resource, &block)
15
+ if authorized?(action, resource)
16
+ yield action, resource
17
+ end
18
+ end
19
+
20
+ #
21
+ # Link to user's page ('<%= table_name %>/1')
22
+ #
23
+ # By default, their login is used as link text and link title (tooltip)
24
+ #
25
+ # Takes options
26
+ # * :content_text => 'Content text in place of <%= file_name %>.login', escaped with
27
+ # the standard h() function.
28
+ # * :content_method => :<%= file_name %>_instance_method_to_call_for_content_text
29
+ # * :title_method => :<%= file_name %>_instance_method_to_call_for_title_attribute
30
+ # * as well as link_to()'s standard options
31
+ #
32
+ # Examples:
33
+ # link_to_<%= file_name %> @<%= file_name %>
34
+ # # => <a href="/<%= table_name %>/3" title="barmy">barmy</a>
35
+ #
36
+ # # if you've added a .name attribute:
37
+ # content_tag :span, :class => :vcard do
38
+ # (link_to_<%= file_name %> <%= file_name %>, :class => 'fn n', :title_method => :login, :content_method => :name) +
39
+ # ': ' + (content_tag :span, <%= file_name %>.email, :class => 'email')
40
+ # end
41
+ # # => <span class="vcard"><a href="/<%= table_name %>/3" title="barmy" class="fn n">Cyril Fotheringay-Phipps</a>: <span class="email">barmy@blandings.com</span></span>
42
+ #
43
+ # link_to_<%= file_name %> @<%= file_name %>, :content_text => 'Your user page'
44
+ # # => <a href="/<%= table_name %>/3" title="barmy" class="nickname">Your user page</a>
45
+ #
46
+ def link_to_<%= file_name %>(<%= file_name %>, options={})
47
+ raise "Invalid <%= file_name %>" unless <%= file_name %>
48
+ options.reverse_merge! :content_method => :login, :title_method => :login, :class => :nickname
49
+ content_text = options.delete(:content_text)
50
+ content_text ||= <%= file_name %>.send(options.delete(:content_method))
51
+ options[:title] ||= <%= file_name %>.send(options.delete(:title_method))
52
+ link_to h(content_text), <%= model_controller_routing_name.singularize %>_path(<%= file_name %>), options
53
+ end
54
+
55
+ #
56
+ # Link to login page using remote ip address as link content
57
+ #
58
+ # The :title (and thus, tooltip) is set to the IP address
59
+ #
60
+ # Examples:
61
+ # link_to_login_with_IP
62
+ # # => <a href="/login" title="169.69.69.69">169.69.69.69</a>
63
+ #
64
+ # link_to_login_with_IP :content_text => 'not signed in'
65
+ # # => <a href="/login" title="169.69.69.69">not signed in</a>
66
+ #
67
+ def link_to_login_with_IP content_text=nil, options={}
68
+ ip_addr = request.remote_ip
69
+ content_text ||= ip_addr
70
+ options.reverse_merge! :title => ip_addr
71
+ if tag = options.delete(:tag)
72
+ content_tag tag, h(content_text), options
73
+ else
74
+ link_to h(content_text), login_path, options
75
+ end
76
+ end
77
+
78
+ #
79
+ # Link to the current user's page (using link_to_<%= file_name %>) or to the login page
80
+ # (using link_to_login_with_IP).
81
+ #
82
+ def link_to_current_<%= file_name %>(options={})
83
+ if current_<%= file_name %>
84
+ link_to_<%= file_name %> current_<%= file_name %>, options
85
+ else
86
+ content_text = options.delete(:content_text) || 'not signed in'
87
+ # kill ignored options from link_to_<%= file_name %>
88
+ [:content_method, :title_method].each{|opt| options.delete(opt)}
89
+ link_to_login_with_IP content_text, options
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,157 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ include ApplicationHelper
3
+ include <%= model_controller_class_name %>Helper
4
+
5
+ describe "<%= model_controller_class_name %>Helper.link_to_<%= file_name %>" do
6
+ before do
7
+ @<%= file_name %> = <%= class_name %>.new({
8
+ :name => '<%= class_name %> Name',
9
+ :login => '<%= file_name %>_name',
10
+ })
11
+ @<%= file_name %>.id = 1 # set non-attr_accessible specifically
12
+ end
13
+
14
+ it "should give an error on a nil <%= file_name %>" do
15
+ lambda { link_to_<%= file_name %>(nil) }.should raise_error('Invalid <%= file_name %>')
16
+ end
17
+
18
+ it "should link to the given <%= file_name %>" do
19
+ link_to_<%= file_name %>(@<%= file_name %>).should have_tag("a[href='/<%= table_name %>/1']")
20
+ end
21
+
22
+ it "should use given link text if :content_text is specified" do
23
+ link_to_<%= file_name %>(@<%= file_name %>, :content_text => 'Hello there!').should have_tag("a", 'Hello there!')
24
+ end
25
+
26
+ it "should use the login as link text with no :content_method specified" do
27
+ link_to_<%= file_name %>(@<%= file_name %>).should have_tag("a", '<%= file_name %>_name')
28
+ end
29
+
30
+ it "should use the name as link text with :content_method => :name" do
31
+ link_to_<%= file_name %>(@<%= file_name %>, :content_method => :name).should have_tag("a", '<%= class_name %> Name')
32
+ end
33
+
34
+ it "should use the login as title with no :title_method specified" do
35
+ link_to_<%= file_name %>(@<%= file_name %>).should have_tag("a[title='<%= file_name %>_name']")
36
+ end
37
+
38
+ it "should use the name as link title with :content_method => :name" do
39
+ link_to_<%= file_name %>(@<%= file_name %>, :title_method => :name).should have_tag("a[title='<%= class_name %> Name']")
40
+ end
41
+
42
+ it "should have nickname as a class by default" do
43
+ link_to_<%= file_name %>(@<%= file_name %>).should have_tag("a.nickname")
44
+ end
45
+
46
+ it "should take other classes and no longer have the nickname class" do
47
+ result = link_to_<%= file_name %>(@<%= file_name %>, :class => 'foo bar')
48
+ result.should have_tag("a.foo")
49
+ result.should have_tag("a.bar")
50
+ end
51
+ end
52
+
53
+ describe "<%= model_controller_class_name %>Helper.link_to_signin_with_IP" do
54
+ before do
55
+ end
56
+
57
+ it "should link to the signin_path" do
58
+ link_to_signin_with_IP().should have_tag("a[href='/signin']")
59
+ end
60
+
61
+ it "should use given link text if :content_text is specified" do
62
+ link_to_signin_with_IP(:content_text => 'Hello there!').should have_tag("a", 'Hello there!')
63
+ end
64
+
65
+ it "should use the login as link text with no :content_method specified" do
66
+ link_to_signin_with_IP().should have_tag("a", '0.0.0.0')
67
+ end
68
+
69
+ it "should use the ip address as title" do
70
+ link_to_signin_with_IP().should have_tag("a[title='0.0.0.0']")
71
+ end
72
+
73
+ it "should by default be like school in summer and have no class" do
74
+ link_to_signin_with_IP().should_not have_tag("a.nickname")
75
+ end
76
+
77
+ it "should have some class if you tell it to" do
78
+ result = link_to_signin_with_IP(:class => 'foo bar')
79
+ result.should have_tag("a.foo")
80
+ result.should have_tag("a.bar")
81
+ end
82
+ end
83
+
84
+ describe "<%= model_controller_class_name %>Helper.link_to_current_<%= file_name %>, When logged in" do
85
+ include AuthenticatedTestHelper
86
+ before do
87
+ log_in
88
+ end
89
+
90
+ it "should link to the given <%= file_name %>" do
91
+ link_to_current_<%= file_name %>().should have_tag("a[href='/<%= table_name %>/1']")
92
+ end
93
+
94
+ it "should use given link text if :content_text is specified" do
95
+ link_to_current_<%= file_name %>(:content_text => 'Hello there!').should have_tag("a", 'Hello there!')
96
+ end
97
+
98
+ it "should use the login as link text with no :content_method specified" do
99
+ link_to_current_<%= file_name %>().should have_tag("a", 'quentin')
100
+ end
101
+
102
+ it "should use the name as link text with :content_method => :name" do
103
+ link_to_current_<%= file_name %>(:content_method => :name).should have_tag("a", 'Quentin')
104
+ end
105
+
106
+ it "should use the login as title with no :title_method specified" do
107
+ link_to_current_<%= file_name %>().should have_tag("a[title='quentin']")
108
+ end
109
+
110
+ it "should use the name as link title with :content_method => :name" do
111
+ link_to_current_<%= file_name %>(:title_method => :name).should have_tag("a[title='Quentin']")
112
+ end
113
+
114
+ it "should have nickname as a class" do
115
+ link_to_current_<%= file_name %>().should have_tag("a.nickname")
116
+ end
117
+
118
+ it "should take other classes and no longer have the nickname class" do
119
+ result = link_to_current_<%= file_name %>(:class => 'foo bar')
120
+ result.should have_tag("a.foo")
121
+ result.should have_tag("a.bar")
122
+ end
123
+ end
124
+
125
+
126
+
127
+ describe "<%= model_controller_class_name %>Helper.link_to_current_<%= file_name %>, When logged out" do
128
+ include AuthenticatedTestHelper
129
+ before do
130
+ end
131
+
132
+ it "should link to the signin_path" do
133
+ link_to_current_<%= file_name %>().should have_tag("a[href='/signin']")
134
+ end
135
+
136
+ it "should use given link text if :content_text is specified" do
137
+ link_to_current_<%= file_name %>(:content_text => 'Hello there!').should have_tag("a", 'Hello there!')
138
+ end
139
+
140
+ it "should use the IP address as link text with no :content_method specified" do
141
+ link_to_current_<%= file_name %>().should have_tag("a", '0.0.0.0')
142
+ end
143
+
144
+ it "should use the ip address as title" do
145
+ link_to_current_<%= file_name %>().should have_tag("a[title='0.0.0.0']")
146
+ end
147
+
148
+ it "should by default be like school in summer and have no class" do
149
+ link_to_current_<%= file_name %>().should_not have_tag("a.nickname")
150
+ end
151
+
152
+ it "should have some class if you tell it to" do
153
+ result = link_to_current_<%= file_name %>(:class => 'foo bar')
154
+ result.should have_tag("a.foo")
155
+ result.should have_tag("a.bar")
156
+ end
157
+ end