summaryrefslogtreecommitdiff
path: root/vendor/gems/omniauth-cas3/spec
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gems/omniauth-cas3/spec')
-rw-r--r--vendor/gems/omniauth-cas3/spec/fixtures/cas_failure.xml4
-rw-r--r--vendor/gems/omniauth-cas3/spec/fixtures/cas_success.xml14
-rw-r--r--vendor/gems/omniauth-cas3/spec/fixtures/cas_success_jasig.xml16
-rw-r--r--vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3/logout_request_spec.rb127
-rw-r--r--vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3/service_ticket_validator_spec.rb55
-rw-r--r--vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3_spec.rb250
-rw-r--r--vendor/gems/omniauth-cas3/spec/spec_helper.rb13
7 files changed, 479 insertions, 0 deletions
diff --git a/vendor/gems/omniauth-cas3/spec/fixtures/cas_failure.xml b/vendor/gems/omniauth-cas3/spec/fixtures/cas_failure.xml
new file mode 100644
index 00000000000..f8238a18014
--- /dev/null
+++ b/vendor/gems/omniauth-cas3/spec/fixtures/cas_failure.xml
@@ -0,0 +1,4 @@
+<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
+ <cas:authenticationFailure>
+ </cas:authenticationFailure>
+</cas:serviceResponse>
diff --git a/vendor/gems/omniauth-cas3/spec/fixtures/cas_success.xml b/vendor/gems/omniauth-cas3/spec/fixtures/cas_success.xml
new file mode 100644
index 00000000000..18904f64b35
--- /dev/null
+++ b/vendor/gems/omniauth-cas3/spec/fixtures/cas_success.xml
@@ -0,0 +1,14 @@
+<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
+ <cas:authenticationSuccess>
+ <cas:user>psegel</cas:user>
+ <cas:employeeid>54</cas:employeeid>
+ <cas:first_name>P. Segel</cas:first_name>
+ <cas:first_name>Peter</cas:first_name>
+ <cas:last_name>Segel</cas:last_name>
+ <cas:email>psegel@intridea.com</cas:email>
+ <cas:location>Washington, D.C.</cas:location>
+ <cas:image>/images/user.jpg</cas:image>
+ <cas:phone>555-555-5555</cas:phone>
+ <cas:hire_date>2004-07-13</cas:hire_date>
+ </cas:authenticationSuccess>
+</cas:serviceResponse>
diff --git a/vendor/gems/omniauth-cas3/spec/fixtures/cas_success_jasig.xml b/vendor/gems/omniauth-cas3/spec/fixtures/cas_success_jasig.xml
new file mode 100644
index 00000000000..72f58edfb46
--- /dev/null
+++ b/vendor/gems/omniauth-cas3/spec/fixtures/cas_success_jasig.xml
@@ -0,0 +1,16 @@
+<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
+ <cas:authenticationSuccess>
+ <cas:user>psegel</cas:user>
+ <cas:attributes>
+ <cas:employeeid>54</cas:employeeid>
+ <cas:first_name>P. Segel</cas:first_name>
+ <cas:first_name>Peter</cas:first_name>
+ <cas:last_name>Segel</cas:last_name>
+ <cas:email>psegel@intridea.com</cas:email>
+ <cas:location>Washington, D.C.</cas:location>
+ <cas:image>/images/user.jpg</cas:image>
+ <cas:phone>555-555-5555</cas:phone>
+ <cas:hire_date>2004-07-13</cas:hire_date>
+ </cas:attributes>
+ </cas:authenticationSuccess>
+</cas:serviceResponse>
diff --git a/vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3/logout_request_spec.rb b/vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3/logout_request_spec.rb
new file mode 100644
index 00000000000..4834347fa03
--- /dev/null
+++ b/vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3/logout_request_spec.rb
@@ -0,0 +1,127 @@
+require 'spec_helper'
+
+describe OmniAuth::Strategies::CAS3::LogoutRequest do
+ let(:strategy) { double('strategy') }
+ let(:env) do
+ { 'rack.input' => StringIO.new('','r') }
+ end
+ let(:request) { double('request', params:params, env:env) }
+ let(:params) { { 'url' => url, 'logoutRequest' => logoutRequest } }
+ let(:url) { 'http://notes.dev/signed_in' }
+ let(:logoutRequest) do
+ %Q[
+ <samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion\" ID="123abc-1234-ab12-cd34-1234abcd" Version="2.0" IssueInstant="#{Time.now.to_s}">
+ <saml:NameID>@NOT_USED@</saml:NameID>
+ <samlp:SessionIndex>ST-123456-123abc456def</samlp:SessionIndex>
+ </samlp:LogoutRequest>
+ ]
+ end
+
+ subject { described_class.new(strategy, request).call(options) }
+
+ describe 'SAML attributes' do
+ let(:callback) { Proc.new{} }
+ let(:options) do
+ { on_single_sign_out: callback }
+ end
+
+ before do
+ @rack_input = nil
+ allow(callback).to receive(:call) do |req|
+ @rack_input = req.env['rack.input'].read
+ true
+ end
+ end
+
+ it 'are parsed and injected into the Rack Request parameters', :skip => true do
+ subject
+ expect(@rack_input).to eq 'name_id=%40NOT_USED%40&session_index=ST-123456-123abc456def'
+ end
+
+ it 'are parsed and injected even if saml defined inside NameID', :skip => true do
+ request.params['logoutRequest'] =
+ %Q[
+ <samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="foobarbaz" Version="2.0" IssueInstant="2014-10-19T17:13:50Z">
+ <saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">@NOT_USED@</saml:NameID>
+ <samlp:SessionIndex>ST-foo-bar</samlp:SessionIndex>
+ </samlp:LogoutRequest>
+ ]
+ subject
+ expect(@rack_input).to eq 'name_id=%40NOT_USED%40&session_index=ST-foo-bar'
+ end
+
+ it 'are parsed and injected even if saml and samlp namespaces not defined', :skip => true do
+ request.params['logoutRequest'] =
+ %Q[
+ <samlp:LogoutRequest ID="123abc-1234-ab12-cd34-1234abcd" Version="2.0" IssueInstant="#{Time.now.to_s}">
+ <saml:NameID>@NOT_USED@</saml:NameID>
+ <samlp:SessionIndex>ST-789000-456def789ghi</samlp:SessionIndex>
+ </samlp:LogoutRequest>
+ ]
+ subject
+ expect(@rack_input).to eq 'name_id=%40NOT_USED%40&session_index=ST-789000-456def789ghi'
+ end
+
+ context 'that raise when parsed' do
+ let(:env) { { 'rack.input' => nil } }
+
+ before do
+ allow(strategy).to receive(:fail!)
+ subject
+ expect(strategy).to have_received(:fail!)
+ end
+
+ it 'responds with an error', skip: true do
+ expect(strategy).to have_received(:fail!)
+ end
+ end
+ end
+
+ describe 'with a configured callback' do
+ let(:options) do
+ { on_single_sign_out: callback }
+ end
+
+ context 'that returns TRUE' do
+ let(:callback) { Proc.new{true} }
+
+ it 'responds with OK', skip: true do
+ expect(subject[0]).to eq 200
+ expect(subject[2].body).to eq ['OK']
+ end
+ end
+
+ context 'that returns Nil' do
+ let(:callback) { Proc.new{} }
+
+ it 'responds with OK', skip: true do
+ expect(subject[0]).to eq 200
+ expect(subject[2].body).to eq ['OK']
+ end
+ end
+
+ context 'that returns a tuple' do
+ let(:callback) { Proc.new{ [400,{},'Bad Request'] } }
+
+ it 'responds with OK', skip: true do
+ expect(subject[0]).to eq 400
+ expect(subject[2].body).to eq ['Bad Request']
+ end
+ end
+
+ context 'that raises an error' do
+ let(:exception) { RuntimeError.new('error' )}
+ let(:callback) { Proc.new{raise exception} }
+
+ before do
+ allow(strategy).to receive(:fail!)
+ subject
+ end
+
+ it 'responds with an error', skip: true do
+ expect(strategy).to have_received(:fail!)
+ .with(:logout_request, exception)
+ end
+ end
+ end
+end
diff --git a/vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3/service_ticket_validator_spec.rb b/vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3/service_ticket_validator_spec.rb
new file mode 100644
index 00000000000..b031d1d68fc
--- /dev/null
+++ b/vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3/service_ticket_validator_spec.rb
@@ -0,0 +1,55 @@
+require 'spec_helper'
+
+describe OmniAuth::Strategies::CAS3::ServiceTicketValidator do
+ let(:strategy) do
+ double('strategy',
+ service_validate_url: 'https://example.org/serviceValidate'
+ )
+ end
+ let(:provider_options) do
+ double('provider_options',
+ disable_ssl_verification?: false,
+ ca_path: '/etc/ssl/certsZOMG'
+ )
+ end
+ let(:validator) do
+ OmniAuth::Strategies::CAS3::ServiceTicketValidator.new( strategy, provider_options, '/foo', nil )
+ end
+
+ describe '#call' do
+ before do
+ stub_request(:get, 'https://example.org/serviceValidate?')
+ .to_return(status: 200, body: '')
+ end
+
+ subject { validator.call }
+
+ it 'returns itself' do
+ expect(subject).to eq validator
+ end
+
+ it 'uses the configured CA path' do
+ subject
+ expect(provider_options).to have_received :ca_path
+ end
+ end
+
+ describe '#user_info' do
+ let(:ok_fixture) do
+ File.expand_path(File.join(File.dirname(__FILE__), '../../../fixtures/cas_success.xml'))
+ end
+ let(:service_response) { File.read(ok_fixture) }
+
+ before do
+ stub_request(:get, 'https://example.org/serviceValidate?')
+ .to_return(status: 200, body:service_response)
+ validator.call
+ end
+
+ subject { validator.user_info }
+
+ it 'parses user info from the response' do
+ expect(subject).to include 'user' => 'psegel'
+ end
+ end
+end
diff --git a/vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3_spec.rb b/vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3_spec.rb
new file mode 100644
index 00000000000..fd61fc79580
--- /dev/null
+++ b/vendor/gems/omniauth-cas3/spec/omniauth/strategies/cas3_spec.rb
@@ -0,0 +1,250 @@
+require 'spec_helper'
+
+describe OmniAuth::Strategies::CAS3, type: :strategy do
+ include Rack::Test::Methods
+
+ let(:my_cas_provider) { Class.new(OmniAuth::Strategies::CAS3) }
+ before do
+ stub_const 'MyCasProvider', my_cas_provider
+ end
+ let(:app) do
+ Rack::Builder.new {
+ use OmniAuth::Test::PhonySession
+ use MyCasProvider, name: :cas3, host: 'cas.example.org', ssl: false, port: 8080, uid_field: :employeeid
+ run lambda { |env| [404, {'Content-Type' => 'text/plain'}, [env.key?('omniauth.auth').to_s]] }
+ }.to_app
+ end
+
+ # TODO: Verify that these are even useful tests
+ shared_examples_for 'a CAS redirect response' do
+ let(:redirect_params) { 'service=' + Rack::Utils.escape("http://example.org/auth/cas3/callback?url=#{Rack::Utils.escape(return_url)}") }
+
+ before { get url, nil, request_env }
+
+ subject { last_response }
+
+ it { should be_redirect }
+
+ it 'redirects to the CAS server' do
+ expect(subject.headers).to include 'Location' => "http://cas.example.org:8080/login?#{redirect_params}"
+ end
+ end
+
+ describe '#cas_url' do
+ let(:params) { Hash.new }
+ let(:provider) { MyCasProvider.new(nil, params) }
+
+ subject { provider.cas_url }
+
+ it 'raises an ArgumentError' do
+ expect{subject}.to raise_error ArgumentError, %r{:host and :login_url MUST be provided}
+ end
+
+ context 'with an explicit :url option' do
+ let(:url) { 'https://example.org:8080/my_cas' }
+ let(:params) { super().merge url:url }
+
+ before { subject }
+
+ it { should eq url }
+
+ it 'parses the URL into it the appropriate strategy options' do
+ expect(provider.options).to include ssl:true
+ expect(provider.options).to include host:'example.org'
+ expect(provider.options).to include port:8080
+ expect(provider.options).to include path:'/my_cas'
+ end
+ end
+
+ context 'with explicit URL component' do
+ let(:params) { super().merge host:'example.org', port:1234, ssl:true, path:'/a/path' }
+
+ before { subject }
+
+ it { should eq 'https://example.org:1234/a/path' }
+
+ it 'parses the URL into it the appropriate strategy options' do
+ expect(provider.options).to include ssl:true
+ expect(provider.options).to include host:'example.org'
+ expect(provider.options).to include port:1234
+ expect(provider.options).to include path:'/a/path'
+ end
+ end
+ end
+
+ describe 'defaults' do
+ subject { MyCasProvider.default_options.to_hash }
+
+ it { should include('ssl' => true) }
+ end
+
+ describe 'GET /auth/cas3' do
+ let(:return_url) { 'http://myapp.com/admin/foo' }
+
+ context 'with a referer' do
+ let(:url) { '/auth/cas3' }
+
+ let(:request_env) { { 'HTTP_REFERER' => return_url } }
+
+ it_behaves_like 'a CAS redirect response'
+ end
+
+ context 'with an explicit return URL' do
+ let(:url) { "/auth/cas3?url=#{return_url}" }
+
+ let(:request_env) { {} }
+
+ it_behaves_like 'a CAS redirect response'
+ end
+ end
+
+ describe 'GET /auth/cas3/callback' do
+ context 'without a ticket' do
+ before { get '/auth/cas3/callback' }
+
+ subject { last_response }
+
+ it { should be_redirect }
+
+ it 'redirects with a failure message' do
+ expect(subject.headers).to include 'Location' => '/auth/failure?message=no_ticket&strategy=cas3'
+ end
+ end
+
+ context 'with an invalid ticket' do
+ before do
+ stub_request(:get, /^http:\/\/cas.example.org:8080?\/p3\/serviceValidate\?([^&]+&)?ticket=9391d/).
+ to_return( body: File.read('spec/fixtures/cas_failure.xml') )
+ get '/auth/cas3/callback?ticket=9391d'
+ end
+
+ subject { last_response }
+
+ it { should be_redirect }
+
+ it 'redirects with a failure message' do
+ expect(subject.headers).to include 'Location' => '/auth/failure?message=invalid_ticket&strategy=cas3'
+ end
+ end
+
+ describe 'with a valid ticket' do
+ shared_examples :successful_validation do
+ before do
+ stub_request(:get, /^http:\/\/cas.example.org:8080?\/p3\/serviceValidate\?([^&]+&)?ticket=593af/)
+ .with { |request| @request_uri = request.uri.to_s }
+ .to_return( body: File.read("spec/fixtures/#{xml_file_name}") )
+
+ get "/auth/cas3/callback?ticket=593af&url=#{return_url}"
+ end
+
+ it 'strips the ticket parameter from the callback URL' do
+ expect(@request_uri.scan('ticket=').size).to eq 1
+ end
+
+ it 'properly encodes the service URL' do
+ expect(WebMock).to have_requested(:get, 'http://cas.example.org:8080/p3/serviceValidate')
+ .with(query: {
+ ticket: '593af',
+ service: 'http://example.org/auth/cas3/callback?url=' + Rack::Utils.escape('http://127.0.0.10/?some=parameter')
+ })
+ end
+
+ context "request.env['omniauth.auth']" do
+ subject { last_request.env['omniauth.auth'] }
+
+ it { should be_kind_of Hash }
+
+ it 'identifes the provider' do
+ expect(subject.provider).to eq :cas3
+ end
+
+ it 'returns the UID of the user' do
+ expect(subject.uid).to eq '54'
+ end
+
+ context 'the info hash' do
+ subject { last_request.env['omniauth.auth']['info'] }
+
+ it 'includes user info attributes' do
+ expect(subject.name).to eq 'Peter Segel'
+ expect(subject.first_name).to eq 'Peter'
+ expect(subject.last_name).to eq 'Segel'
+ expect(subject.nickname).to eq 'psegel'
+ expect(subject.email).to eq 'psegel@intridea.com'
+ expect(subject.location).to eq 'Washington, D.C.'
+ expect(subject.image).to eq '/images/user.jpg'
+ expect(subject.phone).to eq '555-555-5555'
+ end
+ end
+
+ context 'the extra hash' do
+ subject { last_request.env['omniauth.auth']['extra'] }
+
+ it 'includes additional user attributes' do
+ expect(subject.user).to eq 'psegel'
+ expect(subject.employeeid).to eq '54'
+ expect(subject.hire_date).to eq '2004-07-13'
+ end
+ end
+
+ context 'the credentials hash' do
+ subject { last_request.env['omniauth.auth']['credentials'] }
+
+ it 'has a ticket value' do
+ expect(subject.ticket).to eq '593af'
+ end
+ end
+ end
+
+ it 'calls through to the master app' do
+ expect(last_response.body).to eq 'true'
+ end
+ end
+
+ let(:return_url) { 'http://127.0.0.10/?some=parameter' }
+
+ context 'with JASIG flavored XML' do
+ let(:xml_file_name) { 'cas_success_jasig.xml' }
+
+ it_behaves_like :successful_validation
+ end
+
+ context 'with classic XML' do
+ let(:xml_file_name) { 'cas_success.xml' }
+
+ it_behaves_like :successful_validation
+ end
+ end
+ end
+
+ describe 'POST /auth/cas3/callback' do
+ describe 'with a Single Sign-Out logoutRequest' do
+ let(:logoutRequest) do
+ %Q[
+ <samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion\" ID="123abc-1234-ab12-cd34-1234abcd" Version="2.0" IssueInstant="#{Time.now.to_s}">
+ <saml:NameID>@NOT_USED@</saml:NameID>
+ <samlp:SessionIndex>ST-123456-123abc456def</samlp:SessionIndex>
+ </samlp:LogoutRequest>
+ ]
+ end
+
+ let(:logout_request) { double('logout_request', call:[200,{},'OK']) }
+
+ subject do
+ post 'auth/cas3/callback', logoutRequest:logoutRequest
+ end
+
+ before do
+ allow_any_instance_of(MyCasProvider)
+ .to receive(:logout_request_service)
+ .and_return double('LogoutRequest', new:logout_request)
+
+ subject
+ end
+
+ it 'initializes a LogoutRequest' do
+ expect(logout_request).to have_received :call
+ end
+ end
+ end
+end
diff --git a/vendor/gems/omniauth-cas3/spec/spec_helper.rb b/vendor/gems/omniauth-cas3/spec/spec_helper.rb
new file mode 100644
index 00000000000..75231268ff3
--- /dev/null
+++ b/vendor/gems/omniauth-cas3/spec/spec_helper.rb
@@ -0,0 +1,13 @@
+require 'bundler/setup'
+require 'awesome_print'
+
+RSpec.configure do |c|
+ c.filter_run focus: true
+ c.run_all_when_everything_filtered = true
+end
+
+require 'rack/test'
+require 'webmock/rspec'
+require 'omniauth-cas3'
+
+OmniAuth.config.logger = Logger.new( '/dev/null' )