action_interceptor 0.4.2 → 0.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e6f93ac6fa7c78a37f96b25bb4ab379ade1a116c
4
- data.tar.gz: 623fd90ba2bca94868f9fc225dbd18f08f1650ec
3
+ metadata.gz: 9917c52164470d451b2fe730c0b95975a006eb59
4
+ data.tar.gz: 44dde1824b2307cdff19e5b6aea9bb6eed142c9a
5
5
  SHA512:
6
- metadata.gz: 4f04a024c8f10af888a129440e7c44957927d59620a98374cc92f74838c7da01a17f7ed18aa729018677a8d6dbcd06ff922db0b2981db7746292221258128fa2
7
- data.tar.gz: a8a717896e5d9ced3b7df4b3350e0da05932e53553fb6657cd62e058fe9340e03acb84cf423d952e1b7481fa0ddaaf5947bab782c762a94e27b2e7a7d76ca4c6
6
+ metadata.gz: 12136e90006094d68efee066d82b60656e053b48fbe97860866e10295333d0520040b82e6c413e3397117083b447b5fd58388becf0edd4e90b4c5d890d5d0de2
7
+ data.tar.gz: a37aa52a41c91ca9627337a414a080707e25c2fd9107ea739e00a2afe47e9ab065a9507ecc761c09e7dd303bec98a9895ad05880d69236ac38ef88d8a839e283
data/README.md CHANGED
@@ -33,14 +33,7 @@ $ rake action_interceptor:install
33
33
 
34
34
  In case Action Interceptor is completely unable to determine which page a user
35
35
  came from (should rarely happen if properly configured), it will send the user
36
- to your application or gem's root_url. So make sure it is defined:
37
-
38
- ```rb
39
- root :to => 'some_controller#some_action'
40
- ```
41
-
42
- Alternatively, you can always stub root_url in your
43
- ApplicationController and make it a helper method.
36
+ to your application or gem's root (the '/' path).
44
37
 
45
38
  ## Usage
46
39
 
@@ -1,4 +1,7 @@
1
1
  ActionInterceptor.configure do
2
+ # The following options can be set in this initializer
3
+ # or passed directly to acts_as_interceptor:
4
+
2
5
  # intercepted_url_key(key)
3
6
  # Type: Method
4
7
  # Arguments: key (Symbol)
@@ -12,12 +15,28 @@ ActionInterceptor.configure do
12
15
  # If true, the url_options method will be overriden for any controller that
13
16
  # `acts_as_interceptor`. This option causes all links and redirects from any
14
17
  # such controller to include a parameter containing the intercepted_url_key
15
- # and the intercepted url. Set to false to disable for all controllers.
18
+ # and the intercepted url.
16
19
  # If set to false, you must use the interceptor_url_options method to obtain
17
20
  # the hash and pass it to any links or redirects that need to use it.
18
21
  # Default: true
19
22
  override_url_options true
20
23
 
24
+ # skip_session(bool)
25
+ # Type: Method
26
+ # Arguments: bool (Boolean)
27
+ # If set to false, ActionInterceptor will store and use the intercepted url
28
+ # in the session object, under the :interceptor key. ActionInterceptor will
29
+ # attempt to retrieve the intercepted url from the url params, session and
30
+ # referer, in this order.
31
+ # If true, ActionInterceptor will ignore the session, so only the url params
32
+ # and the referer will be checked, in this order.
33
+ # Useful if you expect to get redirects that do not or cannot properly set
34
+ # the url params and must rely on the referer instead.
35
+ # Default: false
36
+ skip_session false
37
+
38
+ # The following options can only be set in this initializer:
39
+
21
40
  # interceptor(interceptor_name, &block)
22
41
  # Type: Method
23
42
  # Arguments: interceptor name (Symbol or String),
@@ -1,14 +1,17 @@
1
1
  require 'action_interceptor/engine'
2
2
 
3
3
  module ActionInterceptor
4
- def self.intercepted_url_key(key = nil)
5
- @intercepted_url_key = key.to_s unless key.blank?
6
- @intercepted_url_key || 'r'
7
- end
8
4
 
9
- def self.override_url_options(bool = nil)
10
- @override_url_options = bool unless bool.nil?
11
- @override_url_options.nil? ? true : @override_url_options
5
+ DEFAULT_CONFIG = {}
6
+
7
+ INTERCEPTOR_ATTRIBUTES = [:intercepted_url_key,
8
+ :override_url_options,
9
+ :skip_session]
10
+
11
+ INTERCEPTOR_ATTRIBUTES.each do |attribute|
12
+ define_singleton_method(attribute) do |value|
13
+ DEFAULT_CONFIG[attribute] = value
14
+ end
12
15
  end
13
16
 
14
17
  def self.interceptors
@@ -22,4 +25,5 @@ module ActionInterceptor
22
25
  def self.configure(&block)
23
26
  instance_exec &block
24
27
  end
28
+
25
29
  end
@@ -6,25 +6,30 @@ module ActionInterceptor
6
6
  module ActionController
7
7
 
8
8
  def self.included(base)
9
- base.class_attribute :is_interceptor, :use_interceptor,
10
- :interceptor_filters
11
- base.is_interceptor = false
12
- base.use_interceptor = false
9
+ base.class_attribute :interceptor_config, :interceptor_filters
13
10
  base.interceptor_filters = {}
14
11
 
15
- base.before_filter :delete_intercepted_url
12
+ base.send :attr_accessor, :interceptor_enabled
16
13
 
17
- base.helper_method :is_interceptor, :use_interceptor, :use_interceptor=,
18
- :current_page?, :current_url, :current_url_hash,
14
+ base.before_filter :interceptor_setup
15
+
16
+ base.helper_method :_compute_redirect_to_location,
17
+ :interceptor_enabled, :interceptor_enabled=,
18
+ :is_interceptor?, :current_page?,
19
+ :current_url, :current_url_hash,
19
20
 
20
21
  base.extend(ClassMethods)
21
22
  end
22
23
 
24
+ protected
25
+
23
26
  def _compute_redirect_to_location(*args, &block)
24
27
  url_for(super(*args, &block))
25
28
  end
26
29
 
27
- protected
30
+ def is_interceptor?
31
+ !interceptor_config.nil?
32
+ end
28
33
 
29
34
  def current_page?(url)
30
35
  # Blank is the current page
@@ -38,7 +43,7 @@ module ActionInterceptor
38
43
  def current_url_hash
39
44
  return @current_url_hash if @current_url_hash
40
45
 
41
- key = ActionInterceptor.intercepted_url_key
46
+ key = interceptor_config[:intercepted_url_key]
42
47
 
43
48
  # Can't redirect back to non-get
44
49
  # Also, can't call root_url here, so use '/' instead
@@ -47,8 +52,15 @@ module ActionInterceptor
47
52
  @current_url_hash = {key => url}
48
53
  end
49
54
 
50
- def delete_intercepted_url
51
- session.delete(ActionInterceptor.intercepted_url_key)
55
+ def interceptor_setup
56
+ config = interceptor_config
57
+ if is_interceptor?
58
+ self.interceptor_enabled = interceptor_config[:override_url_options]
59
+ session.delete(:interceptor) if interceptor_config[:skip_session]
60
+ else
61
+ self.interceptor_enabled = false
62
+ session.delete(:interceptor)
63
+ end
52
64
  end
53
65
 
54
66
  module ClassMethods
@@ -83,18 +95,13 @@ module ActionInterceptor
83
95
  skip_before_filter *fnames, options
84
96
  end
85
97
 
86
- def acts_as_interceptor(options = {})
87
- self.is_interceptor = true
88
- self.use_interceptor = options[:override_url_options].nil? ? \
89
- ActionInterceptor.override_url_options : \
90
- options[:override_url_options]
98
+ def acts_as_interceptor(opts = {})
99
+ self.interceptor_config = ActionInterceptor::DEFAULT_CONFIG.merge(opts)
91
100
 
92
101
  class_exec do
93
102
 
94
103
  attr_writer :intercepted_url
95
104
 
96
- skip_before_filter :delete_intercepted_url
97
-
98
105
  # Ensure that we always store the intercepted url
99
106
  before_filter :intercepted_url
100
107
 
@@ -105,8 +112,11 @@ module ActionInterceptor
105
112
  def intercepted_url
106
113
  return @intercepted_url if @intercepted_url
107
114
 
108
- key = ActionInterceptor.intercepted_url_key
115
+ key = interceptor_config[:intercepted_url_key]
109
116
  encrypted_url = params[key]
117
+ session_hash = session[:interceptor] \
118
+ unless interceptor_config[:skip_session]
119
+ session_hash ||= {}
110
120
 
111
121
  begin
112
122
  # URL params are the most reliable, as they preserve
@@ -114,17 +124,24 @@ module ActionInterceptor
114
124
  # We need to sign them to prevent the Open Redirect vulnerability
115
125
  @intercepted_url = Encryptor.decrypt_and_verify(encrypted_url)
116
126
 
117
- # If we got this far, the encrypted url is valid, so reuse it
127
+ # If we got this far, the encrypted url is valid
128
+ # (i.e. we signed it), so reuse it
118
129
  @intercepted_url_hash = {key => encrypted_url}
119
130
  rescue ActiveSupport::MessageVerifier::InvalidSignature
120
131
  # If the param is not available, use our best guess
121
132
  # Session and referer are safe for redirects (for that user)
122
133
  # Also, can't call root_url here, so use '/' instead
123
- @intercepted_url = session[key] || request.referer || '/'
134
+ @intercepted_url = session_hash[key] || request.referer || '/'
124
135
  end
136
+
137
+ # Prevent self-redirect
138
+ @intercepted_url = '/' if current_page?(@intercepted_url)
139
+
125
140
  # Session is a signed plaintext in Rails 3
126
141
  # In Rails 4, it is encrypted by default
127
- session[key] = @intercepted_url
142
+ session[:interceptor] = session_hash.merge(
143
+ key => @intercepted_url) unless interceptor_config[:skip_session]
144
+
128
145
  @intercepted_url
129
146
  end
130
147
 
@@ -135,21 +152,15 @@ module ActionInterceptor
135
152
  return @intercepted_url_hash if @intercepted_url_hash
136
153
 
137
154
  url = Encryptor.encrypt_and_sign(unencrypted_url)
138
- key = ActionInterceptor.intercepted_url_key
155
+ key = interceptor_config[:intercepted_url_key]
139
156
 
140
157
  @intercepted_url_hash = {key => url}
141
158
  end
142
159
 
143
160
  def redirect_back(options = {})
144
- url = intercepted_url
145
-
146
161
  # Disable the return_to param
147
162
  without_interceptor do
148
- # Convert '/' back to root_url
149
- # Also, prevent self redirects
150
- url = root_url if url == '/' || current_page?(url)
151
-
152
- redirect_to url, options
163
+ redirect_to intercepted_url, options
153
164
  end
154
165
  end
155
166
 
@@ -2,16 +2,16 @@ module ActionInterceptor
2
2
  module ActionMailer
3
3
 
4
4
  def self.included(base)
5
- base.helper_method :use_interceptor, :use_interceptor=
5
+ base.helper_method :interceptor_enabled, :interceptor_enabled=
6
6
  end
7
7
 
8
8
  protected
9
9
 
10
- def use_interceptor
10
+ def interceptor_enabled
11
11
  false
12
12
  end
13
13
 
14
- def use_interceptor=(arg)
14
+ def interceptor_enabled=(arg)
15
15
  false
16
16
  end
17
17
 
@@ -9,9 +9,9 @@ module ActionInterceptor
9
9
 
10
10
  def url_for_with_interceptor(options = {})
11
11
  url = url_for_without_interceptor(options)
12
- return url unless use_interceptor
12
+ return url unless interceptor_enabled
13
13
 
14
- @interceptor_url_for_hash ||= is_interceptor ? \
14
+ @interceptor_url_for_hash ||= is_interceptor? ? \
15
15
  intercepted_url_hash : \
16
16
  current_url_hash
17
17
 
@@ -26,12 +26,12 @@ module ActionInterceptor
26
26
 
27
27
  # Executes the given block as if it was inside an interceptor
28
28
  def with_interceptor(&block)
29
- previous_use_interceptor = use_interceptor
29
+ previous_interceptor_enabled = interceptor_enabled
30
30
 
31
31
  begin
32
32
  # Send the referer with intercepted requests
33
33
  # So we don't rely on the user's browser to do it for us
34
- self.use_interceptor = true
34
+ self.interceptor_enabled = true
35
35
 
36
36
  # Execute the block as if it was defined in this controller
37
37
  instance_exec &block
@@ -40,18 +40,18 @@ module ActionInterceptor
40
40
  # and return the given value
41
41
  e.exit_value
42
42
  ensure
43
- self.use_interceptor = previous_use_interceptor
43
+ self.interceptor_enabled = previous_interceptor_enabled
44
44
  end
45
45
  end
46
46
 
47
47
  # Executes the given block as if it was not inside an interceptor
48
48
  def without_interceptor(&block)
49
- previous_use_interceptor = use_interceptor
49
+ previous_interceptor_enabled = interceptor_enabled
50
50
 
51
51
  begin
52
52
  # Send the referer with intercepted requests
53
53
  # So we don't rely on the user's browser to do it for us
54
- self.use_interceptor = false
54
+ self.interceptor_enabled = false
55
55
 
56
56
  # Execute the block as if it was defined in this controller
57
57
  instance_exec &block
@@ -60,7 +60,7 @@ module ActionInterceptor
60
60
  # and return the given value
61
61
  e.exit_value
62
62
  ensure
63
- self.use_interceptor = previous_use_interceptor
63
+ self.interceptor_enabled = previous_interceptor_enabled
64
64
  end
65
65
  end
66
66
 
@@ -1,3 +1,3 @@
1
1
  module ActionInterceptor
2
- VERSION = '0.4.2'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -3,6 +3,8 @@ ActionInterceptor.configure do
3
3
 
4
4
  override_url_options true
5
5
 
6
+ skip_session false
7
+
6
8
  interceptor :registration do
7
9
  end
8
10
 
@@ -4,16 +4,19 @@ module ActionInterceptor
4
4
  describe ActionController do
5
5
 
6
6
  it 'modifies ActionController::Base' do
7
- expect(::ActionController::Base).to respond_to(:is_interceptor)
8
- expect(::ActionController::Base).to respond_to(:use_interceptor)
9
7
  expect(::ActionController::Base).to respond_to(:interceptor_filters)
10
- expect(::ActionController::Base.is_interceptor).to eq(false)
11
8
  expect(::ActionController::Base.interceptor_filters).to be_a(Hash)
12
9
 
13
10
  expect(::ActionController::Base).to respond_to(:interceptor)
14
11
  expect(::ActionController::Base).to respond_to(:skip_interceptor)
15
12
  expect(::ActionController::Base).to respond_to(:acts_as_interceptor)
16
13
 
14
+ expect(::ActionController::Base.new.respond_to?(
15
+ :is_interceptor?, true)).to eq(true)
16
+ expect(::ActionController::Base.new.send :is_interceptor?).to eq(false)
17
+
18
+ expect(::ActionController::Base.new.respond_to?(
19
+ :interceptor_enabled, true)).to eq(true)
17
20
  expect(::ActionController::Base.new.respond_to?(
18
21
  :current_page?, true)).to eq(true)
19
22
  expect(::ActionController::Base.new.respond_to?(
@@ -23,7 +26,7 @@ module ActionInterceptor
23
26
  end
24
27
 
25
28
  it 'modifies classes that act_as_interceptor' do
26
- expect(RegistrationsController.is_interceptor).to eq(true)
29
+ expect(RegistrationsController.new.send :is_interceptor?).to eq(true)
27
30
 
28
31
  expect(RegistrationsController.new.respond_to?(
29
32
  :intercepted_url, true)).to eq(true)
@@ -5,11 +5,11 @@ module ActionInterceptor
5
5
 
6
6
  it 'modifies ActionMailer::Base' do
7
7
  mailer = ::ActionMailer::Base.send(:new)
8
- expect(mailer.respond_to?(:use_interceptor, true)).to eq(true)
9
- expect(mailer.respond_to?(:use_interceptor=, true)).to eq(true)
8
+ expect(mailer.respond_to?(:interceptor_enabled, true)).to eq(true)
9
+ expect(mailer.respond_to?(:interceptor_enabled=, true)).to eq(true)
10
10
 
11
- expect(mailer.send(:use_interceptor)).to eq(false)
12
- expect(mailer.send(:use_interceptor=, true)).to eq(false)
11
+ expect(mailer.send(:interceptor_enabled)).to eq(false)
12
+ expect(mailer.send(:interceptor_enabled=, true)).to eq(false)
13
13
  end
14
14
 
15
15
  end
@@ -2,8 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe ActionInterceptor do
4
4
  it 'must be configurable' do
5
- expect(ActionInterceptor.intercepted_url_key).to eq('dummy_key')
6
- expect(ActionInterceptor.override_url_options).to eq(true)
5
+ expect(ActionInterceptor::DEFAULT_CONFIG[:intercepted_url_key]).to eq(:dummy_key)
6
+ expect(ActionInterceptor::DEFAULT_CONFIG[:override_url_options]).to eq(true)
7
+ expect(ActionInterceptor::DEFAULT_CONFIG[:skip_session]).to eq(false)
7
8
  expect(ActionInterceptor.interceptors.keys).to include(:registration)
8
9
 
9
10
  my_block = lambda { 'my_block' }
@@ -11,11 +12,13 @@ describe ActionInterceptor do
11
12
  ActionInterceptor.configure do
12
13
  intercepted_url_key :my_key
13
14
  override_url_options false
15
+ skip_session true
14
16
  interceptor :my_name, &my_block
15
17
  end
16
18
 
17
- expect(ActionInterceptor.intercepted_url_key).to eq('my_key')
18
- expect(ActionInterceptor.override_url_options).to eq(false)
19
+ expect(ActionInterceptor::DEFAULT_CONFIG[:intercepted_url_key]).to eq(:my_key)
20
+ expect(ActionInterceptor::DEFAULT_CONFIG[:override_url_options]).to eq(false)
21
+ expect(ActionInterceptor::DEFAULT_CONFIG[:skip_session]).to eq(true)
19
22
  expect(ActionInterceptor.interceptors).to include({:my_name => my_block})
20
23
  end
21
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_interceptor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dante Soares
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-23 00:00:00.000000000 Z
11
+ date: 2014-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails