sanger-rack_authentication_sso 0.1.1

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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2009, Wellcome Trust Sanger Institute
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name of the Wellcome Trust Sanger Institute nor the names of its
13
+ contributors may be used to endorse or promote products derived from this
14
+ software without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.rdoc ADDED
@@ -0,0 +1,13 @@
1
+ = Sanger::Rack::Authentication::SSO
2
+
3
+ This app is a piece of Rack Middleware to abstract the Single Sign-On used
4
+ by the Sanger Institute.
5
+
6
+ It may or (more likely) may not work with other SSO solutions.
7
+
8
+ At this moment, see the tests for the settings that need to be passed in when
9
+ using this middleware in a Rackup file or similar.
10
+
11
+ == Copyright
12
+
13
+ Copyright (c) 2009 Wellcome Trust Sanger Institute. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rack_authentication_sso"
8
+ gem.summary = %Q{Rack middleware to abstract Sanger SSO}
9
+ gem.email = "paul.thornthwaite@sanger.ac.uk"
10
+ gem.homepage = "http://github.com/sanger/rack_authentication_sso"
11
+ gem.authors = ["Paul Thornthwaite"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ end
14
+
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*_test.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
37
+ end
38
+
39
+
40
+ task :default => :test
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ if File.exist?('VERSION.yml')
45
+ config = YAML.load(File.read('VERSION.yml'))
46
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
47
+ else
48
+ version = ""
49
+ end
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "rack_authentication_sso #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
56
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,64 @@
1
+ require "cgi"
2
+ require "open-uri"
3
+ require "openssl"
4
+ require "ostruct"
5
+
6
+ module Sanger
7
+ module Rack
8
+ module Authentication
9
+ class SSO
10
+
11
+ def initialize(app, settings = {})
12
+ @config = OpenStruct.new
13
+ @config.magic_header_name = settings["magic_header_name"]
14
+ @config.cookie_name = settings["cookie_name"]
15
+ @config.validation_url = settings["validation_url"]
16
+ @config.user_agent = settings["user_agent"]
17
+ @config.sso_redirection_url = settings["sso_redirection_url"]
18
+ @config.error_text = settings["error_text"]
19
+
20
+ @app = app
21
+ end
22
+
23
+ def call(env)
24
+ @request = ::Rack::Request.new(env)
25
+ @request.env.delete(@config.magic_header_name)
26
+ cookie_value = @request.cookies[@config.cookie_name]
27
+ begin
28
+ user = sso_login_from_cookie(cookie_value) unless cookie_value.nil?
29
+ if user
30
+ @request.env[@config.magic_header_name] = user
31
+ @app.call(@request.env)
32
+ else
33
+ redirect_to_sso_server
34
+ end
35
+ rescue ::OpenURI::HTTPError
36
+ error_text = @config.error_text.to_s
37
+ [503, {"Content-Type" => "text/plain", "Content-Length" => error_text.length.to_s}, [error_text]]
38
+ end
39
+ end
40
+
41
+ def sso_login_from_cookie(cookie_value)
42
+ login = nil
43
+ ::OpenURI.open_uri(@config.validation_url,
44
+ "Cookie" => "#{@config.cookie_name}=#{cookie_value}",
45
+ "User-Agent" => @config.user_agent) do |http|
46
+ login = http.read.strip
47
+ end
48
+ if login == '*'
49
+ return nil
50
+ else
51
+ return login
52
+ end
53
+ end
54
+
55
+ def redirect_to_sso_server
56
+ @response = ::Rack::Response.new
57
+ destination = ::CGI::escape(@request.url)
58
+ @response.redirect([@config.sso_redirection_url, destination].join)
59
+ @response.finish
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,46 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{rack_authentication_sso}
5
+ s.version = "0.1.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Paul Thornthwaite"]
9
+ s.date = %q{2009-06-23}
10
+ s.email = %q{paul.thornthwaite@sanger.ac.uk}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".document",
17
+ ".gitignore",
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "lib/rack_authentication_sso.rb",
23
+ "rack_authentication_sso.gemspec",
24
+ "test/rack_authentication_sso_test.rb",
25
+ "test/test_helper.rb"
26
+ ]
27
+ s.homepage = %q{http://github.com/sanger/rack_authentication_sso}
28
+ s.rdoc_options = ["--charset=UTF-8"]
29
+ s.require_paths = ["lib"]
30
+ s.rubygems_version = %q{1.3.4}
31
+ s.summary = %q{Rack middleware to abstract Sanger SSO}
32
+ s.test_files = [
33
+ "test/rack_authentication_sso_test.rb",
34
+ "test/test_helper.rb"
35
+ ]
36
+
37
+ if s.respond_to? :specification_version then
38
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
39
+ s.specification_version = 3
40
+
41
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
42
+ else
43
+ end
44
+ else
45
+ end
46
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ class MainTest < Test::Unit::TestCase
4
+ include Rack::Test::Methods
5
+
6
+ MAGIC_HEADER_NAME = "SEQUENCESCAPE_LOGIN"
7
+ COOKIE_NAME = "MyCookie"
8
+
9
+ def app
10
+ settings = {
11
+ "magic_header_name" => MAGIC_HEADER_NAME,
12
+ "cookie_name" => COOKIE_NAME,
13
+ "validation_url" => "https://sso.example.com/validation",
14
+ "user_agent" => "Ruby/prodsoft-code",
15
+ "sso_redirect_url_prefix" => "https://sso.example.com/login?destination=",
16
+ "error_text" => "Service unavailable"
17
+ }
18
+ Sanger::Rack::Authentication::SSO.new(lambda { |env| [200, {}, ["OK"]] }, settings)
19
+ end
20
+
21
+ def test_should_authenticate_if_cookie_passed_in
22
+ Sanger::Rack::Authentication::SSO.any_instance.\
23
+ expects(:sso_login_from_cookie).returns("ab3")
24
+ get "/", {}, {"HTTP_COOKIE" => "#{COOKIE_NAME}=12345"}
25
+ assert_equal 200, last_response.status
26
+ end
27
+
28
+ def test_should_not_authenticate_if_login_not_returned
29
+ Sanger::Rack::Authentication::SSO.any_instance.\
30
+ expects(:sso_login_from_cookie).returns("*")
31
+ get "/", {}, {"HTTP_COOKIE" => "#{COOKIE_NAME}=12345"}
32
+ assert_equal 200, last_response.status
33
+ end
34
+
35
+ def test_should_not_authenticate_if_network_error
36
+ ::OpenURI.expects(:open_uri).raises(::OpenURI::HTTPError.new("Network error", nil))
37
+ get "/", {}, {"HTTP_COOKIE" => "#{COOKIE_NAME}=12345"}
38
+ assert_equal 503, last_response.status
39
+ end
40
+
41
+ def test_should_redirect_if_no_headers
42
+ get "/", {}, {}
43
+ assert_equal 302, last_response.status
44
+ assert last_response.headers.include?("Location")
45
+ end
46
+
47
+ def test_should_clear_passed_login_header
48
+ get "/", {}, {MAGIC_HEADER_NAME => "sneak"}
49
+ assert_equal 302, last_response.status
50
+ end
51
+ end
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require "rack/test"
5
+ require "mocha"
6
+
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
9
+ require 'rack_authentication_sso'
10
+
11
+ class Test::Unit::TestCase
12
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sanger-rack_authentication_sso
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Paul Thornthwaite
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-23 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: paul.thornthwaite@sanger.ac.uk
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .document
27
+ - .gitignore
28
+ - LICENSE
29
+ - README.rdoc
30
+ - Rakefile
31
+ - VERSION
32
+ - lib/rack_authentication_sso.rb
33
+ - rack_authentication_sso.gemspec
34
+ - test/rack_authentication_sso_test.rb
35
+ - test/test_helper.rb
36
+ has_rdoc: false
37
+ homepage: http://github.com/sanger/rack_authentication_sso
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --charset=UTF-8
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.2.0
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: Rack middleware to abstract Sanger SSO
62
+ test_files:
63
+ - test/rack_authentication_sso_test.rb
64
+ - test/test_helper.rb