saml_idp 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +1 -1
  3. data/README.md +11 -5
  4. data/lib/saml_idp/configurator.rb +1 -0
  5. data/lib/saml_idp/controller.rb +6 -6
  6. data/lib/saml_idp/incoming_metadata.rb +4 -1
  7. data/lib/saml_idp/request.rb +13 -0
  8. data/lib/saml_idp/service_provider.rb +14 -0
  9. data/lib/saml_idp/version.rb +1 -1
  10. data/saml_idp.gemspec +25 -22
  11. data/spec/acceptance/idp_controller_spec.rb +5 -4
  12. data/spec/lib/saml_idp/algorithmable_spec.rb +6 -6
  13. data/spec/lib/saml_idp/assertion_builder_spec.rb +8 -8
  14. data/spec/lib/saml_idp/attribute_decorator_spec.rb +8 -8
  15. data/spec/lib/saml_idp/configurator_spec.rb +7 -7
  16. data/spec/lib/saml_idp/controller_spec.rb +23 -20
  17. data/spec/lib/saml_idp/encryptor_spec.rb +4 -4
  18. data/spec/lib/saml_idp/incoming_metadata_spec.rb +41 -0
  19. data/spec/lib/saml_idp/metadata_builder_spec.rb +7 -17
  20. data/spec/lib/saml_idp/name_id_formatter_spec.rb +3 -3
  21. data/spec/lib/saml_idp/request_spec.rb +22 -22
  22. data/spec/lib/saml_idp/response_builder_spec.rb +2 -2
  23. data/spec/lib/saml_idp/saml_response_spec.rb +6 -6
  24. data/spec/lib/saml_idp/service_provider_spec.rb +2 -2
  25. data/spec/lib/saml_idp/signable_spec.rb +1 -1
  26. data/spec/lib/saml_idp/signature_builder_spec.rb +2 -2
  27. data/spec/lib/saml_idp/signed_info_builder_spec.rb +3 -3
  28. data/spec/rails_app/app/controllers/saml_controller.rb +5 -1
  29. data/spec/rails_app/config/application.rb +0 -6
  30. data/spec/rails_app/config/environments/development.rb +1 -6
  31. data/spec/rails_app/config/environments/production.rb +1 -0
  32. data/spec/rails_app/config/environments/test.rb +1 -0
  33. data/spec/spec_helper.rb +3 -0
  34. data/spec/support/saml_request_macros.rb +2 -1
  35. data/spec/xml_security_spec.rb +12 -12
  36. metadata +71 -39
  37. data/spec/lib/saml_idp/.assertion_builder_spec.rb.swp +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 67d795e966607dc7c0553d2889e7da7e33b0ba92
4
- data.tar.gz: c5eb9c3ab9ae64be8ad5e412a94ad8600b329bbd
2
+ SHA256:
3
+ metadata.gz: 33008cf3468ff0038f5308fb5820edc2023c071d1d0a046c6778f9fd393d96da
4
+ data.tar.gz: 95e3adfcc852d0384ae3fa5c8740a820f16db073f83aef78bdba524d3581f8ed
5
5
  SHA512:
6
- metadata.gz: 4d41a8d82d518fc503b50d7206c1f12a59e822aa73dcd03f067d25521404446f66aba9d6c6ec478bfa7b9bb9794859c92d530e41cdae5ebcf5fe26e61f96e0a9
7
- data.tar.gz: c143f75f4326f1f1b927b91b5226797881d2bf2ea69155a4769d3805bd628d199f08edd5466529865cdffe57b2fc657cda3f100138a86aa3040af1e8682f0d10
6
+ metadata.gz: e66b93acbc0ab6b965258a6ba2c205e4563e197206b94c50dbd5a7603a36ebda7c2dc47d57932b821dcbd4a4e3e033616d2c6879141222b0496a0faa1811af6f
7
+ data.tar.gz: d3aee5f5466e2b7c70cb9434eb6c0fe3036d55335ec65555c489124ce4d4889e4051969d8f1cc87e2b3a523f1fbbc447a8a609a86e62a4ffd53f0cf4a7f31285
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
  gemspec
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Ruby SAML Identity Provider (IdP)
2
2
  Forked from https://github.com/lawrencepit/ruby-saml-idp
3
3
 
4
- [![Build Status](https://travis-ci.org/sportngin/saml_idp.png)](https://travis-ci.org/sportngin/saml_idp)
5
- [![Gem Version](https://badge.fury.io/rb/saml_idp.png)](http://badge.fury.io/rb/saml_idp)
4
+ [![Build Status](https://travis-ci.org/saml-idp/saml_idp.svg)](https://travis-ci.org/saml-idp/saml_idp)
5
+ [![Gem Version](https://badge.fury.io/rb/saml_idp.svg)](http://badge.fury.io/rb/saml_idp)
6
6
 
7
7
  The ruby SAML Identity Provider library is for implementing the server side of SAML authentication. It allows
8
8
  your application to act as an IdP (Identity Provider) using the
@@ -93,6 +93,8 @@ CERT
93
93
  # config.organization_url = "http://example.com"
94
94
  # config.base_saml_location = "#{base}/saml"
95
95
  # config.reference_id_generator # Default: -> { UUID.generate }
96
+ # config.single_logout_service_post_location = "#{base}/saml/logout"
97
+ # config.single_logout_service_redirect_location = "#{base}/saml/logout"
96
98
  # config.attribute_service_location = "#{base}/saml/attributes"
97
99
  # config.single_service_post_location = "#{base}/saml/auth"
98
100
  # config.session_expiry = 86400 # Default: 0 which means never
@@ -169,7 +171,11 @@ CERT
169
171
  service_providers = {
170
172
  "some-issuer-url.com/saml" => {
171
173
  fingerprint: "9E:65:2E:03:06:8D:80:F2:86:C7:6C:77:A1:D9:14:97:0A:4D:F4:4D",
172
- metadata_url: "http://some-issuer-url.com/saml/metadata"
174
+ metadata_url: "http://some-issuer-url.com/saml/metadata",
175
+
176
+ # We now validate AssertionConsumerServiceURL will match the MetadataURL set above.
177
+ # *If* it's not going to match your Metadata URL's Host, then set this so we can validate the host using this list
178
+ response_hosts: ["foo.some-issuer-url.com"]
173
179
  },
174
180
  }
175
181
 
@@ -177,7 +183,7 @@ CERT
177
183
  # settings is an IncomingMetadata object which has a to_h method that needs to be persisted
178
184
  config.service_provider.metadata_persister = ->(identifier, settings) {
179
185
  fname = identifier.to_s.gsub(/\/|:/,"_")
180
- `mkdir -p #{Rails.root.join("cache/saml/metadata")}`
186
+ FileUtils.mkdir_p(Rails.root.join('cache', 'saml', 'metadata').to_s)
181
187
  File.open Rails.root.join("cache/saml/metadata/#{fname}"), "r+b" do |f|
182
188
  Marshal.dump settings.to_h, f
183
189
  end
@@ -188,7 +194,7 @@ CERT
188
194
  # `service_provider` you should return the settings.to_h from above
189
195
  config.service_provider.persisted_metadata_getter = ->(identifier, service_provider){
190
196
  fname = identifier.to_s.gsub(/\/|:/,"_")
191
- `mkdir -p #{Rails.root.join("cache/saml/metadata")}`
197
+ FileUtils.mkdir_p(Rails.root.join('cache', 'saml', 'metadata').to_s)
192
198
  full_filename = Rails.root.join("cache/saml/metadata/#{fname}")
193
199
  if File.file?(full_filename)
194
200
  File.open full_filename, "rb" do |f|
@@ -17,6 +17,7 @@ module SamlIdp
17
17
  attr_accessor :single_logout_service_redirect_location
18
18
  attr_accessor :attributes
19
19
  attr_accessor :service_provider
20
+ attr_accessor :assertion_consumer_service_hosts
20
21
  attr_accessor :session_expiry
21
22
 
22
23
  def initialize
@@ -35,13 +35,13 @@ module SamlIdp
35
35
 
36
36
  def validate_saml_request(raw_saml_request = params[:SAMLRequest])
37
37
  decode_request(raw_saml_request)
38
- unless valid_saml_request?
39
- if Rails::VERSION::MAJOR >= 4
40
- head :forbidden
41
- else
42
- render nothing: true, status: :forbidden
43
- end
38
+ return true if valid_saml_request?
39
+ if Rails::VERSION::MAJOR >= 4
40
+ head :forbidden
41
+ else
42
+ render nothing: true, status: :forbidden
44
43
  end
44
+ false
45
45
  end
46
46
 
47
47
  def decode_request(raw_saml_request)
@@ -22,7 +22,10 @@ module SamlIdp
22
22
  ds: signature_namespace,
23
23
  md: metadata_namespace
24
24
  ).first
25
- doc ? !!doc["WantAssertionsSigned"] : false
25
+ if (doc && !doc['WantAssertionsSigned'].nil?)
26
+ return doc['WantAssertionsSigned'].strip.downcase == 'true'
27
+ end
28
+ return false
26
29
  end
27
30
  hashable :sign_assertions
28
31
 
@@ -105,6 +105,11 @@ module SamlIdp
105
105
  return false
106
106
  end
107
107
 
108
+ if !service_provider.acceptable_response_hosts.include?(response_host)
109
+ log "No acceptable AssertionConsumerServiceURL, either configure them via config.service_provider.response_hosts or match to your metadata_url host"
110
+ return false
111
+ end
112
+
108
113
  return true
109
114
  end
110
115
 
@@ -136,6 +141,14 @@ module SamlIdp
136
141
  @_session_index ||= xpath("//samlp:SessionIndex", samlp: samlp).first.try(:content)
137
142
  end
138
143
 
144
+ def response_host
145
+ uri = URI(response_url)
146
+ if uri
147
+ uri.host
148
+ end
149
+ end
150
+ private :response_host
151
+
139
152
  def document
140
153
  @_document ||= Saml::XML::Document.parse(raw_xml)
141
154
  end
@@ -13,6 +13,7 @@ module SamlIdp
13
13
  attribute :validate_signature
14
14
  attribute :acs_url
15
15
  attribute :assertion_consumer_logout_service_url
16
+ attribute :response_hosts
16
17
 
17
18
  delegate :config, to: :SamlIdp
18
19
 
@@ -46,6 +47,19 @@ module SamlIdp
46
47
  @current_metadata ||= get_current_or_build
47
48
  end
48
49
 
50
+ def acceptable_response_hosts
51
+ hosts = Array(self.response_hosts)
52
+ hosts.push(metadata_url_host) if metadata_url_host
53
+
54
+ hosts
55
+ end
56
+
57
+ def metadata_url_host
58
+ if metadata_url.present?
59
+ URI(metadata_url).host
60
+ end
61
+ end
62
+
49
63
  def get_current_or_build
50
64
  persisted = metadata_getter[identifier, self]
51
65
  if persisted.is_a? Hash
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module SamlIdp
3
- VERSION = '0.7.2'
3
+ VERSION = '0.8.0'
4
4
  end
@@ -7,28 +7,29 @@ Gem::Specification.new do |s|
7
7
  s.version = SamlIdp::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Jon Phenow"]
10
- s.email = %q{jon.phenow@sportngin.com}
11
- s.homepage = %q{http://github.com/sportngin/saml_idp}
12
- s.summary = %q{SAML Indentity Provider in ruby}
13
- s.description = %q{SAML IdP (Identity Provider) library in ruby}
10
+ s.email = 'jon.phenow@sportngin.com'
11
+ s.homepage = 'https://github.com/saml-idp/saml_idp'
12
+ s.summary = 'SAML Indentity Provider for Ruby'
13
+ s.description = 'SAML IdP (Identity Provider) Library for Ruby'
14
14
  s.date = Time.now.utc.strftime("%Y-%m-%d")
15
- s.files = Dir.glob("app/**/*") + Dir.glob("lib/**/*") + [
16
- "LICENSE",
17
- "README.md",
18
- "Gemfile",
19
- "saml_idp.gemspec"
20
- ]
15
+ s.files = Dir['app/**/*', 'lib/**/*', 'LICENSE', 'README.md', 'Gemfile', 'saml_idp.gemspec']
21
16
  s.required_ruby_version = '>= 2.2'
22
- s.license = "LICENSE"
17
+ s.license = 'MIT'
23
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
20
  s.require_paths = ["lib"]
26
- s.rdoc_options = ["--charset=UTF-8"]
21
+ s.rdoc_options = ['--charset=UTF-8']
22
+ s.metadata = {
23
+ 'homepage_uri' => 'https://github.com/saml-idp/saml_idp',
24
+ 'source_code_uri' => 'https://github.com/saml-idp/saml_idp',
25
+ 'bug_tracker_uri' => 'https://github.com/saml-idp/saml_idp/issues',
26
+ 'documentation_uri' => "http://rdoc.info/gems/saml_idp/#{SamlIdp::VERSION}"
27
+ }
27
28
 
28
29
  s.post_install_message = <<-INST
29
30
  If you're just recently updating saml_idp - please be aware we've changed the default
30
31
  certificate. See the PR and a description of why we've done this here:
31
- https://github.com/sportngin/saml_idp/pull/29
32
+ https://github.com/saml-idp/saml_idp/pull/29
32
33
 
33
34
  If you just need to see the certificate `bundle open saml_idp` and go to
34
35
  `lib/saml_idp/default.rb`
@@ -43,17 +44,19 @@ section of the README.
43
44
  INST
44
45
 
45
46
  s.add_dependency('activesupport', '>= 3.2')
46
- s.add_dependency('uuid', '~> 2.3')
47
- s.add_dependency('builder', '~> 3.0')
47
+ s.add_dependency('uuid', '>= 2.3')
48
+ s.add_dependency('builder', '>= 3.0')
48
49
  s.add_dependency('nokogiri', '>= 1.6.2')
49
50
 
50
- s.add_development_dependency('rake', '~> 10.4.2')
51
- s.add_development_dependency('simplecov', '~> 0.12')
52
- s.add_development_dependency('rspec', '~> 2.5')
53
- s.add_development_dependency('ruby-saml', '~> 1.3')
54
- s.add_development_dependency('rails', '~> 3.2')
55
- s.add_development_dependency('capybara', '~> 2.11.0')
56
- s.add_development_dependency('timecop', '~> 0.8')
51
+ s.add_development_dependency('rake')
52
+ s.add_development_dependency('simplecov')
53
+ s.add_development_dependency('rspec', '>= 3.7.0')
54
+ s.add_development_dependency('ruby-saml', '>= 1.5')
55
+ s.add_development_dependency('rails', '>= 3.2')
56
+ s.add_development_dependency('activeresource', '>= 3.2')
57
+ s.add_development_dependency('capybara', '>= 2.16')
58
+ s.add_development_dependency('timecop', '>= 0.8')
57
59
  s.add_development_dependency('xmlenc', '>= 0.6.4')
60
+ s.add_development_dependency('appraisal')
58
61
  end
59
62
 
@@ -4,11 +4,12 @@ feature 'IdpController' do
4
4
  scenario 'Login via default signup page' do
5
5
  saml_request = make_saml_request("http://foo.example.com/saml/consume")
6
6
  visit "/saml/auth?SAMLRequest=#{CGI.escape(saml_request)}"
7
- fill_in 'Email', :with => "foo@example.com"
8
- fill_in 'Password', :with => "okidoki"
7
+ expect(status_code).to eq(200)
8
+ fill_in 'email', :with => "foo@example.com"
9
+ fill_in 'password', :with => "okidoki"
9
10
  click_button 'Sign in'
10
11
  click_button 'Submit' # simulating onload
11
- current_url.should == 'http://foo.example.com/saml/consume'
12
- page.should have_content "foo@example.com"
12
+ expect(current_url).to eq('http://foo.example.com/saml/consume')
13
+ expect(page).to have_content "foo@example.com"
13
14
  end
14
15
  end
@@ -9,11 +9,11 @@ module SamlIdp
9
9
  end
10
10
 
11
11
  it "finds algorithm class" do
12
- algorithm.should == OpenSSL::Digest::SHA256
12
+ expect(algorithm).to eq(OpenSSL::Digest::SHA256)
13
13
  end
14
14
 
15
15
  it "finds the name" do
16
- algorithm_name.should == "sha256"
16
+ expect(algorithm_name).to eq("sha256")
17
17
  end
18
18
  end
19
19
 
@@ -23,11 +23,11 @@ module SamlIdp
23
23
  end
24
24
 
25
25
  it "finds algorithm class" do
26
- algorithm.should == OpenSSL::Digest::SHA512
26
+ expect(algorithm).to eq(OpenSSL::Digest::SHA512)
27
27
  end
28
28
 
29
29
  it "finds the name" do
30
- algorithm_name.should == "sha512"
30
+ expect(algorithm_name).to eq("sha512")
31
31
  end
32
32
  end
33
33
 
@@ -37,11 +37,11 @@ module SamlIdp
37
37
  end
38
38
 
39
39
  it "finds algorithm class" do
40
- algorithm.should == OpenSSL::Digest::SHA1
40
+ expect(algorithm).to eq(OpenSSL::Digest::SHA1)
41
41
  end
42
42
 
43
43
  it "finds the name" do
44
- algorithm_name.should == "sha1"
44
+ expect(algorithm_name).to eq("sha1")
45
45
  end
46
46
  end
47
47
  end
@@ -36,14 +36,14 @@ module SamlIdp
36
36
 
37
37
  it "builds a legit raw XML file" do
38
38
  Timecop.travel(Time.zone.local(2010, 6, 1, 13, 0, 0)) do
39
- subject.raw.should == "<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\">foo@example.com</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement><AttributeStatement><Attribute Name=\"email-address\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"emailAddress\"><AttributeValue>foo@example.com</AttributeValue></Attribute></AttributeStatement></Assertion>"
39
+ expect(subject.raw).to eq("<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\">foo@example.com</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement><AttributeStatement><Attribute Name=\"email-address\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"emailAddress\"><AttributeValue>foo@example.com</AttributeValue></Attribute></AttributeStatement></Assertion>")
40
40
  end
41
41
  end
42
42
  end
43
43
 
44
44
  it "builds a legit raw XML file" do
45
45
  Timecop.travel(Time.zone.local(2010, 6, 1, 13, 0, 0)) do
46
- subject.raw.should == "<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\">foo@example.com</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData InResponseTo=\"123\" NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement><AttributeStatement><Attribute Name=\"email-address\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"emailAddress\"><AttributeValue>foo@example.com</AttributeValue></Attribute></AttributeStatement></Assertion>"
46
+ expect(subject.raw).to eq("<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\">foo@example.com</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData InResponseTo=\"123\" NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement><AttributeStatement><Attribute Name=\"email-address\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"emailAddress\"><AttributeValue>foo@example.com</AttributeValue></Attribute></AttributeStatement></Assertion>")
47
47
  end
48
48
  end
49
49
 
@@ -55,12 +55,12 @@ module SamlIdp
55
55
  email_address: ->(p) { "foo@example.com" }
56
56
  }
57
57
  }
58
- SamlIdp.stub(config: config)
58
+ allow(SamlIdp).to receive(:config).and_return(config)
59
59
  end
60
60
 
61
61
  it "doesn't include attribute statement" do
62
62
  Timecop.travel(Time.zone.local(2010, 6, 1, 13, 0, 0)) do
63
- subject.raw.should == "<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\">foo@example.com</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData InResponseTo=\"123\" NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement></Assertion>"
63
+ expect(subject.raw).to eq("<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\">foo@example.com</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData InResponseTo=\"123\" NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement></Assertion>")
64
64
  end
65
65
  end
66
66
  end
@@ -81,7 +81,7 @@ module SamlIdp
81
81
  expiry
82
82
  )
83
83
  Timecop.travel(Time.zone.local(2010, 6, 1, 13, 0, 0)) do
84
- builder.raw.should == "<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\">foo@example.com</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData InResponseTo=\"123\" NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement><AttributeStatement><Attribute Name=\"emailAddress\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"emailAddress\"><AttributeValue>foo@example.com</AttributeValue></Attribute></AttributeStatement></Assertion>"
84
+ expect(builder.raw).to eq("<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\">foo@example.com</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData InResponseTo=\"123\" NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement><AttributeStatement><Attribute Name=\"emailAddress\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"emailAddress\"><AttributeValue>foo@example.com</AttributeValue></Attribute></AttributeStatement></Assertion>")
85
85
  end
86
86
  end
87
87
  end
@@ -100,14 +100,14 @@ module SamlIdp
100
100
  encryption_opts
101
101
  )
102
102
  encrypted_xml = builder.encrypt
103
- encrypted_xml.should_not match(audience_uri)
103
+ expect(encrypted_xml).to_not match(audience_uri)
104
104
  end
105
105
 
106
106
  describe "with custom session_expiry configuration" do
107
107
  let(:config) { SamlIdp::Configurator.new }
108
108
  before do
109
109
  config.session_expiry = 8
110
- SamlIdp.stub(config: config)
110
+ allow(SamlIdp).to receive(:config).and_return(config)
111
111
  end
112
112
 
113
113
  it "sets default session_expiry from config" do
@@ -123,7 +123,7 @@ module SamlIdp
123
123
  expiry,
124
124
  encryption_opts
125
125
  )
126
- builder.session_expiry.should == 8
126
+ expect(builder.session_expiry).to eq(8)
127
127
  end
128
128
  end
129
129
  end
@@ -12,19 +12,19 @@ module SamlIdp
12
12
  let(:values) { nil }
13
13
 
14
14
  it "has a valid name" do
15
- subject.name.should be_nil
15
+ expect(subject.name).to be_nil
16
16
  end
17
17
 
18
18
  it "has a valid friendly_name" do
19
- subject.friendly_name.should be_nil
19
+ expect(subject.friendly_name).to be_nil
20
20
  end
21
21
 
22
22
  it "has a valid name_format" do
23
- subject.name_format.should == Saml::XML::Namespaces::Formats::Attr::URI
23
+ expect(subject.name_format).to eq(Saml::XML::Namespaces::Formats::Attr::URI)
24
24
  end
25
25
 
26
26
  it "has a valid values" do
27
- subject.values.should == []
27
+ expect(subject.values).to eq []
28
28
  end
29
29
 
30
30
  describe "with values set" do
@@ -34,19 +34,19 @@ module SamlIdp
34
34
  let(:values) { :val }
35
35
 
36
36
  it "has a valid name" do
37
- subject.name.should == name
37
+ expect(subject.name).to eq(name)
38
38
  end
39
39
 
40
40
  it "has a valid friendly_name" do
41
- subject.friendly_name.should == friendly_name
41
+ expect(subject.friendly_name).to eq(friendly_name)
42
42
  end
43
43
 
44
44
  it "has a valid name_format" do
45
- subject.name_format.should == name_format
45
+ expect(subject.name_format).to eq(name_format)
46
46
  end
47
47
 
48
48
  it "has a valid values" do
49
- subject.values.should == [values]
49
+ expect(subject.values).to eq [values]
50
50
  end
51
51
  end
52
52
  end
@@ -18,32 +18,32 @@ module SamlIdp
18
18
  it { should respond_to :session_expiry }
19
19
 
20
20
  it "has a valid x509_certificate" do
21
- subject.x509_certificate.should == Default::X509_CERTIFICATE
21
+ expect(subject.x509_certificate).to eq(Default::X509_CERTIFICATE)
22
22
  end
23
23
 
24
24
  it "has a valid secret_key" do
25
- subject.secret_key.should == Default::SECRET_KEY
25
+ expect(subject.secret_key).to eq(Default::SECRET_KEY)
26
26
  end
27
27
 
28
28
  it "has a valid algorithm" do
29
- subject.algorithm.should == :sha1
29
+ expect(subject.algorithm).to eq(:sha1)
30
30
  end
31
31
 
32
32
  it "has a valid reference_id_generator" do
33
- subject.reference_id_generator.should respond_to :call
33
+ expect(subject.reference_id_generator).to respond_to :call
34
34
  end
35
35
 
36
36
 
37
37
  it "can call service provider finder" do
38
- subject.service_provider.finder.should respond_to :call
38
+ expect(subject.service_provider.finder).to respond_to :call
39
39
  end
40
40
 
41
41
  it "can call service provider metadata persister" do
42
- subject.service_provider.metadata_persister.should respond_to :call
42
+ expect(subject.service_provider.metadata_persister).to respond_to :call
43
43
  end
44
44
 
45
45
  it 'has a valid session_expiry' do
46
- subject.session_expiry.should == 0
46
+ expect(subject.session_expiry).to eq(0)
47
47
  end
48
48
  end
49
49
  end