caleb-restful-authentication 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/CHANGELOG +68 -0
  2. data/README.textile +240 -0
  3. data/Rakefile +32 -0
  4. data/TODO +15 -0
  5. data/generators/authenticated/USAGE +1 -0
  6. data/generators/authenticated/authenticated_generator.rb +508 -0
  7. data/generators/authenticated/lib/insert_routes.rb +54 -0
  8. data/generators/authenticated/templates/_model_partial.html.erb +8 -0
  9. data/generators/authenticated/templates/activation.erb +3 -0
  10. data/generators/authenticated/templates/authenticated_system.rb +189 -0
  11. data/generators/authenticated/templates/authenticated_test_helper.rb +22 -0
  12. data/generators/authenticated/templates/controller.rb +43 -0
  13. data/generators/authenticated/templates/helper.rb +2 -0
  14. data/generators/authenticated/templates/login.html.erb +21 -0
  15. data/generators/authenticated/templates/mailer.rb +33 -0
  16. data/generators/authenticated/templates/migration.rb +29 -0
  17. data/generators/authenticated/templates/model.rb +101 -0
  18. data/generators/authenticated/templates/model_controller.rb +117 -0
  19. data/generators/authenticated/templates/model_helper.rb +93 -0
  20. data/generators/authenticated/templates/model_helper_spec.rb +158 -0
  21. data/generators/authenticated/templates/observer.rb +14 -0
  22. data/generators/authenticated/templates/signup.html.erb +21 -0
  23. data/generators/authenticated/templates/signup_notification.erb +8 -0
  24. data/generators/authenticated/templates/site_keys.rb +38 -0
  25. data/generators/authenticated/templates/spec/controllers/access_control_spec.rb +90 -0
  26. data/generators/authenticated/templates/spec/controllers/authenticated_system_spec.rb +102 -0
  27. data/generators/authenticated/templates/spec/controllers/sessions_controller_spec.rb +139 -0
  28. data/generators/authenticated/templates/spec/controllers/users_controller_spec.rb +200 -0
  29. data/generators/authenticated/templates/spec/fixtures/users.yml +66 -0
  30. data/generators/authenticated/templates/spec/helpers/users_helper_spec.rb +141 -0
  31. data/generators/authenticated/templates/spec/models/user_spec.rb +295 -0
  32. data/generators/authenticated/templates/stories/rest_auth_stories.rb +22 -0
  33. data/generators/authenticated/templates/stories/rest_auth_stories_helper.rb +81 -0
  34. data/generators/authenticated/templates/stories/steps/ra_navigation_steps.rb +49 -0
  35. data/generators/authenticated/templates/stories/steps/ra_resource_steps.rb +179 -0
  36. data/generators/authenticated/templates/stories/steps/ra_response_steps.rb +171 -0
  37. data/generators/authenticated/templates/stories/steps/user_steps.rb +153 -0
  38. data/generators/authenticated/templates/stories/users/accounts.story +194 -0
  39. data/generators/authenticated/templates/stories/users/sessions.story +134 -0
  40. data/generators/authenticated/templates/test/functional_test.rb +82 -0
  41. data/generators/authenticated/templates/test/mailer_test.rb +31 -0
  42. data/generators/authenticated/templates/test/model_functional_test.rb +95 -0
  43. data/generators/authenticated/templates/test/unit_test.rb +166 -0
  44. data/init.rb +1 -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 +63 -0
  51. data/lib/trustification.rb +14 -0
  52. data/lib/trustification/email_validation.rb +20 -0
  53. data/rails/init.rb +6 -0
  54. metadata +115 -0
@@ -0,0 +1,82 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require '<%= controller_file_name %>_controller'
3
+
4
+ # Re-raise errors caught by the controller.
5
+ class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end
6
+
7
+ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
8
+ # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead
9
+ # Then, you can remove it from this and the units test.
10
+ include AuthenticatedTestHelper
11
+
12
+ fixtures :<%= table_name %>
13
+
14
+ def test_should_login_and_redirect
15
+ post :create, :<%= options[:login_field_name] -%> => 'quentin<%= "@example.com" if options[:email_as_login] -%>', :password => 'monkey'
16
+ assert session[:<%= file_name %>_id]
17
+ assert_response :redirect
18
+ end
19
+
20
+ def test_should_fail_login_and_not_redirect
21
+ post :create, :<%= options[:login_field_name] -%> => 'quentin<%= "@example.com" if options[:email_as_login] -%>', :password => 'bad password'
22
+ assert_nil session[:<%= file_name %>_id]
23
+ assert_response :success
24
+ end
25
+
26
+ def test_should_logout
27
+ login_as :quentin
28
+ get :destroy
29
+ assert_nil session[:<%= file_name %>_id]
30
+ assert_response :redirect
31
+ end
32
+
33
+ def test_should_remember_me
34
+ @request.cookies["auth_token"] = nil
35
+ post :create, :<%= options[:login_field_name] -%> => 'quentin<%= "@example.com" if options[:email_as_login] -%>', :password => 'monkey', :remember_me => "1"
36
+ assert_not_nil @response.cookies["auth_token"]
37
+ end
38
+
39
+ def test_should_not_remember_me
40
+ @request.cookies["auth_token"] = nil
41
+ post :create, :<%= options[:login_field_name] -%> => 'quentin<%= "@example.com" if options[:email_as_login] -%>', :password => 'monkey', :remember_me => "0"
42
+ puts @response.cookies["auth_token"]
43
+ assert @response.cookies["auth_token"].blank?
44
+ end
45
+
46
+ def test_should_delete_token_on_logout
47
+ login_as :quentin
48
+ get :destroy
49
+ assert @response.cookies["auth_token"].blank?
50
+ end
51
+
52
+ def test_should_login_with_cookie
53
+ <%= table_name %>(:quentin).remember_me
54
+ @request.cookies["auth_token"] = cookie_for(:quentin)
55
+ get :new
56
+ assert @controller.send(:logged_in?)
57
+ end
58
+
59
+ def test_should_fail_expired_cookie_login
60
+ <%= table_name %>(:quentin).remember_me
61
+ <%= table_name %>(:quentin).update_attribute :remember_token_expires_at, 5.minutes.ago
62
+ @request.cookies["auth_token"] = cookie_for(:quentin)
63
+ get :new
64
+ assert !@controller.send(:logged_in?)
65
+ end
66
+
67
+ def test_should_fail_cookie_login
68
+ <%= table_name %>(:quentin).remember_me
69
+ @request.cookies["auth_token"] = auth_token('invalid_auth_token')
70
+ get :new
71
+ assert !@controller.send(:logged_in?)
72
+ end
73
+
74
+ protected
75
+ def auth_token(token)
76
+ CGI::Cookie.new('name' => 'auth_token', 'value' => token)
77
+ end
78
+
79
+ def cookie_for(<%= file_name %>)
80
+ auth_token <%= table_name %>(<%= file_name %>).remember_token
81
+ end
82
+ end
@@ -0,0 +1,31 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require '<%= file_name %>_mailer'
3
+
4
+ class <%= class_name %>MailerTest < Test::Unit::TestCase
5
+ FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures'
6
+ CHARSET = "utf-8"
7
+
8
+ include ActionMailer::Quoting
9
+
10
+ def setup
11
+ ActionMailer::Base.delivery_method = :test
12
+ ActionMailer::Base.perform_deliveries = true
13
+ ActionMailer::Base.deliveries = []
14
+
15
+ @expected = TMail::Mail.new
16
+ @expected.set_content_type "text", "plain", { "charset" => CHARSET }
17
+ end
18
+
19
+ def test_dummy_test
20
+ #do nothing
21
+ end
22
+
23
+ private
24
+ def read_fixture(action)
25
+ IO.readlines("#{FIXTURES_PATH}/<%= file_name %>_mailer/#{action}")
26
+ end
27
+
28
+ def encode(subject)
29
+ quoted_printable(subject, CHARSET)
30
+ end
31
+ end
@@ -0,0 +1,95 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require '<%= model_controller_file_name %>_controller'
3
+
4
+ # Re-raise errors caught by the controller.
5
+ class <%= model_controller_class_name %>Controller; def rescue_action(e) raise e end; end
6
+
7
+ class <%= model_controller_class_name %>ControllerTest < ActionController::TestCase
8
+ # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead
9
+ # Then, you can remove it from this and the units test.
10
+ include AuthenticatedTestHelper
11
+
12
+ fixtures :<%= table_name %>
13
+
14
+ def test_should_allow_signup
15
+ assert_difference '<%= class_name %>.count' do
16
+ create_<%= file_name %>
17
+ assert_response :redirect
18
+ end
19
+ end
20
+
21
+ <% unless options[:email_as_login] -%>
22
+ def test_should_require_login_on_signup
23
+ assert_no_difference '<%= class_name %>.count' do
24
+ create_<%= file_name %>(:login => nil)
25
+ assert assigns(:<%= file_name %>).errors.on(:login)
26
+ assert_response :success
27
+ end
28
+ end
29
+ <% end -%>
30
+
31
+ def test_should_require_password_on_signup
32
+ assert_no_difference '<%= class_name %>.count' do
33
+ create_<%= file_name %>(:password => nil)
34
+ assert assigns(:<%= file_name %>).errors.on(:password)
35
+ assert_response :success
36
+ end
37
+ end
38
+
39
+ def test_should_require_password_confirmation_on_signup
40
+ assert_no_difference '<%= class_name %>.count' do
41
+ create_<%= file_name %>(:password_confirmation => nil)
42
+ assert assigns(:<%= file_name %>).errors.on(:password_confirmation)
43
+ assert_response :success
44
+ end
45
+ end
46
+
47
+ def test_should_require_email_on_signup
48
+ assert_no_difference '<%= class_name %>.count' do
49
+ create_<%= file_name %>(:email => nil)
50
+ assert assigns(:<%= file_name %>).errors.on(:email)
51
+ assert_response :success
52
+ end
53
+ end
54
+ <% if options[:stateful] %>
55
+ def test_should_sign_up_user_in_pending_state
56
+ create_<%= file_name %>
57
+ assigns(:<%= file_name %>).reload
58
+ assert assigns(:<%= file_name %>).pending?
59
+ end<% end %>
60
+
61
+ <% if options[:include_activation] %>
62
+ def test_should_sign_up_user_with_activation_code
63
+ create_<%= file_name %>
64
+ assigns(:<%= file_name %>).reload
65
+ assert_not_nil assigns(:<%= file_name %>).activation_code
66
+ end
67
+
68
+ def test_should_activate_user
69
+ assert_nil <%= class_name %>.authenticate('aaron<%= "@example.com" if options[:email_as_login] -%>', 'test')
70
+ get :activate, :activation_code => <%= table_name %>(:aaron).activation_code
71
+ assert_redirected_to '/<%= controller_routing_path %>/new'
72
+ assert_not_nil flash[:notice]
73
+ assert_equal <%= table_name %>(:aaron), <%= class_name %>.authenticate('aaron<%= "@example.com" if options[:email_as_login] -%>', 'monkey')
74
+ end
75
+
76
+ def test_should_not_activate_user_without_key
77
+ get :activate
78
+ assert_nil flash[:notice]
79
+ rescue ActionController::RoutingError
80
+ # in the event your routes deny this, we'll just bow out gracefully.
81
+ end
82
+
83
+ def test_should_not_activate_user_with_blank_key
84
+ get :activate, :activation_code => ''
85
+ assert_nil flash[:notice]
86
+ rescue ActionController::RoutingError
87
+ # well played, sir
88
+ end<% end %>
89
+
90
+ protected
91
+ def create_<%= file_name %>(options = {})
92
+ post :create, :<%= file_name %> => { <% unless options[:email_as_login] -%>:login => 'quire', <% end -%>:email => 'quire@example.com',
93
+ :password => 'quire69', :password_confirmation => 'quire69' }.merge(options)
94
+ end
95
+ end
@@ -0,0 +1,166 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class <%= class_name %>Test < ActiveSupport::TestCase
4
+ # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead.
5
+ # Then, you can remove it from this and the functional test.
6
+ include AuthenticatedTestHelper
7
+ fixtures :<%= table_name %>
8
+
9
+ def test_should_create_<%= file_name %>
10
+ assert_difference '<%= class_name %>.count' do
11
+ <%= file_name %> = create_<%= file_name %>
12
+ assert !<%= file_name %>.new_record?, "#{<%= file_name %>.errors.full_messages.to_sentence}"
13
+ end
14
+ end
15
+ <% if options[:include_activation] %>
16
+ def test_should_initialize_activation_code_upon_creation
17
+ <%= file_name %> = create_<%= file_name %>
18
+ <%= file_name %>.reload
19
+ assert_not_nil <%= file_name %>.activation_code
20
+ end
21
+ <% end %><% if options[:stateful] %>
22
+ def test_should_create_and_start_in_pending_state
23
+ <%= file_name %> = create_<%= file_name %>
24
+ <%= file_name %>.reload
25
+ assert <%= file_name %>.pending?
26
+ end
27
+
28
+ <% end %>
29
+ <% unless options[:email_as_login] -%>
30
+ def test_should_require_login
31
+ assert_no_difference '<%= class_name %>.count' do
32
+ u = create_<%= file_name %>(:login => nil)
33
+ assert u.errors.on(:login)
34
+ end
35
+ end
36
+ <% end -%>
37
+
38
+ def test_should_require_password
39
+ assert_no_difference '<%= class_name %>.count' do
40
+ u = create_<%= file_name %>(:password => nil)
41
+ assert u.errors.on(:password)
42
+ end
43
+ end
44
+
45
+ def test_should_require_password_confirmation
46
+ assert_no_difference '<%= class_name %>.count' do
47
+ u = create_<%= file_name %>(:password_confirmation => nil)
48
+ assert u.errors.on(:password_confirmation)
49
+ end
50
+ end
51
+
52
+ def test_should_require_email
53
+ assert_no_difference '<%= class_name %>.count' do
54
+ u = create_<%= file_name %>(:email => nil)
55
+ assert u.errors.on(:email)
56
+ end
57
+ end
58
+
59
+ def test_should_reset_password
60
+ <%= table_name %>(:quentin).update_attributes(:password => 'new password', :password_confirmation => 'new password')
61
+ assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin<%= "@example.com" if options[:email_as_login] -%>', 'new password')
62
+ end
63
+
64
+ def test_should_not_rehash_password
65
+ <%= table_name %>(:quentin).update_attributes(:<%= options[:login_field_name] -%> => 'quentin2')
66
+ assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin2<%= "@example.com" if options[:email_as_login] -%>', 'monkey')
67
+ end
68
+
69
+ def test_should_authenticate_<%= file_name %>
70
+ assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin<%= "@example.com" if options[:email_as_login] -%>', 'monkey')
71
+ end
72
+
73
+ def test_should_set_remember_token
74
+ <%= table_name %>(:quentin).remember_me
75
+ assert_not_nil <%= table_name %>(:quentin).remember_token
76
+ assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at
77
+ end
78
+
79
+ def test_should_unset_remember_token
80
+ <%= table_name %>(:quentin).remember_me
81
+ assert_not_nil <%= table_name %>(:quentin).remember_token
82
+ <%= table_name %>(:quentin).forget_me
83
+ assert_nil <%= table_name %>(:quentin).remember_token
84
+ end
85
+
86
+ def test_should_remember_me_for_one_week
87
+ before = 1.week.from_now.utc
88
+ <%= table_name %>(:quentin).remember_me_for 1.week
89
+ after = 1.week.from_now.utc
90
+ assert_not_nil <%= table_name %>(:quentin).remember_token
91
+ assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at
92
+ assert <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after)
93
+ end
94
+
95
+ def test_should_remember_me_until_one_week
96
+ time = 1.week.from_now.utc
97
+ <%= table_name %>(:quentin).remember_me_until time
98
+ assert_not_nil <%= table_name %>(:quentin).remember_token
99
+ assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at
100
+ assert_equal <%= table_name %>(:quentin).remember_token_expires_at, time
101
+ end
102
+
103
+ def test_should_remember_me_default_two_weeks
104
+ before = 2.weeks.from_now.utc
105
+ <%= table_name %>(:quentin).remember_me
106
+ after = 2.weeks.from_now.utc
107
+ assert_not_nil <%= table_name %>(:quentin).remember_token
108
+ assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at
109
+ assert <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after)
110
+ end
111
+ <% if options[:stateful] %>
112
+ def test_should_register_passive_<%= file_name %>
113
+ <%= file_name %> = create_<%= file_name %>(:password => nil, :password_confirmation => nil)
114
+ assert <%= file_name %>.passive?
115
+ <%= file_name %>.update_attributes(:password => 'new password', :password_confirmation => 'new password')
116
+ <%= file_name %>.register!
117
+ assert <%= file_name %>.pending?
118
+ end
119
+
120
+ def test_should_suspend_<%= file_name %>
121
+ <%= table_name %>(:quentin).suspend!
122
+ assert <%= table_name %>(:quentin).suspended?
123
+ end
124
+
125
+ def test_suspended_<%= file_name %>_should_not_authenticate
126
+ <%= table_name %>(:quentin).suspend!
127
+ assert_not_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin<%= "@example.com" if options[:email_as_login] -%>', 'test')
128
+ end
129
+
130
+ def test_should_unsuspend_<%= file_name %>_to_active_state
131
+ <%= table_name %>(:quentin).suspend!
132
+ assert <%= table_name %>(:quentin).suspended?
133
+ <%= table_name %>(:quentin).unsuspend!
134
+ assert <%= table_name %>(:quentin).active?
135
+ end
136
+
137
+ def test_should_unsuspend_<%= file_name %>_with_nil_activation_code_and_activated_at_to_passive_state
138
+ <%= table_name %>(:quentin).suspend!
139
+ <%= class_name %>.update_all :activation_code => nil, :activated_at => nil
140
+ assert <%= table_name %>(:quentin).suspended?
141
+ <%= table_name %>(:quentin).reload.unsuspend!
142
+ assert <%= table_name %>(:quentin).passive?
143
+ end
144
+
145
+ def test_should_unsuspend_<%= file_name %>_with_activation_code_and_nil_activated_at_to_pending_state
146
+ <%= table_name %>(:quentin).suspend!
147
+ <%= class_name %>.update_all :activation_code => 'foo-bar', :activated_at => nil
148
+ assert <%= table_name %>(:quentin).suspended?
149
+ <%= table_name %>(:quentin).reload.unsuspend!
150
+ assert <%= table_name %>(:quentin).pending?
151
+ end
152
+
153
+ def test_should_delete_<%= file_name %>
154
+ assert_nil <%= table_name %>(:quentin).deleted_at
155
+ <%= table_name %>(:quentin).delete!
156
+ assert_not_nil <%= table_name %>(:quentin).deleted_at
157
+ assert <%= table_name %>(:quentin).deleted?
158
+ end
159
+ <% end %>
160
+ protected
161
+ def create_<%= file_name %>(options = {})
162
+ record = <%= class_name %>.new({ <% unless options[:email_as_login] -%>:login => 'quire', <% end -%>:email => 'quire@example.com', :password => 'quire69', :password_confirmation => 'quire69' }.merge(options))
163
+ record.<% if options[:stateful] %>register! if record.valid?<% else %>save<% end %>
164
+ record
165
+ end
166
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), "rails", "init")
@@ -0,0 +1,40 @@
1
+ module Authentication
2
+ mattr_accessor :login_regex, :bad_login_message,
3
+ :name_regex, :bad_name_message,
4
+ :email_name_regex, :domain_head_regex, :domain_tld_regex, :email_regex, :bad_email_message
5
+
6
+ self.login_regex = /\A\w[\w\.\-_@]+\z/ # ASCII, strict
7
+ # self.login_regex = /\A[[:alnum:]][[:alnum:]\.\-_@]+\z/ # Unicode, strict
8
+ # self.login_regex = /\A[^[:cntrl:]\\<>\/&]*\z/ # Unicode, permissive
9
+
10
+ self.bad_login_message = "use only letters, numbers, and .-_@ please.".freeze
11
+
12
+ self.name_regex = /\A[^[:cntrl:]\\<>\/&]*\z/ # Unicode, permissive
13
+ self.bad_name_message = "avoid non-printing characters and \\&gt;&lt;&amp;/ please.".freeze
14
+
15
+ self.email_name_regex = '[\w\.%\+\-]+'.freeze
16
+ self.domain_head_regex = '(?:[A-Z0-9\-]+\.)+'.freeze
17
+ self.domain_tld_regex = '(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|jobs|museum)'.freeze
18
+ self.email_regex = /\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i
19
+ self.bad_email_message = "should look like an email address.".freeze
20
+
21
+ def self.included(recipient)
22
+ recipient.extend(ModelClassMethods)
23
+ recipient.class_eval do
24
+ include ModelInstanceMethods
25
+ end
26
+ end
27
+
28
+ module ModelClassMethods
29
+ def secure_digest(*args)
30
+ Digest::SHA1.hexdigest(args.flatten.join('--'))
31
+ end
32
+
33
+ def make_token
34
+ secure_digest(Time.now, (1..10).map{ rand.to_s })
35
+ end
36
+ end # class methods
37
+
38
+ module ModelInstanceMethods
39
+ end # instance methods
40
+ end
@@ -0,0 +1,82 @@
1
+ # -*- coding: mule-utf-8 -*-
2
+ module Authentication
3
+ module ByCookieToken
4
+ # Stuff directives into including module
5
+ def self.included(recipient)
6
+ recipient.extend(ModelClassMethods)
7
+ recipient.class_eval do
8
+ include ModelInstanceMethods
9
+ end
10
+ end
11
+
12
+ #
13
+ # Class Methods
14
+ #
15
+ module ModelClassMethods
16
+ end # class methods
17
+
18
+ #
19
+ # Instance Methods
20
+ #
21
+ module ModelInstanceMethods
22
+ def remember_token?
23
+ (!remember_token.blank?) &&
24
+ remember_token_expires_at && (Time.now.utc < remember_token_expires_at.utc)
25
+ end
26
+
27
+ # These create and unset the fields required for remembering users between browser closes
28
+ def remember_me
29
+ remember_me_for 2.weeks
30
+ end
31
+
32
+ def remember_me_for(time)
33
+ remember_me_until time.from_now.utc
34
+ end
35
+
36
+ def remember_me_until(time)
37
+ self.remember_token_expires_at = time
38
+ self.remember_token = self.class.make_token
39
+ save(false)
40
+ end
41
+
42
+ # refresh token (keeping same expires_at) if it exists
43
+ def refresh_token
44
+ if remember_token?
45
+ self.remember_token = self.class.make_token
46
+ save(false)
47
+ end
48
+ end
49
+
50
+ #
51
+ # Deletes the server-side record of the authentication token. The
52
+ # client-side (browser cookie) and server-side (this remember_token) must
53
+ # always be deleted together.
54
+ #
55
+ def forget_me
56
+ self.remember_token_expires_at = nil
57
+ self.remember_token = nil
58
+ save(false)
59
+ end
60
+ end # instance methods
61
+ end
62
+
63
+ module ByCookieTokenController
64
+ # Stuff directives into including module
65
+ def self.included( recipient )
66
+ recipient.extend( ControllerClassMethods )
67
+ recipient.class_eval do
68
+ include ControllerInstanceMethods
69
+ end
70
+ end
71
+
72
+ #
73
+ # Class Methods
74
+ #
75
+ module ControllerClassMethods
76
+ end # class methods
77
+
78
+ module ControllerInstanceMethods
79
+ end # instance methods
80
+ end
81
+ end
82
+