safe_redirection 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ safe_redirection (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ builder (3.0.0)
10
+ cucumber (1.2.1)
11
+ builder (>= 2.1.2)
12
+ diff-lcs (>= 1.1.3)
13
+ gherkin (~> 2.11.0)
14
+ json (>= 1.4.6)
15
+ diff-lcs (1.1.3)
16
+ gherkin (2.11.1)
17
+ json (>= 1.4.6)
18
+ json (1.7.3)
19
+ rake (0.9.2.2)
20
+ rspec (2.11.0)
21
+ rspec-core (~> 2.11.0)
22
+ rspec-expectations (~> 2.11.0)
23
+ rspec-mocks (~> 2.11.0)
24
+ rspec-core (2.11.0)
25
+ rspec-expectations (2.11.1)
26
+ diff-lcs (~> 1.1.3)
27
+ rspec-mocks (2.11.1)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ cucumber
34
+ rake
35
+ rspec
36
+ safe_redirection!
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # SafeRedirection
2
+
3
+ SafeRedirection allows you to easily sanitize your URLs.
4
+
5
+ ## Getting started
6
+
7
+ ```ruby
8
+ require 'safe_redirection'
9
+
10
+ class MyResolver < SafeRedirection::Resolvers::Resolver
11
+ def recognize_path(path, options = {})
12
+ if path =~ /^special/
13
+ "http://my.app.tld/special_page"
14
+ else
15
+ raise 'Not found'
16
+ end
17
+ end
18
+ end
19
+
20
+ resolver = MyResolver.new
21
+ my_sanitizer = SafeRedirection::Sanitizer.new(resolver, 'http://my.app.tld/root/path/', 'http://my.app.tld/root/path/default_url')
22
+
23
+ my_sanitizer.safe_url_for 'http://www.outside.tld/some/path'
24
+ # => "http://my.app.tld/root/path/default_url"
25
+ my_sanitizer.safe_url_for 'http://my.app.tld/root/path/special/subpath'
26
+ # => "http://my.app.tld/special_page"
27
+ my_sanitizer.safe_url_for 'ftp://my.app.tld/root/path/special/subpath'
28
+ # => "http://my.app.tld/root/path/default_url"
29
+ my_sanitizer.safe_url_for 'http://my.app.tld2/root/path/special/subpath'
30
+ # => "http://my.app.tld/special_page"
31
+ ```
32
+
33
+ Everything that responds to `recognize_path` could be a resolver and guess what! `ActionController::Routing::Routes` with Rails 2.x and `MyApplication::Application.routes` in Rails 3.x do respond to this method. It can therefore be used as a resolver in a code like this :
34
+
35
+ ```ruby
36
+ resolver = SafeRedirection::Resolvers::ExceptionsResolver.new(MyApplication::Application.routes)
37
+ resolver.legitimate_base_urls << "http://www.outsite.tld/"
38
+ sanitizer = SafeRedirection::Sanitizer.new(resolver, 'http://my.app.tld/', 'http://my.app.tld/')
39
+
40
+ sanitizer.safe_url_for "http://my.app.tld/articles/2"
41
+ # => { :controller => "articles", :action => "show", :id => 2 }
42
+ sanitizer.safe_url_for "http://www.outside.tld/path"
43
+ # => "http://www.outside.tld/path"
44
+ sanitizer.safe_url_fo "http://www.outside.but_somewhere_else.com/"
45
+ # => "http://my.app.tld/"
46
+ ```
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require "cucumber/rake/task"
2
+ require "rspec/core/rake_task"
3
+
4
+ $:.unshift File.expand_path('lib', __FILE__)
5
+
6
+ Cucumber::Rake::Task.new(:cucumber) do |task|
7
+ end
8
+
9
+ namespace :cucumber do
10
+ Cucumber::Rake::Task.new(:wip) do |task|
11
+ task.cucumber_opts = %w{--tags @wip}
12
+ end
13
+ end
14
+
15
+ RSpec::Core::RakeTask.new do |t|
16
+ t.rspec_opts = '--color'
17
+ end
data/example.rb ADDED
@@ -0,0 +1,20 @@
1
+ $:.unshift File.expand_path('lib', File.dirname(__FILE__))
2
+ require 'safe_redirection'
3
+
4
+ class MyResolver < SafeRedirection::Resolvers::Resolver
5
+ def recognize_path(path, options = {})
6
+ if path =~ /^special/
7
+ "http://my.app.tld/special_page"
8
+ else
9
+ raise 'Not found'
10
+ end
11
+ end
12
+ end
13
+
14
+ resolver = MyResolver.new
15
+ my_sanitizer = SafeRedirection::Sanitizer.new(resolver, 'http://my.app.tld/root/path/', 'http://my.app.tld/root/path/default_url')
16
+
17
+ puts my_sanitizer.safe_url_for('http://www.outside.tld/some/path')
18
+ puts my_sanitizer.safe_url_for('http://my.app.tld/root/path/special/subpath')
19
+ puts my_sanitizer.safe_url_for('ftp://my.app.tld/root/path/special/subpath')
20
+ puts my_sanitizer.safe_url_for('http://my.app.tld2/root/path/special/subpath')
File without changes
@@ -0,0 +1,3 @@
1
+ module SafeRedirection
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,22 @@
1
+ module SafeRedirection
2
+ module Resolvers
3
+ class ExceptionsResolver < Resolver
4
+ attr_accessor :legitimate_urls, :legitimate_base_urls
5
+
6
+ def initialize(*args)
7
+ super(*args)
8
+ @legitimate_urls = []
9
+ @legitimate_base_urls = []
10
+ end
11
+
12
+ def recognize_path(path, options = {})
13
+ if self.legitimate_urls.include?(path) ||
14
+ self.legitimate_base_urls.any? { |base| path.start_with? base }
15
+ path
16
+ else
17
+ resolver.recognize_path path, options
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module SafeRedirection
2
+ module Resolvers
3
+ class Resolver
4
+ attr_accessor :resolver
5
+
6
+ def initialize(resolver = nil)
7
+ @resolver = resolver
8
+ end
9
+
10
+ def recognize_path(*args)
11
+ raise NotImplementedError
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,2 @@
1
+ require 'safe_redirection/resolvers/resolver'
2
+ require 'safe_redirection/resolvers/exceptions_resolver'
@@ -0,0 +1,30 @@
1
+ module SafeRedirection
2
+ class Sanitizer
3
+ attr_accessor :resolver, :base_url, :default_url
4
+
5
+ def initialize(resolver, base_url, default_url)
6
+ @resolver = resolver
7
+ @base_url = base_url
8
+ @default_url = default_url
9
+ end
10
+
11
+ def safe_url_for(redirect_url)
12
+ uri = URI(redirect_url)
13
+ path = relative_path(uri.path)
14
+
15
+ if %w{http https}.include? uri.scheme
16
+ resolver.recognize_path(path, :method => :get) rescue default_url
17
+ else
18
+ default_url
19
+ end
20
+ end
21
+
22
+ def base_path
23
+ URI(base_url).path
24
+ end
25
+
26
+ def relative_path(path)
27
+ path.start_with?(base_path) ? path.sub(base_path, '') : path
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,8 @@
1
+ require 'uri'
2
+
3
+ require 'safe_redirection/constants'
4
+ require 'safe_redirection/sanitizer'
5
+ require 'safe_redirection/resolvers'
6
+
7
+ module SafeRedirection
8
+ end
@@ -0,0 +1,21 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ require "safe_redirection/constants"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "safe_redirection"
6
+ s.version = SafeRedirection::VERSION
7
+ s.authors = ["Thomas Feron"]
8
+ s.description = "A small library for sanitization of URLs for redirections in Rails"
9
+ s.summary = "safe_redirection-#{s.version}"
10
+ s.email = "tho.feron@gmail.com"
11
+
12
+ s.platform = Gem::Platform::RUBY
13
+
14
+ s.add_development_dependency "rake"
15
+ s.add_development_dependency "cucumber"
16
+ s.add_development_dependency "rspec"
17
+
18
+ s.files = `git ls-files`.split("\n").reject { |path| path =~ /\.gitignore$/ }
19
+ s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
20
+ s.require_path = "lib"
21
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe SafeRedirection::Resolvers::ExceptionsResolver do
4
+ let(:resolver) { double('resolver') }
5
+
6
+ subject { SafeRedirection::Resolvers::ExceptionsResolver.new(resolver) }
7
+
8
+ describe "#recognize_path" do
9
+ it "should delegate to the resolver" do
10
+ resolver.should_receive(:recognize_path)
11
+ subject.recognize_path("http://test.tld/some/path")
12
+ end
13
+
14
+ context "with a legitimate URL" do
15
+ it "should return this URL" do
16
+ legitimate_url = "http://else.where/far/far/away"
17
+ subject.legitimate_urls << legitimate_url
18
+ subject.recognize_path(legitimate_url).should == legitimate_url
19
+ end
20
+ end
21
+
22
+ context "with a legitimate base URL" do
23
+ it "should return the URL passed" do
24
+ legitimate_base_url = "http://else.where/far/"
25
+ legitimate_url = "#{legitimate_base_url}far/away"
26
+ subject.legitimate_base_urls << legitimate_base_url
27
+ subject.recognize_path(legitimate_url).should == legitimate_url
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe SafeRedirection::Sanitizer do
4
+ let(:resolver) { double('resolver') }
5
+ let(:base_url) { "http://test.tld/" }
6
+ let(:default_url) { "http://test.tld/default" }
7
+
8
+ subject { SafeRedirection::Sanitizer.new(resolver, base_url, default_url) }
9
+
10
+ describe '#safe_url_for' do
11
+ context "with a valid URL" do
12
+ let(:valid_url) { "http://test.tld/valid" }
13
+ let(:params) { { :controller => 'home', :action => 'valid' } }
14
+
15
+ it "should return this very URL" do
16
+ resolver.should_receive(:recognize_path).with('valid', anything).and_return(params)
17
+ subject.safe_url_for(valid_url).should == params
18
+ end
19
+ end
20
+
21
+ context "with an invalid URL" do
22
+ it "should return the default URL" do
23
+ resolver.should_receive(:recognize_path).with('rubbish', anything).and_raise('ActionController::RoutingError')
24
+ subject.safe_url_for("http://test.tld/rubbish").should == default_url
25
+ end
26
+
27
+ it "should return the default URL with a non-HTTP(s) scheme" do
28
+ subject.safe_url_for("ftp://test.tld/").should == default_url
29
+ end
30
+ end
31
+
32
+ context "when the application is not at the root" do
33
+ let(:base_url) { "http://test.tld/some/path/" }
34
+
35
+ it "should try to resolve the subpath" do
36
+ resolver.should_receive(:recognize_path).with('subpath', anything)
37
+ subject.safe_url_for('http://test.tld/some/path/subpath')
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "#relative_path" do
43
+ let(:base_url) { "http://test.tld/in/so.me/path/" }
44
+
45
+ it "should strip the base path" do
46
+ subject.relative_path('/in/so.me/path/subpath').should == 'subpath'
47
+ end
48
+
49
+ it "should not strip it if it's not in the beginning" do
50
+ path = '/not/in/so.me/path/subpath'
51
+ subject.relative_path(path).should == path
52
+ end
53
+
54
+ it "should not interpret regular expressions in the base URL's path" do
55
+ path = '/in/soZme/path/subpath'
56
+ subject.relative_path(path).should == path
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,3 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'safe_redirection'
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: safe_redirection
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Thomas Feron
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: cucumber
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: A small library for sanitization of URLs for redirections in Rails
63
+ email: tho.feron@gmail.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - Gemfile
69
+ - Gemfile.lock
70
+ - README.md
71
+ - Rakefile
72
+ - example.rb
73
+ - features/support/env.rb
74
+ - lib/safe_redirection.rb
75
+ - lib/safe_redirection/constants.rb
76
+ - lib/safe_redirection/resolvers.rb
77
+ - lib/safe_redirection/resolvers/exceptions_resolver.rb
78
+ - lib/safe_redirection/resolvers/resolver.rb
79
+ - lib/safe_redirection/sanitizer.rb
80
+ - safe_redirection.gemspec
81
+ - spec/lib/safe_redirection/resolvers/exceptions_resolver_spec.rb
82
+ - spec/lib/safe_redirection/sanitizer_spec.rb
83
+ - spec/spec_helper.rb
84
+ homepage:
85
+ licenses: []
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 1.8.24
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: safe_redirection-0.0.1
108
+ test_files: []