Commit dff7ad2
Changed files (3)
lib
saml
spec
lib/saml/kit/service_provider_metadata.rb
@@ -0,0 +1,55 @@
+module Saml
+ module Kit
+ class ServiceProviderMetadata
+ def initialize(xml)
+ @xml = xml
+ end
+
+ def to_xml
+ @xml
+ end
+
+ class Builder
+ attr_accessor :id, :entity_id, :acs_url
+
+ def initialize
+ @id = SecureRandom.uuid
+ end
+
+ def to_xml
+ xml = ::Builder::XmlMarkup.new
+ xml.instruct!
+ xml.EntityDescriptor entity_descriptor_options do
+ xml.tag! "md:SPSSODescriptor", descriptor_options do
+ xml.tag! "md:NameIDFormat", Namespaces::Formats::NameId::PERSISTENT
+ xml.tag! "md:AssertionConsumerService", Binding: Namespaces::Bindings::POST, Location: acs_url, index: "0", isDefault: "true"
+ end
+ end
+ xml.target!
+ end
+
+ def build
+ ServiceProviderMetadata.new(to_xml)
+ end
+
+ private
+
+ def entity_descriptor_options
+ {
+ 'xmlns:md': Namespaces::METADATA,
+ ID: "_#{id}",
+ entityID: entity_id,
+ }
+ end
+
+ def descriptor_options
+ {
+ AuthnRequestsSigned: "true",
+ WantAssertionsSigned: "true",
+ protocolSupportEnumeration: Namespaces::PROTOCOL,
+ }
+ end
+ end
+ end
+ end
+end
lib/saml/kit.rb
@@ -12,6 +12,7 @@ require "saml/kit/request"
require "saml/kit/response"
require "saml/kit/service_provider_registry"
require "saml/kit/identity_provider_metadata"
+require "saml/kit/service_provider_metadata"
module Saml
module Kit
spec/saml/service_provider_metadata_spec.rb
@@ -0,0 +1,40 @@
+require 'spec_helper'
+
+RSpec.describe Saml::Kit::ServiceProviderMetadata do
+ describe described_class::Builder do
+ let(:entity_id) { FFaker::Movie.title }
+ let(:acs_url) { "https://#{FFaker::Internet.domain_name}/acs" }
+
+ <<-XML
+<?xml version="1.0" encoding="UTF-8"?>
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+ ID="_a94ad660-23cc-4491-8fe0-1429b7f5a6d8"
+ entityID="https://service.dev/metadata">
+ <md:SPSSODescriptor
+ AuthnRequestsSigned="true"
+ WantAssertionsSigned="true"
+ protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://service.dev/acs" index="0" isDefault="true"/>
+ </md:SPSSODescriptor>
+</md:EntityDescriptor>
+ XML
+ it 'builds the service provider metadata' do
+ subject.entity_id = entity_id
+ subject.acs_url = acs_url
+ result = Hash.from_xml(subject.build.to_xml)
+
+ expect(result['EntityDescriptor']['xmlns:md']).to eql("urn:oasis:names:tc:SAML:2.0:metadata")
+ expect(result['EntityDescriptor']['ID']).to be_present
+ expect(result['EntityDescriptor']['entityID']).to eql(entity_id)
+ expect(result['EntityDescriptor']['SPSSODescriptor']['AuthnRequestsSigned']).to eql('true')
+ expect(result['EntityDescriptor']['SPSSODescriptor']['WantAssertionsSigned']).to eql('true')
+ expect(result['EntityDescriptor']['SPSSODescriptor']['protocolSupportEnumeration']).to eql('urn:oasis:names:tc:SAML:2.0:protocol')
+ expect(result['EntityDescriptor']['SPSSODescriptor']['NameIDFormat']).to eql("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent")
+ expect(result['EntityDescriptor']['SPSSODescriptor']['AssertionConsumerService']['Binding']).to eql("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST")
+ expect(result['EntityDescriptor']['SPSSODescriptor']['AssertionConsumerService']['Location']).to eql(acs_url)
+ expect(result['EntityDescriptor']['SPSSODescriptor']['AssertionConsumerService']['isDefault']).to eql('true')
+ expect(result['EntityDescriptor']['SPSSODescriptor']['AssertionConsumerService']['index']).to eql('0')
+ end
+ end
+end