File: metadata_test.rb

package info (click to toggle)
ruby-saml 1.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 1,524 kB
  • ctags: 436
  • sloc: ruby: 5,687; xml: 1,070; makefile: 4
file content (217 lines) | stat: -rw-r--r-- 9,767 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))

require 'onelogin/ruby-saml/metadata'

class MetadataTest < Minitest::Test

  describe 'Metadata' do
    let(:settings)          { OneLogin::RubySaml::Settings.new }
    let(:xml_text)          { OneLogin::RubySaml::Metadata.new.generate(settings, false) }
    let(:xml_doc)           { REXML::Document.new(xml_text) }
    let(:spsso_descriptor)  { REXML::XPath.first(xml_doc, "//md:SPSSODescriptor") }
    let(:acs)               { REXML::XPath.first(xml_doc, "//md:AssertionConsumerService") }

    before do
      settings.issuer = "https://example.com"
      settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
      settings.assertion_consumer_service_url = "https://foo.example/saml/consume"
    end

    it "generates Pretty Print Service Provider Metadata" do
      xml_text = OneLogin::RubySaml::Metadata.new.generate(settings, true)
      # assert correct xml declaration
      start = "<?xml version='1.0' encoding='UTF-8'?>\n<md:EntityDescriptor"
      assert_equal xml_text[0..start.length-1],start

      assert_equal "https://example.com", REXML::XPath.first(xml_doc, "//md:EntityDescriptor").attribute("entityID").value

      assert_equal "urn:oasis:names:tc:SAML:2.0:protocol", spsso_descriptor.attribute("protocolSupportEnumeration").value
      assert_equal "false", spsso_descriptor.attribute("AuthnRequestsSigned").value
      assert_equal "false", spsso_descriptor.attribute("WantAssertionsSigned").value

      assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", REXML::XPath.first(xml_doc, "//md:NameIDFormat").text.strip

      assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", acs.attribute("Binding").value
      assert_equal "https://foo.example/saml/consume", acs.attribute("Location").value      

      assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
    end

    it "generates Service Provider Metadata" do
      settings.single_logout_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
      settings.single_logout_service_url = "https://foo.example/saml/sls"
      xml_metadata = OneLogin::RubySaml::Metadata.new.generate(settings, false)

      start = "<?xml version='1.0' encoding='UTF-8'?><md:EntityDescriptor"
      assert_equal xml_metadata[0..start.length-1],start

      doc_metadata = REXML::Document.new(xml_metadata)
      sls = REXML::XPath.first(doc_metadata, "//md:SingleLogoutService")

      assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", sls.attribute("Binding").value
      assert_equal "https://foo.example/saml/sls", sls.attribute("Location").value
      assert_equal "https://foo.example/saml/sls", sls.attribute("ResponseLocation").value
      assert_nil sls.attribute("isDefault")
      assert_nil sls.attribute("index")

      assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
    end

    it "generates Service Provider Metadata with single logout service" do
      start = "<?xml version='1.0' encoding='UTF-8'?><md:EntityDescriptor"
      assert_equal xml_text[0..start.length-1], start

      assert_equal "https://example.com", REXML::XPath.first(xml_doc, "//md:EntityDescriptor").attribute("entityID").value

      assert_equal "urn:oasis:names:tc:SAML:2.0:protocol", spsso_descriptor.attribute("protocolSupportEnumeration").value
      assert_equal "false", spsso_descriptor.attribute("AuthnRequestsSigned").value
      assert_equal "false", spsso_descriptor.attribute("WantAssertionsSigned").value

      assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", REXML::XPath.first(xml_doc, "//md:NameIDFormat").text.strip

      assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", acs.attribute("Binding").value
      assert_equal "https://foo.example/saml/consume", acs.attribute("Location").value

      assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
    end

    describe "WantAssertionsSigned" do
      it "generates Service Provider Metadata with WantAssertionsSigned = false" do
        settings.security[:want_assertions_signed] = false
        assert_equal "false", spsso_descriptor.attribute("WantAssertionsSigned").value
        assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
      end

      it "generates Service Provider Metadata with WantAssertionsSigned = true" do
        settings.security[:want_assertions_signed] = true
        assert_equal "true", spsso_descriptor.attribute("WantAssertionsSigned").value
        assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
      end
    end

    describe "when auth requests are signed" do
      let(:key_descriptors) do
        REXML::XPath.match(
          xml_doc,
          "//md:KeyDescriptor",
          "md" => "urn:oasis:names:tc:SAML:2.0:metadata"
        )
      end
      let(:cert_nodes) do
        REXML::XPath.match(
          xml_doc,
          "//md:KeyDescriptor/ds:KeyInfo/ds:X509Data/ds:X509Certificate",
          "md" => "urn:oasis:names:tc:SAML:2.0:metadata",
          "ds" => "http://www.w3.org/2000/09/xmldsig#"
        )
      end
      let(:cert)  { OpenSSL::X509::Certificate.new(Base64.decode64(cert_nodes[0].text)) }

      before do
        settings.certificate = ruby_saml_cert_text
      end

      it "generates Service Provider Metadata with AuthnRequestsSigned" do
        settings.security[:authn_requests_signed] = true
        assert_equal "true", spsso_descriptor.attribute("AuthnRequestsSigned").value
        assert_equal ruby_saml_cert.to_der, cert.to_der

        assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
      end

      it "generates Service Provider Metadata with X509Certificate for sign and encrypt" do
        assert_equal 2, key_descriptors.length
        assert_equal "signing", key_descriptors[0].attribute("use").value
        assert_equal "encryption", key_descriptors[1].attribute("use").value

        assert_equal 2, cert_nodes.length
        assert_equal ruby_saml_cert.to_der, cert.to_der
        assert_equal cert_nodes[0].text, cert_nodes[1].text

        assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
      end
    end

    describe "when attribute service is configured" do
      let(:attr_svc)  { REXML::XPath.first(xml_doc, "//md:AttributeConsumingService") }
      let(:req_attr)  { REXML::XPath.first(xml_doc, "//md:RequestedAttribute") }

      before do
        settings.attribute_consuming_service.configure do
          service_name "Test Service"
          add_attribute(:name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name", :attribute_value => "Attribute Value")
        end
      end

      it "generates attribute service" do
        assert_equal "true", attr_svc.attribute("isDefault").value
        assert_equal "1", attr_svc.attribute("index").value
        assert_equal REXML::XPath.first(xml_doc, "//md:ServiceName").text.strip, "Test Service"

        assert_equal "Name", req_attr.attribute("Name").value
        assert_equal "Name Format", req_attr.attribute("NameFormat").value
        assert_equal "Friendly Name", req_attr.attribute("FriendlyName").value
        assert_equal "Attribute Value", REXML::XPath.first(xml_doc, "//saml:AttributeValue").text.strip

        assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
      end

      describe "#service_name" do
        before do
          settings.attribute_consuming_service.service_name("Test2 Service")
        end

        it "change service name" do
          assert_equal REXML::XPath.first(xml_doc, "//md:ServiceName").text.strip, "Test2 Service"
        end
      end

      describe "#service_index" do
        before do
          settings.attribute_consuming_service.service_index(2)
        end

        it "change service index" do
          assert_equal "2", attr_svc.attribute("index").value
        end
      end
    end

    describe "when the settings indicate to sign (embedded) metadata" do
      before do
        settings.security[:metadata_signed] = true
        settings.certificate = ruby_saml_cert_text
        settings.private_key = ruby_saml_key_text
      end

      it "creates a signed metadata" do
        assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>]m, xml_text
        assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], xml_text
        assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], xml_text
        signed_metadata = XMLSecurity::SignedDocument.new(xml_text)
        assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false)        

        assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
      end

      describe "when digest and signature methods are specified" do
        before do
          settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
          settings.security[:digest_method] = XMLSecurity::Document::SHA512
        end

        it "creates a signed metadata with specified digest and signature methods" do
          assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>]m, xml_text
          assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], xml_text
          assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha512'/>], xml_text

          signed_metadata_2 = XMLSecurity::SignedDocument.new(xml_text)

          assert signed_metadata_2.validate_document(ruby_saml_cert_fingerprint, false)          

          assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
        end
      end
    end
  end
end