jcnetdev-restful-authentication 1.0.20080704

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. data/CHANGELOG +68 -0
  2. data/README +176 -0
  3. data/Rakefile +22 -0
  4. data/TODO +15 -0
  5. data/generators/authenticated/USAGE +1 -0
  6. data/generators/authenticated/authenticated_generator.rb +478 -0
  7. data/generators/authenticated/lib/insert_routes.rb +50 -0
  8. data/generators/authenticated/templates/_model_partial.html.erb +8 -0
  9. data/generators/authenticated/templates/activation.html.erb +3 -0
  10. data/generators/authenticated/templates/authenticated_system.rb +187 -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 +16 -0
  15. data/generators/authenticated/templates/mailer.rb +25 -0
  16. data/generators/authenticated/templates/migration.rb +26 -0
  17. data/generators/authenticated/templates/model.rb +69 -0
  18. data/generators/authenticated/templates/model_controller.rb +86 -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 +11 -0
  22. data/generators/authenticated/templates/signup.html.erb +19 -0
  23. data/generators/authenticated/templates/signup_notification.html.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 +101 -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 +198 -0
  29. data/generators/authenticated/templates/spec/fixtures/users.yml +60 -0
  30. data/generators/authenticated/templates/spec/helpers/users_helper_spec.rb +141 -0
  31. data/generators/authenticated/templates/spec/models/user_spec.rb +290 -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 +186 -0
  39. data/generators/authenticated/templates/stories/users/sessions.story +134 -0
  40. data/generators/authenticated/templates/test/functional_test.rb +88 -0
  41. data/generators/authenticated/templates/test/mailer_test.rb +31 -0
  42. data/generators/authenticated/templates/test/model_functional_test.rb +99 -0
  43. data/generators/authenticated/templates/test/unit_test.rb +164 -0
  44. data/init.rb +1 -0
  45. data/lib/authentication.rb +43 -0
  46. data/lib/authentication/by_cookie_token.rb +85 -0
  47. data/lib/authentication/by_password.rb +65 -0
  48. data/lib/authorization.rb +15 -0
  49. data/lib/authorization/aasm_roles.rb +64 -0
  50. data/lib/authorization/stateful_roles.rb +63 -0
  51. data/lib/trustification.rb +15 -0
  52. data/lib/trustification/email_validation.rb +20 -0
  53. data/rails/init.rb +3 -0
  54. data/restful-authentication.gemspec +74 -0
  55. metadata +116 -0
@@ -0,0 +1,88 @@
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 < Test::Unit::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 setup
15
+ @controller = <%= controller_class_name %>Controller.new
16
+ @request = ActionController::TestRequest.new
17
+ @response = ActionController::TestResponse.new
18
+ end
19
+
20
+ def test_should_login_and_redirect
21
+ post :create, :login => 'quentin', :password => 'monkey'
22
+ assert session[:<%= file_name %>_id]
23
+ assert_response :redirect
24
+ end
25
+
26
+ def test_should_fail_login_and_not_redirect
27
+ post :create, :login => 'quentin', :password => 'bad password'
28
+ assert_nil session[:<%= file_name %>_id]
29
+ assert_response :success
30
+ end
31
+
32
+ def test_should_logout
33
+ login_as :quentin
34
+ get :destroy
35
+ assert_nil session[:<%= file_name %>_id]
36
+ assert_response :redirect
37
+ end
38
+
39
+ def test_should_remember_me
40
+ @request.cookies["auth_token"] = nil
41
+ post :create, :login => 'quentin', :password => 'monkey', :remember_me => "1"
42
+ assert_not_nil @response.cookies["auth_token"]
43
+ end
44
+
45
+ def test_should_not_remember_me
46
+ @request.cookies["auth_token"] = nil
47
+ post :create, :login => 'quentin', :password => 'monkey', :remember_me => "0"
48
+ puts @response.cookies["auth_token"]
49
+ assert @response.cookies["auth_token"].blank?
50
+ end
51
+
52
+ def test_should_delete_token_on_logout
53
+ login_as :quentin
54
+ get :destroy
55
+ assert @response.cookies["auth_token"].blank?
56
+ end
57
+
58
+ def test_should_login_with_cookie
59
+ <%= table_name %>(:quentin).remember_me
60
+ @request.cookies["auth_token"] = cookie_for(:quentin)
61
+ get :new
62
+ assert @controller.send(:logged_in?)
63
+ end
64
+
65
+ def test_should_fail_expired_cookie_login
66
+ <%= table_name %>(:quentin).remember_me
67
+ <%= table_name %>(:quentin).update_attribute :remember_token_expires_at, 5.minutes.ago
68
+ @request.cookies["auth_token"] = cookie_for(:quentin)
69
+ get :new
70
+ assert !@controller.send(:logged_in?)
71
+ end
72
+
73
+ def test_should_fail_cookie_login
74
+ <%= table_name %>(:quentin).remember_me
75
+ @request.cookies["auth_token"] = auth_token('invalid_auth_token')
76
+ get :new
77
+ assert !@controller.send(:logged_in?)
78
+ end
79
+
80
+ protected
81
+ def auth_token(token)
82
+ CGI::Cookie.new('name' => 'auth_token', 'value' => token)
83
+ end
84
+
85
+ def cookie_for(<%= file_name %>)
86
+ auth_token <%= table_name %>(<%= file_name %>).remember_token
87
+ end
88
+ 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,99 @@
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 < Test::Unit::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 setup
15
+ @controller = <%= model_controller_class_name %>Controller.new
16
+ @request = ActionController::TestRequest.new
17
+ @response = ActionController::TestResponse.new
18
+ end
19
+
20
+ def test_should_allow_signup
21
+ assert_difference '<%= class_name %>.count' do
22
+ create_<%= file_name %>
23
+ assert_response :redirect
24
+ end
25
+ end
26
+
27
+ def test_should_require_login_on_signup
28
+ assert_no_difference '<%= class_name %>.count' do
29
+ create_<%= file_name %>(:login => nil)
30
+ assert assigns(:<%= file_name %>).errors.on(:login)
31
+ assert_response :success
32
+ end
33
+ end
34
+
35
+ def test_should_require_password_on_signup
36
+ assert_no_difference '<%= class_name %>.count' do
37
+ create_<%= file_name %>(:password => nil)
38
+ assert assigns(:<%= file_name %>).errors.on(:password)
39
+ assert_response :success
40
+ end
41
+ end
42
+
43
+ def test_should_require_password_confirmation_on_signup
44
+ assert_no_difference '<%= class_name %>.count' do
45
+ create_<%= file_name %>(:password_confirmation => nil)
46
+ assert assigns(:<%= file_name %>).errors.on(:password_confirmation)
47
+ assert_response :success
48
+ end
49
+ end
50
+
51
+ def test_should_require_email_on_signup
52
+ assert_no_difference '<%= class_name %>.count' do
53
+ create_<%= file_name %>(:email => nil)
54
+ assert assigns(:<%= file_name %>).errors.on(:email)
55
+ assert_response :success
56
+ end
57
+ end
58
+ <% if options[:stateful] %>
59
+ def test_should_sign_up_user_in_pending_state
60
+ create_<%= file_name %>
61
+ assigns(:<%= file_name %>).reload
62
+ assert assigns(:<%= file_name %>).pending?
63
+ end<% end %>
64
+
65
+ <% if options[:include_activation] %>
66
+ def test_should_sign_up_user_with_activation_code
67
+ create_<%= file_name %>
68
+ assigns(:<%= file_name %>).reload
69
+ assert_not_nil assigns(:<%= file_name %>).activation_code
70
+ end
71
+
72
+ def test_should_activate_user
73
+ assert_nil <%= class_name %>.authenticate('aaron', 'test')
74
+ get :activate, :activation_code => <%= table_name %>(:aaron).activation_code
75
+ assert_redirected_to '/<%= controller_routing_path %>/new'
76
+ assert_not_nil flash[:notice]
77
+ assert_equal <%= table_name %>(:aaron), <%= class_name %>.authenticate('aaron', 'monkey')
78
+ end
79
+
80
+ def test_should_not_activate_user_without_key
81
+ get :activate
82
+ assert_nil flash[:notice]
83
+ rescue ActionController::RoutingError
84
+ # in the event your routes deny this, we'll just bow out gracefully.
85
+ end
86
+
87
+ def test_should_not_activate_user_with_blank_key
88
+ get :activate, :activation_code => ''
89
+ assert_nil flash[:notice]
90
+ rescue ActionController::RoutingError
91
+ # well played, sir
92
+ end<% end %>
93
+
94
+ protected
95
+ def create_<%= file_name %>(options = {})
96
+ post :create, :<%= file_name %> => { :login => 'quire', :email => 'quire@example.com',
97
+ :password => 'quire69', :password_confirmation => 'quire69' }.merge(options)
98
+ end
99
+ end
@@ -0,0 +1,164 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class <%= class_name %>Test < Test::Unit::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
+ def test_should_require_login
30
+ assert_no_difference '<%= class_name %>.count' do
31
+ u = create_<%= file_name %>(:login => nil)
32
+ assert u.errors.on(:login)
33
+ end
34
+ end
35
+
36
+ def test_should_require_password
37
+ assert_no_difference '<%= class_name %>.count' do
38
+ u = create_<%= file_name %>(:password => nil)
39
+ assert u.errors.on(:password)
40
+ end
41
+ end
42
+
43
+ def test_should_require_password_confirmation
44
+ assert_no_difference '<%= class_name %>.count' do
45
+ u = create_<%= file_name %>(:password_confirmation => nil)
46
+ assert u.errors.on(:password_confirmation)
47
+ end
48
+ end
49
+
50
+ def test_should_require_email
51
+ assert_no_difference '<%= class_name %>.count' do
52
+ u = create_<%= file_name %>(:email => nil)
53
+ assert u.errors.on(:email)
54
+ end
55
+ end
56
+
57
+ def test_should_reset_password
58
+ <%= table_name %>(:quentin).update_attributes(:password => 'new password', :password_confirmation => 'new password')
59
+ assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin', 'new password')
60
+ end
61
+
62
+ def test_should_not_rehash_password
63
+ <%= table_name %>(:quentin).update_attributes(:login => 'quentin2')
64
+ assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin2', 'monkey')
65
+ end
66
+
67
+ def test_should_authenticate_<%= file_name %>
68
+ assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin', 'monkey')
69
+ end
70
+
71
+ def test_should_set_remember_token
72
+ <%= table_name %>(:quentin).remember_me
73
+ assert_not_nil <%= table_name %>(:quentin).remember_token
74
+ assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at
75
+ end
76
+
77
+ def test_should_unset_remember_token
78
+ <%= table_name %>(:quentin).remember_me
79
+ assert_not_nil <%= table_name %>(:quentin).remember_token
80
+ <%= table_name %>(:quentin).forget_me
81
+ assert_nil <%= table_name %>(:quentin).remember_token
82
+ end
83
+
84
+ def test_should_remember_me_for_one_week
85
+ before = 1.week.from_now.utc
86
+ <%= table_name %>(:quentin).remember_me_for 1.week
87
+ after = 1.week.from_now.utc
88
+ assert_not_nil <%= table_name %>(:quentin).remember_token
89
+ assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at
90
+ assert <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after)
91
+ end
92
+
93
+ def test_should_remember_me_until_one_week
94
+ time = 1.week.from_now.utc
95
+ <%= table_name %>(:quentin).remember_me_until time
96
+ assert_not_nil <%= table_name %>(:quentin).remember_token
97
+ assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at
98
+ assert_equal <%= table_name %>(:quentin).remember_token_expires_at, time
99
+ end
100
+
101
+ def test_should_remember_me_default_two_weeks
102
+ before = 2.weeks.from_now.utc
103
+ <%= table_name %>(:quentin).remember_me
104
+ after = 2.weeks.from_now.utc
105
+ assert_not_nil <%= table_name %>(:quentin).remember_token
106
+ assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at
107
+ assert <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after)
108
+ end
109
+ <% if options[:stateful] %>
110
+ def test_should_register_passive_<%= file_name %>
111
+ <%= file_name %> = create_<%= file_name %>(:password => nil, :password_confirmation => nil)
112
+ assert <%= file_name %>.passive?
113
+ <%= file_name %>.update_attributes(:password => 'new password', :password_confirmation => 'new password')
114
+ <%= file_name %>.register!
115
+ assert <%= file_name %>.pending?
116
+ end
117
+
118
+ def test_should_suspend_<%= file_name %>
119
+ <%= table_name %>(:quentin).suspend!
120
+ assert <%= table_name %>(:quentin).suspended?
121
+ end
122
+
123
+ def test_suspended_<%= file_name %>_should_not_authenticate
124
+ <%= table_name %>(:quentin).suspend!
125
+ assert_not_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin', 'test')
126
+ end
127
+
128
+ def test_should_unsuspend_<%= file_name %>_to_active_state
129
+ <%= table_name %>(:quentin).suspend!
130
+ assert <%= table_name %>(:quentin).suspended?
131
+ <%= table_name %>(:quentin).unsuspend!
132
+ assert <%= table_name %>(:quentin).active?
133
+ end
134
+
135
+ def test_should_unsuspend_<%= file_name %>_with_nil_activation_code_and_activated_at_to_passive_state
136
+ <%= table_name %>(:quentin).suspend!
137
+ <%= class_name %>.update_all :activation_code => nil, :activated_at => nil
138
+ assert <%= table_name %>(:quentin).suspended?
139
+ <%= table_name %>(:quentin).reload.unsuspend!
140
+ assert <%= table_name %>(:quentin).passive?
141
+ end
142
+
143
+ def test_should_unsuspend_<%= file_name %>_with_activation_code_and_nil_activated_at_to_pending_state
144
+ <%= table_name %>(:quentin).suspend!
145
+ <%= class_name %>.update_all :activation_code => 'foo-bar', :activated_at => nil
146
+ assert <%= table_name %>(:quentin).suspended?
147
+ <%= table_name %>(:quentin).reload.unsuspend!
148
+ assert <%= table_name %>(:quentin).pending?
149
+ end
150
+
151
+ def test_should_delete_<%= file_name %>
152
+ assert_nil <%= table_name %>(:quentin).deleted_at
153
+ <%= table_name %>(:quentin).delete!
154
+ assert_not_nil <%= table_name %>(:quentin).deleted_at
155
+ assert <%= table_name %>(:quentin).deleted?
156
+ end
157
+ <% end %>
158
+ protected
159
+ def create_<%= file_name %>(options = {})
160
+ record = <%= class_name %>.new({ :login => 'quire', :email => 'quire@example.com', :password => 'quire69', :password_confirmation => 'quire69' }.merge(options))
161
+ record.<% if options[:stateful] %>register! if record.valid?<% else %>save<% end %>
162
+ record
163
+ end
164
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + "/rails/init"
@@ -0,0 +1,43 @@
1
+ module Authentication
2
+ unless defined? CONSTANTS_DEFINED
3
+ # Uncomment to suit
4
+ RE_LOGIN_OK = /\A\w[\w\.\-_@]+\z/ # ASCII, strict
5
+ # RE_LOGIN_OK = /\A[[:alnum:]][[:alnum:]\.\-_@]+\z/ # Unicode, strict
6
+ # RE_LOGIN_OK = /\A[^[:cntrl:]\\<>\/&]*\z/ # Unicode, permissive
7
+ MSG_LOGIN_BAD = "use only letters, numbers, and .-_@ please."
8
+
9
+ RE_NAME_OK = /\A[^[:cntrl:]\\<>\/&]*\z/ # Unicode, permissive
10
+ MSG_NAME_BAD = "avoid non-printing characters and \\&gt;&lt;&amp;/ please."
11
+
12
+ # This is purposefully imperfect -- it's just a check for bogus input. See
13
+ # http://www.regular-expressions.info/email.html
14
+ RE_EMAIL_NAME = '[\w\.%\+\-]+' # what you actually see in practice
15
+ #RE_EMAIL_NAME = '0-9A-Z!#\$%\&\'\*\+_/=\?^\-`\{|\}~\.' # technically allowed by RFC-2822
16
+ RE_DOMAIN_HEAD = '(?:[A-Z0-9\-]+\.)+'
17
+ RE_DOMAIN_TLD = '(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)'
18
+ RE_EMAIL_OK = /\A#{RE_EMAIL_NAME}@#{RE_DOMAIN_HEAD}#{RE_DOMAIN_TLD}\z/i
19
+ MSG_EMAIL_BAD = "should look like an email address."
20
+
21
+ CONSTANTS_DEFINED = 'yup' # sorry for the C idiom
22
+ end
23
+
24
+ def self.included( recipient )
25
+ recipient.extend( ModelClassMethods )
26
+ recipient.class_eval do
27
+ include ModelInstanceMethods
28
+ end
29
+ end
30
+
31
+ module ModelClassMethods
32
+ def secure_digest(*args)
33
+ Digest::SHA1.hexdigest(args.flatten.join('--'))
34
+ end
35
+ def make_token
36
+ secure_digest(Time.now, (1..10).map{ rand.to_s })
37
+ end
38
+ end # class methods
39
+
40
+ module ModelInstanceMethods
41
+ end # instance methods
42
+
43
+ end
@@ -0,0 +1,85 @@
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
+
64
+ #
65
+ #
66
+ module ByCookieTokenController
67
+ # Stuff directives into including module
68
+ def self.included( recipient )
69
+ recipient.extend( ControllerClassMethods )
70
+ recipient.class_eval do
71
+ include ControllerInstanceMethods
72
+ end
73
+ end
74
+
75
+ #
76
+ # Class Methods
77
+ #
78
+ module ControllerClassMethods
79
+ end # class methods
80
+
81
+ module ControllerInstanceMethods
82
+ end # instance methods
83
+ end
84
+ end
85
+