authlogic 0.10.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of authlogic might be problematic. Click here for more details.

Files changed (111) hide show
  1. data/CHANGELOG.rdoc +11 -0
  2. data/Manifest +18 -81
  3. data/README.rdoc +53 -17
  4. data/Rakefile +1 -1
  5. data/authlogic.gemspec +7 -6
  6. data/lib/authlogic.rb +5 -0
  7. data/lib/authlogic/active_record/acts_as_authentic.rb +90 -58
  8. data/lib/authlogic/active_record/authenticates_many.rb +37 -0
  9. data/lib/authlogic/controller_adapters/abstract_adapter.rb +5 -7
  10. data/lib/authlogic/controller_adapters/merb_adapter.rb +55 -0
  11. data/lib/authlogic/controller_adapters/rails_adapter.rb +21 -15
  12. data/lib/authlogic/session/base.rb +64 -116
  13. data/lib/authlogic/session/callbacks.rb +29 -13
  14. data/lib/authlogic/session/config.rb +5 -1
  15. data/lib/authlogic/session/scopes.rb +101 -0
  16. data/lib/authlogic/version.rb +3 -3
  17. data/test/active_record_acts_as_authentic_test.rb +213 -0
  18. data/test/active_record_authenticates_many_test.rb +28 -0
  19. data/{test_app/test → test}/fixtures/companies.yml +0 -2
  20. data/test/fixtures/employees.yml +17 -0
  21. data/{test_app/test → test}/fixtures/projects.yml +1 -2
  22. data/{test_app/test → test}/fixtures/users.yml +3 -5
  23. data/test/test_helper.rb +142 -0
  24. data/test/user_session_active_record_trickery_test.rb +12 -0
  25. data/test/user_session_base_test.rb +316 -0
  26. data/test/user_session_config_test.rb +144 -0
  27. data/test/user_session_scopes_test.rb +19 -0
  28. data/test_libs/aes128_crypto_provider.rb +17 -0
  29. data/test_libs/mock_controller.rb +19 -0
  30. data/test_libs/mock_cookie_jar.rb +6 -0
  31. data/test_libs/mock_request.rb +5 -0
  32. data/test_libs/ordered_hash.rb +9 -0
  33. metadata +32 -87
  34. data/test_app/README +0 -256
  35. data/test_app/Rakefile +0 -10
  36. data/test_app/app/controllers/application.rb +0 -72
  37. data/test_app/app/controllers/companies_controller.rb +0 -2
  38. data/test_app/app/controllers/user_sessions_controller.rb +0 -25
  39. data/test_app/app/controllers/users_controller.rb +0 -61
  40. data/test_app/app/helpers/application_helper.rb +0 -3
  41. data/test_app/app/helpers/companies_helper.rb +0 -2
  42. data/test_app/app/helpers/user_sessions_helper.rb +0 -2
  43. data/test_app/app/helpers/users_helper.rb +0 -2
  44. data/test_app/app/models/company.rb +0 -4
  45. data/test_app/app/models/project.rb +0 -3
  46. data/test_app/app/models/user.rb +0 -5
  47. data/test_app/app/models/user_session.rb +0 -3
  48. data/test_app/app/views/layouts/application.html.erb +0 -27
  49. data/test_app/app/views/user_sessions/new.html.erb +0 -15
  50. data/test_app/app/views/users/_form.erb +0 -15
  51. data/test_app/app/views/users/edit.html.erb +0 -8
  52. data/test_app/app/views/users/new.html.erb +0 -8
  53. data/test_app/app/views/users/show.html.erb +0 -29
  54. data/test_app/config/boot.rb +0 -109
  55. data/test_app/config/database.yml +0 -19
  56. data/test_app/config/environment.rb +0 -69
  57. data/test_app/config/environments/development.rb +0 -17
  58. data/test_app/config/environments/production.rb +0 -22
  59. data/test_app/config/environments/test.rb +0 -22
  60. data/test_app/config/initializers/inflections.rb +0 -10
  61. data/test_app/config/initializers/mime_types.rb +0 -5
  62. data/test_app/config/initializers/new_rails_defaults.rb +0 -17
  63. data/test_app/config/routes.rb +0 -11
  64. data/test_app/db/development.sqlite3 +0 -0
  65. data/test_app/db/migrate/20081023040052_create_users.rb +0 -20
  66. data/test_app/db/migrate/20081103003828_create_companies.rb +0 -14
  67. data/test_app/db/migrate/20081103003834_create_projects.rb +0 -18
  68. data/test_app/db/schema.rb +0 -46
  69. data/test_app/db/test.sqlite3 +0 -0
  70. data/test_app/doc/README_FOR_APP +0 -2
  71. data/test_app/public/404.html +0 -30
  72. data/test_app/public/422.html +0 -30
  73. data/test_app/public/500.html +0 -30
  74. data/test_app/public/dispatch.cgi +0 -10
  75. data/test_app/public/dispatch.fcgi +0 -24
  76. data/test_app/public/dispatch.rb +0 -10
  77. data/test_app/public/favicon.ico +0 -0
  78. data/test_app/public/images/rails.png +0 -0
  79. data/test_app/public/javascripts/application.js +0 -2
  80. data/test_app/public/javascripts/controls.js +0 -963
  81. data/test_app/public/javascripts/dragdrop.js +0 -972
  82. data/test_app/public/javascripts/effects.js +0 -1120
  83. data/test_app/public/javascripts/prototype.js +0 -4225
  84. data/test_app/public/robots.txt +0 -5
  85. data/test_app/public/stylesheets/scaffold.css +0 -62
  86. data/test_app/script/about +0 -4
  87. data/test_app/script/console +0 -3
  88. data/test_app/script/dbconsole +0 -3
  89. data/test_app/script/destroy +0 -3
  90. data/test_app/script/generate +0 -3
  91. data/test_app/script/performance/benchmarker +0 -3
  92. data/test_app/script/performance/profiler +0 -3
  93. data/test_app/script/performance/request +0 -3
  94. data/test_app/script/plugin +0 -3
  95. data/test_app/script/process/inspector +0 -3
  96. data/test_app/script/process/reaper +0 -3
  97. data/test_app/script/process/spawner +0 -3
  98. data/test_app/script/runner +0 -3
  99. data/test_app/script/server +0 -3
  100. data/test_app/test/functional/companies_controller_test.rb +0 -8
  101. data/test_app/test/functional/user_sessions_controller_test.rb +0 -36
  102. data/test_app/test/functional/users_controller_test.rb +0 -8
  103. data/test_app/test/integration/company_user_session_stories_test.rb +0 -46
  104. data/test_app/test/integration/user_sesion_stories_test.rb +0 -105
  105. data/test_app/test/integration/user_session_config_test.rb +0 -24
  106. data/test_app/test/integration/user_session_test.rb +0 -161
  107. data/test_app/test/test_helper.rb +0 -81
  108. data/test_app/test/unit/account_test.rb +0 -8
  109. data/test_app/test/unit/company_test.rb +0 -8
  110. data/test_app/test/unit/project_test.rb +0 -8
  111. data/test_app/test/unit/user_test.rb +0 -80
@@ -7,7 +7,7 @@ module Authlogic
7
7
  CALLBACKS = %w(before_create after_create before_destroy after_destroy before_save after_save before_update after_update before_validation after_validation)
8
8
 
9
9
  def self.included(base) #:nodoc:
10
- [:destroy, :save, :valid?, :validate_credentials].each do |method|
10
+ [:destroy, :save, :validate].each do |method|
11
11
  base.send :alias_method_chain, method, :callbacks
12
12
  end
13
13
 
@@ -15,41 +15,57 @@ module Authlogic
15
15
  base.define_callbacks *CALLBACKS
16
16
  end
17
17
 
18
- def destroy_with_callbacks # :nodoc:
18
+ # Run the following callbacks:
19
+ #
20
+ # before_destroy
21
+ # destroy
22
+ # after_destroy # only if destroy is successful
23
+ def destroy_with_callbacks
19
24
  run_callbacks(:before_destroy)
20
25
  result = destroy_without_callbacks
21
26
  run_callbacks(:after_destroy) if result
22
27
  result
23
28
  end
24
29
 
25
- def save_with_callbacks # :nodoc:
30
+ # Runs the following callbacks:
31
+ #
32
+ # before_save
33
+ # before_create # only if new_session? == true
34
+ # before_update # only if new_session? == false
35
+ # save
36
+ # # the following are only run is save is successful
37
+ # after_save
38
+ # before_update # only if new_session? == false
39
+ # before_create # only if new_session? == true
40
+ def save_with_callbacks
41
+ run_callbacks(:before_save)
26
42
  if new_session?
27
43
  run_callbacks(:before_create)
28
44
  else
29
45
  run_callbacks(:before_update)
30
46
  end
31
- run_callbacks(:before_save)
32
47
  result = save_without_callbacks
33
48
  if result
49
+ run_callbacks(:after_save)
50
+
34
51
  if new_session?
35
52
  run_callbacks(:after_create)
36
53
  else
37
54
  run_callbacks(:after_update)
38
55
  end
39
- run_callbacks(:after_save)
40
56
  end
41
57
  result
42
58
  end
43
59
 
44
- def valid_with_callbacks?
45
- result = valid_without_callbacks?
46
- run_callbacks(:after_validation) if result
47
- result
48
- end
49
-
50
- def validate_credentials_with_callbacks # :nodoc:
60
+ # Runs the following callbacks:
61
+ #
62
+ # before_validation
63
+ # validate
64
+ # after_validation # only if errors.empty?
65
+ def validate_with_callbacks
51
66
  run_callbacks(:before_validation)
52
- validate_credentials_without_callbacks
67
+ validate_without_callbacks
68
+ run_callbacks(:after_validation) if errors.empty?
53
69
  end
54
70
  end
55
71
  end
@@ -22,6 +22,10 @@ module Authlogic
22
22
  # # ... more configuration
23
23
  # end
24
24
  #
25
+ # You can also access the values in the same fashion:
26
+ #
27
+ # UserSession.authenticate_with
28
+ #
25
29
  # See the methods belows for all configuration options.
26
30
  module ClassMethods
27
31
  # Lets you change which model to use for authentication.
@@ -84,7 +88,7 @@ module Authlogic
84
88
  read_inheritable_attribute(:find_with) || find_with(:session, :cookie, :http_auth)
85
89
  else
86
90
  values.flatten!
87
- write_inheritable_array(:find_with, values)
91
+ write_inheritable_attribute(:find_with, values)
88
92
  end
89
93
  end
90
94
  alias_method :find_with=, :find_with
@@ -0,0 +1,101 @@
1
+ module Authlogic
2
+ module Session
3
+ # = Scopes
4
+ #
5
+ # Authentication can be scoped, but scoping authentication can get a little tricky. Checkout the section "Scoping" in the readme for more details.
6
+ #
7
+ # What with_scopes focuses on is scoping the query when finding the object and the name of the cookie / session. It works very similar to
8
+ # ActiveRecord::Base#with_scopes. It accepts a hash with any of the following options:
9
+ #
10
+ # * <tt>find_options:</tt> any options you can pass into ActiveRecord::Base.find. This is used when trying to find the record.
11
+ # * <tt>id:</tt> The id of the session, this gets merged with the real id. For information ids see the id method.
12
+ #
13
+ # Here is how you use it:
14
+ #
15
+ # UserSession.with_scope(:find_options => {:conditions => "account_id = 2"}, :id => "account_2") do
16
+ # UserSession.find
17
+ # end
18
+ #
19
+ # Eseentially what the above does is scope the searching of the object with the sql you provided. So instead of:
20
+ #
21
+ # User.find(:first, :conditions => "login = 'ben'")
22
+ #
23
+ # it would be:
24
+ #
25
+ # User.find(:first, :conditions => "login = 'ben' and account_id = 2")
26
+ #
27
+ # You will also notice the :id option. This works just like the id method. It scopes your cookies. So the name of your cookie will be:
28
+ #
29
+ # account_2_user_credentials
30
+ #
31
+ # instead of:
32
+ #
33
+ # user_credentials
34
+ #
35
+ # What is also nifty about scoping with an :id is that it merges your id's. So if you do:
36
+ #
37
+ # UserSession.with_scope(:find_options => {:conditions => "account_id = 2"}, :id => "account_2") do
38
+ # session = UserSession.new
39
+ # session.id = :secure
40
+ # end
41
+ #
42
+ # The name of your cookies will be:
43
+ #
44
+ # secure_account_2_user_credentials
45
+ module Scopes # :nodoc:
46
+ def self.included(klass)
47
+ klass.extend(ClassMethods)
48
+ klass.send(:include, InstanceMethods)
49
+ klass.class_eval do
50
+ attr_writer :scope
51
+ alias_method_chain :initialize, :scopes
52
+ alias_method_chain :search_for_record, :scopes
53
+ end
54
+ end
55
+
56
+ # = Scopes
57
+ module ClassMethods
58
+ # The current scope set, should be used in the block passed to with_scope.
59
+ def scope
60
+ scopes[Thread.current]
61
+ end
62
+
63
+ # See the documentation for this class for more information on how to use this method.
64
+ def with_scope(options = {}, &block)
65
+ raise ArgumentError.new("You must provide a block") unless block_given?
66
+ self.scope = options
67
+ result = yield
68
+ self.scope = nil
69
+ result
70
+ end
71
+
72
+ private
73
+ def scope=(value)
74
+ scopes[Thread.current] = value
75
+ end
76
+
77
+ def scopes
78
+ @scopes ||= {}
79
+ end
80
+ end
81
+
82
+ module InstanceMethods
83
+ def initialize_with_scopes(*args) # :nodoc:
84
+ self.scope = self.class.scope
85
+ initialize_without_scopes(*args)
86
+ end
87
+
88
+ # See the documentation for this class for more information on how to use this method.
89
+ def scope
90
+ @scope ||= {}
91
+ end
92
+
93
+ def search_for_record_with_scopes(*args) # :nodoc:
94
+ klass.send(:with_scope, :find => (scope[:find_options] || {})) do
95
+ search_for_record_without_scopes(*args)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -42,9 +42,9 @@ module Authlogic # :nodoc:
42
42
  [@major, @minor, @tiny]
43
43
  end
44
44
 
45
- MAJOR = 0
46
- MINOR = 10
47
- TINY = 4
45
+ MAJOR = 1
46
+ MINOR = 0
47
+ TINY = 0
48
48
 
49
49
  # The current version as a Version instance
50
50
  CURRENT = new(MAJOR, MINOR, TINY)
@@ -0,0 +1,213 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class ActiveRecordActsAsAuthenticTest < ActiveSupport::TestCase
4
+ def test_user_validations
5
+ user = User.new
6
+ assert !user.valid?
7
+ assert user.errors.on(:login)
8
+ assert user.errors.on(:password)
9
+
10
+ user.login = "a"
11
+ assert !user.valid?
12
+ assert user.errors.on(:login)
13
+ assert user.errors.on(:password)
14
+
15
+ user.login = "%ben*"
16
+ assert !user.valid?
17
+ assert user.errors.on(:login)
18
+ assert user.errors.on(:password)
19
+
20
+ user.login = "bjohnson"
21
+ assert !user.valid?
22
+ assert user.errors.on(:login)
23
+ assert user.errors.on(:password)
24
+
25
+ user.login = "my login"
26
+ assert !user.valid?
27
+ assert !user.errors.on(:login)
28
+ assert user.errors.on(:password)
29
+
30
+ user.password = "my pass"
31
+ assert !user.valid?
32
+ assert !user.errors.on(:password)
33
+ assert user.errors.on(:confirm_password)
34
+
35
+ user.confirm_password = "my pizass"
36
+ assert !user.valid?
37
+ assert !user.errors.on(:password)
38
+ assert user.errors.on(:confirm_password)
39
+
40
+ user.confirm_password = "my pass"
41
+ assert user.valid?
42
+ end
43
+
44
+ def test_employee_validations
45
+ employee = Employee.new
46
+ employee.password = "pass"
47
+ employee.confirm_password = "pass"
48
+
49
+ assert !employee.valid?
50
+ assert employee.errors.on(:email)
51
+
52
+ employee.email = "fdsf"
53
+ assert !employee.valid?
54
+ assert employee.errors.on(:email)
55
+
56
+ employee.email = "fake@email.fake"
57
+ assert !employee.valid?
58
+ assert employee.errors.on(:email)
59
+
60
+ employee.email = "notfake@email.com"
61
+ assert employee.valid?
62
+ end
63
+
64
+ def test_named_scopes
65
+ assert_equal 0, User.logged_in.count
66
+ assert_equal User.count, User.logged_out.count
67
+ http_basic_auth_for(users(:ben)) { UserSession.find }
68
+ assert_equal 1, User.logged_in.count
69
+ assert_equal User.count - 1, User.logged_out.count
70
+ end
71
+
72
+ def test_unique_token
73
+ assert_equal 128, User.unique_token.length
74
+ assert_equal 128, Employee.unique_token.length # make sure encryptions use hashes also
75
+
76
+ unique_tokens = []
77
+ 1000.times { unique_tokens << User.unique_token }
78
+ unique_tokens.uniq!
79
+
80
+ assert_equal 1000, unique_tokens.size
81
+ end
82
+
83
+ def test_crypto_provider
84
+ assert_equal Authlogic::Sha512CryptoProvider, User.crypto_provider
85
+ assert_equal AES128CryptoProvider, Employee.crypto_provider
86
+ end
87
+
88
+ def test_forget_all
89
+ http_basic_auth_for(users(:ben)) { UserSession.find }
90
+ http_basic_auth_for(users(:zack)) { UserSession.find(:ziggity_zack) }
91
+ assert UserSession.find
92
+ assert UserSession.find(:ziggity_zack)
93
+ User.forget_all!
94
+ assert !UserSession.find
95
+ assert !UserSession.find(:ziggity_zack)
96
+ end
97
+
98
+ def test_logged_in
99
+ ben = users(:ben)
100
+ assert !ben.logged_in?
101
+ http_basic_auth_for(ben) { UserSession.find }
102
+ assert ben.reload.logged_in?
103
+ end
104
+
105
+ def test_password
106
+ user = User.new
107
+ user.password = "sillywilly"
108
+ assert user.crypted_password
109
+ assert user.password_salt
110
+ assert user.remember_token
111
+ assert_equal true, user.tried_to_set_password
112
+ assert_equal nil, user.password
113
+
114
+ employee = Employee.new
115
+ employee.password = "awesome"
116
+ assert employee.crypted_password
117
+ assert employee.remember_token
118
+ assert_equal true, employee.tried_to_set_password
119
+ assert_equal nil, employee.password
120
+ end
121
+
122
+ def test_valid_password
123
+ ben = users(:ben)
124
+ assert ben.valid_password?("benrocks")
125
+ assert ben.valid_password?(ben.crypted_password)
126
+
127
+ drew = employees(:drew)
128
+ assert drew.valid_password?("drewrocks")
129
+ assert drew.valid_password?(drew.crypted_password)
130
+ end
131
+
132
+ def test_forget
133
+ ben = users(:ben)
134
+ zack = users(:zack)
135
+ http_basic_auth_for(ben) { UserSession.find }
136
+ http_basic_auth_for(zack) { UserSession.find(:ziggity_zack) }
137
+
138
+ assert ben.reload.logged_in?
139
+ assert zack.reload.logged_in?
140
+
141
+ ben.forget!
142
+
143
+ assert !UserSession.find
144
+ assert UserSession.find(:ziggity_zack)
145
+ end
146
+
147
+ def test_reset_password
148
+ ben = users(:ben)
149
+ UserSession.create(ben)
150
+ old_password = ben.crypted_password
151
+ old_salt = ben.password_salt
152
+ old_remember_token = ben.remember_token
153
+ ben.reset_password!
154
+ ben.reload
155
+ assert_not_equal old_password, ben.crypted_password
156
+ assert_not_equal old_salt, ben.password_salt
157
+ assert_not_equal old_remember_token, ben.remember_token
158
+ assert !UserSession.find
159
+ end
160
+
161
+ def test_login_after_create
162
+ assert User.create(:login => "awesome", :password => "saweet", :confirm_password => "saweet")
163
+ assert UserSession.find
164
+ end
165
+
166
+ def test_update_session_after_password_modify
167
+ ben = users(:ben)
168
+ UserSession.create(ben)
169
+ old_session_key = @controller.session["user_credentials"]
170
+ old_cookie_key = @controller.cookies["user_credentials"]
171
+ ben.password = "newpass"
172
+ ben.confirm_password = "newpass"
173
+ ben.save
174
+ assert @controller.session["user_credentials"]
175
+ assert @controller.cookies["user_credentials"]
176
+ assert_not_equal @controller.session["user_credentials"], old_session_key
177
+ assert_not_equal @controller.cookies["user_credentials"], old_cookie_key
178
+ end
179
+
180
+ def test_no_session_update_after_modify
181
+ ben = users(:ben)
182
+ UserSession.create(ben)
183
+ old_session_key = @controller.session["user_credentials"]
184
+ old_cookie_key = @controller.cookies["user_credentials"]
185
+ ben.first_name = "Ben"
186
+ ben.save
187
+ assert_equal @controller.session["user_credentials"], old_session_key
188
+ assert_equal @controller.cookies["user_credentials"], old_cookie_key
189
+ end
190
+
191
+ def test_updating_other_user
192
+ ben = users(:ben)
193
+ UserSession.create(ben)
194
+ old_session_key = @controller.session["user_credentials"]
195
+ old_cookie_key = @controller.cookies["user_credentials"]
196
+ zack = users(:zack)
197
+ zack.password = "newpass"
198
+ zack.confirm_password = "newpass"
199
+ zack.save
200
+ assert_equal @controller.session["user_credentials"], old_session_key
201
+ assert_equal @controller.cookies["user_credentials"], old_cookie_key
202
+ end
203
+
204
+ def test_resetting_password_when_logged_out
205
+ ben = users(:ben)
206
+ assert !UserSession.find
207
+ ben.password = "newpass"
208
+ ben.confirm_password = "newpass"
209
+ ben.save
210
+ assert UserSession.find
211
+ assert_equal ben, UserSession.find.record
212
+ end
213
+ end
@@ -0,0 +1,28 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class ActiveRecordAuthenticatesManyTest < ActiveSupport::TestCase
4
+ def test_authenticates_many_new
5
+ binary_logic = companies(:binary_logic)
6
+ user_session = binary_logic.user_sessions.new
7
+ assert_equal({:find_options => {:conditions => "\"users\".company_id = #{binary_logic.id}"}, :id => nil}, user_session.scope)
8
+
9
+ employee_session = binary_logic.employee_sessions.new
10
+ assert_equal({:find_options => {:conditions => "\"employees\".company_id = #{binary_logic.id}"}, :id => nil}, employee_session.scope)
11
+ end
12
+
13
+ def test_authenticates_many_create_and_find
14
+ binary_logic = companies(:binary_logic)
15
+ logic_over_data = companies(:logic_over_data)
16
+ ben = users(:ben)
17
+ zack = users(:zack)
18
+
19
+ assert !binary_logic.user_sessions.find
20
+ assert !logic_over_data.user_sessions.find
21
+ assert logic_over_data.user_sessions.create(zack)
22
+ assert !binary_logic.user_sessions.find
23
+ assert logic_over_data.user_sessions.find
24
+ assert binary_logic.user_sessions.create(ben)
25
+ assert binary_logic.user_sessions.find
26
+ assert !logic_over_data.user_sessions.find
27
+ end
28
+ end