action_interceptor 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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