redirectr 0.1.1 → 1.0.3

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
- SHA1:
3
- metadata.gz: 2d2e5bda91ce0407fb196a450cf6adf0fc33aba2
4
- data.tar.gz: bc3a10bed54b7ff7a3804d2894de0c8cb64d3a2d
2
+ SHA256:
3
+ metadata.gz: aab12433022382d5fc61e4964d815430d39cf08aec7b6bbc32672065fdf7d115
4
+ data.tar.gz: 54b286ec8bc69898564184f1d2488189b3523f0da279d8d61b0ac3cd7444176a
5
5
  SHA512:
6
- metadata.gz: 3f6eba38b0be27a841e24ed82381723befad33f545cd6ac603f8da33e91d582afb7b4d826a7e65032d6f48113cc2c8ddd7c77bb8adab01c24e62694f05b3cbca
7
- data.tar.gz: 9bc23622bb0a245bff831d0c7323149e91da3c44c011d8209cf22a90b9c0ae1c9d07d84ad011492bb6a5631423c3aa399be8763fceb2abebc1b745a4066275df
6
+ metadata.gz: 96332b3a061883e9b49881d74d1a54475f2850f4b9952404c5bf7bc2e478fc698c3e0097b5ea2cc53075274632249f34d80e390b2692ff95936c309065c04eb1
7
+ data.tar.gz: 582e0f5a9a7175068924b6d5dec1d7ef2044b14b6c935861d35dc555302cfd461317425ea69e913fa92c46be903d185753e2f925fe2130247da156008c8cba25
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2020 Willem van Kerkhof
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # Redirectr
2
+
3
+ In many web applications, the user triggers actions that result in simple or complex workflows that should, after that workflow is finished, result in the user being redirected to the page where he initially started it. Another example would be a "back"-Link on any page.
4
+ A simple but completely Un-RESTful way would be to store the "current" page in a cookie each time the user calls an action and redirect to the url stored there if needed.
5
+
6
+ A much better (and potentially even cacheable) way is to encode the "backlink" URL in an URL parameter or form field and pass it along with every workflow step until the last (or only) action uses it to redirect the user back to where he initially came from.
7
+
8
+ Redirectr really does nothing more than provide a simple API for exactly that.
9
+
10
+ Redirectr provides a few Controller and Helper methods that will be included in your ApplicationController and ApplicationHelper, respectively.
11
+
12
+ ## Installation
13
+
14
+ when Using bundler, just at the following to your Gemfile
15
+
16
+ gem 'redirectr'
17
+
18
+ and then call
19
+
20
+ bundle install
21
+
22
+ ## Migrating from 0.1.x to 1.0.0
23
+
24
+ Please read this section if you are already using an older version of Redirectr in yout project. Otherwise, you may skip it.
25
+
26
+ Pre-1.0 versions of Redirectr automatically included some view helpers (`hidden_referrer_input_tag`, `link_to_back`). This is no longer the case, so please add the following to your `app/helper/application_helper.rb`:
27
+
28
+ module ApplicationHelper
29
+ include Redirectr::ApplicationHelper
30
+ end
31
+
32
+ Please note that methods like `current_path`, `referrer_path` have been removed. Only `current_url`, `referrer_url` exist. Please do also note that the value returned by these methods is not a String containing an URI value anymore. Instead, a Redirectr::ReferrerToken is returned which maps a token to an URI. To get the URI value, call `#to_s` (e.g. when used in a `redirect_to` call). When used as an URL parameter, Rails calls `#to_param` which returns the token.
33
+
34
+ Summary:
35
+
36
+ # pre-1.0.0:
37
+ referrer_url.inspect # => 'https://example.com/...'
38
+ redirect_to referrer_url
39
+ redirect_to back_or_default
40
+
41
+ # post-1.0.0:
42
+ referrer_url.inspect # => '#<Redirectr::ReferrerToken:... @url="..." @token="...">'
43
+ redirect_to referrer_url.to_s
44
+ redirect_to back_or_default.to_s
45
+ # OR, if you mount Redirectr::Engine in your routes
46
+ redirect_to referrer_url
47
+ redirect_to back_or_default
48
+
49
+ # pre-1.0.0:
50
+ link_to 'take me back', back_or_default(my_url)
51
+
52
+ # post-1.0.0:
53
+ link_to 'take me back', back_or_default(my_url).to_s
54
+ # OR, if you mount Redirectr::Engine in your routes
55
+ link_to 'take me back', back_or_default(my_url)
56
+
57
+ ## Examples
58
+
59
+ ### Contact Form
60
+
61
+ Suppose you have an application with a contact form that can be reached via a footer link on every page. After submitting the form, the user should be redirected to the page he was before clicking on the "contact form" link.
62
+
63
+ for the footer link to the contact form:
64
+
65
+ <%= link_to 'Contact us!', new_contact_path(referrer_param => current_url) %>
66
+
67
+ In the 'new contact' view:
68
+
69
+ <%= form_for ... do |f| %>
70
+ <%= hidden_referrer_input_tag %>
71
+ <!-- ... -->
72
+ <% end %>
73
+
74
+ and finally, in the 'create' action of your ContactsController:
75
+
76
+ def create
77
+ # ...
78
+ redirect_to back_or_default.to_s
79
+ end
80
+
81
+ ### Custom default_url
82
+
83
+ The above will redirect the user back to the page specified in the referrer param. However, if you want to provide a custom fallback url per controller in case no referrer param is provided, just define the `#default_url` in your controller:
84
+
85
+ class MyController < ApplicationController
86
+ def default_url
87
+ if @record
88
+ my_record_path(@record)
89
+ else
90
+ my_record_index_path
91
+ end
92
+ end
93
+ end
94
+
95
+ ### Nesting referrers
96
+
97
+ Referrer params can be nested, which is helpful if your workflow involves branching into subworkflows. Thus, it is always possible to pass the referrer_param to another url:
98
+
99
+ <%= link_to 'go back directly', referrer_or_current_url %>
100
+ <%= link_to 'add new Foobar before going back', new_foobar_url(:foobar => {:name => 'My Foo'}, referrer_param => referrer_or_current_url) %>
101
+
102
+ NOTE: If your URLs include lots of params, it is very advisable to use Referrer Tokens instead of plain URLs to avoud "URI too long" errors. See next section.
103
+
104
+ ## Unvalidated Redirect Mitigation
105
+
106
+ Simply redirecting to an URI provided by HTTP params is considered a security vulnerability (see OWASP cheat sheet https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html). Earlier versions of redirectr did not take any potential issues into account, allowing all kinds of phishing attacs.
107
+
108
+ Redirectr offers three kinds of mitigation, two of them being optional:
109
+
110
+ * checking the referrer param against a whitelist before performing a redirect (mandatory): by default, the request's host name and port number are allowed and all other hosts are disallowed.
111
+ * encrypting and signing the referrer URL using the Rails secret key base: makes the referrer param absolutely tamper-proof but requires all services to use the same secret_key_base in a multi-service deployment.
112
+ * using random tokens instead of referrer URLs and an token-to-URL lookup service. This leaves you with the additional side effect of also having an URL shortener.
113
+
114
+ ### Using the whitelist
115
+
116
+ By default, Redirectr checks the protocol, hostname and port of the referrer against the corresponding values of the current request. You may add your own:
117
+
118
+ YourApp::Application.configure do
119
+ config.x.redirectr.whitelist = %w( http://localhost:3000 https://my.host.com )
120
+ end
121
+
122
+ ### Token instead of URL (URL-shortener)
123
+
124
+ Instead of using a URL in the referrer token, redirectr can act as an URL shortener that maps random tokens to URLs. This requires a storage_implementation to be defined:
125
+
126
+
127
+ require 'redirectr/referrer_token/active_record_storage'
128
+
129
+ YourApp::Application.configure do
130
+ config.x.redirectr.use_referrer_token = true
131
+ config.x.redirectr.reuse_tokens = true # set to false to generate a new token for each and every link
132
+ config.x.redirectr.storage_implementation = Redirectr::ReferrerToken::ActiveRecordStorage
133
+ end
134
+
135
+ This example requires a table named 'redirectr_referrer_tokens' to be present with two columns: `url` and `token`. To install and apply the required schema migration, run:
136
+
137
+ bundle exec rails redirectr:install:migrations
138
+ bundle exec rails db:migrate
139
+
140
+ Redirectr::ReferrerToken has two representations: #to_s displays the URL and #to_param its tokenized form. Depending on your config, this can be either a random token, an encrypted URL or the plaintext URL.
141
+
142
+ ## Contributions
143
+
144
+ Contributions like bugfixes and new ideas are more than welcome. Please just fork this project on github (https://github.com/wvk/redirectr) and send me a pull request with your changes.
145
+
146
+ Thanks so far to:
147
+
148
+ * Falk Hoppe for Rails 2.3.x interoperability
149
+ * Dimitar Haralanov for Rails 3.0.x interoperability
150
+ * Raffael Schmid for spotting a typo in the gemspec description ;)
151
+ * Till Schulte-Coerne for removing implicit dependencies and cleaning up unused code
152
+
153
+ Copyright (c) 2010 Willem van Kerkhof <wvk@consolving.de>, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Redirectr'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+ task default: :test
@@ -0,0 +1,19 @@
1
+ module Redirectr
2
+ module ApplicationHelper
3
+ # Create a link back to the path specified in the referrer-param.
4
+ # title can be either a text string or anything else like an image.
5
+ # Remember to call #html_safe on the title argument if it contains
6
+ # HTML and you are using Rails >=3.
7
+ def link_to_back(title, options = {})
8
+ link_to title, back_or_default.to_s, options.merge(rel: 'back')
9
+ end
10
+
11
+ # Create a hidden input field containing the referrer or current path.
12
+ # Handy for use in forms that are called with a referrer param which
13
+ # has to be passed on and respected by the form processing action.
14
+ def hidden_referrer_input_tag(options = {})
15
+ hidden_field_tag :referrer, referrer_or_current_url.to_param, options
16
+ end
17
+
18
+ end
19
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ Redirectr::Engine.routes.draw do
2
+
3
+ #resources :referrer_tokens # for future use as URL shortener
4
+
5
+ end
@@ -0,0 +1,10 @@
1
+ class CreateRedirectrReferrerTokens < ActiveRecord::Migration[6.0]
2
+ def change
3
+ create_table :redirectr_referrer_tokens do |t|
4
+ t.string :url, index: true
5
+ t.string :token, unique: true
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ module Redirectr
2
+ class Engine < ::Rails::Engine
3
+ #isolate_namespace Redirectr
4
+ end
5
+ end
@@ -0,0 +1,28 @@
1
+ module Redirectr
2
+ class ReferrerToken
3
+
4
+ # this is a stora implementation for activerecord-
5
+ class ActiveRecordStorage < ActiveRecord::Base
6
+ validates_presence_of :url, :token
7
+
8
+ self.table_name = :redirectr_referrer_tokens
9
+
10
+ class << self
11
+ def store(record)
12
+ self.find_or_create_by url: record.url, token: record.token
13
+ record.url
14
+ end
15
+
16
+ def fetch(token)
17
+ url = self.find_by(token: token)&.url
18
+ ReferrerToken(url) if url
19
+ end
20
+
21
+ def token_for_url(url)
22
+ self.find_by(url: url)&.token
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ module Redirectr
2
+ class ReferrerToken
3
+
4
+ class GlobalVarStorage
5
+
6
+ def persisted?
7
+ false
8
+ end
9
+
10
+ class << self
11
+ def store(record)
12
+ $referrer_lookup[record.token] = record.url
13
+ end
14
+
15
+ def fetch(token)
16
+ ReferrerToken($referrer_lookup[token])
17
+ end
18
+
19
+ def token_for_url(url)
20
+ $referrer_lookup.key(url)
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,73 @@
1
+ require 'active_model'
2
+
3
+ module Redirectr
4
+ class ReferrerToken
5
+
6
+ extend ActiveModel::Naming
7
+
8
+ attr_reader :url, :token
9
+
10
+ def initialize(url, token=nil)
11
+ @url = url
12
+ @token = token
13
+
14
+ if Redirectr.config.use_referrer_token
15
+ if Redirectr.config.storage_implementation.nil?
16
+ raise "Missing storage implementation for referrer tokens! please define config.x.redirectr.storage_implementation"
17
+ end
18
+
19
+ if Redirectr.config.reuse_tokens
20
+ @token ||= Redirectr.config.storage_implementation.token_for_url(url)
21
+ end
22
+ @token ||= SecureRandom.hex(16)
23
+ elsif Redirectr.config.encrypt_referrer
24
+ @token ||= self.class.cryptr.encrypt_and_sign url
25
+ else
26
+ @token ||= url
27
+ end
28
+ end
29
+
30
+ def to_param
31
+ @token
32
+ end
33
+
34
+ def to_model
35
+ self
36
+ end
37
+
38
+ def to_s
39
+ @url
40
+ end
41
+
42
+ def persisted?
43
+ true
44
+ end
45
+
46
+ def save
47
+ if Redirectr.config.use_referrer_token
48
+ Redirectr.config.storage_implementation.store self
49
+ end
50
+ end
51
+
52
+ def self.from_param(param)
53
+ if Redirectr.config.encrypt_referrer
54
+ ReferrerToken.new self.class.cryptr.decrypt_and_verify param
55
+ elsif Redirectr.config.use_referrer_token
56
+ self.lookup(param)
57
+ else
58
+ ReferrerToken.new param
59
+ end
60
+ end
61
+
62
+ def self.lookup(token)
63
+ Redirectr.config.storage_implementation.fetch token
64
+ end
65
+
66
+ private
67
+
68
+ def self.cryptr
69
+ @cryptr ||= ActiveSupport::MessageEncryptor.new(Rails.application.secrets.secret_key_base)
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ module Redirectr
2
+ VERSION = '1.0.3'
3
+ end
data/lib/redirectr.rb CHANGED
@@ -1,16 +1,48 @@
1
+ require 'securerandom'
2
+
3
+ require 'redirectr/engine'
4
+ require 'redirectr/referrer_token'
5
+
6
+ def ReferrerToken(url, token=nil)
7
+ case url
8
+ when Redirectr::ReferrerToken
9
+ url
10
+ when nil
11
+ nil
12
+ else
13
+ Redirectr::ReferrerToken.new(url, token).tap do |rt|
14
+ #puts "Token for #{url}: #{rt.token}"
15
+ rt.save
16
+ end
17
+ end
18
+ end
19
+
20
+ $referrer_lookup ||= {}
1
21
 
2
22
  module Redirectr
3
23
  REFERRER_PARAM_NAME = :referrer
4
24
 
25
+ class UrlNotInWhitelist < ArgumentError
26
+ end
27
+
28
+ class InvalidReferrerToken < ArgumentError
29
+ end
30
+
31
+ def self.config
32
+ Rails.configuration.x.redirectr
33
+ end
34
+
5
35
  module ControllerMethods
6
36
  extend ActiveSupport::Concern
7
37
 
8
38
  included do
9
- helper_method :current_path, :current_url,
10
- :referrer_or_current_path, :referrer_or_current_url,
39
+ helper_method :current_url,
40
+ :referrer_or_current_url,
11
41
  :back_or_default,
12
- :referrer_path, :referrer_url,
13
- :referrer_param
42
+ :referrer_url,
43
+ :referrer_param,
44
+ :redirectr_referrer_token_url,
45
+ :redirectr_referrer_token_path
14
46
  end
15
47
 
16
48
  module ClassMethods
@@ -24,67 +56,64 @@ module Redirectr
24
56
  # end
25
57
  #
26
58
  def use_referrer_param_name(new_name)
27
- const_set Redirectr::REFERRER_PARAM_NAME, new_name.to_sym
59
+ Redirectr.remove_constant :REFERRER_PARAM_NAME
60
+ Redirectr.const_set :REFERRER_PARAM_NAME, new_name.to_sym
28
61
  end
29
62
  end
30
63
 
64
+ def redirectr_referrer_token_url(rt)
65
+ rt.to_s
66
+ end
67
+
68
+ def redirectr_referrer_token_path(rt)
69
+ rt.to_s
70
+ end
31
71
 
32
72
  # Return the name of the parameter used to pass the referrer path.
33
73
  # Use this instead of the real param name in creating your own links
34
74
  # to allow easily changing the name later
35
75
  # Example:
36
76
  #
37
- # <%= link_to my_messages_path :filter_by => 'date', referrer_param => current_path %>
77
+ # <%= link_to my_messages_url :filter_by => 'date', referrer_param => current_url %>
38
78
  #
39
79
  def referrer_param
40
80
  Redirectr::REFERRER_PARAM_NAME
41
81
  end
42
82
 
43
83
  # Return the complete URL of the current request.
44
- # Note that this path does include ALL query parameters and the host name,
84
+ # Note that this does include ALL query parameters and the host name,
45
85
  # thus allowing you to navigate back and forth between different hosts. If you
46
86
  # want the pre-0.1.0 behaviour back, just overwrite this method
47
87
  # in your controller so it returns "request.env['PATH_INFO']".
48
88
  # Example:
49
89
  #
50
- # <%= link_to my_messages_path referrer_param => current_path %>
90
+ # <%= link_to my_messages_url referrer_param => current_url %>
51
91
  #
52
92
  def current_url
53
- # request.env['PATH_INFO'] # old behaviour
54
93
  if request.respond_to? :url # for rack >= 2.0.0
55
- request.url
94
+ ReferrerToken(request.url)
56
95
  elsif request.respond_to? :original_url # for rails >= 4.0.0
57
- request.original_url
96
+ ReferrerToken(request.original_url)
58
97
  else
59
- request.env['REQUEST_URI']
98
+ ReferrerToken(request.env['REQUEST_URI'])
60
99
  end
61
100
  end
62
101
 
63
- # deprecated
64
- def current_path
65
- current_url
66
- end
67
-
68
102
  # Return the referrer or the current path, it the former is not set.
69
103
  # Useful in cases where there might be a redirect path that has to be
70
104
  # taken note of but in case it is not present, the current path will be
71
105
  # redirected back to.
72
106
  # Example:
73
107
  #
74
- # <%= link_to my_messages_path referrer_param => referrer_or_current_path %>
108
+ # <%= link_to my_messages_url referrer_param => referrer_or_current_url %>
75
109
  #
76
110
  def referrer_or_current_url
77
- referrer_path.blank? ? current_url : referrer_url
78
- end
79
-
80
- # deprecated
81
- def referrer_or_current_path
82
- referrer_or_current_url
111
+ referrer_url.blank? ? current_url : referrer_url
83
112
  end
84
113
 
85
114
  # Used in back links, referrer based redirection after actions etc.
86
115
  # Accepts a default redirect path in case no param[referrer_param]
87
- # is set, default being root_path.
116
+ # is set, default being root_url.
88
117
  # To set an own default path (per controller), you can overwrite
89
118
  # the default_url method (see below).
90
119
  # Example:
@@ -92,12 +121,12 @@ module Redirectr
92
121
  # class MyController
93
122
  # def create
94
123
  # @my = My.create(...)
95
- # redirect_to back_or_default(my_path)
124
+ # redirect_to back_or_default(my_url)
96
125
  # end
97
126
  # end
98
127
  #
99
- # The above example will redirect to the referrer_path if it is defined, otherwise
100
- # it will redirect to the my_path
128
+ # The above example will redirect to the referrer_url if it is defined, otherwise
129
+ # it will redirect to the my_url
101
130
  #
102
131
  # Example:
103
132
  #
@@ -108,57 +137,72 @@ module Redirectr
108
137
  # end
109
138
  # end
110
139
  #
111
- # The above example will redirect to the referrer_path if it is defined, otherwise
112
- # it will redirect to the root_path of the application.
140
+ # The above example will redirect to the referrer_url if it is defined, otherwise
141
+ # it will redirect to the root_url of the application.
113
142
  def back_or_default(default = nil)
114
- unless referrer_path.blank?
115
- referrer_path
143
+ if self.referrer_url.present?
144
+ self.referrer_url
116
145
  else
117
- default || default_url
146
+ case default
147
+ when nil
148
+ ReferrerToken(self.default_url)
149
+ when String
150
+ ReferrerToken(default)
151
+ else
152
+ ReferrerToken(url_for(default))
153
+ end
118
154
  end
119
155
  end
120
156
 
121
157
  # to be overwritten by your controllers
122
158
  def default_url
123
- root_path
124
- end
125
-
126
- # deprecated
127
- def default_path
128
- default_url
159
+ root_url
129
160
  end
130
161
 
131
- # Convenience method for params[referrer_param]
162
+ # reads referrer_param from HTTP params and validates it against the whitelist
132
163
  def referrer_url
133
- params[referrer_param]
134
- end
164
+ return nil if params[referrer_param].blank?
135
165
 
136
- # deprecated
137
- def referrer_path
138
- referrer_url
166
+ referrer_token = ReferrerToken.from_param params[referrer_param]
167
+ raise Redirectr::InvalidReferrerToken, "no URL matches given token value #{params[referrer_param]}" if referrer_token.blank?
168
+
169
+ parsed_url = URI.parse referrer_token.to_s
170
+ if parsed_url.absolute? and in_whitelist? parsed_url
171
+ referrer_token
172
+ elsif parsed_url.relative?
173
+ referrer_token
174
+ else
175
+ raise Redirectr::UrlNotInWhitelist, "#{parsed_url.inspect} - #{redirect_whitelist.inspect}"
176
+ end
139
177
  end
140
- end
141
178
 
142
- module Helpers
143
- extend ActiveSupport::Concern
179
+ def redirect_to_with_whitelist(redirect_url)
180
+ case redirect_url
181
+ when nil
182
+ raise 'Cannot redirect to nil'
183
+ when String
184
+ parsed_url = URI.parse(redirect_url)
185
+ if parsed_url.relative? or in_whitelist? parsed_url
186
+ redirect_to parsed_url
187
+ else
188
+ raise Redirectr::UrlNotInWhitelist, "#{parsed_url.inspect} - #{redirect_whitelist.inspect}"
189
+ end
190
+ else
191
+ redirect_to default
192
+ end
193
+ end
144
194
 
145
- # Create a link back to the path specified in the referrer-param.
146
- # title can be either a text string or anything else like an image.
147
- # Remember to call #html_safe on the title argument if it contains
148
- # HTML and you are using Rails 3.
149
- def link_to_back(title, options = {})
150
- link_to title, back_or_default, options
195
+ def in_whitelist?(parsed_url)
196
+ redirect_whitelist.find {|url| parsed_url.host == url.host and parsed_url.port == url.port }
151
197
  end
152
198
 
153
- # Create a hidden input field containing the referrer or current path.
154
- # Handy for use in forms that are called with a referrer param which
155
- # has to be passed on and respected by the form processing action.
156
- def hidden_referrer_input_tag(options = {})
157
- hidden_field_tag :referrer, referrer_or_current_url, options
199
+ def redirect_whitelist
200
+ @redirect_whitelist ||= [URI.parse(self.current_url.to_s)] +
201
+ Array(Redirectr.config.whitelist).map {|url| URI.parse url.to_s }
158
202
  end
159
- end # module Helpers
203
+ end
204
+
160
205
  end # module Redirectr
161
206
 
162
207
  ActionController::Base.send :include, Redirectr::ControllerMethods
163
- ActionView::Helpers.send :include, Redirectr::Helpers
164
- ActionView::Base.send :include, Redirectr::Helpers
208
+
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :redirectr do
3
+ # # Task goes here
4
+ # end
metadata CHANGED
@@ -1,28 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redirectr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Willem van Kerkhof
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-18 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2023-02-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  description: Provides Rails-helper methods for referrer-style backlinks and setting
14
42
  redirect URLs after form submission
15
- email: wvk@consolving.de
43
+ email:
44
+ - wvk@consolving.de
16
45
  executables: []
17
46
  extensions: []
18
47
  extra_rdoc_files: []
19
48
  files:
20
- - README
49
+ - MIT-LICENSE
50
+ - README.md
51
+ - Rakefile
52
+ - app/helpers/redirectr/application_helper.rb
53
+ - config/routes.rb
54
+ - db/migrate/20201120110532_create_redirectr_referrer_tokens.rb
21
55
  - lib/redirectr.rb
56
+ - lib/redirectr/engine.rb
57
+ - lib/redirectr/referrer_token.rb
58
+ - lib/redirectr/referrer_token/active_record_storage.rb
59
+ - lib/redirectr/referrer_token/global_var_storage.rb
60
+ - lib/redirectr/version.rb
61
+ - lib/tasks/redirectr_tasks.rake
22
62
  homepage: http://github.com/wvk/redirectr
23
- licenses: []
63
+ licenses:
64
+ - MIT
24
65
  metadata: {}
25
- post_install_message:
66
+ post_install_message:
26
67
  rdoc_options: []
27
68
  require_paths:
28
69
  - lib
@@ -37,9 +78,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
37
78
  - !ruby/object:Gem::Version
38
79
  version: '0'
39
80
  requirements: []
40
- rubyforge_project:
41
- rubygems_version: 2.5.2.1
42
- signing_key:
81
+ rubygems_version: 3.3.15
82
+ signing_key:
43
83
  specification_version: 4
44
- summary: Provides Rails helper methods for referrer-style backlinks
84
+ summary: Rails referrer-URL handling done right
45
85
  test_files: []
data/README DELETED
@@ -1,86 +0,0 @@
1
- h1. Redirectr
2
-
3
- In many web applications, the user triggers actions that result in simple or complex workflows that should, after that workflow is finished, result in the user being redirected to the page where he initially started it. Another example would be a "back"-Link on any page.
4
- A simple but completely Un-RESTful way would be to store the "current" page in a cookie each time the user calls an action and redirect to the url stored there if needed.
5
-
6
- A much better (and potentially even cacheable) way is to encode the "backlink" URL in an URL parameter or form field and pass it along with every workflow step until the last (or only) action uses it to redirect the user back to where he initially came from.
7
-
8
- Redirectr really does nothing more than provide a simple API for exactly that.
9
-
10
- Redirectr provides a few Controller and Helper methods that will be included in your ApplicationController and ApplicationHelper, respectively.
11
-
12
- h2. Installation
13
-
14
- when Using bundler, just at the following to your Gemfile
15
-
16
- gem 'redirectr'
17
-
18
- and then call
19
-
20
- bundle install
21
-
22
- h2. Examples
23
-
24
- h3. Contact Form
25
-
26
- Suppose you have an application with a contact form that can be reached via a footer link on every page. After submitting the form, the user should be redirected to the page he was before clicking on the "contact form" link.
27
-
28
- for the footer link to the contact form:
29
-
30
- <%= link_to 'Contact us!', new_contact_path(referrer_param => current_url) %>
31
-
32
- In the 'new contact' view:
33
-
34
- <%= form_for ... do |f| %>
35
- <%= hidden_referrer_input_tag %>
36
- <!-- ... -->
37
- <% end %>
38
-
39
- and finally, in the 'create' action of your ContactsController:
40
-
41
- def create
42
- # ...
43
- redirect_to back_or_default
44
- end
45
-
46
- h3. Custom default_url
47
-
48
- The above will redirect the user back to the page specified in the referrer param. However, if you want to provide a custom fallback url per controller in case no referrer param is provided, just define the `#default_url` in your controller:
49
-
50
- class MyController < ApplicationController
51
- def default_url
52
- if @record
53
- my_record_path(@record)
54
- else
55
- my_record_index_path
56
- end
57
- end
58
- end
59
-
60
- h3. Nesting referrers
61
-
62
- Referrer params can be nested, which is helpful if your workflow involves branching into subworkflows. Thus, it is always possible to pass the referrer_param to another url:
63
-
64
- <%= link_to 'go back directly', referrer_or_current_url %>
65
- <%= link_to 'add new Foobar before going back', new_foobar_url(:foobar => {:name => 'My Foo'}, referrer_param => referrer_or_current_url) %>
66
-
67
- for more detailed examples, see the Rdoc documentation.
68
-
69
- h2. Contributions
70
-
71
- Contributions like bugfixes and new ideas are more than welcome. Please just fork this project on github (https://github.com/wvk/redirectr) and send me a pull request with your changes.
72
-
73
- Thanks so far to:
74
-
75
- * Falk Hoppe for Rails 2.3.x interoperability
76
- * Dimitar Haralanov for Rails 3.0.x interoperability
77
- * Raffael Schmid for spotting a typo in the gemspec description ;)
78
-
79
- ## Changelog
80
-
81
- 0.1.1: deprecate *_path methods; improve Rails 5 compatibility by removing `alias` in view helpers
82
- 0.1.0: Use absolute URI instead of path in current_path method
83
- 0.0.8: Use ActiveSupport::Concern (Thanks to Dimitar Haralanov)
84
- 0.0.7: Add Rails 3.0 compatibility (Thanks to Falk Hoppe)
85
-
86
- Copyright (c) 2010 Willem van Kerkhof <wvk@consolving.de>, released under the MIT license