action_interceptor 0.5.3 → 1.0.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 +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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce38ce707a8334bb66b8acf906521d3b3767d4b8
|
4
|
+
data.tar.gz: 27684b0414dbd5d8c7b7e1eeb89c7595afaa8c94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77ae4ca36711165371f3001101bf52e6f2cb3710bdcbaf17f2d48ee7c210c0f2130fb19e0ec8478cfebac4f73e01f173d66338e1cf296775c5c10c13119c99e3
|
7
|
+
data.tar.gz: 489a4126575dd1928b1840b420b38896e55e5a6de05403de093115657d6385ec290f8a4ad8318239c0361208dd781a13ca9683966af3396c2eb7391162a08010
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright 2014 Rice University
|
1
|
+
Copyright 2014-2015 Rice University
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
@@ -18,4 +18,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
-
|
data/README.md
CHANGED
@@ -4,11 +4,11 @@
|
|
4
4
|
[](https://travis-ci.org/openstax/action_interceptor)
|
5
5
|
[](https://codeclimate.com/github/openstax/action_interceptor)
|
6
6
|
|
7
|
-
Action Interceptor is a Rails engine that makes it easy to
|
8
|
-
|
9
|
-
they were when the interception happened.
|
7
|
+
Action Interceptor is a Rails engine that makes it easy to store and
|
8
|
+
retrieve return url's across multiple requests and different controllers.
|
10
9
|
|
11
|
-
This can be used, for example, for registration, authentication,
|
10
|
+
This can be used, for example, for registration, authentication,
|
11
|
+
signing terms of use, etc.
|
12
12
|
|
13
13
|
## Installation
|
14
14
|
|
@@ -33,121 +33,44 @@ $ 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
|
36
|
+
to your application's root url.
|
37
37
|
|
38
38
|
## Usage
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
Before your before_filter or controller redirects the user to the
|
41
|
+
login/registration/terms of use page, call `store_url`
|
42
|
+
to store the current url.
|
43
43
|
|
44
|
-
|
45
|
-
|
44
|
+
In the login/registration/terms of use page, call `store_fallback`
|
45
|
+
to store the http referer, in case the user reached that page
|
46
|
+
through an unexpected path.
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
return if current_user.try(:is_registered?)
|
51
|
-
|
52
|
-
respond_to do |format|
|
53
|
-
format.html { redirect_to register_path }
|
54
|
-
format.json { head(:forbidden) }
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
```
|
59
|
-
|
60
|
-
What makes interceptors different from before_filters is that they will
|
61
|
-
save the user's current url before redirecting. This is done through
|
62
|
-
signed url params by default, falling back to session variables if those
|
63
|
-
params are absent or invalid.
|
64
|
-
|
65
|
-
Once declared, you can use an interceptor in any controller. For example,
|
66
|
-
you might want to ensure that all logged in users have to complete
|
67
|
-
a form before using your site. In that case, you could add the following
|
68
|
-
to your `ApplicationController`:
|
69
|
-
|
70
|
-
```rb
|
71
|
-
class ApplicationController < ActionController::Base
|
48
|
+
When the user is done with their task, call `redirect_back`
|
49
|
+
to send them back to where they were before.
|
72
50
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
The controllers your interceptors redirect to should
|
79
|
-
call the `acts_as_interceptor` method:
|
80
|
-
|
81
|
-
```rb
|
82
|
-
class RegistrationsController < ApplicationController
|
83
|
-
|
84
|
-
acts_as_interceptor
|
85
|
-
|
86
|
-
skip_interceptor :registration, only: [:new, :create]
|
87
|
-
|
88
|
-
end
|
89
|
-
```
|
90
|
-
|
91
|
-
As shown above, interceptions work like before_filters and
|
92
|
-
can be skipped using the skip_interceptor method.
|
51
|
+
All of those methods can also take an options hash,
|
52
|
+
where you can pass a `:key` argument.
|
53
|
+
If your site uses multiple different redirects, you can specify
|
54
|
+
a different `:key` for each in order to have them not overwrite each other.
|
93
55
|
|
94
56
|
Just by including the gem in your app, the following convenience methods
|
95
57
|
will also be added to all controllers as helper methods, so they will also
|
96
|
-
be available in views: `current_page?(url)`, `current_url
|
97
|
-
`with_interceptor(&block)` and `without_interceptor(&block)`.
|
98
|
-
|
99
|
-
- `with_interceptor(&block)` executes the given block:
|
100
|
-
- Adding the intercepted URL param to all links and redirects
|
101
|
-
- As if it was declared in the context of `self`
|
102
|
-
- `without_interceptor(&block)` executes the given block:
|
103
|
-
- With the default URL params for all links and redirects
|
104
|
-
- As if it was declared in the context of `self`
|
105
|
-
|
106
|
-
- `current_url_hash` returns a hash containing the `intercepted_url_key` and the
|
107
|
-
`current_url`, signed and encrypted.
|
58
|
+
be available in views: `current_page?(url)`, `current_url` and `stored_url`.
|
108
59
|
|
109
|
-
- And the following methods, backported from Rails 4:
|
110
60
|
- `current_url` returns the current url.
|
111
61
|
- `current_page?(url)` returns true iif the given url is the `current_url`.
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
-
|
124
|
-
`redirect_back(options = {})`, `intercepted_url`,
|
125
|
-
`intercepted_url=` and `intercepted_url_hash`.
|
126
|
-
These methods have the following behavior:
|
127
|
-
|
128
|
-
- redirect_back(options = {}) redirects the user back to where the
|
129
|
-
interception occurred, passing the given options to the redirect method.
|
130
|
-
|
131
|
-
- `intercepted_url` returns the intercepted url. Can be used in views to make
|
132
|
-
links that redirect the user back to where the interception happened.
|
133
|
-
|
134
|
-
- `intercepted_url=` can be used to overwrite the intercepted url, if needed.
|
135
|
-
|
136
|
-
- `intercepted_url_hash` returns a hash containing the `interceptor_url_key`
|
137
|
-
and the signed `intercepted_url`.
|
138
|
-
|
139
|
-
When users complete the given task, use the following method to
|
140
|
-
redirect them back to where the interception occurred:
|
141
|
-
|
142
|
-
```rb
|
143
|
-
redirect_back
|
144
|
-
```
|
145
|
-
|
146
|
-
Alternatively, you can use `intercepted_url` in views:
|
147
|
-
|
148
|
-
```erb
|
149
|
-
<%= link_to 'Back', intercepted_url %>
|
150
|
-
```
|
62
|
+
- `stored_url` returns the stored url.
|
63
|
+
|
64
|
+
The following convenience methods are also added to controllers:
|
65
|
+
`store_url`, `store_fallback`, `delete_stored_url` and `redirect_back`.
|
66
|
+
These methods have the following behavior:
|
67
|
+
|
68
|
+
- `store_url` stores the current url
|
69
|
+
(or specify the url using the `:url` option).
|
70
|
+
- `store_fallback` stores the http referer only if no stored url
|
71
|
+
is already present (or specify the fallback url using `:url` option).
|
72
|
+
- `delete_stored_url` deletes the stored url.
|
73
|
+
- `redirect_back` redirects the user to the stored url and deletes it.
|
151
74
|
|
152
75
|
## Contributing
|
153
76
|
|
@@ -1,51 +1,25 @@
|
|
1
|
-
ActionInterceptor.configure do
|
2
|
-
#
|
3
|
-
#
|
1
|
+
ActionInterceptor.configure do |config|
|
2
|
+
# default_strategies
|
3
|
+
# Type: Array
|
4
|
+
# Array of the default strategies used to store and retrieve url's.
|
5
|
+
# When storing a url, all strategies will be used.
|
6
|
+
# When attempting to retrieve stored url's, strategies will be called
|
7
|
+
# in order until one of them returns a non-blank string.
|
8
|
+
# Available strategies: :session
|
9
|
+
# Default: [ :session ]
|
10
|
+
config.default_strategies = [ :session ]
|
4
11
|
|
5
|
-
#
|
6
|
-
# Type:
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# Default:
|
10
|
-
|
11
|
-
|
12
|
-
# override_url_options(bool)
|
13
|
-
# Type: Method
|
14
|
-
# Arguments: bool (Boolean)
|
15
|
-
# If true, the url_options method will be overriden for any controller that
|
16
|
-
# `acts_as_interceptor`. This option causes all links and redirects from any
|
17
|
-
# such controller to include a parameter containing the intercepted_url_key
|
18
|
-
# and the intercepted url.
|
19
|
-
# If set to false, you must use the interceptor_url_options method to obtain
|
20
|
-
# the hash and pass it to any links or redirects that need to use it.
|
21
|
-
# Default: true
|
22
|
-
override_url_options true
|
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
|
12
|
+
# default_url
|
13
|
+
# Type: String
|
14
|
+
# If no stored url is found, or if the stored url would cause a self redirect,
|
15
|
+
# controller methods will use (redirect to) this url instead.
|
16
|
+
# Default: nil (root_url)
|
17
|
+
config.default_url = nil
|
37
18
|
|
38
|
-
#
|
39
|
-
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
|
44
|
-
# Defines an interceptor.
|
45
|
-
# Default: none
|
46
|
-
# Example: interceptor :my_name do
|
47
|
-
# redirect_to my_action_users_url if some_condition
|
48
|
-
# end
|
49
|
-
#
|
50
|
-
# (Conditionally redirects to :my_action in UsersController)
|
19
|
+
# default_key
|
20
|
+
# Type: Symbol
|
21
|
+
# The default key under which url's are stored in the session.
|
22
|
+
# Used if the :key option is not provided when storing or retrieving url's.
|
23
|
+
# Default: :r
|
24
|
+
config.default_key = :r
|
51
25
|
end
|
data/lib/action_interceptor.rb
CHANGED
@@ -1,29 +1,16 @@
|
|
1
1
|
require 'action_interceptor/engine'
|
2
|
+
require 'action_interceptor/configuration'
|
3
|
+
require 'action_interceptor/strategies'
|
4
|
+
require 'action_interceptor/strategies/session'
|
2
5
|
|
3
6
|
module ActionInterceptor
|
4
7
|
|
5
|
-
|
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
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.interceptors
|
18
|
-
@interceptors ||= {}
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.interceptor(interceptor_name, &block)
|
22
|
-
interceptors.merge!({interceptor_name => block})
|
8
|
+
def self.config
|
9
|
+
@config ||= Configuration.new
|
23
10
|
end
|
24
11
|
|
25
12
|
def self.configure(&block)
|
26
|
-
|
13
|
+
yield config
|
27
14
|
end
|
28
15
|
|
29
16
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module ActionInterceptor
|
2
|
+
module ActionController
|
3
|
+
module Base
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.helper_method :current_page?, :current_url, :stored_url
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def current_page?(url)
|
12
|
+
# Return true for blank (blank links redirect to the same page)
|
13
|
+
return true if url.blank?
|
14
|
+
|
15
|
+
uri = URI(url)
|
16
|
+
uri.path == request.path && (
|
17
|
+
uri.relative? || (
|
18
|
+
uri.host == request.host && uri.port == request.port
|
19
|
+
)
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def current_url
|
24
|
+
"#{request.protocol}#{request.host_with_port}#{request.fullpath}"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Stores the given url or the current url
|
28
|
+
def store_url(options = {})
|
29
|
+
strats = ActionInterceptor::Strategies.find_all(self,
|
30
|
+
options[:strategies])
|
31
|
+
key = options[:key] || ActionInterceptor.config.default_key
|
32
|
+
|
33
|
+
url = options.has_key?(:url) ? options[:url] : current_url
|
34
|
+
|
35
|
+
strats.each do |strat|
|
36
|
+
strat.set(key, url)
|
37
|
+
end
|
38
|
+
|
39
|
+
url
|
40
|
+
end
|
41
|
+
|
42
|
+
# Retrieves the stored url
|
43
|
+
def stored_url(options = {})
|
44
|
+
strats = ActionInterceptor::Strategies.find_all(self,
|
45
|
+
options[:strategies])
|
46
|
+
key = options[:key] || ActionInterceptor.config.default_key
|
47
|
+
|
48
|
+
strats.each do |strat|
|
49
|
+
url = strat.get(key)
|
50
|
+
return url unless url.blank?
|
51
|
+
end
|
52
|
+
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
# Stores the given url or the referer if no stored url is present
|
57
|
+
def store_fallback(options = {})
|
58
|
+
store_url({url: request.referer}.merge(options)) \
|
59
|
+
if stored_url(options).blank?
|
60
|
+
end
|
61
|
+
|
62
|
+
# Deletes to the stored url
|
63
|
+
def delete_stored_url(options = {})
|
64
|
+
strats = ActionInterceptor::Strategies.find_all(self,
|
65
|
+
options[:strategies])
|
66
|
+
key = options[:key] || ActionInterceptor.config.default_key
|
67
|
+
|
68
|
+
strats.each do |strat|
|
69
|
+
strat.unset(key)
|
70
|
+
end
|
71
|
+
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
# Redirects to the stored url and deletes it from storage
|
76
|
+
def redirect_back(options = {})
|
77
|
+
interceptor_options = options.slice(:key, :strategies)
|
78
|
+
redirect_options = options.except(:key, :strategies)
|
79
|
+
|
80
|
+
url = stored_url(interceptor_options)
|
81
|
+
delete_stored_url(interceptor_options)
|
82
|
+
|
83
|
+
# Prevent self redirects
|
84
|
+
url = (ActionInterceptor.config.default_url || main_app.root_url) \
|
85
|
+
if current_page?(url)
|
86
|
+
|
87
|
+
redirect_to url, redirect_options
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
ActionController::Base.send :include, ActionInterceptor::ActionController::Base
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActionInterceptor
|
2
|
+
module Strategies
|
3
|
+
|
4
|
+
def self.register(name, strategy_class)
|
5
|
+
@strategy_map ||= HashWithIndifferentAccess.new
|
6
|
+
@strategy_map[name] = strategy_class
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.find(controller, name)
|
10
|
+
@strategy_map[name].new(controller)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find_all(controller, names)
|
14
|
+
names ||= ActionInterceptor.config.default_strategies
|
15
|
+
names.collect{|name| find(controller, name)}
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'action_interceptor/strategies'
|
2
|
+
|
3
|
+
module ActionInterceptor
|
4
|
+
module Strategies
|
5
|
+
class Session
|
6
|
+
|
7
|
+
def initialize(controller)
|
8
|
+
@session = controller.session
|
9
|
+
end
|
10
|
+
|
11
|
+
def set(key, string)
|
12
|
+
@session[key] = string
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(key)
|
16
|
+
@session[key]
|
17
|
+
end
|
18
|
+
|
19
|
+
def unset(key)
|
20
|
+
@session.delete(key)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
ActionInterceptor::Strategies.register(:session,
|
28
|
+
ActionInterceptor::Strategies::Session)
|