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
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
|
[![Build Status](https://travis-ci.org/openstax/action_interceptor.svg?branch=master)](https://travis-ci.org/openstax/action_interceptor)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/openstax/action_interceptor.png)](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)
|