saml_idp 0.7.2 → 0.8.0

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.
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