ggoodale-restful-authentication 1.1.1
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.
- data/CHANGELOG +68 -0
- data/README.textile +224 -0
- data/Rakefile +32 -0
- data/TODO +15 -0
- data/generators/authenticated/USAGE +1 -0
- data/generators/authenticated/authenticated_generator.rb +478 -0
- data/generators/authenticated/lib/insert_routes.rb +54 -0
- data/generators/authenticated/templates/_model_partial.html.erb +8 -0
- data/generators/authenticated/templates/activation.erb +3 -0
- data/generators/authenticated/templates/authenticated_system.rb +189 -0
- data/generators/authenticated/templates/authenticated_test_helper.rb +22 -0
- data/generators/authenticated/templates/controller.rb +43 -0
- data/generators/authenticated/templates/helper.rb +2 -0
- data/generators/authenticated/templates/login.html.erb +16 -0
- data/generators/authenticated/templates/mailer.rb +25 -0
- data/generators/authenticated/templates/migration.rb +26 -0
- data/generators/authenticated/templates/model.rb +83 -0
- data/generators/authenticated/templates/model_controller.rb +85 -0
- data/generators/authenticated/templates/model_helper.rb +93 -0
- data/generators/authenticated/templates/model_helper_spec.rb +158 -0
- data/generators/authenticated/templates/observer.rb +11 -0
- data/generators/authenticated/templates/signup.html.erb +19 -0
- data/generators/authenticated/templates/signup_notification.erb +8 -0
- data/generators/authenticated/templates/site_keys.rb +38 -0
- data/generators/authenticated/templates/spec/controllers/access_control_spec.rb +90 -0
- data/generators/authenticated/templates/spec/controllers/authenticated_system_spec.rb +102 -0
- data/generators/authenticated/templates/spec/controllers/sessions_controller_spec.rb +139 -0
- data/generators/authenticated/templates/spec/controllers/users_controller_spec.rb +198 -0
- data/generators/authenticated/templates/spec/fixtures/users.yml +60 -0
- data/generators/authenticated/templates/spec/helpers/users_helper_spec.rb +141 -0
- data/generators/authenticated/templates/spec/models/user_spec.rb +290 -0
- data/generators/authenticated/templates/stories/rest_auth_stories.rb +22 -0
- data/generators/authenticated/templates/stories/rest_auth_stories_helper.rb +81 -0
- data/generators/authenticated/templates/stories/steps/ra_navigation_steps.rb +49 -0
- data/generators/authenticated/templates/stories/steps/ra_resource_steps.rb +179 -0
- data/generators/authenticated/templates/stories/steps/ra_response_steps.rb +171 -0
- data/generators/authenticated/templates/stories/steps/user_steps.rb +153 -0
- data/generators/authenticated/templates/stories/users/accounts.story +186 -0
- data/generators/authenticated/templates/stories/users/sessions.story +134 -0
- data/generators/authenticated/templates/test/functional_test.rb +82 -0
- data/generators/authenticated/templates/test/mailer_test.rb +31 -0
- data/generators/authenticated/templates/test/model_functional_test.rb +93 -0
- data/generators/authenticated/templates/test/unit_test.rb +164 -0
- data/init.rb +1 -0
- data/lib/authentication.rb +40 -0
- data/lib/authentication/by_cookie_token.rb +82 -0
- data/lib/authentication/by_password.rb +64 -0
- data/lib/authorization.rb +14 -0
- data/lib/authorization/aasm_roles.rb +63 -0
- data/lib/authorization/stateful_roles.rb +62 -0
- data/lib/trustification.rb +14 -0
- data/lib/trustification/email_validation.rb +20 -0
- data/rails/init.rb +3 -0
- 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, :login => 'quentin', :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, :login => 'quentin', :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, :login => 'quentin', :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, :login => 'quentin', :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,93 @@
|
|
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
|
+
def test_should_require_login_on_signup
|
22
|
+
assert_no_difference '<%= class_name %>.count' do
|
23
|
+
create_<%= file_name %>(:login => nil)
|
24
|
+
assert assigns(:<%= file_name %>).errors.on(:login)
|
25
|
+
assert_response :success
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_should_require_password_on_signup
|
30
|
+
assert_no_difference '<%= class_name %>.count' do
|
31
|
+
create_<%= file_name %>(:password => nil)
|
32
|
+
assert assigns(:<%= file_name %>).errors.on(:password)
|
33
|
+
assert_response :success
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_should_require_password_confirmation_on_signup
|
38
|
+
assert_no_difference '<%= class_name %>.count' do
|
39
|
+
create_<%= file_name %>(:password_confirmation => nil)
|
40
|
+
assert assigns(:<%= file_name %>).errors.on(:password_confirmation)
|
41
|
+
assert_response :success
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_should_require_email_on_signup
|
46
|
+
assert_no_difference '<%= class_name %>.count' do
|
47
|
+
create_<%= file_name %>(:email => nil)
|
48
|
+
assert assigns(:<%= file_name %>).errors.on(:email)
|
49
|
+
assert_response :success
|
50
|
+
end
|
51
|
+
end
|
52
|
+
<% if options[:stateful] %>
|
53
|
+
def test_should_sign_up_user_in_pending_state
|
54
|
+
create_<%= file_name %>
|
55
|
+
assigns(:<%= file_name %>).reload
|
56
|
+
assert assigns(:<%= file_name %>).pending?
|
57
|
+
end<% end %>
|
58
|
+
|
59
|
+
<% if options[:include_activation] %>
|
60
|
+
def test_should_sign_up_user_with_activation_code
|
61
|
+
create_<%= file_name %>
|
62
|
+
assigns(:<%= file_name %>).reload
|
63
|
+
assert_not_nil assigns(:<%= file_name %>).activation_code
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_should_activate_user
|
67
|
+
assert_nil <%= class_name %>.authenticate('aaron', 'test')
|
68
|
+
get :activate, :activation_code => <%= table_name %>(:aaron).activation_code
|
69
|
+
assert_redirected_to '/<%= controller_routing_path %>/new'
|
70
|
+
assert_not_nil flash[:notice]
|
71
|
+
assert_equal <%= table_name %>(:aaron), <%= class_name %>.authenticate('aaron', 'monkey')
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_should_not_activate_user_without_key
|
75
|
+
get :activate
|
76
|
+
assert_nil flash[:notice]
|
77
|
+
rescue ActionController::RoutingError
|
78
|
+
# in the event your routes deny this, we'll just bow out gracefully.
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_should_not_activate_user_with_blank_key
|
82
|
+
get :activate, :activation_code => ''
|
83
|
+
assert_nil flash[:notice]
|
84
|
+
rescue ActionController::RoutingError
|
85
|
+
# well played, sir
|
86
|
+
end<% end %>
|
87
|
+
|
88
|
+
protected
|
89
|
+
def create_<%= file_name %>(options = {})
|
90
|
+
post :create, :<%= file_name %> => { :login => 'quire', :email => 'quire@example.com',
|
91
|
+
:password => 'quire69', :password_confirmation => 'quire69' }.merge(options)
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,164 @@
|
|
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
|
+
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.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 \\><&/ 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
|
+
|