quo_vadis 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- quo_vadis (1.0.4)
4
+ quo_vadis (1.0.5)
5
5
  bcrypt-ruby (~> 2.1.4)
6
6
  rails (~> 3.0)
7
7
 
data/README.md CHANGED
@@ -11,6 +11,7 @@ Features:
11
11
  * Easy to customise.
12
12
  * Uses BCrypt to encrypt passwords.
13
13
  * Sign in, sign out, forgotten password, authenticate actions, remember user between browser sessions.
14
+ * Block accounts.
14
15
 
15
16
  Forthcoming features:
16
17
 
@@ -10,6 +10,11 @@ module ControllerMixin
10
10
 
11
11
  private
12
12
 
13
+ # Returns true if the sign-in process is blocked to the user, false otherwise.
14
+ def blocked?
15
+ QuoVadis.blocked?(self)
16
+ end
17
+
13
18
  # Remembers the authenticated <tt>user</tt> (in this session and future sessions).
14
19
  #
15
20
  # If you want to sign in a <tt>user</tt>, call <tt>QuoVadis::SessionsController#sign_in</tt>
@@ -8,7 +8,10 @@ class QuoVadis::SessionsController < ApplicationController
8
8
 
9
9
  # POST sign_in_path
10
10
  def create
11
- if user = User.authenticate(params[:username], params[:password])
11
+ if blocked?
12
+ flash.now[:alert] = t('quo_vadis.flash.sign_in.blocked') unless t('quo_vadis.flash.sign_in.blocked').blank?
13
+ render 'sessions/new'
14
+ elsif user = User.authenticate(params[:username], params[:password])
12
15
  flash[:notice] = t('quo_vadis.flash.sign_in.after') unless t('quo_vadis.flash.sign_in.after').blank?
13
16
  sign_in user
14
17
  else
@@ -28,7 +28,7 @@ QuoVadis.configure do |config|
28
28
  # Code to run when someone has tried but failed to sign in. E.g.:
29
29
  #
30
30
  # config.failed_sign_in_hook = Proc.new do |controller|
31
- # logger.info "Failed sign in from #{controller.request.remote_ip}"
31
+ # Rails.logger.info "Failed sign in from #{controller.request.remote_ip}"
32
32
  # end
33
33
  config.failed_sign_in_hook = nil
34
34
 
@@ -36,6 +36,14 @@ QuoVadis.configure do |config|
36
36
  # Set to <tt>nil</tt> to never remember user.
37
37
  config.remember_for = 2.weeks
38
38
 
39
+ # Code to run to determine whether the sign-in process is blocked to the user. E.g.:
40
+ #
41
+ # config.blocked = Proc.new do |controller|
42
+ # # Assuming a SignIn model with scopes for `failed`, `last_day`, `for_ip`.
43
+ # SignIn.failed.last_day.for_ip(controller.request.remote_ip) >= 5
44
+ # end
45
+ config.blocked = false
46
+
39
47
 
40
48
  #
41
49
  # Sign out
@@ -5,6 +5,7 @@ en:
5
5
  before: 'Please sign in first.'
6
6
  after: 'You have successfully signed in.'
7
7
  failed: 'Sorry, we did not recognise you.'
8
+ blocked: 'Sorry, your account is blocked.'
8
9
 
9
10
  sign_out: 'You have successfully signed out.'
10
11
 
@@ -1,3 +1,3 @@
1
1
  module QuoVadis
2
- VERSION = '1.0.4'
2
+ VERSION = '1.0.5'
3
3
  end
data/lib/quo_vadis.rb CHANGED
@@ -45,6 +45,15 @@ module QuoVadis
45
45
  @@remember_for = 2.weeks
46
46
 
47
47
 
48
+ # Whether the sign-in process is blocked to the user.
49
+ mattr_writer :blocked
50
+ @@blocked = false
51
+
52
+ def self.blocked?(controller) # :nodoc:
53
+ @@blocked.respond_to?(:call) ? @@blocked.call(controller) : @@blocked
54
+ end
55
+
56
+
48
57
  #
49
58
  # Sign out
50
59
  #
@@ -1,7 +1,7 @@
1
1
  QuoVadis.configure do |config|
2
2
 
3
3
  #
4
- # Redirection URLs
4
+ # Sign in
5
5
  #
6
6
 
7
7
  # The URL to redirect the user to after s/he signs in.
@@ -18,14 +18,6 @@ QuoVadis.configure do |config|
18
18
  # to reach when they were made to authenticate.
19
19
  config.override_original_url = false
20
20
 
21
- # The URL to redirect the user to after s/he signs out.
22
- config.signed_out_url = :root
23
-
24
-
25
- #
26
- # Hooks
27
- #
28
-
29
21
  # Code to run when the user has signed in. E.g.:
30
22
  #
31
23
  # config.signed_in_hook = Proc.new do |user, controller|
@@ -36,10 +28,30 @@ QuoVadis.configure do |config|
36
28
  # Code to run when someone has tried but failed to sign in. E.g.:
37
29
  #
38
30
  # config.failed_sign_in_hook = Proc.new do |controller|
39
- # logger.info "Failed sign in from #{controller.request.remote_ip}"
31
+ # Rails.logger.info "Failed sign in from #{controller.request.remote_ip}"
40
32
  # end
41
33
  config.failed_sign_in_hook = nil
42
34
 
35
+ # How long to remember user across browser sessions.
36
+ # Set to <tt>nil</tt> to never remember user.
37
+ config.remember_for = 2.weeks
38
+
39
+ # Code to run to determine whether the sign-in process is blocked to the user. E.g.:
40
+ #
41
+ # config.blocked = Proc.new do |controller|
42
+ # # Assuming a SignIn model with scopes for `failed`, `last_day`, `for_ip`.
43
+ # SignIn.failed.last_day.for_ip(controller.request.remote_ip) >= 5
44
+ # end
45
+ config.blocked = false
46
+
47
+
48
+ #
49
+ # Sign out
50
+ #
51
+
52
+ # The URL to redirect the user to after s/he signs out.
53
+ config.signed_out_url = :root
54
+
43
55
  # Code to run just before the user has signed out. E.g.:
44
56
  #
45
57
  # config.signed_out_hook = Proc.new do |user, controller|
@@ -48,6 +60,17 @@ QuoVadis.configure do |config|
48
60
  config.signed_out_hook = nil
49
61
 
50
62
 
63
+ #
64
+ # Forgotten-password Mailer
65
+ #
66
+
67
+ # From whom the forgotten-password email should be sent.
68
+ config.from = 'noreply@example.com'
69
+
70
+ # Subject of the forgotten-password email.
71
+ config.subject = 'Change your password'
72
+
73
+
51
74
  #
52
75
  # Miscellaneous
53
76
  #
@@ -5,4 +5,13 @@ en:
5
5
  before: 'Please sign in first.'
6
6
  after: 'You have successfully signed in.'
7
7
  failed: 'Sorry, we did not recognise you.'
8
+ blocked: 'Sorry, your account is blocked.'
9
+
8
10
  sign_out: 'You have successfully signed out.'
11
+
12
+ forgotten:
13
+ unknown: "Sorry, we did not recognise you."
14
+ no_email: "Sorry, we don't have an email address for you."
15
+ sent_email: "We've emailed you a link where you can change your password."
16
+ invalid_token: "Sorry, this link isn't valid anymore."
17
+ password_changed: "You have successfully changed your password and you're now signed in."
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ class BlockedTest < ActiveSupport::IntegrationCase
4
+
5
+ test 'sign-in process can be blocked' do
6
+ user_factory 'Bob', 'bob', 'secret'
7
+ user_factory 'Jim', 'jim', 'secret'
8
+
9
+ QuoVadis.blocked = Proc.new do |controller|
10
+ controller.params[:username] == 'bob'
11
+ end
12
+
13
+ sign_in_as 'bob', 'secret'
14
+ within '.flash' do
15
+ assert page.has_content?('Sorry, your account is blocked.')
16
+ end
17
+
18
+ sign_in_as 'jim', 'secret'
19
+ within '.flash' do
20
+ assert page.has_content?('You have successfully signed in.')
21
+ end
22
+ end
23
+ end
@@ -6,11 +6,6 @@ class ConfigTest < ActiveSupport::IntegrationCase
6
6
  user_factory 'Bob', 'bob', 'secret'
7
7
  end
8
8
 
9
- teardown do
10
- Capybara.reset_sessions!
11
- reset_quo_vadis_configuration
12
- end
13
-
14
9
  test 'signed_in_url config' do
15
10
  sign_in_as 'bob', 'secret'
16
11
  assert_equal root_path, current_path
@@ -51,6 +46,20 @@ class ConfigTest < ActiveSupport::IntegrationCase
51
46
  assert_equal root_path, current_path
52
47
  end
53
48
 
49
+ test 'blocked config' do
50
+ QuoVadis.blocked = Proc.new do |controller|
51
+ controller.params[:username] == 'bob'
52
+ end
53
+ sign_in_as 'bob', 'secret'
54
+ within '.flash' do
55
+ assert page.has_content?('Sorry, your account is blocked.')
56
+ end
57
+ sign_in_as 'jim', 'secret'
58
+ within '.flash' do
59
+ assert page.has_no_content?('Sorry, your account is blocked.')
60
+ end
61
+ end
62
+
54
63
  test 'signed_out_url config' do
55
64
  visit sign_out_path
56
65
  assert_equal root_path, current_path
@@ -2,11 +2,6 @@ require 'test_helper'
2
2
 
3
3
  class CookieTest < ActiveSupport::IntegrationCase
4
4
 
5
- teardown do
6
- Capybara.reset_sessions!
7
- reset_quo_vadis_configuration
8
- end
9
-
10
5
  test 'authenticated user is remembered between browser sessions' do
11
6
  user_factory 'Bob', 'bob', 'secret'
12
7
  sign_in_as 'bob', 'secret'
@@ -66,6 +66,27 @@ class LocaleTest < ActiveSupport::IntegrationCase
66
66
  end
67
67
  end
68
68
 
69
+ test 'sign_in.blocked flash' do
70
+ QuoVadis.blocked = true
71
+ user_factory 'Bob', 'bob', 'secret'
72
+ sign_in_as 'bob', 'secret'
73
+ within '.flash' do
74
+ assert page.has_content?('Sorry, your account is blocked.')
75
+ end
76
+ end
77
+
78
+ test 'sign_in.blocked flash is optional' do
79
+ begin
80
+ I18n.backend.store_translations :en, {:quo_vadis => {:flash => {:sign_in => {:blocked => ''}}}}
81
+ QuoVadis.blocked = true
82
+ user_factory 'Bob', 'bob', 'secret'
83
+ sign_in_as 'bob', 'secret'
84
+ assert page.has_no_css?('div.flash')
85
+ ensure
86
+ I18n.reload!
87
+ end
88
+ end
89
+
69
90
  test 'sign_out flash is optional' do
70
91
  begin
71
92
  I18n.backend.store_translations :en, {:quo_vadis => {:flash => {:sign_out => ''}}}
@@ -2,10 +2,6 @@ require 'test_helper'
2
2
 
3
3
  class SignInTest < ActiveSupport::IntegrationCase
4
4
 
5
- teardown do
6
- Capybara.reset_sessions!
7
- end
8
-
9
5
  test 'failed sign in' do
10
6
  sign_in_as 'bob', 'secret'
11
7
 
@@ -2,4 +2,10 @@
2
2
  class ActiveSupport::IntegrationCase < ActiveSupport::TestCase
3
3
  include Capybara
4
4
  include Rails.application.routes.url_helpers
5
- end
5
+
6
+ teardown do
7
+ Capybara.reset_sessions!
8
+ reset_quo_vadis_configuration
9
+ end
10
+
11
+ end
data/test/test_helper.rb CHANGED
@@ -53,6 +53,7 @@ def reset_quo_vadis_configuration
53
53
  QuoVadis.from = 'noreply@example.com'
54
54
  QuoVadis.subject = 'Change your password'
55
55
  QuoVadis.remember_for = 2.weeks
56
+ QuoVadis.blocked = false
56
57
  end
57
58
 
58
59
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quo_vadis
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 4
10
- version: 1.0.4
9
+ - 5
10
+ version: 1.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andy Stewart
@@ -15,13 +15,12 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-22 00:00:00 +00:00
18
+ date: 2011-02-23 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: rails
23
22
  prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
23
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
25
  requirements:
27
26
  - - ~>
@@ -31,12 +30,12 @@ dependencies:
31
30
  - 3
32
31
  - 0
33
32
  version: "3.0"
33
+ requirement: *id001
34
+ name: rails
34
35
  type: :runtime
35
- version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- name: bcrypt-ruby
38
37
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
38
+ version_requirements: &id002 !ruby/object:Gem::Requirement
40
39
  none: false
41
40
  requirements:
42
41
  - - ~>
@@ -47,12 +46,12 @@ dependencies:
47
46
  - 1
48
47
  - 4
49
48
  version: 2.1.4
49
+ requirement: *id002
50
+ name: bcrypt-ruby
50
51
  type: :runtime
51
- version_requirements: *id002
52
52
  - !ruby/object:Gem::Dependency
53
- name: rails
54
53
  prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
54
+ version_requirements: &id003 !ruby/object:Gem::Requirement
56
55
  none: false
57
56
  requirements:
58
57
  - - ">="
@@ -63,12 +62,12 @@ dependencies:
63
62
  - 0
64
63
  - 4
65
64
  version: 3.0.4
65
+ requirement: *id003
66
+ name: rails
66
67
  type: :development
67
- version_requirements: *id003
68
68
  - !ruby/object:Gem::Dependency
69
- name: sqlite3-ruby
70
69
  prerelease: false
71
- requirement: &id004 !ruby/object:Gem::Requirement
70
+ version_requirements: &id004 !ruby/object:Gem::Requirement
72
71
  none: false
73
72
  requirements:
74
73
  - - ">="
@@ -77,12 +76,12 @@ dependencies:
77
76
  segments:
78
77
  - 0
79
78
  version: "0"
79
+ requirement: *id004
80
+ name: sqlite3-ruby
80
81
  type: :development
81
- version_requirements: *id004
82
82
  - !ruby/object:Gem::Dependency
83
- name: capybara
84
83
  prerelease: false
85
- requirement: &id005 !ruby/object:Gem::Requirement
84
+ version_requirements: &id005 !ruby/object:Gem::Requirement
86
85
  none: false
87
86
  requirements:
88
87
  - - ">="
@@ -93,12 +92,12 @@ dependencies:
93
92
  - 4
94
93
  - 0
95
94
  version: 0.4.0
95
+ requirement: *id005
96
+ name: capybara
96
97
  type: :development
97
- version_requirements: *id005
98
98
  - !ruby/object:Gem::Dependency
99
- name: launchy
100
99
  prerelease: false
101
- requirement: &id006 !ruby/object:Gem::Requirement
100
+ version_requirements: &id006 !ruby/object:Gem::Requirement
102
101
  none: false
103
102
  requirements:
104
103
  - - ">="
@@ -107,8 +106,9 @@ dependencies:
107
106
  segments:
108
107
  - 0
109
108
  version: "0"
109
+ requirement: *id006
110
+ name: launchy
110
111
  type: :development
111
- version_requirements: *id006
112
112
  description: Simple username/password authentication for Rails 3.
113
113
  email:
114
114
  - boss@airbladesoftware.com
@@ -193,6 +193,7 @@ files:
193
193
  - test/dummy/tmp/capybara/capybara-20110124134214.html
194
194
  - test/dummy/tmp/capybara/capybara-20110124135435.html
195
195
  - test/integration/authenticate_test.rb
196
+ - test/integration/blocked_test.rb
196
197
  - test/integration/config_test.rb
197
198
  - test/integration/cookie_test.rb
198
199
  - test/integration/csrf_test.rb
@@ -296,6 +297,7 @@ test_files:
296
297
  - test/dummy/tmp/capybara/capybara-20110124134214.html
297
298
  - test/dummy/tmp/capybara/capybara-20110124135435.html
298
299
  - test/integration/authenticate_test.rb
300
+ - test/integration/blocked_test.rb
299
301
  - test/integration/config_test.rb
300
302
  - test/integration/cookie_test.rb
301
303
  - test/integration/csrf_test.rb