saml_idp 0.7.2 → 0.16.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 (57) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +1 -1
  3. data/README.md +59 -52
  4. data/lib/saml_idp/assertion_builder.rb +28 -3
  5. data/lib/saml_idp/configurator.rb +7 -1
  6. data/lib/saml_idp/controller.rb +21 -13
  7. data/lib/saml_idp/encryptor.rb +0 -1
  8. data/lib/saml_idp/fingerprint.rb +19 -0
  9. data/lib/saml_idp/incoming_metadata.rb +22 -1
  10. data/lib/saml_idp/metadata_builder.rb +23 -8
  11. data/lib/saml_idp/persisted_metadata.rb +4 -0
  12. data/lib/saml_idp/request.rb +26 -6
  13. data/lib/saml_idp/response_builder.rb +26 -6
  14. data/lib/saml_idp/saml_response.rb +62 -28
  15. data/lib/saml_idp/service_provider.rb +15 -6
  16. data/lib/saml_idp/signable.rb +1 -2
  17. data/lib/saml_idp/version.rb +1 -1
  18. data/lib/saml_idp/xml_security.rb +1 -1
  19. data/lib/saml_idp.rb +2 -1
  20. data/saml_idp.gemspec +45 -42
  21. data/spec/acceptance/idp_controller_spec.rb +5 -4
  22. data/spec/lib/saml_idp/algorithmable_spec.rb +6 -6
  23. data/spec/lib/saml_idp/assertion_builder_spec.rb +151 -8
  24. data/spec/lib/saml_idp/attribute_decorator_spec.rb +8 -8
  25. data/spec/lib/saml_idp/configurator_spec.rb +9 -7
  26. data/spec/lib/saml_idp/controller_spec.rb +53 -20
  27. data/spec/lib/saml_idp/encryptor_spec.rb +4 -4
  28. data/spec/lib/saml_idp/fingerprint_spec.rb +14 -0
  29. data/spec/lib/saml_idp/incoming_metadata_spec.rb +60 -0
  30. data/spec/lib/saml_idp/metadata_builder_spec.rb +30 -17
  31. data/spec/lib/saml_idp/name_id_formatter_spec.rb +3 -3
  32. data/spec/lib/saml_idp/request_spec.rb +78 -27
  33. data/spec/lib/saml_idp/response_builder_spec.rb +5 -3
  34. data/spec/lib/saml_idp/saml_response_spec.rb +127 -12
  35. data/spec/lib/saml_idp/service_provider_spec.rb +2 -2
  36. data/spec/lib/saml_idp/signable_spec.rb +1 -1
  37. data/spec/lib/saml_idp/signature_builder_spec.rb +2 -2
  38. data/spec/lib/saml_idp/signed_info_builder_spec.rb +3 -3
  39. data/spec/rails_app/app/controllers/saml_controller.rb +1 -1
  40. data/spec/rails_app/app/controllers/saml_idp_controller.rb +55 -3
  41. data/{app → spec/rails_app/app}/views/saml_idp/idp/new.html.erb +1 -5
  42. data/{app → spec/rails_app/app}/views/saml_idp/idp/saml_post.html.erb +1 -1
  43. data/spec/rails_app/config/application.rb +1 -6
  44. data/spec/rails_app/config/boot.rb +1 -1
  45. data/spec/rails_app/config/environments/development.rb +2 -5
  46. data/spec/rails_app/config/environments/production.rb +1 -0
  47. data/spec/rails_app/config/environments/test.rb +1 -0
  48. data/spec/spec_helper.rb +23 -1
  49. data/spec/support/certificates/sp_cert_req.csr +12 -0
  50. data/spec/support/certificates/sp_private_key.pem +16 -0
  51. data/spec/support/certificates/sp_x509_cert.crt +18 -0
  52. data/spec/support/saml_request_macros.rb +66 -4
  53. data/spec/support/security_helpers.rb +10 -0
  54. data/spec/xml_security_spec.rb +12 -12
  55. metadata +135 -81
  56. data/app/controllers/saml_idp/idp_controller.rb +0 -59
  57. data/spec/lib/saml_idp/.assertion_builder_spec.rb.swp +0 -0
@@ -1,9 +1,61 @@
1
- class SamlIdpController < SamlIdp::IdpController
1
+ class SamlIdpController < ApplicationController
2
+ include SamlIdp::Controller
3
+
4
+ if Rails::VERSION::MAJOR >= 4
5
+ before_action :add_view_path, only: [:new, :create, :logout]
6
+ before_action :validate_saml_request, only: [:new, :create, :logout]
7
+ else
8
+ before_filter :add_view_path, only: [:new, :create, :logout]
9
+ before_filter :validate_saml_request, only: [:new, :create, :logout]
10
+ end
11
+
12
+ def new
13
+ render template: "saml_idp/idp/new"
14
+ end
15
+
16
+ def show
17
+ render xml: SamlIdp.metadata.signed
18
+ end
19
+
20
+ def create
21
+ unless params[:email].blank? && params[:password].blank?
22
+ person = idp_authenticate(params[:email], params[:password])
23
+ if person.nil?
24
+ @saml_idp_fail_msg = "Incorrect email or password."
25
+ else
26
+ @saml_response = idp_make_saml_response(person)
27
+ render :template => "saml_idp/idp/saml_post", :layout => false
28
+ return
29
+ end
30
+ end
31
+ render :template => "saml_idp/idp/new"
32
+ end
33
+
34
+ def logout
35
+ idp_logout
36
+ @saml_response = idp_make_saml_response(nil)
37
+ render :template => "saml_idp/idp/saml_post", :layout => false
38
+ end
39
+
40
+ def idp_logout
41
+ raise NotImplementedError
42
+ end
43
+ private :idp_logout
44
+
2
45
  def idp_authenticate(email, password)
3
46
  { :email => email }
4
47
  end
48
+ protected :idp_authenticate
5
49
 
6
- def idp_make_saml_response(user)
7
- encode_response(user[:email])
50
+ def idp_make_saml_response(person)
51
+ encode_response(person[:email])
8
52
  end
53
+ protected :idp_make_saml_response
54
+
55
+ private
56
+
57
+ def add_view_path
58
+ prepend_view_path("app/views")
59
+ end
60
+
9
61
  end
@@ -1,22 +1,18 @@
1
1
  <% if @saml_idp_fail_msg %>
2
2
  <div id="saml_idp_fail_msg" class="flash error"><%= @saml_idp_fail_msg %></div>
3
3
  <% end %>
4
-
5
4
  <%= form_tag do %>
6
5
  <%= hidden_field_tag("SAMLRequest", params[:SAMLRequest]) %>
7
6
  <%= hidden_field_tag("RelayState", params[:RelayState]) %>
8
-
9
7
  <p>
10
8
  <%= label_tag :email %>
11
9
  <%= email_field_tag :email, params[:email], :autocapitalize => "off", :autocorrect => "off", :autofocus => "autofocus", :spellcheck => "false", :size => 30, :class => "email_pwd txt" %>
12
10
  </p>
13
-
14
11
  <p>
15
12
  <%= label_tag :password %>
16
13
  <%= password_field_tag :password, params[:password], :autocapitalize => "off", :autocorrect => "off", :spellcheck => "false", :size => 30, :class => "email_pwd txt" %>
17
14
  </p>
18
-
19
15
  <p>
20
16
  <%= submit_tag "Sign in", :class => "button big blueish" %>
21
17
  </p>
22
- <% end %>
18
+ <% end %>
@@ -11,4 +11,4 @@
11
11
  <%= submit_tag "Submit" %>
12
12
  <% end %>
13
13
  </body>
14
- </html>
14
+ </html>
@@ -18,6 +18,7 @@ module RailsApp
18
18
 
19
19
  # Custom directories with classes and modules you want to be autoloadable.
20
20
  # config.autoload_paths += %W(#{config.root}/extras)
21
+ config.autoload_paths += %w[app/controllers]
21
22
 
22
23
  # Only load the plugins named here, in the order given (default is alphabetical).
23
24
  # :all can be used as a placeholder for all plugins not explicitly named.
@@ -50,11 +51,5 @@ module RailsApp
50
51
  # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
51
52
  # parameters by using an attr_accessible or attr_protected declaration.
52
53
  # config.active_record.whitelist_attributes = true
53
-
54
- # Enable the asset pipeline
55
- config.assets.enabled = true
56
-
57
- # Version of your assets, change this if you want to expire all your assets
58
- config.assets.version = '1.0'
59
54
  end
60
55
  end
@@ -3,4 +3,4 @@ require 'rubygems'
3
3
  # Set up gems listed in the Gemfile.
4
4
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
5
5
 
6
- require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
6
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
@@ -4,6 +4,7 @@ RailsApp::Application.configure do
4
4
  # In the development environment your application's code is reloaded on
5
5
  # every request. This slows down response time but is perfect for development
6
6
  # since you don't have to restart the web server when you make code changes.
7
+ config.eager_load = false if config.respond_to?(:eager_load)
7
8
  config.cache_classes = false
8
9
 
9
10
  # Log error messages when you accidentally call methods on nil.
@@ -29,9 +30,5 @@ RailsApp::Application.configure do
29
30
  # with SQLite, MySQL, and PostgreSQL)
30
31
  #config.active_record.auto_explain_threshold_in_seconds = 0.5
31
32
 
32
- # Do not compress assets
33
- config.assets.compress = false
34
-
35
- # Expands the lines which load the assets
36
- config.assets.debug = true
33
+ config.hosts << "foo.example.com" if config.respond_to?(:hosts)
37
34
  end
@@ -2,6 +2,7 @@ RailsApp::Application.configure do
2
2
  # Settings specified here will take precedence over those in config/application.rb
3
3
 
4
4
  # Code is not reloaded between requests
5
+ config.eager_load = true if config.respond_to?(:eager_load)
5
6
  config.cache_classes = true
6
7
 
7
8
  # Full error reports are disabled and caching is turned on
@@ -5,6 +5,7 @@ RailsApp::Application.configure do
5
5
  # test suite. You never need to work with it otherwise. Remember that
6
6
  # your test database is "scratch space" for the test suite and is wiped
7
7
  # and recreated between test runs. Don't rely on the data there!
8
+ config.eager_load = true if config.respond_to?(:eager_load)
8
9
  config.cache_classes = true
9
10
 
10
11
  # Configure static asset server for tests with Cache-Control for performance
data/spec/spec_helper.rb CHANGED
@@ -43,6 +43,28 @@ RSpec.configure do |config|
43
43
  }
44
44
  end
45
45
  end
46
+
47
+ # To reset to default config
48
+ config.after do
49
+ SamlIdp.instance_variable_set(:@config, nil)
50
+ SamlIdp.configure do |c|
51
+ c.attributes = {
52
+ emailAddress: {
53
+ name: "email-address",
54
+ getter: ->(p) { "foo@example.com" }
55
+ }
56
+ }
57
+
58
+ c.name_id.formats = {
59
+ "1.1" => {
60
+ email_address: ->(p) { "foo@example.com" }
61
+ }
62
+ }
63
+ end
64
+ end
46
65
  end
47
66
 
48
- Capybara.default_host = "https://app.example.com"
67
+ SamlIdp::Default::SERVICE_PROVIDER[:metadata_url] = 'https://example.com/meta'
68
+ SamlIdp::Default::SERVICE_PROVIDER[:response_hosts] = ['foo.example.com']
69
+ SamlIdp::Default::SERVICE_PROVIDER[:assertion_consumer_logout_service_url] = 'https://foo.example.com/saml/logout'
70
+ Capybara.default_host = "https://foo.example.com"
@@ -0,0 +1,12 @@
1
+ -----BEGIN CERTIFICATE REQUEST-----
2
+ MIIByTCCATICAQAwgYgxCzAJBgNVBAYTAmpwMQ4wDAYDVQQIDAVUb2t5bzELMAkG
3
+ A1UECgwCR1MxIDAeBgNVBAMMF2h0dHBzOi8vZm9vLmV4YW1wbGUuY29tMQwwCgYD
4
+ VQQHDANGb28xDDAKBgNVBAsMA0JvbzEeMBwGCSqGSIb3DQEJARYPZm9vQGV4YW1w
5
+ bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8DVj2mVLQV7AjT+cn
6
+ Lv3kDnQFvAo3RdUeGGhplsYFacYByzNRD/jeguu1ahrvznDyZN8p3yB7OPbmt0r0
7
+ aGr+yYzPh6brgkf5u6FMtWTj94vLQuT/uyQGuzdBkiLb5mAWRMtm43oHXDK0v25J
8
+ tsG1PJnntkXfBDpFP1eWLO+jZwIDAQABoAAwDQYJKoZIhvcNAQENBQADgYEAd/J6
9
+ 5zjrMhgjxuaMuWCiNN7IS4F9SKy+gEmhkpNVCpChbpggruaEIoERjDP/TkZn2dgL
10
+ VUeHTZB92t+wWfQbHNvEfbzqlV3XkuHkxewCwofnIV/k+8zG1Al5ELSKHehItxig
11
+ rnTuBrFYsd2j4HEVqLzm4NyCfL+xzn/D4U2ec50=
12
+ -----END CERTIFICATE REQUEST-----
@@ -0,0 +1,16 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALwNWPaZUtBXsCNP
3
+ 5ycu/eQOdAW8CjdF1R4YaGmWxgVpxgHLM1EP+N6C67VqGu/OcPJk3ynfIHs49ua3
4
+ SvRoav7JjM+HpuuCR/m7oUy1ZOP3i8tC5P+7JAa7N0GSItvmYBZEy2bjegdcMrS/
5
+ bkm2wbU8mee2Rd8EOkU/V5Ys76NnAgMBAAECgYEArwclVHCkebIECPnnxbqhKNCj
6
+ AGtifsuKbrZ9CDoDGSq31xeQLdTV6BSm2nVlmOnmilWEuG4qx0Xf2CGlrBI78kmv
7
+ vHCfFdaGnTxbmYnD0HN0u4RK2trsxWO+rEkJk14JE2eVD6ZRPrq1UOSMgGPrQSMb
8
+ SuwAHUu/j94eL8BXuhECQQD3jTlo3Y4VPWttP6XPNqKDP+jRYJs5G0Bch//S9Qy7
9
+ QzmU9/yAUk0BEOyqYcLxinjJhoq6bR2fiIibn+77z3jtAkEAwnhLwkGYOb7Nt3V6
10
+ dQLKx1BP9dnYH7qG/sCmAs7GHPv4LGluaz4zsh2pdEDF/Xar4gwTzUpxYo8FpkCH
11
+ rf4nIwJAVfWnGr/cR4nVVNFGHUcGdXbqvFHEdLb+yWK8NZ+79Qap5w2Zk2GAtb8P
12
+ vzZFQCRqPuhGIegj4jLB5PBLRwtLHQJBAJiWyWL4ExikRUhBTr/HXBL+Sm9u6i0j
13
+ L89unBQx6LNPZhB6/Z/6Y5fLvG2ycWgLGJ06usLnOYaLEHS9x3hXpp8CQQCdtQHw
14
+ xeLBPhRDpfWWbSmFr+bFxyD/4iQHTHToIs3kaecn6OJ4rczIFpGm2Bm7f4X7F3H3
15
+ DDy4jZ0R6iDqCcQD
16
+ -----END PRIVATE KEY-----
@@ -0,0 +1,18 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIC2DCCAkGgAwIBAgIBADANBgkqhkiG9w0BAQ0FADCBiDELMAkGA1UEBhMCanAx
3
+ DjAMBgNVBAgMBVRva3lvMQswCQYDVQQKDAJHUzEgMB4GA1UEAwwXaHR0cHM6Ly9m
4
+ b28uZXhhbXBsZS5jb20xDDAKBgNVBAcMA0ZvbzEMMAoGA1UECwwDQm9vMR4wHAYJ
5
+ KoZIhvcNAQkBFg9mb29AZXhhbXBsZS5jb20wHhcNMjAwMTIzMDYyMzI5WhcNNDcw
6
+ NjA5MDYyMzI5WjCBiDELMAkGA1UEBhMCanAxDjAMBgNVBAgMBVRva3lvMQswCQYD
7
+ VQQKDAJHUzEgMB4GA1UEAwwXaHR0cHM6Ly9mb28uZXhhbXBsZS5jb20xDDAKBgNV
8
+ BAcMA0ZvbzEMMAoGA1UECwwDQm9vMR4wHAYJKoZIhvcNAQkBFg9mb29AZXhhbXBs
9
+ ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALwNWPaZUtBXsCNP5ycu
10
+ /eQOdAW8CjdF1R4YaGmWxgVpxgHLM1EP+N6C67VqGu/OcPJk3ynfIHs49ua3SvRo
11
+ av7JjM+HpuuCR/m7oUy1ZOP3i8tC5P+7JAa7N0GSItvmYBZEy2bjegdcMrS/bkm2
12
+ wbU8mee2Rd8EOkU/V5Ys76NnAgMBAAGjUDBOMB0GA1UdDgQWBBQMtOtrh2VS/mh4
13
+ awGbKA37vVnw+zAfBgNVHSMEGDAWgBQMtOtrh2VS/mh4awGbKA37vVnw+zAMBgNV
14
+ HRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAHjTTm4Hyx1rfzygknc6q1dYwpEv
15
+ /3AsPiTnF4AfH/5kGIIXNzwg0ADsziFMJYRRR9eMu97CHQbr8gHt99P8uaen6cmJ
16
+ 4VCwJLP2N8gZrycssimA3M83DWRRVZbxZhpuUWNajtYIxwyUbB7eRSJgz3Tc0opF
17
+ 933YwucWuFzKSqn3
18
+ -----END CERTIFICATE-----
@@ -1,9 +1,9 @@
1
1
  require 'saml_idp/logout_request_builder'
2
2
 
3
3
  module SamlRequestMacros
4
- def make_saml_request(requested_saml_acs_url = "https://foo.example.com/saml/consume")
4
+ def make_saml_request(requested_saml_acs_url = "https://foo.example.com/saml/consume", enable_secure_options = false)
5
5
  auth_request = OneLogin::RubySaml::Authrequest.new
6
- auth_url = auth_request.create(saml_settings(requested_saml_acs_url))
6
+ auth_url = auth_request.create(saml_settings(requested_saml_acs_url, enable_secure_options))
7
7
  CGI.unescape(auth_url.split("=").last)
8
8
  end
9
9
 
@@ -15,19 +15,81 @@ module SamlRequestMacros
15
15
  'some_name_id',
16
16
  OpenSSL::Digest::SHA256
17
17
  )
18
- request_builder.encoded
18
+ Base64.strict_encode64(request_builder.signed)
19
19
  end
20
20
 
21
- def saml_settings(saml_acs_url = "https://foo.example.com/saml/consume")
21
+ def generate_sp_metadata(saml_acs_url = "https://foo.example.com/saml/consume", enable_secure_options = false)
22
+ sp_metadata = OneLogin::RubySaml::Metadata.new
23
+ sp_metadata.generate(saml_settings(saml_acs_url, enable_secure_options), true)
24
+ end
25
+
26
+ def saml_settings(saml_acs_url = "https://foo.example.com/saml/consume", enable_secure_options = false)
22
27
  settings = OneLogin::RubySaml::Settings.new
23
28
  settings.assertion_consumer_service_url = saml_acs_url
24
29
  settings.issuer = "http://example.com/issuer"
25
30
  settings.idp_sso_target_url = "http://idp.com/saml/idp"
31
+ settings.assertion_consumer_logout_service_url = 'https://foo.example.com/saml/logout'
26
32
  settings.idp_cert_fingerprint = SamlIdp::Default::FINGERPRINT
27
33
  settings.name_identifier_format = SamlIdp::Default::NAME_ID_FORMAT
34
+ add_securty_options(settings) if enable_secure_options
28
35
  settings
29
36
  end
30
37
 
38
+ def add_securty_options(settings, authn_requests_signed: true,
39
+ embed_sign: true,
40
+ logout_requests_signed: true,
41
+ logout_responses_signed: true,
42
+ digest_method: XMLSecurity::Document::SHA256,
43
+ signature_method: XMLSecurity::Document::RSA_SHA256,
44
+ assertions_signed: true)
45
+ # Security section
46
+ settings.idp_cert = SamlIdp::Default::X509_CERTIFICATE
47
+ # Signed embedded singature
48
+ settings.security[:authn_requests_signed] = authn_requests_signed
49
+ settings.security[:embed_sign] = embed_sign
50
+ settings.security[:logout_requests_signed] = logout_requests_signed
51
+ settings.security[:logout_responses_signed] = logout_responses_signed
52
+ settings.security[:metadata_signed] = digest_method
53
+ settings.security[:digest_method] = digest_method
54
+ settings.security[:signature_method] = signature_method
55
+ settings.security[:want_assertions_signed] = assertions_signed
56
+ settings.private_key = sp_pv_key
57
+ settings.certificate = sp_x509_cert
58
+ end
59
+
60
+ def idp_configure(saml_acs_url = "https://foo.example.com/saml/consume", enable_secure_options = false)
61
+ SamlIdp.configure do |config|
62
+ config.x509_certificate = SamlIdp::Default::X509_CERTIFICATE
63
+ config.secret_key = SamlIdp::Default::SECRET_KEY
64
+ config.password = nil
65
+ config.algorithm = :sha256
66
+ config.organization_name = 'idp.com'
67
+ config.organization_url = 'http://idp.com'
68
+ config.base_saml_location = 'http://idp.com/saml/idp'
69
+ config.single_logout_service_post_location = 'http://idp.com/saml/idp/logout'
70
+ config.single_logout_service_redirect_location = 'http://idp.com/saml/idp/logout'
71
+ config.attribute_service_location = 'http://idp.com/saml/idp/attribute'
72
+ config.single_service_post_location = 'http://idp.com/saml/idp/sso'
73
+ config.name_id.formats = SamlIdp::Default::NAME_ID_FORMAT
74
+ config.service_provider.metadata_persister = lambda { |_identifier, _service_provider|
75
+ raw_metadata = generate_sp_metadata(saml_acs_url, enable_secure_options)
76
+ SamlIdp::IncomingMetadata.new(raw_metadata).to_h
77
+ }
78
+ config.service_provider.persisted_metadata_getter = lambda { |_identifier, _settings|
79
+ raw_metadata = generate_sp_metadata(saml_acs_url, enable_secure_options)
80
+ SamlIdp::IncomingMetadata.new(raw_metadata).to_h
81
+ }
82
+ config.service_provider.finder = lambda { |_issuer_or_entity_id|
83
+ {
84
+ response_hosts: [URI(saml_acs_url).host],
85
+ acs_url: saml_acs_url,
86
+ cert: sp_x509_cert,
87
+ fingerprint: SamlIdp::Fingerprint.certificate_digest(sp_x509_cert)
88
+ }
89
+ }
90
+ end
91
+ end
92
+
31
93
  def print_pretty_xml(xml_string)
32
94
  doc = REXML::Document.new xml_string
33
95
  outbuf = ""
@@ -58,4 +58,14 @@ module SecurityHelpers
58
58
  def r1_signature_2
59
59
  @signature2 ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'r1_certificate2_base64'))
60
60
  end
61
+
62
+ # Generated by SAML tool https://www.samltool.com/self_signed_certs.php
63
+ def sp_pv_key
64
+ @sp_pv_key ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'sp_private_key.pem'))
65
+ end
66
+
67
+ # Generated by SAML tool https://www.samltool.com/self_signed_certs.php, expired date is 9999
68
+ def sp_x509_cert
69
+ @sp_x509_cert ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'sp_x509_cert.crt'))
70
+ end
61
71
  end
@@ -7,7 +7,7 @@ module SamlIdp
7
7
  let(:base64cert) { document.elements["//ds:X509Certificate"].text }
8
8
 
9
9
  it "it run validate without throwing NS related exceptions" do
10
- document.validate_doc(base64cert, true).should be_falsey
10
+ expect(document.validate_doc(base64cert, true)).to be_falsey
11
11
  end
12
12
 
13
13
  it "it run validate with throwing NS related exceptions" do
@@ -57,22 +57,22 @@ module SamlIdp
57
57
  describe "Algorithms" do
58
58
  it "validate using SHA1" do
59
59
  document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha1, false))
60
- document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72").should be_truthy
60
+ expect(document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")).to be_truthy
61
61
  end
62
62
 
63
63
  it "validate using SHA256" do
64
64
  document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha256, false))
65
- document.validate("28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA").should be_truthy
65
+ expect(document.validate("28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA")).to be_truthy
66
66
  end
67
67
 
68
68
  it "validate using SHA384" do
69
69
  document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha384, false))
70
- document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72").should be_truthy
70
+ expect(document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")).to be_truthy
71
71
  end
72
72
 
73
73
  it "validate using SHA512" do
74
74
  document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha512, false))
75
- document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72").should be_truthy
75
+ expect(document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")).to be_truthy
76
76
  end
77
77
  end
78
78
 
@@ -83,7 +83,7 @@ module SamlIdp
83
83
  document = XMLSecurity::SignedDocument.new(response)
84
84
  inclusive_namespaces = document.send(:extract_inclusive_namespaces)
85
85
 
86
- inclusive_namespaces.should == %w[xs]
86
+ expect(inclusive_namespaces).to eq %w[xs]
87
87
  end
88
88
 
89
89
  it "support implicit namespace resolution for exclusive canonicalization" do
@@ -91,7 +91,7 @@ module SamlIdp
91
91
  document = XMLSecurity::SignedDocument.new(response)
92
92
  inclusive_namespaces = document.send(:extract_inclusive_namespaces)
93
93
 
94
- inclusive_namespaces.should == %w[#default saml ds xs xsi]
94
+ expect(inclusive_namespaces).to eq %w[#default saml ds xs xsi]
95
95
  end
96
96
 
97
97
  it "return an empty list when inclusive namespace element is missing" do
@@ -101,7 +101,7 @@ module SamlIdp
101
101
  document = XMLSecurity::SignedDocument.new(response)
102
102
  inclusive_namespaces = document.send(:extract_inclusive_namespaces)
103
103
 
104
- inclusive_namespaces.should be_empty
104
+ expect(inclusive_namespaces).to be_empty
105
105
  end
106
106
  end
107
107
 
@@ -116,20 +116,20 @@ module SamlIdp
116
116
 
117
117
  it "be able to validate a good response" do
118
118
  Timecop.freeze Time.parse('2012-11-28 17:55:00 UTC') do
119
- response.stub(:validate_subject_confirmation).and_return(true)
120
- response.should be_is_valid
119
+ allow(response).to receive(:validate_subject_confirmation).and_return(true)
120
+ expect(response).to be_is_valid
121
121
  end
122
122
  end
123
123
 
124
124
  it "fail before response is valid" do
125
125
  Timecop.freeze Time.parse('2012-11-20 17:55:00 UTC') do
126
- response.should_not be_is_valid
126
+ expect(response).to_not be_is_valid
127
127
  end
128
128
  end
129
129
 
130
130
  it "fail after response expires" do
131
131
  Timecop.freeze Time.parse('2012-11-30 17:55:00 UTC') do
132
- response.should_not be_is_valid
132
+ expect(response).to_not be_is_valid
133
133
  end
134
134
  end
135
135
  end