authenticate 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -4
  3. data/CHANGELOG.md +12 -0
  4. data/Gemfile +1 -0
  5. data/Gemfile.lock +21 -6
  6. data/app/controllers/authenticate/passwords_controller.rb +1 -1
  7. data/authenticate.gemspec +7 -3
  8. data/config/locales/authenticate.en.yml +1 -1
  9. data/gemfiles/rails42.gemfile +6 -1
  10. data/lib/authenticate/callbacks/brute_force.rb +3 -4
  11. data/lib/authenticate/configuration.rb +2 -2
  12. data/lib/authenticate/controller.rb +1 -2
  13. data/lib/authenticate/model/brute_force.rb +2 -2
  14. data/lib/authenticate/model/db_password.rb +2 -3
  15. data/lib/authenticate/model/email.rb +3 -6
  16. data/lib/authenticate/model/lifetimed.rb +1 -1
  17. data/lib/authenticate/model/password_reset.rb +1 -1
  18. data/lib/authenticate/model/timeoutable.rb +2 -2
  19. data/lib/authenticate/model/trackable.rb +1 -1
  20. data/lib/authenticate/model/username.rb +1 -1
  21. data/lib/authenticate/session.rb +0 -4
  22. data/lib/authenticate/user.rb +12 -0
  23. data/lib/authenticate/version.rb +1 -1
  24. data/spec/controllers/passwords_controller_spec.rb +119 -0
  25. data/spec/controllers/secured_controller_spec.rb +70 -0
  26. data/spec/controllers/sessions_controller_spec.rb +86 -0
  27. data/spec/controllers/users_controller_spec.rb +82 -0
  28. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  29. data/spec/dummy/app/controllers/welcome_controller.rb +4 -0
  30. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  31. data/spec/dummy/app/views/welcome/index.html.erb +4 -0
  32. data/spec/dummy/config/application.rb +2 -0
  33. data/spec/dummy/config/environments/production.rb +12 -0
  34. data/spec/dummy/config/initializers/authenticate.rb +4 -11
  35. data/spec/dummy/config/routes.rb +3 -0
  36. data/spec/dummy/db/test.sqlite3 +0 -0
  37. data/spec/factories/users.rb +2 -4
  38. data/spec/features/brute_force_spec.rb +49 -0
  39. data/spec/features/max_session_lifetime_spec.rb +30 -0
  40. data/spec/features/password_reset_spec.rb +69 -0
  41. data/spec/features/password_update_spec.rb +41 -0
  42. data/spec/features/sign_in_spec.rb +29 -0
  43. data/spec/features/sign_out_spec.rb +22 -0
  44. data/spec/features/sign_up_spec.rb +42 -0
  45. data/spec/features/timeoutable_spec.rb +30 -0
  46. data/spec/model/brute_force_spec.rb +26 -29
  47. data/spec/model/configuration_spec.rb +61 -0
  48. data/spec/model/db_password_spec.rb +8 -9
  49. data/spec/model/email_spec.rb +0 -1
  50. data/spec/model/lifetimed_spec.rb +6 -18
  51. data/spec/model/password_reset_spec.rb +2 -9
  52. data/spec/model/session_spec.rb +16 -23
  53. data/spec/model/timeoutable_spec.rb +8 -7
  54. data/spec/model/trackable_spec.rb +0 -1
  55. data/spec/model/user_spec.rb +1 -2
  56. data/spec/spec_helper.rb +33 -131
  57. data/spec/support/controllers/controller_helpers.rb +24 -0
  58. data/spec/support/features/feature_helpers.rb +36 -0
  59. metadata +80 -8
  60. data/spec/configuration_spec.rb +0 -60
@@ -3,7 +3,6 @@ require 'authenticate/model/email'
3
3
 
4
4
 
5
5
  describe Authenticate::Model::Email do
6
-
7
6
  it 'validates email' do
8
7
  user = build(:user, :without_email)
9
8
  user.save
@@ -3,31 +3,19 @@ require 'authenticate/model/lifetimed'
3
3
 
4
4
 
5
5
  describe Authenticate::Model::Lifetimed do
6
-
7
6
  context '#max_session_lifetime_exceeded?' do
8
- before {
9
- Authenticate.configure do |config|
10
- config.max_session_lifetime = 10.minutes
11
- end
12
- }
13
7
 
14
8
  it 'passes fresh sessions' do
15
- user = create(:user, current_sign_in_at: 1.minute.ago.utc)
16
- expect(user).to_not be_max_session_lifetime_exceeded
9
+ Timecop.freeze do
10
+ user = create(:user, current_sign_in_at: 1.minute.ago.utc)
11
+ expect(user).to_not be_max_session_lifetime_exceeded
12
+ end
17
13
  end
18
14
 
19
15
  it 'detects timed out sessions' do
20
- user = create(:user, current_sign_in_at: 5.hours.ago.utc)
21
- expect(user).to be_max_session_lifetime_exceeded
22
- end
23
-
24
- describe 'max_session_lifetime param not set' do
25
- it 'does not time out' do
16
+ Timecop.freeze do
26
17
  user = create(:user, current_sign_in_at: 5.hours.ago.utc)
27
- Authenticate.configure do |config|
28
- config.max_session_lifetime = nil
29
- end
30
- expect(user).to_not be_max_session_lifetime_exceeded
18
+ expect(user).to be_max_session_lifetime_exceeded
31
19
  end
32
20
  end
33
21
  end
@@ -3,9 +3,6 @@ require 'authenticate/model/password_reset'
3
3
 
4
4
 
5
5
  describe Authenticate::Model::PasswordReset do
6
- before(:all) {
7
- Authenticate.configuration.reset_password_within = 5.minutes
8
- }
9
6
  context 'forgot_password!' do
10
7
  subject { create(:user) }
11
8
  before { subject.forgot_password! }
@@ -22,14 +19,13 @@ describe Authenticate::Model::PasswordReset do
22
19
 
23
20
  context '#reset_password_period_valid?' do
24
21
  subject { create(:user) }
25
- before(:each) {
26
- Authenticate.configuration.reset_password_within = 5.minutes
27
- }
28
22
 
29
23
  it 'always true if reset_password_within config param is nil' do
24
+ within = Authenticate.configuration.reset_password_within
30
25
  subject.password_reset_sent_at = 10.days.ago
31
26
  Authenticate.configuration.reset_password_within = nil
32
27
  expect(subject.reset_password_period_valid?).to be_truthy
28
+ Authenticate.configuration.reset_password_within = within
33
29
  end
34
30
 
35
31
  it 'false if time exceeded' do
@@ -45,9 +41,6 @@ describe Authenticate::Model::PasswordReset do
45
41
 
46
42
  context '#update_password' do
47
43
  subject { create(:user) }
48
- before(:each) {
49
- Authenticate.configuration.reset_password_within = 5.minutes
50
- }
51
44
 
52
45
  context 'within time time' do
53
46
  before(:each) {
@@ -2,24 +2,23 @@ require 'spec_helper'
2
2
 
3
3
 
4
4
  describe Authenticate::Session do
5
-
6
5
  describe 'session token' do
7
6
  it 'finds a user from session token' do
8
7
  user = create(:user, :with_session_token)
9
- request = {}
10
- cookies = {authenticate_session_token: user.session_token}
8
+ request = mock_request
9
+ cookies = cookies_for user
11
10
  session = Authenticate::Session.new(request, cookies)
12
11
  expect(session.current_user).to eq user
13
12
  end
14
- it 'returns nil without a session token' do
15
- request = {}
16
- cookies = {session_token: nil}
13
+ it 'nil user without a session token' do
14
+ request = mock_request
15
+ cookies = {}
17
16
  session = Authenticate::Session.new(request, cookies)
18
17
  expect(session.current_user).to be_nil
19
18
  end
20
19
  it 'returns nil with a bogus session token' do
21
- request = {}
22
- cookies = {session_token: 'some made up value'}
20
+ request = mock_request
21
+ cookies = {Authenticate.configuration.cookie_name.freeze.to_sym => 'some made up value'}
23
22
  session = Authenticate::Session.new(request, cookies)
24
23
  expect(session.current_user).to be_nil
25
24
  end
@@ -27,23 +26,20 @@ describe Authenticate::Session do
27
26
 
28
27
  describe '#login' do
29
28
  it 'sets current_user' do
30
- user = build(:user, :with_session_token)
29
+ user = create(:user)
31
30
  session = Authenticate::Session.new(mock_request, {})
32
31
  session.login(user)
33
32
  expect(session.current_user).to eq user
34
33
  end
35
34
  context 'with a block' do
36
35
  it 'passes the success status to the block when login succeeds' do
37
- user = build(:user, :with_session_token)
36
+ user = create(:user)
38
37
  session = Authenticate::Session.new(mock_request, {})
39
- session.login user do |status|
38
+ session.login(user) do |status|
40
39
  expect(status.success?).to eq true
41
40
  end
42
41
  end
43
42
  it 'passes the failure status to the block when login fails' do
44
- Authenticate.configure do |config|
45
- config.max_consecutive_bad_logins_allowed = nil
46
- end
47
43
  session = Authenticate::Session.new(mock_request, {})
48
44
  session.login nil do |status|
49
45
  expect(status.success?).to eq false
@@ -65,20 +61,17 @@ describe Authenticate::Session do
65
61
  expect{session.login(user)}.to change{user.sign_in_count}.by(1)
66
62
  end
67
63
  it 'fails login if a callback fails' do
68
- failure_message = 'THIS IS A FORCED FAIL'
69
- Authenticate.lifecycle.after_authentication do |user, session, opts|
70
- throw(:failure, failure_message)
71
- end
72
- user = create(:user, :with_session_token, last_access_at: 10.minutes.ago)
73
- cookies = {authenticate_session_token: user.session_token}
64
+ cookies = {}
74
65
  session = Authenticate::Session.new(mock_request, cookies)
75
- session.login user do |status|
66
+ session.login nil do |status|
76
67
  expect(status.success?).to eq false
77
- expect(status.message).to eq failure_message
68
+ expect(status.message).to eq I18n.t('callbacks.authenticatable.failure')
78
69
  end
79
70
  end
80
71
  end
81
72
  end
73
+ end
82
74
 
83
-
75
+ def cookies_for user
76
+ { Authenticate.configuration.cookie_name.freeze.to_sym => user.session_token }
84
77
  end
@@ -3,18 +3,19 @@ require 'authenticate/model/timeoutable'
3
3
 
4
4
 
5
5
  describe Authenticate::Model::Timeoutable do
6
- before(:all) {
7
- Authenticate.configuration.timeout_in = 45.minutes
8
- }
9
6
  subject { create(:user) }
10
7
 
11
8
  it 'does not timeout while last_access_at is valid' do
12
- subject.last_access_at = 10.minutes.ago
13
- expect(subject.timedout?).to be_falsey
9
+ Timecop.freeze do
10
+ subject.last_access_at = 10.minutes.ago
11
+ expect(subject.timedout?).to be_falsey
12
+ end
14
13
  end
15
14
 
16
15
  it 'does timeout when last_access_at is stale' do
17
- subject.last_access_at = 46.minutes.ago
18
- expect(subject.timedout?).to be_truthy
16
+ Timecop.freeze do
17
+ subject.last_access_at = 46.minutes.ago
18
+ expect(subject.timedout?).to be_truthy
19
+ end
19
20
  end
20
21
  end
@@ -4,7 +4,6 @@ require 'authenticate/model/trackable'
4
4
 
5
5
  describe Authenticate::Model::Trackable do
6
6
  subject {create(:user)}
7
-
8
7
  context '#last_sign_in_at' do
9
8
  it 'sets to old current_sign_in_at if it is not nil' do
10
9
  old_sign_in = 2.days.ago.utc
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Authenticate::User do
4
-
5
4
  context 'session tokens' do
6
5
  it 'generates a new session token' do
7
6
  user = create(:user, :with_session_token)
@@ -19,4 +18,4 @@ describe Authenticate::User do
19
18
  end
20
19
  end
21
20
 
22
- end
21
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,56 +1,52 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ ENV['RAILS_ENV'] ||= 'test'
3
3
 
4
-
5
- ENV["RAILS_ENV"] ||= 'test'
6
-
7
- MY_ORM = :active_record
8
-
9
- # require 'simplecov'
10
- # SimpleCov.root File.join(File.dirname(__FILE__), '..', 'lib')
11
- # SimpleCov.start
12
-
13
-
14
- require 'rails/all'
4
+ require File.expand_path('../dummy/config/environment.rb', __FILE__)
15
5
  require 'rspec/rails'
16
- require 'factory_girl_rails'
17
- # require 'timecop'
18
-
19
- require 'authenticate'
6
+ require 'shoulda-matchers'
7
+ require 'capybara/rails'
8
+ require 'capybara/rspec'
9
+ require 'database_cleaner'
10
+ require 'factory_girl'
11
+ require 'timecop'
20
12
 
21
- ENGINE_RAILS_ROOT=File.join(File.dirname(__FILE__), '../')
22
- Dir[File.join(ENGINE_RAILS_ROOT, "spec/factories/**/*.rb")].each {|f| require f }
13
+ Rails.backtrace_cleaner.remove_silencers!
14
+ DatabaseCleaner.strategy = :truncation
23
15
 
24
- def setup_orm; end
25
- def teardown_orm; end
26
-
27
- require "orm/#{MY_ORM}"
16
+ # No longer autoloading support, individually requiring instead.
17
+ #
18
+ # Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
28
19
 
29
- # require "rails_app/config/environment"
30
- require "dummy/config/environment"
20
+ # Load factory girl factories.
21
+ Dir[File.join(File.dirname(__FILE__), 'factories/**/*.rb')].each { |f| require f }
31
22
 
32
- # class TestMailer < ActionMailer::Base;end
23
+ RSpec.configure do |config|
24
+ config.include FactoryGirl::Syntax::Methods
25
+ config.infer_spec_type_from_file_location!
26
+ config.order = :random
27
+ config.use_transactional_fixtures = true
33
28
 
34
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
29
+ # config.mock_with :rspec
35
30
 
36
- RSpec.configure do |config|
37
- config.fixture_path = "#{::Rails.root}/spec/factories"
31
+ config.expect_with :rspec do |expectations|
32
+ expectations.syntax = :expect
33
+ end
38
34
 
39
- config.include RSpec::Rails::ControllerExampleGroup, :file_path => /controller(.)*_spec.rb$/
40
- config.mock_with :rspec
41
- config.include FactoryGirl::Syntax::Methods
35
+ config.mock_with :rspec do |mocks|
36
+ mocks.syntax = :expect
37
+ end
42
38
 
43
- config.use_transactional_fixtures = true
44
39
 
45
- config.before(:suite) { setup_orm }
46
- config.after(:suite) { teardown_orm }
47
- config.before(:each) { ActionMailer::Base.deliveries.clear }
40
+ config.after(:each, :type => :feature) do
41
+ DatabaseCleaner.clean # Truncate the database
42
+ Capybara.reset_sessions! # Forget the (simulated) browser state
43
+ Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
44
+ end
48
45
  end
49
46
 
50
47
 
51
48
  def restore_default_configuration
52
- Authenticate.configuration = nil
53
- Authenticate.configure {}
49
+ puts 'restore_default_configuration called!!!!!!!!!!!!!!!!!!!!!'
54
50
  end
55
51
 
56
52
  def mock_request(params = {})
@@ -59,97 +55,3 @@ def mock_request(params = {})
59
55
  allow(req).to receive(:remote_ip).and_return('111.111.111.111')
60
56
  req
61
57
  end
62
-
63
-
64
- # # This file was generated by the `rails generate rspec:install` command. Conventionally, all
65
- # # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
66
- # # The generated `.rspec` file contains `--require spec_helper` which will cause
67
- # # this file to always be loaded, without a need to explicitly require it in any
68
- # # files.
69
- # #
70
- # # Given that it is always loaded, you are encouraged to keep this file as
71
- # # light-weight as possible. Requiring heavyweight dependencies from this file
72
- # # will add to the boot time of your test suite on EVERY test run, even for an
73
- # # individual file that may not need all of that loaded. Instead, consider making
74
- # # a separate helper file that requires the additional dependencies and performs
75
- # # the additional setup, and require it from the spec files that actually need
76
- # # it.
77
- # #
78
- # # The `.rspec` file also contains a few flags that are not defaults but that
79
- # # users commonly want.
80
- # #
81
- # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
82
- # RSpec.configure do |config|
83
- # # rspec-expectations config goes here. You can use an alternate
84
- # # assertion/expectation library such as wrong or the stdlib/minitest
85
- # # assertions if you prefer.
86
- # config.expect_with :rspec do |expectations|
87
- # # This option will default to `true` in RSpec 4. It makes the `description`
88
- # # and `failure_message` of custom matchers include text for helper methods
89
- # # defined using `chain`, e.g.:
90
- # # be_bigger_than(2).and_smaller_than(4).description
91
- # # # => "be bigger than 2 and smaller than 4"
92
- # # ...rather than:
93
- # # # => "be bigger than 2"
94
- # expectations.include_chain_clauses_in_custom_matcher_descriptions = true
95
- # end
96
- #
97
- # # rspec-mocks config goes here. You can use an alternate test double
98
- # # library (such as bogus or mocha) by changing the `mock_with` option here.
99
- # config.mock_with :rspec do |mocks|
100
- # # Prevents you from mocking or stubbing a method that does not exist on
101
- # # a real object. This is generally recommended, and will default to
102
- # # `true` in RSpec 4.
103
- # mocks.verify_partial_doubles = true
104
- # end
105
- #
106
- # # The settings below are suggested to provide a good initial experience
107
- # # with RSpec, but feel free to customize to your heart's content.
108
- # =begin
109
- # # These two settings work together to allow you to limit a spec run
110
- # # to individual examples or groups you care about by tagging them with
111
- # # `:focus` metadata. When nothing is tagged with `:focus`, all examples
112
- # # get run.
113
- # config.filter_run :focus
114
- # config.run_all_when_everything_filtered = true
115
- #
116
- # # Allows RSpec to persist some state between runs in order to support
117
- # # the `--only-failures` and `--next-failure` CLI options. We recommend
118
- # # you configure your source control system to ignore this file.
119
- # config.example_status_persistence_file_path = "spec/examples.txt"
120
- #
121
- # # Limits the available syntax to the non-monkey patched syntax that is
122
- # # recommended. For more details, see:
123
- # # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
124
- # # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
125
- # # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
126
- # config.disable_monkey_patching!
127
- #
128
- # # Many RSpec users commonly either run the entire suite or an individual
129
- # # file, and it's useful to allow more verbose output when running an
130
- # # individual spec file.
131
- # if config.files_to_run.one?
132
- # # Use the documentation formatter for detailed output,
133
- # # unless a formatter has already been configured
134
- # # (e.g. via a command-line flag).
135
- # config.default_formatter = 'doc'
136
- # end
137
- #
138
- # # Print the 10 slowest examples and example groups at the
139
- # # end of the spec run, to help surface which specs are running
140
- # # particularly slow.
141
- # config.profile_examples = 10
142
- #
143
- # # Run specs in random order to surface order dependencies. If you find an
144
- # # order dependency and want to debug it, you can fix the order by providing
145
- # # the seed, which is printed after each run.
146
- # # --seed 1234
147
- # config.order = :random
148
- #
149
- # # Seed global randomization in this process using the `--seed` CLI option.
150
- # # Setting this allows you to use `--seed` to deterministically reproduce
151
- # # test failures related to randomization by passing the same `--seed` value
152
- # # as the one that triggered the failure.
153
- # Kernel.srand config.seed
154
- # =end
155
- # end
@@ -0,0 +1,24 @@
1
+ require 'authenticate/controller'
2
+
3
+ module Controllers
4
+ module ControllerHelpers
5
+
6
+ def sign_in
7
+ user = create(:user)
8
+ sign_in_as user
9
+ end
10
+
11
+ def sign_in_as(user)
12
+ controller.login user
13
+ end
14
+
15
+ def sign_out
16
+ controller.logout
17
+ end
18
+
19
+ end
20
+ end
21
+
22
+ RSpec.configure do |config|
23
+ config.include Controllers::ControllerHelpers, type: :controller
24
+ end
@@ -0,0 +1,36 @@
1
+ module Features
2
+ module FeatureHelpers
3
+
4
+
5
+ def sign_in_with(email, password)
6
+ visit sign_in_path
7
+ fill_in 'session_email', with: email
8
+ fill_in 'session_password', with: password
9
+ click_button 'Sign in'
10
+ end
11
+
12
+ def sign_out
13
+ within '#header' do
14
+ click_link I18n.t("layouts.application.sign_out")
15
+ end
16
+ end
17
+
18
+ def expect_user_to_be_signed_in
19
+ visit root_path
20
+ expect(page).to have_link 'Sign out'
21
+ end
22
+
23
+ def expect_page_to_display_sign_in_error
24
+ expect(page).to have_content 'Invalid id or password'
25
+ end
26
+
27
+ def expect_user_to_be_signed_out
28
+ expect(page).to have_content 'Sign in'
29
+ end
30
+
31
+ end
32
+ end
33
+
34
+ RSpec.configure do |config|
35
+ config.include Features::FeatureHelpers, type: :feature
36
+ end