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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -2
  3. data/README.md +30 -107
  4. data/config/initializers/action_interceptor.rb +22 -48
  5. data/lib/action_interceptor.rb +6 -19
  6. data/lib/action_interceptor/action_controller/base.rb +94 -0
  7. data/lib/action_interceptor/configuration.rb +7 -0
  8. data/lib/action_interceptor/engine.rb +1 -3
  9. data/lib/action_interceptor/strategies.rb +19 -0
  10. data/lib/action_interceptor/strategies/session.rb +28 -0
  11. data/lib/action_interceptor/version.rb +1 -1
  12. data/spec/dummy/config/application.rb +0 -2
  13. data/spec/dummy/config/environments/production.rb +1 -1
  14. data/spec/dummy/config/environments/test.rb +1 -1
  15. data/spec/dummy/config/initializers/action_interceptor.rb +3 -11
  16. data/spec/dummy/lib/strategies/dummy.rb +24 -0
  17. data/spec/dummy/log/test.log +1 -0
  18. data/spec/lib/action_interceptor/action_controller/base_spec.rb +65 -0
  19. data/spec/lib/action_interceptor/configuration_spec.rb +20 -0
  20. data/spec/lib/action_interceptor/strategies/session_spec.rb +29 -0
  21. data/spec/lib/action_interceptor/strategies_spec.rb +23 -0
  22. data/spec/lib/action_interceptor_spec.rb +2 -18
  23. metadata +35 -35
  24. data/lib/action_interceptor/action_controller.rb +0 -175
  25. data/lib/action_interceptor/action_mailer.rb +0 -21
  26. data/lib/action_interceptor/common.rb +0 -74
  27. data/lib/action_interceptor/encryptor.rb +0 -36
  28. data/lib/action_interceptor/undefined_interceptor.rb +0 -4
  29. data/spec/lib/action_interceptor/action_controller_spec.rb +0 -62
  30. data/spec/lib/action_interceptor/action_mailer_spec.rb +0 -16
  31. data/spec/lib/action_interceptor/common_spec.rb +0 -25
  32. 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: 44ab9883cb1bb5fcebed393839f0e9c59922793a
4
- data.tar.gz: d3837244011aaf89a4a280f116505bfe6ed503fa
3
+ metadata.gz: ce38ce707a8334bb66b8acf906521d3b3767d4b8
4
+ data.tar.gz: 27684b0414dbd5d8c7b7e1eeb89c7595afaa8c94
5
5
  SHA512:
6
- metadata.gz: b5701a304ec6e2782e31a0d1795b22ee335fa1b5bfe46ae9a518ed4d75979ed025e2d107380908519ec4698bc1322a2796d195d7ce6150e8a693d6eb4f05b495
7
- data.tar.gz: ea4bed34a80eaa1def6bb9ce09f88df0539357b67dc1ba35ece2ed502856cec109c63e3db043988e3c2287f07e534ad07c743322b4f32a8011dc685d79f5433b
6
+ metadata.gz: 77ae4ca36711165371f3001101bf52e6f2cb3710bdcbaf17f2d48ee7c210c0f2130fb19e0ec8478cfebac4f73e01f173d66338e1cf296775c5c10c13119c99e3
7
+ data.tar.gz: 489a4126575dd1928b1840b420b38896e55e5a6de05403de093115657d6385ec290f8a4ad8318239c0361208dd781a13ca9683966af3396c2eb7391162a08010
@@ -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 have controllers intercept
8
- actions from other controllers, have users perform a task and then return them to where
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, signing terms of use, etc.
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 or gem's root (the '/' path).
36
+ to your application's root url.
37
37
 
38
38
  ## Usage
39
39
 
40
- Interceptors are blocks of code that are declared in Action Interceptor's
41
- initializer. They execute in the context of your controllers and work
42
- very much like before_filters.
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
- For example, the following interceptor could be used to ensure that users
45
- have filled out a registration form:
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
- ```rb
48
- interceptor :registration do
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
- interceptor :registration
74
-
75
- end
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`, `current_url_hash`,
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
- When called, the `acts_as_interceptor` method will ensure the following:
114
-
115
- - The `url_options` method for that controller will be overriden, causing all
116
- links and redirects for the controller and associated views to include
117
- the signed return url. This behavior can be skipped by passing
118
- `:override_url_options => false` to the `acts_as_interceptor` call,
119
- like so: `acts_as_interceptor :override_url_options => false`.
120
- In that case, you are responsible for wrapping any internal links and
121
- redirects in `with_interceptor` blocks.
122
-
123
- - The following convenience methods will be added to the controller:
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
- # The following options can be set in this initializer
3
- # or passed directly to acts_as_interceptor:
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
- # intercepted_url_key(key)
6
- # Type: Method
7
- # Arguments: key (Symbol)
8
- # The parameter/session variable that will hold the intercepted URL.
9
- # Default: :r
10
- intercepted_url_key :r
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
- # The following options can only be set in this initializer:
39
-
40
- # interceptor(interceptor_name, &block)
41
- # Type: Method
42
- # Arguments: interceptor name (Symbol or String),
43
- # &block (Proc)
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
@@ -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
- 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
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
- instance_exec &block
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,7 @@
1
+ module ActionInterceptor
2
+ class Configuration
3
+
4
+ attr_accessor :default_strategies, :default_url, :default_key
5
+
6
+ end
7
+ end
@@ -1,6 +1,4 @@
1
- require 'action_interceptor/common'
2
- require 'action_interceptor/action_controller'
3
- require 'action_interceptor/action_mailer'
1
+ require 'action_interceptor/action_controller/base'
4
2
 
5
3
  module ActionInterceptor
6
4
  class Engine < ::Rails::Engine
@@ -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)