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.
- data/.document +5 -0
- data/.gitignore +25 -0
- data/HISTORY.txt +7 -0
- data/README.rdoc +127 -1
- data/Rakefile +45 -13
- data/TODO +4 -0
- data/VERSION +1 -1
- data/app/controllers/sparkly_accounts_controller.rb +20 -13
- data/app/controllers/sparkly_controller.rb +5 -4
- data/app/controllers/sparkly_sessions_controller.rb +16 -9
- data/app/helpers/sparkly_accounts_helper.rb +2 -0
- data/app/helpers/sparkly_helper.rb +2 -0
- data/app/helpers/sparkly_sessions_helper.rb +2 -0
- data/app/models/remembrance_token.rb +3 -1
- data/app/views/sparkly_accounts/_rails2_form.html.erb +24 -0
- data/app/views/sparkly_accounts/_rails3_form.html.erb +26 -0
- data/app/views/sparkly_accounts/edit.html.erb +5 -23
- data/app/views/sparkly_accounts/new.html.erb +4 -23
- data/app/views/sparkly_sessions/_rails2_form.html.erb +22 -0
- data/app/views/sparkly_sessions/_rails3_form.html.erb +22 -0
- data/app/views/sparkly_sessions/new.html.erb +4 -21
- data/features/create_sparkly_account.feature +12 -0
- data/features/delete_sparkly_account.feature +12 -0
- data/features/edit_sparkly_account.feature +54 -0
- data/features/lock_abused_sparkly_account.feature +7 -0
- data/features/login_sparkly_session.feature +43 -0
- data/features/logout_sparkly_session.feature +16 -0
- data/features/setup/sparkly.rb +4 -0
- data/features/show_sparkly_account.feature +13 -0
- data/features/sparkly_session_timeout.feature +6 -0
- data/features/step_definitions/account/account_steps.rb +16 -0
- data/features/step_definitions/account/brief_steps.rb +9 -0
- data/features/step_definitions/debug_steps.rb +3 -0
- data/features/step_definitions/email_steps.rb +182 -0
- data/features/step_definitions/session/brief_steps.rb +0 -0
- data/features/step_definitions/session/logged_in_steps.rb +42 -0
- data/features/step_definitions/session/login_steps.rb +37 -0
- data/features/step_definitions/session/logout_steps.rb +5 -0
- data/features/step_definitions/session_steps.rb +16 -0
- data/features/step_definitions/sparkly_auth_steps.rb +0 -0
- data/features/step_definitions/web_steps.rb +287 -0
- data/features/support/env.rb +10 -0
- data/features/support/paths.rb +35 -0
- data/features/support/sparkly_helpers.rb +42 -0
- data/generators/sparkly/rails2.rb +79 -0
- data/generators/sparkly/rails3.rb +89 -0
- data/generators/sparkly/sparkly_generator.rb +4 -75
- data/generators/sparkly/templates/accounts_controller.rb +14 -13
- data/generators/sparkly/templates/accounts_helper.rb +1 -1
- data/generators/sparkly/templates/sessions_controller.rb +26 -12
- data/generators/sparkly/templates/sessions_helper.rb +1 -1
- data/generators/sparkly/templates/views/sparkly_accounts/_rails2_form.html.erb +24 -0
- data/generators/sparkly/templates/views/sparkly_accounts/_rails3_form.html.erb +26 -0
- data/generators/sparkly/templates/views/sparkly_accounts/edit.html.erb +5 -23
- data/generators/sparkly/templates/views/sparkly_accounts/new.html.erb +4 -23
- data/generators/sparkly/templates/views/sparkly_sessions/_rails2_form.html.erb +22 -0
- data/generators/sparkly/templates/views/sparkly_sessions/_rails3_form.html.erb +22 -0
- data/generators/sparkly/templates/views/sparkly_sessions/new.html.erb +4 -21
- data/lib/auth.rb +22 -1
- data/lib/auth/behavior/base.rb +25 -18
- data/lib/auth/behavior/base/configuration.rb +37 -0
- data/lib/auth/behavior/core.rb +22 -14
- data/lib/auth/behavior/core/authenticated_model_methods.rb +9 -1
- data/lib/auth/behavior/core/controller_extensions.rb +2 -2
- data/lib/auth/behavior/core/controller_extensions/class_methods.rb +1 -1
- data/lib/auth/behavior/core/password_methods.rb +5 -5
- data/lib/auth/behavior/remember_me.rb +7 -3
- data/lib/auth/behavior/remember_me/configuration.rb +8 -11
- data/lib/auth/behavior/remember_me/controller_extensions.rb +1 -1
- data/lib/auth/behavior_lookup.rb +4 -4
- data/lib/auth/builtin_behaviors.rb +3 -0
- data/lib/auth/configuration.rb +71 -25
- data/lib/auth/configuration/keys.rb +50 -0
- data/lib/auth/engine.rb +33 -0
- data/lib/auth/generators/views_generator.rb +13 -4
- data/lib/auth/model.rb +52 -22
- data/{init.rb → rails/hacks/rails2.rb} +1 -14
- data/rails/hacks/rails3.rb +22 -0
- data/rails/init.rb +7 -17
- data/rails/init_rails2.rb +39 -0
- data/rails/init_rails3.rb +2 -0
- data/rails/routes_rails3.rb +37 -0
- data/rake3 +1 -0
- data/rerun.txt +1 -0
- data/run_all_tests +1 -0
- data/sparkly-auth.gemspec +481 -23
- data/spec/behaviors/core/controller_extensions_spec.rb +49 -0
- data/spec/{lib/auth/behavior → behaviors}/core_spec.rb +29 -12
- data/spec/behaviors/remember_me/configuration_spec.rb +16 -0
- data/spec/behaviors/remember_me_spec.rb +167 -0
- data/spec/generators/sanity_checks_spec.rb +58 -0
- data/spec/lib/auth/configuration_spec.rb +61 -0
- data/spec/lib/auth/model_spec.rb +6 -9
- data/spec/lib/auth_spec.rb +2 -2
- data/spec/lib/hacks/rename_attributes_spec.rb +49 -0
- data/spec/routes_spec.rb +8 -2
- data/spec/spec2_helper.rb +52 -0
- data/spec/spec3_helper.rb +72 -0
- data/spec/spec_helper.rb +109 -49
- data/spec_env/rails2/README.1ST +23 -0
- data/spec_env/rails2/Rakefile +10 -0
- data/spec_env/rails2/app/controllers/application_controller.rb +13 -0
- data/spec_env/rails2/app/helpers/application_helper.rb +3 -0
- data/spec_env/rails2/app/models/user.rb +2 -0
- data/spec_env/rails2/app/views/application/not_found.html.erb +9 -0
- data/spec_env/rails2/app/views/layouts/application.html.erb +9 -0
- data/spec_env/rails2/config/boot.rb +110 -0
- data/spec_env/rails2/config/cucumber.yml +7 -0
- data/spec_env/rails2/config/database.yml +25 -0
- data/spec_env/rails2/config/environment.rb +46 -0
- data/spec_env/rails2/config/environments/cucumber.rb +35 -0
- data/spec_env/rails2/config/environments/development.rb +17 -0
- data/spec_env/rails2/config/environments/production.rb +28 -0
- data/spec_env/rails2/config/environments/test.rb +31 -0
- data/spec_env/rails2/config/initializers/backtrace_silencers.rb +7 -0
- data/spec_env/rails2/config/initializers/inflections.rb +10 -0
- data/spec_env/rails2/config/initializers/mime_types.rb +5 -0
- data/spec_env/rails2/config/initializers/new_rails_defaults.rb +21 -0
- data/spec_env/rails2/config/initializers/session_store.rb +15 -0
- data/spec_env/rails2/config/initializers/sparkly_authentication.rb +30 -0
- data/spec_env/rails2/config/locales/en.yml +5 -0
- data/spec_env/rails2/config/routes.rb +46 -0
- data/spec_env/rails2/db/development.sqlite3 +0 -0
- data/spec_env/rails2/db/migrate/001_create_sparkly_passwords.rb +19 -0
- data/spec_env/rails2/db/migrate/002_create_sparkly_remembered_tokens.rb +15 -0
- data/spec_env/rails2/db/migrate/003_add_confirmed_to_sparkly_passwords.rb +9 -0
- data/spec_env/rails2/db/migrate/20100607103543_create_users.rb +12 -0
- data/spec_env/rails2/db/migrate/20100609152058_add_email_to_users.rb +9 -0
- data/spec_env/rails2/db/schema.rb +42 -0
- data/spec_env/rails2/db/seeds.rb +7 -0
- data/spec_env/rails2/db/test.sqlite3 +0 -0
- data/spec_env/rails2/doc/README_FOR_APP +2 -0
- data/spec_env/rails2/doc/sparkly_authentication.txt +56 -0
- data/spec_env/rails2/features/support/env.rb +58 -0
- data/spec_env/rails2/lib/tasks/cucumber.rake +47 -0
- data/spec_env/rails2/lib/tasks/rspec.rake +144 -0
- data/spec_env/rails2/lib/tasks/sparkly_migration.rb +1 -0
- data/spec_env/rails2/log/cucumber.log +8412 -0
- data/spec_env/rails2/log/development.log +317 -0
- data/spec_env/rails2/log/test.log +32053 -0
- data/spec_env/rails2/public/404.html +30 -0
- data/spec_env/rails2/public/422.html +30 -0
- data/spec_env/rails2/public/500.html +30 -0
- data/spec_env/rails2/public/favicon.ico +0 -0
- data/spec_env/rails2/public/images/rails.png +0 -0
- data/spec_env/rails2/public/javascripts/application.js +2 -0
- data/spec_env/rails2/public/javascripts/controls.js +963 -0
- data/spec_env/rails2/public/javascripts/dragdrop.js +973 -0
- data/spec_env/rails2/public/javascripts/effects.js +1128 -0
- data/spec_env/rails2/public/javascripts/prototype.js +4320 -0
- data/spec_env/rails2/public/robots.txt +5 -0
- data/spec_env/rails2/rerun.txt +1 -0
- data/spec_env/rails2/script/about +4 -0
- data/spec_env/rails2/script/autospec +6 -0
- data/spec_env/rails2/script/console +3 -0
- data/spec_env/rails2/script/cucumber +10 -0
- data/spec_env/rails2/script/dbconsole +3 -0
- data/spec_env/rails2/script/destroy +3 -0
- data/spec_env/rails2/script/generate +3 -0
- data/spec_env/rails2/script/performance/benchmarker +3 -0
- data/spec_env/rails2/script/performance/profiler +3 -0
- data/spec_env/rails2/script/plugin +3 -0
- data/spec_env/rails2/script/runner +3 -0
- data/spec_env/rails2/script/server +3 -0
- data/spec_env/rails2/script/spec +10 -0
- data/spec_env/rails2/spec/controllers/sparkly_user_sessions_controller_spec.rb +10 -0
- data/spec_env/rails2/spec/rcov.opts +2 -0
- data/spec_env/rails2/spec/spec.opts +4 -0
- data/spec_env/rails2/spec/spec_helper.rb +54 -0
- data/spec_env/rails2/test/fixtures/users.yml +7 -0
- data/spec_env/rails2/test/performance/browsing_test.rb +9 -0
- data/spec_env/rails2/test/test_helper.rb +38 -0
- data/spec_env/rails2/test/unit/user_test.rb +8 -0
- data/spec_env/rails2/vendor/gems/sparkly-auth-bootstrap-1.0.0/.specification +63 -0
- data/spec_env/rails2/vendor/gems/sparkly-auth-bootstrap-1.0.0/generators/sparkly/sparkly_generator.rb +1 -0
- data/spec_env/rails2/vendor/gems/sparkly-auth-bootstrap-1.0.0/lib/sparkly-auth-bootstrap.rb +6 -0
- data/spec_env/rails2/vendor/gems/sparkly-auth-bootstrap-1.0.0/rails/init.rb +1 -0
- data/spec_env/rails2/vendor/gems/sparkly-auth-bootstrap-1.0.0/sparkly-auth-bootstrap.gemspec +55 -0
- data/spec_env/rails3/.gitignore +4 -0
- data/spec_env/rails3/Gemfile +43 -0
- data/spec_env/rails3/Gemfile.lock +124 -0
- data/spec_env/rails3/README +256 -0
- data/spec_env/rails3/Rakefile +7 -0
- data/spec_env/rails3/app/controllers/application_controller.rb +6 -0
- data/spec_env/rails3/app/helpers/application_helper.rb +2 -0
- data/spec_env/rails3/app/models/user.rb +3 -0
- data/spec_env/rails3/app/views/application/not_found.html.erb +9 -0
- data/spec_env/rails3/app/views/layouts/application.html.erb +22 -0
- data/spec_env/rails3/config.ru +4 -0
- data/spec_env/rails3/config/application.rb +47 -0
- data/spec_env/rails3/config/boot.rb +13 -0
- data/spec_env/rails3/config/cucumber.yml +8 -0
- data/spec_env/rails3/config/database.yml +28 -0
- data/spec_env/rails3/config/environment.rb +5 -0
- data/spec_env/rails3/config/environments/development.rb +22 -0
- data/spec_env/rails3/config/environments/production.rb +49 -0
- data/spec_env/rails3/config/environments/spec.rb +35 -0
- data/spec_env/rails3/config/environments/test.rb +43 -0
- data/spec_env/rails3/config/initializers/backtrace_silencers.rb +7 -0
- data/spec_env/rails3/config/initializers/inflections.rb +10 -0
- data/spec_env/rails3/config/initializers/mime_types.rb +5 -0
- data/spec_env/rails3/config/initializers/secret_token.rb +7 -0
- data/spec_env/rails3/config/initializers/session_store.rb +8 -0
- data/spec_env/rails3/config/initializers/sparkly_authentication.rb +30 -0
- data/spec_env/rails3/config/locales/en.yml +5 -0
- data/spec_env/rails3/config/routes.rb +61 -0
- data/spec_env/rails3/db/migrate/001_create_sparkly_passwords.rb +19 -0
- data/spec_env/rails3/db/migrate/002_create_sparkly_remembered_tokens.rb +15 -0
- data/spec_env/rails3/db/migrate/20100810132843_create_users.rb +13 -0
- data/spec_env/rails3/db/schema.rb +42 -0
- data/spec_env/rails3/db/seeds.rb +7 -0
- data/spec_env/rails3/doc/README_FOR_APP +2 -0
- data/spec_env/rails3/doc/sparkly_authentication.txt +56 -0
- data/spec_env/rails3/features/support/env.rb +62 -0
- data/spec_env/rails3/lib/sparkly/bootstrap.rb +1 -0
- data/spec_env/rails3/lib/tasks/.gitkeep +0 -0
- data/spec_env/rails3/lib/tasks/cucumber.rake +53 -0
- data/spec_env/rails3/lib/tasks/sparkly_migration.rb +1 -0
- data/spec_env/rails3/public/404.html +26 -0
- data/spec_env/rails3/public/422.html +26 -0
- data/spec_env/rails3/public/500.html +26 -0
- data/spec_env/rails3/public/favicon.ico +0 -0
- data/spec_env/rails3/public/images/rails.png +0 -0
- data/spec_env/rails3/public/javascripts/application.js +2 -0
- data/spec_env/rails3/public/javascripts/controls.js +965 -0
- data/spec_env/rails3/public/javascripts/dragdrop.js +974 -0
- data/spec_env/rails3/public/javascripts/effects.js +1123 -0
- data/spec_env/rails3/public/javascripts/prototype.js +6001 -0
- data/spec_env/rails3/public/javascripts/rails.js +175 -0
- data/spec_env/rails3/public/robots.txt +5 -0
- data/spec_env/rails3/public/stylesheets/.gitkeep +0 -0
- data/spec_env/rails3/script/cucumber +10 -0
- data/spec_env/rails3/script/rails +6 -0
- data/spec_env/rails3/test/fixtures/users.yml +7 -0
- data/spec_env/rails3/test/performance/browsing_test.rb +9 -0
- data/spec_env/rails3/test/test_helper.rb +13 -0
- data/spec_env/rails3/test/unit/user_test.rb +8 -0
- data/spec_env/rails3/vendor/plugins/.gitkeep +0 -0
- data/spec_env/rails3/webrat.log +5 -0
- metadata +393 -15
- data/dependencies.rb +0 -1
- data/spec/lib/auth/behavior/remember_me_spec.rb +0 -127
- 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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
data/spec/lib/auth/model_spec.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
49
|
-
Dispatcher.reload_application
|
46
|
+
reload!
|
50
47
|
subject.apply_options!
|
51
48
|
end
|
52
49
|
|