action_interceptor 0.5.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -2
- data/README.md +30 -107
- data/config/initializers/action_interceptor.rb +22 -48
- data/lib/action_interceptor.rb +6 -19
- data/lib/action_interceptor/action_controller/base.rb +94 -0
- data/lib/action_interceptor/configuration.rb +7 -0
- data/lib/action_interceptor/engine.rb +1 -3
- data/lib/action_interceptor/strategies.rb +19 -0
- data/lib/action_interceptor/strategies/session.rb +28 -0
- data/lib/action_interceptor/version.rb +1 -1
- data/spec/dummy/config/application.rb +0 -2
- data/spec/dummy/config/environments/production.rb +1 -1
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/config/initializers/action_interceptor.rb +3 -11
- data/spec/dummy/lib/strategies/dummy.rb +24 -0
- data/spec/dummy/log/test.log +1 -0
- data/spec/lib/action_interceptor/action_controller/base_spec.rb +65 -0
- data/spec/lib/action_interceptor/configuration_spec.rb +20 -0
- data/spec/lib/action_interceptor/strategies/session_spec.rb +29 -0
- data/spec/lib/action_interceptor/strategies_spec.rb +23 -0
- data/spec/lib/action_interceptor_spec.rb +2 -18
- metadata +35 -35
- data/lib/action_interceptor/action_controller.rb +0 -175
- data/lib/action_interceptor/action_mailer.rb +0 -21
- data/lib/action_interceptor/common.rb +0 -74
- data/lib/action_interceptor/encryptor.rb +0 -36
- data/lib/action_interceptor/undefined_interceptor.rb +0 -4
- data/spec/lib/action_interceptor/action_controller_spec.rb +0 -62
- data/spec/lib/action_interceptor/action_mailer_spec.rb +0 -16
- data/spec/lib/action_interceptor/common_spec.rb +0 -25
- data/spec/lib/action_interceptor/encryptor_spec.rb +0 -19
@@ -18,7 +18,5 @@ module Dummy
|
|
18
18
|
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
19
19
|
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
20
20
|
# config.i18n.default_locale = :de
|
21
|
-
|
22
|
-
config.i18n.enforce_available_locales = true
|
23
21
|
end
|
24
22
|
end
|
@@ -20,7 +20,7 @@ Dummy::Application.configure do
|
|
20
20
|
# config.action_dispatch.rack_cache = true
|
21
21
|
|
22
22
|
# Disable Rails's static asset server (Apache or nginx will already do this).
|
23
|
-
config.
|
23
|
+
config.serve_static_files = false
|
24
24
|
|
25
25
|
# Compress JavaScripts and CSS.
|
26
26
|
config.assets.js_compressor = :uglifier
|
@@ -13,7 +13,7 @@ Dummy::Application.configure do
|
|
13
13
|
config.eager_load = false
|
14
14
|
|
15
15
|
# Configure static asset server for tests with Cache-Control for performance.
|
16
|
-
config.
|
16
|
+
config.serve_static_files = true
|
17
17
|
config.static_cache_control = "public, max-age=3600"
|
18
18
|
|
19
19
|
# Show full error reports and disable caching.
|
@@ -1,13 +1,5 @@
|
|
1
|
-
ActionInterceptor.configure do
|
2
|
-
|
1
|
+
ActionInterceptor.configure do |config|
|
2
|
+
config.default_url = '/dummy'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
skip_session false
|
7
|
-
|
8
|
-
interceptor :registration do
|
9
|
-
end
|
10
|
-
|
11
|
-
interceptor :my_interceptor do
|
12
|
-
end
|
4
|
+
config.default_key = :dummy_key
|
13
5
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Strategies
|
2
|
+
class Dummy
|
3
|
+
|
4
|
+
attr_reader :controller
|
5
|
+
|
6
|
+
def initialize(controller)
|
7
|
+
@controller = controller
|
8
|
+
@url = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def set(key, string)
|
12
|
+
@url[key] = string
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(key)
|
16
|
+
@url[key]
|
17
|
+
end
|
18
|
+
|
19
|
+
def unset(key)
|
20
|
+
@url.delete(:key)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
data/spec/dummy/log/test.log
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
Redirected to
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ActionInterceptor
|
4
|
+
module ActionController
|
5
|
+
describe Base do
|
6
|
+
|
7
|
+
let!(:request) {
|
8
|
+
r = ::ActionController::TestRequest.new(host: 'http://test.me')
|
9
|
+
r.env['HTTP_REFERER'] = 'http://refer.er'
|
10
|
+
r
|
11
|
+
}
|
12
|
+
let!(:controller) {
|
13
|
+
c = ::ActionController::Base.new
|
14
|
+
c.request = request
|
15
|
+
c
|
16
|
+
}
|
17
|
+
|
18
|
+
it 'modifies ActionController::Base' do
|
19
|
+
expect(controller.respond_to?(:current_page?, true)).to eq true
|
20
|
+
expect(controller.respond_to?(:current_url, true)).to eq true
|
21
|
+
expect(controller.respond_to?(:store_url, true)).to eq true
|
22
|
+
expect(controller.respond_to?(:stored_url, true)).to eq true
|
23
|
+
expect(controller.respond_to?(:store_fallback, true)).to eq true
|
24
|
+
expect(controller.respond_to?(:delete_stored_url, true)).to eq true
|
25
|
+
expect(controller.respond_to?(:redirect_back, true)).to eq true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "allows controllers to store and retrieve url's" do
|
29
|
+
current_url = controller.send(:current_url)
|
30
|
+
expect(controller.send(:current_page?, current_url)).to eq true
|
31
|
+
referer = request.referer
|
32
|
+
|
33
|
+
expect(controller.send(:current_page?, referer)).to eq false
|
34
|
+
|
35
|
+
expect(controller.send(:stored_url)).to be_blank
|
36
|
+
|
37
|
+
expect(controller.send(:store_url)).to eq current_url
|
38
|
+
expect(controller.send(:stored_url)).to eq current_url
|
39
|
+
|
40
|
+
expect(controller.send(:delete_stored_url)).to be_nil
|
41
|
+
expect(controller.send(:stored_url)).to be_blank
|
42
|
+
|
43
|
+
expect(controller.send(:store_fallback)).to eq referer
|
44
|
+
expect(controller.send(:stored_url)).to eq referer
|
45
|
+
|
46
|
+
expect(controller).to receive(:redirect_to) { |url| url }
|
47
|
+
expect(controller.send(:redirect_back)).to eq(referer)
|
48
|
+
expect(controller.send(:stored_url)).to be_blank
|
49
|
+
|
50
|
+
expect(controller.send(:store_url)).to eq current_url
|
51
|
+
expect(controller.send(:stored_url)).to eq current_url
|
52
|
+
|
53
|
+
expect(controller.send(:store_fallback)).to eq nil
|
54
|
+
expect(controller.send(:stored_url)).to eq current_url
|
55
|
+
|
56
|
+
expect(controller).to receive(:redirect_to) { |url| url }
|
57
|
+
expect(controller.send(:redirect_back)).to(
|
58
|
+
eq ActionInterceptor.config.default_url
|
59
|
+
)
|
60
|
+
expect(controller.send(:stored_url)).to be_blank
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ActionInterceptor
|
4
|
+
describe Configuration do
|
5
|
+
|
6
|
+
let!(:config) { Configuration.new }
|
7
|
+
|
8
|
+
it 'stores configuration options' do
|
9
|
+
expect(config.default_url).to be_nil
|
10
|
+
expect(config.default_key).to be_nil
|
11
|
+
|
12
|
+
config.default_url = '/url'
|
13
|
+
config.default_key = :key
|
14
|
+
|
15
|
+
expect(config.default_url).to eq('/url')
|
16
|
+
expect(config.default_key).to eq(:key)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ActionInterceptor
|
4
|
+
module Strategies
|
5
|
+
describe Session do
|
6
|
+
|
7
|
+
let!(:request) {
|
8
|
+
::ActionController::TestRequest.new(:host => 'http://test.me')
|
9
|
+
}
|
10
|
+
let!(:controller) {
|
11
|
+
c = ::ActionController::Base.new
|
12
|
+
c.request = request
|
13
|
+
c
|
14
|
+
}
|
15
|
+
let!(:strategy) { Session.new(controller) }
|
16
|
+
let!(:key) { :key }
|
17
|
+
let!(:string) { 'string' }
|
18
|
+
|
19
|
+
it "stores and retrieves url's in the session" do
|
20
|
+
expect(strategy.get(key)).to eq nil
|
21
|
+
expect(strategy.set(key, string)).to eq string
|
22
|
+
expect(strategy.get(key)).to eq string
|
23
|
+
expect(strategy.unset(key)).to eq string
|
24
|
+
expect(strategy.get(key)).to eq nil
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dummy/lib/strategies/dummy'
|
3
|
+
|
4
|
+
module ActionInterceptor
|
5
|
+
describe Strategies do
|
6
|
+
|
7
|
+
let!(:controller) { ::ActionController::Base.new }
|
8
|
+
|
9
|
+
it 'registers and instantiates storage strategies' do
|
10
|
+
ActionInterceptor::Strategies.register(:dummy, ::Strategies::Dummy)
|
11
|
+
strategy = ActionInterceptor::Strategies.find(controller, :dummy)
|
12
|
+
expect(strategy).to be_a ::Strategies::Dummy
|
13
|
+
expect(strategy.controller).to eq controller
|
14
|
+
|
15
|
+
strategies = ActionInterceptor::Strategies.find_all(controller, [:dummy])
|
16
|
+
strategies.each do |strategy|
|
17
|
+
expect(strategy).to be_a ::Strategies::Dummy
|
18
|
+
expect(strategy.controller).to eq controller
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -2,23 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ActionInterceptor do
|
4
4
|
it 'must be configurable' do
|
5
|
-
expect(ActionInterceptor
|
6
|
-
expect(ActionInterceptor
|
7
|
-
expect(ActionInterceptor::DEFAULT_CONFIG[:skip_session]).to eq(false)
|
8
|
-
expect(ActionInterceptor.interceptors.keys).to include(:registration)
|
9
|
-
|
10
|
-
my_block = lambda { 'my_block' }
|
11
|
-
|
12
|
-
ActionInterceptor.configure do
|
13
|
-
intercepted_url_key :my_key
|
14
|
-
override_url_options false
|
15
|
-
skip_session true
|
16
|
-
interceptor :my_name, &my_block
|
17
|
-
end
|
18
|
-
|
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)
|
22
|
-
expect(ActionInterceptor.interceptors).to include({:my_name => my_block})
|
5
|
+
expect(ActionInterceptor.config.default_url).to eq('/dummy')
|
6
|
+
expect(ActionInterceptor.config.default_key).to eq(:dummy_key)
|
23
7
|
end
|
24
8
|
end
|
metadata
CHANGED
@@ -1,79 +1,79 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action_interceptor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.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:
|
11
|
+
date: 2015-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '3.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sqlite3
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec-rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
description: Action Interceptor provides
|
56
|
-
|
57
|
-
registration, signing terms of use, etc.
|
55
|
+
description: Action Interceptor provides methods to store return url's across multiple
|
56
|
+
requests. Useful during authentication, registration, signing terms of use, etc.
|
58
57
|
email:
|
59
58
|
- dms3@rice.edu
|
60
59
|
executables: []
|
61
60
|
extensions: []
|
62
61
|
extra_rdoc_files: []
|
63
62
|
files:
|
63
|
+
- MIT-LICENSE
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
64
66
|
- config/initializers/action_interceptor.rb
|
65
|
-
- lib/action_interceptor
|
66
|
-
- lib/action_interceptor/
|
67
|
-
- lib/action_interceptor/
|
68
|
-
- lib/action_interceptor/encryptor.rb
|
67
|
+
- lib/action_interceptor.rb
|
68
|
+
- lib/action_interceptor/action_controller/base.rb
|
69
|
+
- lib/action_interceptor/configuration.rb
|
69
70
|
- lib/action_interceptor/engine.rb
|
70
|
-
- lib/action_interceptor/
|
71
|
+
- lib/action_interceptor/strategies.rb
|
72
|
+
- lib/action_interceptor/strategies/session.rb
|
71
73
|
- lib/action_interceptor/version.rb
|
72
|
-
- lib/action_interceptor.rb
|
73
74
|
- lib/tasks/action_interceptor_tasks.rake
|
74
|
-
-
|
75
|
-
- Rakefile
|
76
|
-
- README.md
|
75
|
+
- spec/dummy/README.md
|
76
|
+
- spec/dummy/Rakefile
|
77
77
|
- spec/dummy/app/assets/javascripts/application.js
|
78
78
|
- spec/dummy/app/assets/stylesheets/application.css
|
79
79
|
- spec/dummy/app/controllers/application_controller.rb
|
@@ -83,6 +83,7 @@ files:
|
|
83
83
|
- spec/dummy/bin/bundle
|
84
84
|
- spec/dummy/bin/rails
|
85
85
|
- spec/dummy/bin/rake
|
86
|
+
- spec/dummy/config.ru
|
86
87
|
- spec/dummy/config/application.rb
|
87
88
|
- spec/dummy/config/boot.rb
|
88
89
|
- spec/dummy/config/database.yml
|
@@ -100,20 +101,18 @@ files:
|
|
100
101
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
101
102
|
- spec/dummy/config/locales/en.yml
|
102
103
|
- spec/dummy/config/routes.rb
|
103
|
-
- spec/dummy/config.ru
|
104
104
|
- spec/dummy/db/test.sqlite3
|
105
|
+
- spec/dummy/lib/strategies/dummy.rb
|
105
106
|
- spec/dummy/log/development.log
|
106
107
|
- spec/dummy/log/test.log
|
107
108
|
- spec/dummy/public/404.html
|
108
109
|
- spec/dummy/public/422.html
|
109
110
|
- spec/dummy/public/500.html
|
110
111
|
- spec/dummy/public/favicon.ico
|
111
|
-
- spec/
|
112
|
-
- spec/
|
113
|
-
- spec/lib/action_interceptor/
|
114
|
-
- spec/lib/action_interceptor/
|
115
|
-
- spec/lib/action_interceptor/common_spec.rb
|
116
|
-
- spec/lib/action_interceptor/encryptor_spec.rb
|
112
|
+
- spec/lib/action_interceptor/action_controller/base_spec.rb
|
113
|
+
- spec/lib/action_interceptor/configuration_spec.rb
|
114
|
+
- spec/lib/action_interceptor/strategies/session_spec.rb
|
115
|
+
- spec/lib/action_interceptor/strategies_spec.rb
|
117
116
|
- spec/lib/action_interceptor_spec.rb
|
118
117
|
- spec/spec_helper.rb
|
119
118
|
homepage: http://github.com/openstax/action_interceptor
|
@@ -126,20 +125,20 @@ require_paths:
|
|
126
125
|
- lib
|
127
126
|
required_ruby_version: !ruby/object:Gem::Requirement
|
128
127
|
requirements:
|
129
|
-
- -
|
128
|
+
- - ">="
|
130
129
|
- !ruby/object:Gem::Version
|
131
130
|
version: '0'
|
132
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
132
|
requirements:
|
134
|
-
- -
|
133
|
+
- - ">="
|
135
134
|
- !ruby/object:Gem::Version
|
136
135
|
version: '0'
|
137
136
|
requirements: []
|
138
137
|
rubyforge_project:
|
139
|
-
rubygems_version: 2.
|
138
|
+
rubygems_version: 2.4.6
|
140
139
|
signing_key:
|
141
140
|
specification_version: 4
|
142
|
-
summary: Handles
|
141
|
+
summary: Handles storage of return url's across multiple requests
|
143
142
|
test_files:
|
144
143
|
- spec/dummy/app/assets/javascripts/application.js
|
145
144
|
- spec/dummy/app/assets/stylesheets/application.css
|
@@ -169,6 +168,7 @@ test_files:
|
|
169
168
|
- spec/dummy/config/routes.rb
|
170
169
|
- spec/dummy/config.ru
|
171
170
|
- spec/dummy/db/test.sqlite3
|
171
|
+
- spec/dummy/lib/strategies/dummy.rb
|
172
172
|
- spec/dummy/log/development.log
|
173
173
|
- spec/dummy/log/test.log
|
174
174
|
- spec/dummy/public/404.html
|
@@ -177,9 +177,9 @@ test_files:
|
|
177
177
|
- spec/dummy/public/favicon.ico
|
178
178
|
- spec/dummy/Rakefile
|
179
179
|
- spec/dummy/README.md
|
180
|
-
- spec/lib/action_interceptor/
|
181
|
-
- spec/lib/action_interceptor/
|
182
|
-
- spec/lib/action_interceptor/
|
183
|
-
- spec/lib/action_interceptor/
|
180
|
+
- spec/lib/action_interceptor/action_controller/base_spec.rb
|
181
|
+
- spec/lib/action_interceptor/configuration_spec.rb
|
182
|
+
- spec/lib/action_interceptor/strategies/session_spec.rb
|
183
|
+
- spec/lib/action_interceptor/strategies_spec.rb
|
184
184
|
- spec/lib/action_interceptor_spec.rb
|
185
185
|
- spec/spec_helper.rb
|
@@ -1,175 +0,0 @@
|
|
1
|
-
require 'action_interceptor/common'
|
2
|
-
require 'action_interceptor/encryptor'
|
3
|
-
require 'action_interceptor/undefined_interceptor'
|
4
|
-
|
5
|
-
module ActionInterceptor
|
6
|
-
module ActionController
|
7
|
-
|
8
|
-
def self.included(base)
|
9
|
-
base.class_attribute :interceptor_config, :interceptor_filters
|
10
|
-
base.interceptor_filters = {}
|
11
|
-
|
12
|
-
base.send :attr_accessor, :interceptor_enabled
|
13
|
-
|
14
|
-
base.before_filter :interceptor_setup
|
15
|
-
|
16
|
-
base.helper_method :interceptor_enabled, :interceptor_enabled=,
|
17
|
-
:is_interceptor?, :current_page?,
|
18
|
-
:current_url, :current_url_hash,
|
19
|
-
|
20
|
-
base.extend(ClassMethods)
|
21
|
-
end
|
22
|
-
|
23
|
-
def _compute_redirect_to_location(*args, &block)
|
24
|
-
url_for(super(*args, &block))
|
25
|
-
end
|
26
|
-
|
27
|
-
protected
|
28
|
-
|
29
|
-
def is_interceptor?
|
30
|
-
!interceptor_config.nil?
|
31
|
-
end
|
32
|
-
|
33
|
-
def current_page?(url)
|
34
|
-
# Blank is the current page
|
35
|
-
url.blank? || URI(url).path == request.path
|
36
|
-
end
|
37
|
-
|
38
|
-
def current_url
|
39
|
-
"#{request.protocol}#{request.host_with_port}#{request.fullpath}"
|
40
|
-
end
|
41
|
-
|
42
|
-
def current_url_hash
|
43
|
-
return @current_url_hash if @current_url_hash
|
44
|
-
|
45
|
-
config = interceptor_config || ActionInterceptor::DEFAULT_CONFIG
|
46
|
-
key = config[:intercepted_url_key]
|
47
|
-
|
48
|
-
# Can't redirect back to non-get
|
49
|
-
# Also, can't call root_url here, so use '/' instead
|
50
|
-
url = Encryptor.encrypt_and_sign(request.get? ? current_url : '/')
|
51
|
-
|
52
|
-
@current_url_hash = {key => url}
|
53
|
-
end
|
54
|
-
|
55
|
-
def interceptor_setup
|
56
|
-
if is_interceptor?
|
57
|
-
self.interceptor_enabled = interceptor_config[:override_url_options]
|
58
|
-
session.delete(:interceptor) if interceptor_config[:skip_session]
|
59
|
-
else
|
60
|
-
self.interceptor_enabled = false
|
61
|
-
session.delete(:interceptor)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
module ClassMethods
|
66
|
-
|
67
|
-
def interceptor(*interceptor_names, &block)
|
68
|
-
options = interceptor_names.extract_options!
|
69
|
-
filter_name = options.delete(:filter_name)
|
70
|
-
fnames = interceptor_names.collect do |iname|
|
71
|
-
fname = filter_name || iname
|
72
|
-
interceptor_filters[iname] = fname
|
73
|
-
|
74
|
-
define_method fname do
|
75
|
-
blk = block || ActionInterceptor.interceptors[iname]
|
76
|
-
raise UndefinedInterceptor, iname unless blk
|
77
|
-
|
78
|
-
with_interceptor &blk
|
79
|
-
end
|
80
|
-
|
81
|
-
fname
|
82
|
-
end
|
83
|
-
|
84
|
-
before_filter *fnames, options
|
85
|
-
end
|
86
|
-
|
87
|
-
def skip_interceptor(*interceptor_names)
|
88
|
-
options = interceptor_names.extract_options!
|
89
|
-
filter_name = options.delete(:filter_name)
|
90
|
-
fnames = interceptor_names.collect do |iname|
|
91
|
-
filter_name || interceptor_filters[iname] || iname
|
92
|
-
end
|
93
|
-
|
94
|
-
skip_before_filter *fnames, options
|
95
|
-
end
|
96
|
-
|
97
|
-
def acts_as_interceptor(opts = {})
|
98
|
-
self.interceptor_config = ActionInterceptor::DEFAULT_CONFIG.merge(opts)
|
99
|
-
|
100
|
-
class_exec do
|
101
|
-
|
102
|
-
attr_writer :intercepted_url
|
103
|
-
|
104
|
-
# Ensure that we always store the intercepted url
|
105
|
-
before_filter :intercepted_url
|
106
|
-
|
107
|
-
helper_method :intercepted_url, :intercepted_url_hash
|
108
|
-
|
109
|
-
protected
|
110
|
-
|
111
|
-
def intercepted_url
|
112
|
-
return @intercepted_url if @intercepted_url
|
113
|
-
|
114
|
-
key = interceptor_config[:intercepted_url_key]
|
115
|
-
encrypted_url = params[key]
|
116
|
-
session_hash = session[:interceptor] \
|
117
|
-
unless interceptor_config[:skip_session]
|
118
|
-
session_hash ||= {}
|
119
|
-
|
120
|
-
begin
|
121
|
-
# URL params are the most reliable, as they preserve
|
122
|
-
# state even if the user presses the back button
|
123
|
-
# We need to sign them to prevent the Open Redirect vulnerability
|
124
|
-
@intercepted_url = Encryptor.decrypt_and_verify(encrypted_url)
|
125
|
-
|
126
|
-
# If we got this far, the encrypted url is valid
|
127
|
-
# (i.e. we signed it), so reuse it
|
128
|
-
@intercepted_url_hash = {key => encrypted_url}
|
129
|
-
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
130
|
-
# If the param is not available, use our best guess
|
131
|
-
# Session and referer are safe for redirects (for that user)
|
132
|
-
# Also, can't call root_url here, so use '/' instead
|
133
|
-
@intercepted_url = session_hash[key] || request.referer || '/'
|
134
|
-
end
|
135
|
-
|
136
|
-
# Prevent self-redirect
|
137
|
-
@intercepted_url = '/' if current_page?(@intercepted_url)
|
138
|
-
|
139
|
-
# Session is a signed plaintext in Rails 3
|
140
|
-
# In Rails 4, it is encrypted by default
|
141
|
-
session[:interceptor] = session_hash.merge(
|
142
|
-
key => @intercepted_url
|
143
|
-
) unless interceptor_config[:skip_session]
|
144
|
-
|
145
|
-
@intercepted_url
|
146
|
-
end
|
147
|
-
|
148
|
-
def intercepted_url_hash
|
149
|
-
# Run intercepted_url to verify the params in case the
|
150
|
-
# encrypted url is in there and can be reused
|
151
|
-
unencrypted_url = intercepted_url
|
152
|
-
return @intercepted_url_hash if @intercepted_url_hash
|
153
|
-
|
154
|
-
url = Encryptor.encrypt_and_sign(unencrypted_url)
|
155
|
-
key = interceptor_config[:intercepted_url_key]
|
156
|
-
|
157
|
-
@intercepted_url_hash = {key => url}
|
158
|
-
end
|
159
|
-
|
160
|
-
def redirect_back(options = {})
|
161
|
-
# Disable the return_to param
|
162
|
-
without_interceptor do
|
163
|
-
redirect_to intercepted_url, options
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
ActionController::Base.send :include, ActionInterceptor::ActionController
|