sparkly-auth 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. data/.document +5 -0
  2. data/.gitignore +25 -0
  3. data/HISTORY.txt +7 -0
  4. data/README.rdoc +127 -1
  5. data/Rakefile +45 -13
  6. data/TODO +4 -0
  7. data/VERSION +1 -1
  8. data/app/controllers/sparkly_accounts_controller.rb +20 -13
  9. data/app/controllers/sparkly_controller.rb +5 -4
  10. data/app/controllers/sparkly_sessions_controller.rb +16 -9
  11. data/app/helpers/sparkly_accounts_helper.rb +2 -0
  12. data/app/helpers/sparkly_helper.rb +2 -0
  13. data/app/helpers/sparkly_sessions_helper.rb +2 -0
  14. data/app/models/remembrance_token.rb +3 -1
  15. data/app/views/sparkly_accounts/_rails2_form.html.erb +24 -0
  16. data/app/views/sparkly_accounts/_rails3_form.html.erb +26 -0
  17. data/app/views/sparkly_accounts/edit.html.erb +5 -23
  18. data/app/views/sparkly_accounts/new.html.erb +4 -23
  19. data/app/views/sparkly_sessions/_rails2_form.html.erb +22 -0
  20. data/app/views/sparkly_sessions/_rails3_form.html.erb +22 -0
  21. data/app/views/sparkly_sessions/new.html.erb +4 -21
  22. data/features/create_sparkly_account.feature +12 -0
  23. data/features/delete_sparkly_account.feature +12 -0
  24. data/features/edit_sparkly_account.feature +54 -0
  25. data/features/lock_abused_sparkly_account.feature +7 -0
  26. data/features/login_sparkly_session.feature +43 -0
  27. data/features/logout_sparkly_session.feature +16 -0
  28. data/features/setup/sparkly.rb +4 -0
  29. data/features/show_sparkly_account.feature +13 -0
  30. data/features/sparkly_session_timeout.feature +6 -0
  31. data/features/step_definitions/account/account_steps.rb +16 -0
  32. data/features/step_definitions/account/brief_steps.rb +9 -0
  33. data/features/step_definitions/debug_steps.rb +3 -0
  34. data/features/step_definitions/email_steps.rb +182 -0
  35. data/features/step_definitions/session/brief_steps.rb +0 -0
  36. data/features/step_definitions/session/logged_in_steps.rb +42 -0
  37. data/features/step_definitions/session/login_steps.rb +37 -0
  38. data/features/step_definitions/session/logout_steps.rb +5 -0
  39. data/features/step_definitions/session_steps.rb +16 -0
  40. data/features/step_definitions/sparkly_auth_steps.rb +0 -0
  41. data/features/step_definitions/web_steps.rb +287 -0
  42. data/features/support/env.rb +10 -0
  43. data/features/support/paths.rb +35 -0
  44. data/features/support/sparkly_helpers.rb +42 -0
  45. data/generators/sparkly/rails2.rb +79 -0
  46. data/generators/sparkly/rails3.rb +89 -0
  47. data/generators/sparkly/sparkly_generator.rb +4 -75
  48. data/generators/sparkly/templates/accounts_controller.rb +14 -13
  49. data/generators/sparkly/templates/accounts_helper.rb +1 -1
  50. data/generators/sparkly/templates/sessions_controller.rb +26 -12
  51. data/generators/sparkly/templates/sessions_helper.rb +1 -1
  52. data/generators/sparkly/templates/views/sparkly_accounts/_rails2_form.html.erb +24 -0
  53. data/generators/sparkly/templates/views/sparkly_accounts/_rails3_form.html.erb +26 -0
  54. data/generators/sparkly/templates/views/sparkly_accounts/edit.html.erb +5 -23
  55. data/generators/sparkly/templates/views/sparkly_accounts/new.html.erb +4 -23
  56. data/generators/sparkly/templates/views/sparkly_sessions/_rails2_form.html.erb +22 -0
  57. data/generators/sparkly/templates/views/sparkly_sessions/_rails3_form.html.erb +22 -0
  58. data/generators/sparkly/templates/views/sparkly_sessions/new.html.erb +4 -21
  59. data/lib/auth.rb +22 -1
  60. data/lib/auth/behavior/base.rb +25 -18
  61. data/lib/auth/behavior/base/configuration.rb +37 -0
  62. data/lib/auth/behavior/core.rb +22 -14
  63. data/lib/auth/behavior/core/authenticated_model_methods.rb +9 -1
  64. data/lib/auth/behavior/core/controller_extensions.rb +2 -2
  65. data/lib/auth/behavior/core/controller_extensions/class_methods.rb +1 -1
  66. data/lib/auth/behavior/core/password_methods.rb +5 -5
  67. data/lib/auth/behavior/remember_me.rb +7 -3
  68. data/lib/auth/behavior/remember_me/configuration.rb +8 -11
  69. data/lib/auth/behavior/remember_me/controller_extensions.rb +1 -1
  70. data/lib/auth/behavior_lookup.rb +4 -4
  71. data/lib/auth/builtin_behaviors.rb +3 -0
  72. data/lib/auth/configuration.rb +71 -25
  73. data/lib/auth/configuration/keys.rb +50 -0
  74. data/lib/auth/engine.rb +33 -0
  75. data/lib/auth/generators/views_generator.rb +13 -4
  76. data/lib/auth/model.rb +52 -22
  77. data/{init.rb → rails/hacks/rails2.rb} +1 -14
  78. data/rails/hacks/rails3.rb +22 -0
  79. data/rails/init.rb +7 -17
  80. data/rails/init_rails2.rb +39 -0
  81. data/rails/init_rails3.rb +2 -0
  82. data/rails/routes_rails3.rb +37 -0
  83. data/rake3 +1 -0
  84. data/rerun.txt +1 -0
  85. data/run_all_tests +1 -0
  86. data/sparkly-auth.gemspec +481 -23
  87. data/spec/behaviors/core/controller_extensions_spec.rb +49 -0
  88. data/spec/{lib/auth/behavior → behaviors}/core_spec.rb +29 -12
  89. data/spec/behaviors/remember_me/configuration_spec.rb +16 -0
  90. data/spec/behaviors/remember_me_spec.rb +167 -0
  91. data/spec/generators/sanity_checks_spec.rb +58 -0
  92. data/spec/lib/auth/configuration_spec.rb +61 -0
  93. data/spec/lib/auth/model_spec.rb +6 -9
  94. data/spec/lib/auth_spec.rb +2 -2
  95. data/spec/lib/hacks/rename_attributes_spec.rb +49 -0
  96. data/spec/routes_spec.rb +8 -2
  97. data/spec/spec2_helper.rb +52 -0
  98. data/spec/spec3_helper.rb +72 -0
  99. data/spec/spec_helper.rb +109 -49
  100. data/spec_env/rails2/README.1ST +23 -0
  101. data/spec_env/rails2/Rakefile +10 -0
  102. data/spec_env/rails2/app/controllers/application_controller.rb +13 -0
  103. data/spec_env/rails2/app/helpers/application_helper.rb +3 -0
  104. data/spec_env/rails2/app/models/user.rb +2 -0
  105. data/spec_env/rails2/app/views/application/not_found.html.erb +9 -0
  106. data/spec_env/rails2/app/views/layouts/application.html.erb +9 -0
  107. data/spec_env/rails2/config/boot.rb +110 -0
  108. data/spec_env/rails2/config/cucumber.yml +7 -0
  109. data/spec_env/rails2/config/database.yml +25 -0
  110. data/spec_env/rails2/config/environment.rb +46 -0
  111. data/spec_env/rails2/config/environments/cucumber.rb +35 -0
  112. data/spec_env/rails2/config/environments/development.rb +17 -0
  113. data/spec_env/rails2/config/environments/production.rb +28 -0
  114. data/spec_env/rails2/config/environments/test.rb +31 -0
  115. data/spec_env/rails2/config/initializers/backtrace_silencers.rb +7 -0
  116. data/spec_env/rails2/config/initializers/inflections.rb +10 -0
  117. data/spec_env/rails2/config/initializers/mime_types.rb +5 -0
  118. data/spec_env/rails2/config/initializers/new_rails_defaults.rb +21 -0
  119. data/spec_env/rails2/config/initializers/session_store.rb +15 -0
  120. data/spec_env/rails2/config/initializers/sparkly_authentication.rb +30 -0
  121. data/spec_env/rails2/config/locales/en.yml +5 -0
  122. data/spec_env/rails2/config/routes.rb +46 -0
  123. data/spec_env/rails2/db/development.sqlite3 +0 -0
  124. data/spec_env/rails2/db/migrate/001_create_sparkly_passwords.rb +19 -0
  125. data/spec_env/rails2/db/migrate/002_create_sparkly_remembered_tokens.rb +15 -0
  126. data/spec_env/rails2/db/migrate/003_add_confirmed_to_sparkly_passwords.rb +9 -0
  127. data/spec_env/rails2/db/migrate/20100607103543_create_users.rb +12 -0
  128. data/spec_env/rails2/db/migrate/20100609152058_add_email_to_users.rb +9 -0
  129. data/spec_env/rails2/db/schema.rb +42 -0
  130. data/spec_env/rails2/db/seeds.rb +7 -0
  131. data/spec_env/rails2/db/test.sqlite3 +0 -0
  132. data/spec_env/rails2/doc/README_FOR_APP +2 -0
  133. data/spec_env/rails2/doc/sparkly_authentication.txt +56 -0
  134. data/spec_env/rails2/features/support/env.rb +58 -0
  135. data/spec_env/rails2/lib/tasks/cucumber.rake +47 -0
  136. data/spec_env/rails2/lib/tasks/rspec.rake +144 -0
  137. data/spec_env/rails2/lib/tasks/sparkly_migration.rb +1 -0
  138. data/spec_env/rails2/log/cucumber.log +8412 -0
  139. data/spec_env/rails2/log/development.log +317 -0
  140. data/spec_env/rails2/log/test.log +32053 -0
  141. data/spec_env/rails2/public/404.html +30 -0
  142. data/spec_env/rails2/public/422.html +30 -0
  143. data/spec_env/rails2/public/500.html +30 -0
  144. data/spec_env/rails2/public/favicon.ico +0 -0
  145. data/spec_env/rails2/public/images/rails.png +0 -0
  146. data/spec_env/rails2/public/javascripts/application.js +2 -0
  147. data/spec_env/rails2/public/javascripts/controls.js +963 -0
  148. data/spec_env/rails2/public/javascripts/dragdrop.js +973 -0
  149. data/spec_env/rails2/public/javascripts/effects.js +1128 -0
  150. data/spec_env/rails2/public/javascripts/prototype.js +4320 -0
  151. data/spec_env/rails2/public/robots.txt +5 -0
  152. data/spec_env/rails2/rerun.txt +1 -0
  153. data/spec_env/rails2/script/about +4 -0
  154. data/spec_env/rails2/script/autospec +6 -0
  155. data/spec_env/rails2/script/console +3 -0
  156. data/spec_env/rails2/script/cucumber +10 -0
  157. data/spec_env/rails2/script/dbconsole +3 -0
  158. data/spec_env/rails2/script/destroy +3 -0
  159. data/spec_env/rails2/script/generate +3 -0
  160. data/spec_env/rails2/script/performance/benchmarker +3 -0
  161. data/spec_env/rails2/script/performance/profiler +3 -0
  162. data/spec_env/rails2/script/plugin +3 -0
  163. data/spec_env/rails2/script/runner +3 -0
  164. data/spec_env/rails2/script/server +3 -0
  165. data/spec_env/rails2/script/spec +10 -0
  166. data/spec_env/rails2/spec/controllers/sparkly_user_sessions_controller_spec.rb +10 -0
  167. data/spec_env/rails2/spec/rcov.opts +2 -0
  168. data/spec_env/rails2/spec/spec.opts +4 -0
  169. data/spec_env/rails2/spec/spec_helper.rb +54 -0
  170. data/spec_env/rails2/test/fixtures/users.yml +7 -0
  171. data/spec_env/rails2/test/performance/browsing_test.rb +9 -0
  172. data/spec_env/rails2/test/test_helper.rb +38 -0
  173. data/spec_env/rails2/test/unit/user_test.rb +8 -0
  174. data/spec_env/rails2/vendor/gems/sparkly-auth-bootstrap-1.0.0/.specification +63 -0
  175. data/spec_env/rails2/vendor/gems/sparkly-auth-bootstrap-1.0.0/generators/sparkly/sparkly_generator.rb +1 -0
  176. data/spec_env/rails2/vendor/gems/sparkly-auth-bootstrap-1.0.0/lib/sparkly-auth-bootstrap.rb +6 -0
  177. data/spec_env/rails2/vendor/gems/sparkly-auth-bootstrap-1.0.0/rails/init.rb +1 -0
  178. data/spec_env/rails2/vendor/gems/sparkly-auth-bootstrap-1.0.0/sparkly-auth-bootstrap.gemspec +55 -0
  179. data/spec_env/rails3/.gitignore +4 -0
  180. data/spec_env/rails3/Gemfile +43 -0
  181. data/spec_env/rails3/Gemfile.lock +124 -0
  182. data/spec_env/rails3/README +256 -0
  183. data/spec_env/rails3/Rakefile +7 -0
  184. data/spec_env/rails3/app/controllers/application_controller.rb +6 -0
  185. data/spec_env/rails3/app/helpers/application_helper.rb +2 -0
  186. data/spec_env/rails3/app/models/user.rb +3 -0
  187. data/spec_env/rails3/app/views/application/not_found.html.erb +9 -0
  188. data/spec_env/rails3/app/views/layouts/application.html.erb +22 -0
  189. data/spec_env/rails3/config.ru +4 -0
  190. data/spec_env/rails3/config/application.rb +47 -0
  191. data/spec_env/rails3/config/boot.rb +13 -0
  192. data/spec_env/rails3/config/cucumber.yml +8 -0
  193. data/spec_env/rails3/config/database.yml +28 -0
  194. data/spec_env/rails3/config/environment.rb +5 -0
  195. data/spec_env/rails3/config/environments/development.rb +22 -0
  196. data/spec_env/rails3/config/environments/production.rb +49 -0
  197. data/spec_env/rails3/config/environments/spec.rb +35 -0
  198. data/spec_env/rails3/config/environments/test.rb +43 -0
  199. data/spec_env/rails3/config/initializers/backtrace_silencers.rb +7 -0
  200. data/spec_env/rails3/config/initializers/inflections.rb +10 -0
  201. data/spec_env/rails3/config/initializers/mime_types.rb +5 -0
  202. data/spec_env/rails3/config/initializers/secret_token.rb +7 -0
  203. data/spec_env/rails3/config/initializers/session_store.rb +8 -0
  204. data/spec_env/rails3/config/initializers/sparkly_authentication.rb +30 -0
  205. data/spec_env/rails3/config/locales/en.yml +5 -0
  206. data/spec_env/rails3/config/routes.rb +61 -0
  207. data/spec_env/rails3/db/migrate/001_create_sparkly_passwords.rb +19 -0
  208. data/spec_env/rails3/db/migrate/002_create_sparkly_remembered_tokens.rb +15 -0
  209. data/spec_env/rails3/db/migrate/20100810132843_create_users.rb +13 -0
  210. data/spec_env/rails3/db/schema.rb +42 -0
  211. data/spec_env/rails3/db/seeds.rb +7 -0
  212. data/spec_env/rails3/doc/README_FOR_APP +2 -0
  213. data/spec_env/rails3/doc/sparkly_authentication.txt +56 -0
  214. data/spec_env/rails3/features/support/env.rb +62 -0
  215. data/spec_env/rails3/lib/sparkly/bootstrap.rb +1 -0
  216. data/spec_env/rails3/lib/tasks/.gitkeep +0 -0
  217. data/spec_env/rails3/lib/tasks/cucumber.rake +53 -0
  218. data/spec_env/rails3/lib/tasks/sparkly_migration.rb +1 -0
  219. data/spec_env/rails3/public/404.html +26 -0
  220. data/spec_env/rails3/public/422.html +26 -0
  221. data/spec_env/rails3/public/500.html +26 -0
  222. data/spec_env/rails3/public/favicon.ico +0 -0
  223. data/spec_env/rails3/public/images/rails.png +0 -0
  224. data/spec_env/rails3/public/javascripts/application.js +2 -0
  225. data/spec_env/rails3/public/javascripts/controls.js +965 -0
  226. data/spec_env/rails3/public/javascripts/dragdrop.js +974 -0
  227. data/spec_env/rails3/public/javascripts/effects.js +1123 -0
  228. data/spec_env/rails3/public/javascripts/prototype.js +6001 -0
  229. data/spec_env/rails3/public/javascripts/rails.js +175 -0
  230. data/spec_env/rails3/public/robots.txt +5 -0
  231. data/spec_env/rails3/public/stylesheets/.gitkeep +0 -0
  232. data/spec_env/rails3/script/cucumber +10 -0
  233. data/spec_env/rails3/script/rails +6 -0
  234. data/spec_env/rails3/test/fixtures/users.yml +7 -0
  235. data/spec_env/rails3/test/performance/browsing_test.rb +9 -0
  236. data/spec_env/rails3/test/test_helper.rb +13 -0
  237. data/spec_env/rails3/test/unit/user_test.rb +8 -0
  238. data/spec_env/rails3/vendor/plugins/.gitkeep +0 -0
  239. data/spec_env/rails3/webrat.log +5 -0
  240. metadata +393 -15
  241. data/dependencies.rb +0 -1
  242. data/spec/lib/auth/behavior/remember_me_spec.rb +0 -127
  243. data/spec/lib/auth/extensions/controller_spec.rb +0 -32
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Auth::Behavior::Core::ControllerExtensions do
4
+ if Rails::VERSION::MAJOR == 2
5
+ subject { ApplicationController.call(Rack::MockRequest.env_for("/").merge('REQUEST_URI' => '')).template.controller }
6
+ elsif Rails::VERSION::MAJOR == 3
7
+ include RSpec::Rails::ControllerExampleGroup
8
+
9
+ # How's this for ANNOYING: at least in its current (admittedly beta) form, RSpec 2 hard codes controller_class to
10
+ # #describes -- which means the setter, self.controller_class=, is useless. Took me much longer than it should
11
+ # have to figure that out.
12
+ def self.controller_class
13
+ ApplicationController
14
+ end
15
+
16
+ subject { controller }
17
+ before(:each) do
18
+ get :not_found
19
+ end
20
+ end
21
+
22
+ configure_auth do |config|
23
+ config.authenticate :user
24
+ config.session_duration = nil
25
+ end
26
+
27
+ before(:each) do
28
+ unless User.count == 1
29
+ u = User.new(:email => "generic4@example.com")
30
+ u.password = u.password_confirmation = "Generic12"
31
+ u.save!
32
+ end
33
+ end
34
+
35
+ it "should let users authenticate with single access token" do
36
+ subject.params = { :single_access_token => User.first.single_access_token }
37
+ subject.current_user.should be_kind_of(User)
38
+ end
39
+
40
+ it "should not raise nil errors when Auth.session_duration is nil" do
41
+ if subject.respond_to?(:session=) # Rails2
42
+ subject.session = { :session_token => User.first.persistence_token }
43
+ else # Rails3
44
+ request.session = { :session_token => User.first.persistence_token }
45
+ end
46
+
47
+ subject.current_user.should be_kind_of(User)
48
+ end
49
+ end
@@ -1,11 +1,16 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Behavior: Core" do
4
- subject { Auth::Model.new(:user, :behaviors => [:core], :password_update_frequency => 30.days) }
5
-
6
- before(:each) do
7
- subject.apply_options!
4
+ configure_auth do |conf|
5
+ conf.authenticate :user
6
+ conf.behaviors = :core
7
+ conf.password_update_frequency = 30.days
8
8
  end
9
+ # subject { Auth::Model.new(:user, :behaviors => [:core], :password_update_frequency => 30.days) }
10
+ #
11
+ # before(:each) do
12
+ # subject.apply_options!
13
+ # end
9
14
 
10
15
  context "user" do
11
16
  it "should not be able to reuse a previous password" do
@@ -50,11 +55,10 @@ describe "Behavior: Core" do
50
55
  password = "Ab12345"
51
56
 
52
57
  User.destroy_all
53
- returning(User.new(:email => email)) { |user|
54
- user.password = password
55
- user.password_confirmation = password
56
- user.save!
57
- }
58
+ user = User.new(:email => email)
59
+ user.password = password
60
+ user.password_confirmation = password
61
+ user.save!
58
62
 
59
63
  User.find_by_email(email).password_matches?(password).should == true
60
64
  end
@@ -135,7 +139,11 @@ describe "Behavior: Core" do
135
139
 
136
140
  pw.secret_confirmation = "Hello1"
137
141
  pw.valid?
138
- pw.errors.on(:secret).should == "doesn't match confirmation"
142
+ if Rails::VERSION::MAJOR == 2
143
+ pw.errors.on(:secret).should == "doesn't match confirmation"
144
+ else
145
+ pw.errors[:secret].should == ["doesn't match confirmation"]
146
+ end
139
147
 
140
148
  pw.secret_confirmation = "Hello12"
141
149
  pw.should be_valid
@@ -150,13 +158,17 @@ describe "Behavior: Core" do
150
158
  end
151
159
 
152
160
  it 'should validate password complexity' do
153
- error_on(Password, :secret, "Ab12345").should == nil
161
+ error_on(Password, :secret, "Ab12345").should be_nil
154
162
  error_on(Password, :secret, "1234567").should ==
155
163
  "must contain at least 1 uppercase, 1 lowercase and 1 number"
156
164
  error_on(Password, :secret, "abcdefg").should ==
157
165
  "must contain at least 1 uppercase, 1 lowercase and 1 number"
158
166
  error_on(Password, :secret, "ABCDEFG").should ==
159
167
  "must contain at least 1 uppercase, 1 lowercase and 1 number"
168
+ error_on(Password, :secret, "a2dfgha").should ==
169
+ "must contain at least 1 uppercase, 1 lowercase and 1 number"
170
+ error_on(Password, :secret, "A2BASDF").should ==
171
+ "must contain at least 1 uppercase, 1 lowercase and 1 number"
160
172
  end
161
173
 
162
174
  it 'should add has_many :passwords to User' do
@@ -171,7 +183,12 @@ describe "Behavior: Core" do
171
183
  end
172
184
 
173
185
  context "with password update frequency 90 days" do
174
- subject { Auth::Model.new(:user, :behaviors => [:core], :password_update_frequency => 90.days) }
186
+ configure_auth do |conf|
187
+ conf.authenticate :user
188
+ conf.behaviors = :core
189
+ conf.password_update_frequency = 90.days
190
+ end
191
+ # subject { Auth::Model.new(:user, :behaviors => [:core], :password_update_frequency => 90.days) }
175
192
 
176
193
  it "should expire passwords after 90 days or if no password is available" do
177
194
  (u = User.new).password_expired?.should be_true # because there're no passwords yet
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Auth::Behavior::RememberMe::Configuration do
4
+ configure_auth do |config|
5
+ config.authenticate :user
6
+ config.behaviors = :core, :remember_me
7
+ end
8
+
9
+ it "should be accessible from a model" do
10
+ User.sparkly_config.remember_me.should be_kind_of(Auth::Behavior::RememberMe::Configuration)
11
+ end
12
+
13
+ it "should be enabled" do
14
+ Auth.remember_me.should be_enabled
15
+ end
16
+ end
@@ -0,0 +1,167 @@
1
+ require 'spec_helper'
2
+
3
+ if RSPEC_VERSION == 1
4
+ require 'spec/rails'
5
+ end
6
+
7
+ describe 'Behavior: Remember Me', :type => :controller do
8
+ if Rails::VERSION::MAJOR == 2
9
+ # nothing, because we overrode self.controller_class
10
+ elsif Rails::VERSION::MAJOR == 3
11
+ include RSpec::Rails::ControllerExampleGroup
12
+ end
13
+
14
+ subject { controller }
15
+
16
+ # How's this for ANNOYING: at least in its current (admittedly beta) form, RSpec 2 hard codes controller_class to
17
+ # #describes -- which means the setter, self.controller_class=, is useless. Took me much longer than it should
18
+ # have to figure that out.
19
+ #
20
+ # Also, RSpec 1 doesn't make it very easy (read: nigh unto impossible) to lazy load the controller class like we
21
+ # need to do -- so it's been overridden here for all versions.
22
+ def self.controller_class
23
+ SparklySessionsController
24
+ end
25
+
26
+ def cookies
27
+ subject.send(:cookies)
28
+ end
29
+
30
+ def reset_auth!
31
+ # the lack of a current user will trigger authentication of various flavors, making these tests possible.
32
+ subject.instance_variable_set("@current_user", nil)
33
+ end
34
+
35
+ configure_auth do |config|
36
+ config.authenticate :user
37
+ config.behaviors = :core, :remember_me
38
+ config.remember_me.duration = 6.months
39
+ end
40
+
41
+ before(:each) do
42
+ u = User.new(:email => "generic12@example.com")
43
+ u.password = u.password_confirmation = "Generic12"
44
+ u.save!
45
+ end
46
+
47
+ context "login" do
48
+ context "with remember_me disabled" do
49
+ before(:each) do
50
+ post :create, { :model => "User", :user => { :email => "generic12@example.com", :password => "Generic12", :remember_me => false } }
51
+ end
52
+
53
+ it("should log in successfully") { subject.current_user.should_not be_nil }
54
+
55
+ it "should not set a remembrance token cookie" do
56
+ session[:session_token].should_not be_blank
57
+ RemembranceToken.count.should == 0
58
+ cookies[:remembrance_token].should be_blank
59
+ end
60
+ end
61
+
62
+ context "with remember_me enabled" do
63
+ before(:each) do
64
+ post :create, { :model => "User", :user => { :email => "generic12@example.com", :password => "Generic12", :remember_me => true } }
65
+ end
66
+
67
+ it("should log in successfully") { subject.current_user.should_not be_nil }
68
+
69
+ it "should set a remembrance token cookie" do
70
+ session[:session_token].should_not be_blank
71
+
72
+ # There should be a token in the remebered_tokens table. We can use that data to decide
73
+ # what should be in the cookie.
74
+ RemembranceToken.count.should == 1
75
+
76
+ # We're looking for a string containing password model ID, series token, and auth token.
77
+ token = RemembranceToken.first
78
+
79
+ cookies[:remembrance_token].should == token.value
80
+ end
81
+ end
82
+ end
83
+
84
+ context "a user with a remember token" do
85
+ before(:each) do
86
+ post :create, { :model => "User", :user => { :email => "generic12@example.com", :password => "Generic12", :remember_me => true } }
87
+ end
88
+
89
+ shared_examples_for "an expired or missing session" do
90
+ it "should authenticate with the auth token cookie" do
91
+ subject.current_user.should_not be_nil
92
+ end
93
+
94
+ it "should generate a new auth token cookie" do
95
+ token = cookies[:remembrance_token]
96
+ subject.current_user
97
+ cookies[:remembrance_token].should_not == token
98
+ end
99
+
100
+ it "should not change the series identifier" do
101
+ subject.current_user
102
+ subject.current_user.remembrance_tokens.first.series_token == @series_identifier
103
+ end
104
+
105
+ context "and an invalid token id but valid series id" do
106
+ before(:each) do
107
+ cookies[:remembrance_token] = { :value => cookies[:remembrance_token]+"1", :expires => 6.months.from_now }
108
+ reset_auth!
109
+ end
110
+
111
+ it "should be considered a theft" do
112
+ # because the token is changed every time - if the wrong token is used it is due either to tampering or to
113
+ # using an expired token, indicating that someone has stolen and used the one-use token.
114
+ subject.current_user
115
+ flash[:error].should == Auth.remember_me.token_theft_message
116
+ end
117
+
118
+ it "should delete all remembrance tokens" do
119
+ subject.current_user.remembrance_tokens.count.should == 0
120
+ end
121
+ end
122
+
123
+ context "and token data is not present" do
124
+ before(:each) do
125
+ cookies[:remembrance_token] = { :value => "", :expires => 6.months.from_now }
126
+ reset_auth!
127
+ end
128
+
129
+ it "should not authenticate the user" do
130
+ subject.current_user.should == false
131
+ end
132
+ end
133
+
134
+ context "and token is missing" do
135
+ before(:each) do
136
+ cookies.delete(:remembrance_token)
137
+ #cookies[:remembrance_token] = nil
138
+ reset_auth!
139
+ end
140
+
141
+ it "should not authenticate the user" do
142
+ subject.current_user.should == false
143
+ end
144
+ end
145
+ end
146
+
147
+ context "and an expired session" do
148
+ before(:each) do
149
+ @series_identifier = subject.current_user.remembrance_tokens.first.series_token
150
+ session[:active_at] = 30.days.ago # i'm pretty sure this is past the session duration.
151
+ reset_auth!
152
+ end
153
+
154
+ it_should_behave_like "an expired or missing session"
155
+ end
156
+
157
+ context "and a missing session" do
158
+ before(:each) do
159
+ @series_identifier = subject.current_user.remembrance_tokens.first.series_token
160
+ session.clear
161
+ reset_auth!
162
+ end
163
+
164
+ it_should_behave_like "an expired or missing session"
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ # Sanity checks that remind me to change a template when I change the corresponding code, or
4
+ # to add a file that I might otherwise forget.
5
+
6
+ describe :sparkly do
7
+ def self.it_should_generate_and_match(to_gen, existing = to_gen)
8
+ it "should generate #{to_gen} which matches #{existing}" do
9
+ existing = File.join(File.dirname(__FILE__), '../../', existing)
10
+ subject.should generate(to_gen) { |content| File.read(existing).strip.should == content.strip }
11
+ end
12
+ end
13
+
14
+ before(:each) do
15
+ Auth.configuration.authenticate(:user,
16
+ :accounts_controller => 'sparkly_accounts',
17
+ :sessions_controller => 'sparkly_sessions')
18
+ Auth.kick!
19
+ end
20
+
21
+ context "sanity checks" do
22
+ with_args "config", '-q' do
23
+ # configs can vary widely but the test here is to verify that the default generated config matches
24
+ # the one we're currently using. That way we can verify that it'll at least work out of the box.
25
+ if Rails::VERSION::MAJOR == 3
26
+ it_should_generate_and_match("config/initializers/sparkly_authentication.rb", "spec_env/rails3/config/initializers/sparkly_authentication.rb")
27
+ else
28
+ it_should_generate_and_match("config/initializers/sparkly_authentication.rb", "spec_env/rails2/config/initializers/sparkly_authentication.rb")
29
+ end
30
+ end
31
+
32
+ context "migrations", '-q' do
33
+ # migrations take care of themselves because I simply add them in place and then regenerate them
34
+ # in the test projects directly.
35
+ end
36
+
37
+ with_args 'views', '-q' do
38
+ base = File.join(Auth.path, "../")
39
+ Dir[File.join(base, "app/views/**/*")].each do |fi|
40
+ if File.file?(fi)
41
+ it_should_generate_and_match(fi.gsub(/^#{Regexp::escape base}/, ''))
42
+ end
43
+ end
44
+ # it_should_generate_and_match('app/views/sparkly_accounts/edit.html.erb')
45
+ # it_should_generate_and_match('app/views/sparkly_accounts/new.html.erb')
46
+ # it_should_generate_and_match('app/views/sparkly_accounts/show.html.erb')
47
+ #
48
+ # it_should_generate_and_match('app/views/sparkly_sessions/new.html.erb')
49
+ end
50
+
51
+ with_args 'controllers', '-q' do
52
+ it_should_generate_and_match('app/controllers/sparkly_accounts_controller.rb')
53
+ it_should_generate_and_match('app/controllers/sparkly_sessions_controller.rb')
54
+ it_should_generate_and_match('app/helpers/sparkly_accounts_helper.rb')
55
+ it_should_generate_and_match('app/helpers/sparkly_sessions_helper.rb')
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,61 @@
1
+ # The majority of the configuration object is transient and is tested between auth_spec and the behaviors.
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Auth::Configuration do
6
+ it "should have #configuration_keys" do
7
+ subject.configuration_keys.should_not be_empty
8
+ end
9
+
10
+ context "given a single behavior" do
11
+ before(:each) { subject.behaviors = :core }
12
+
13
+ it "should return an array" do
14
+ subject.behaviors.should == [:core]
15
+ end
16
+ end
17
+
18
+ context "with an authenticated model" do
19
+ before(:each) { subject.authenticate :user }
20
+
21
+ it "should have a password update frequency option" do
22
+ subject.authenticated_models.first.options.keys.should include(:password_update_frequency)
23
+ end
24
+
25
+ it "should use the default password frequency in the model options" do
26
+ subject.authenticated_models.first.options[:password_update_frequency].should == 30.days
27
+ end
28
+
29
+ context "and a single behavior" do
30
+ before(:each) { subject.behavior = :core }
31
+
32
+ it "should return an array" do
33
+ subject.authenticated_models.first.behaviors.should == [:core]
34
+ end
35
+ end
36
+
37
+ context "and two behaviors" do
38
+ before(:each) { subject.behaviors = :core, :remember_me }
39
+
40
+ it "should use both behaviors in the authenticated model" do
41
+ subject.authenticated_models.first.behaviors.should == [:core, :remember_me]
42
+ end
43
+ end
44
+
45
+ context "and a password update frequency" do
46
+ before(:each) { subject.password_update_frequency = 60.days }
47
+
48
+ it "should use the high level password frequency in the model options (because it lacks an overriding setting)" do
49
+ subject.authenticated_models.first.options[:password_update_frequency].should == 60.days
50
+ end
51
+
52
+ context "followed by an overridden password update frequency" do
53
+ before(:each) { subject.password_update_frequency = 90.days }
54
+
55
+ it "should use the most recent level password frequency in the model options (because it lacks an overriding setting)" do
56
+ subject.authenticated_models.first.options[:password_update_frequency].should == 90.days
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Auth::Model do
4
4
  context "given nonexisting model name" do
5
- subject { Auth::Model.new(:nonexisting_user) }
5
+ subject { Auth::Model.new(:nonexisting_user, :behaviors => [:core]) }
6
6
 
7
7
  it "should fail silently during initialization because it might not have been generated yet" do
8
8
  proc { subject }.should_not raise_error
@@ -10,11 +10,10 @@ describe Auth::Model do
10
10
  end
11
11
 
12
12
  context "with default options" do
13
- subject { Auth::Model.new(:user) }
13
+ subject { Auth::Model.new(:user, :behaviors => [:core]) }
14
14
 
15
15
  before(:each) do
16
- Dispatcher.cleanup_application
17
- Dispatcher.reload_application
16
+ reload!
18
17
  subject.apply_options!
19
18
  end
20
19
 
@@ -30,23 +29,21 @@ describe Auth::Model do
30
29
  context "with an empty :behaviors option" do
31
30
  subject { Auth::Model.new(:user, :behaviors => []) }
32
31
  before(:each) do
33
- Dispatcher.cleanup_application
34
- Dispatcher.reload_application
32
+ reload!
35
33
  subject.apply_options!
36
34
  end
37
35
  it "should have no behaviors" do subject.behaviors.should be_empty end
38
36
  end
39
37
 
40
38
  context "with a hash for :with option" do
41
- subject { Auth::Model.new(:user, :with => {
39
+ subject { Auth::Model.new(:user, :behaviors => [:core], :with => {
42
40
  :secret => :passwd,
43
41
  :format => /^.{8}$/,
44
42
  :message => "must be exactly 8 characters"
45
43
  })}
46
44
 
47
45
  before(:each) do
48
- Dispatcher.cleanup_application
49
- Dispatcher.reload_application
46
+ reload!
50
47
  subject.apply_options!
51
48
  end
52
49