quo_vadis 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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