Comparing changes
v0.2.6
→
v0.2.7
10 commits
23 files changed
Commits
Changed files (23)
lib
saml
kit
bindings
builders
spec
saml
lib/saml/kit/bindings/http_post.rb
@@ -18,9 +18,9 @@ module Saml
[location, saml_params]
end
- def deserialize(params)
+ def deserialize(params, configuration: Saml::Kit.configuration)
xml = decode(saml_param_from(params))
- Saml::Kit::Document.to_saml_document(xml)
+ Saml::Kit::Document.to_saml_document(xml, configuration: configuration)
end
end
end
lib/saml/kit/bindings/http_redirect.rb
@@ -9,14 +9,14 @@ module Saml
end
def serialize(builder, relay_state: nil)
- builder.sign = false
+ builder.embed_signature = false
builder.destination = location
document = builder.build
[UrlBuilder.new(configuration: builder.configuration).build(document, relay_state: relay_state), {}]
end
- def deserialize(params)
- document = deserialize_document_from!(params)
+ def deserialize(params, configuration: Saml::Kit.configuration)
+ document = deserialize_document_from!(params, configuration)
ensure_valid_signature!(params, document)
document.signature_verified!
document
@@ -24,10 +24,10 @@ module Saml
private
- def deserialize_document_from!(params)
+ def deserialize_document_from!(params, configuration)
xml = inflate(decode(unescape(saml_param_from(params))))
Saml::Kit.logger.debug(xml)
- Saml::Kit::Document.to_saml_document(xml)
+ Saml::Kit::Document.to_saml_document(xml, configuration: configuration)
end
def ensure_valid_signature!(params, document)
lib/saml/kit/builders/templates/identity_provider_metadata.builder
@@ -1,32 +1,21 @@
-xml.instruct!
-xml.EntityDescriptor entity_descriptor_options do
- signature_for(reference_id: id, xml: xml)
- xml.IDPSSODescriptor idp_sso_descriptor_options do
- configuration.certificates(use: :signing).each do |certificate|
- render certificate, xml: xml
- end
- configuration.certificates(use: :encryption).each do |certificate|
- render certificate, xml: xml
- end
- logout_urls.each do |item|
- xml.SingleLogoutService Binding: item[:binding], Location: item[:location]
- end
- name_id_formats.each do |format|
- xml.NameIDFormat format
- end
- single_sign_on_urls.each do |item|
- xml.SingleSignOnService Binding: item[:binding], Location: item[:location]
- end
- attributes.each do |attribute|
- xml.tag! 'saml:Attribute', Name: attribute
- end
+signature_for(reference_id: id, xml: xml)
+xml.IDPSSODescriptor descriptor_options do
+ configuration.certificates(use: :signing).each do |certificate|
+ render certificate, xml: xml
end
- xml.Organization do
- xml.OrganizationName organization_name, 'xml:lang': "en"
- xml.OrganizationDisplayName organization_name, 'xml:lang': "en"
- xml.OrganizationURL organization_url, 'xml:lang': "en"
+ configuration.certificates(use: :encryption).each do |certificate|
+ render certificate, xml: xml
end
- xml.ContactPerson contactType: "technical" do
- xml.Company "mailto:#{contact_email}"
+ logout_urls.each do |item|
+ xml.SingleLogoutService Binding: item[:binding], Location: item[:location]
+ end
+ name_id_formats.each do |format|
+ xml.NameIDFormat format
+ end
+ single_sign_on_urls.each do |item|
+ xml.SingleSignOnService Binding: item[:binding], Location: item[:location]
+ end
+ attributes.each do |attribute|
+ xml.tag! 'saml:Attribute', Name: attribute
end
end
lib/saml/kit/builders/templates/metadata.builder
@@ -0,0 +1,13 @@
+xml.instruct!
+xml.EntityDescriptor entity_descriptor_options do
+ render identity_provider, xml: xml
+ render service_provider, xml: xml
+ xml.Organization do
+ xml.OrganizationName organization_name, 'xml:lang': "en"
+ xml.OrganizationDisplayName organization_name, 'xml:lang': "en"
+ xml.OrganizationURL organization_url, 'xml:lang': "en"
+ end
+ xml.ContactPerson contactType: "technical" do
+ xml.Company "mailto:#{contact_email}"
+ end
+end
lib/saml/kit/builders/templates/service_provider_metadata.builder
@@ -1,29 +1,18 @@
-xml.instruct!
-xml.EntityDescriptor entity_descriptor_options do
- signature_for(reference_id: id, xml: xml)
- xml.SPSSODescriptor descriptor_options do
- configuration.certificates(use: :signing).each do |certificate|
- render certificate, xml: xml
- end
- configuration.certificates(use: :encryption).each do |certificate|
- render certificate, xml: xml
- end
- logout_urls.each do |item|
- xml.SingleLogoutService Binding: item[:binding], Location: item[:location]
- end
- name_id_formats.each do |format|
- xml.NameIDFormat format
- end
- acs_urls.each_with_index do |item, index|
- xml.AssertionConsumerService Binding: item[:binding], Location: item[:location], index: index, isDefault: index == 0 ? true : false
- end
+signature_for(reference_id: id, xml: xml)
+xml.SPSSODescriptor descriptor_options do
+ configuration.certificates(use: :signing).each do |certificate|
+ render certificate, xml: xml
end
- xml.Organization do
- xml.OrganizationName organization_name, 'xml:lang': "en"
- xml.OrganizationDisplayName organization_name, 'xml:lang': "en"
- xml.OrganizationURL organization_url, 'xml:lang': "en"
+ configuration.certificates(use: :encryption).each do |certificate|
+ render certificate, xml: xml
end
- xml.ContactPerson contactType: "technical" do
- xml.Company "mailto:#{contact_email}"
+ logout_urls.each do |item|
+ xml.SingleLogoutService Binding: item[:binding], Location: item[:location]
+ end
+ name_id_formats.each do |format|
+ xml.NameIDFormat format
+ end
+ acs_urls.each_with_index do |item, index|
+ xml.AssertionConsumerService Binding: item[:binding], Location: item[:location], index: index, isDefault: index == 0 ? true : false
end
end
lib/saml/kit/builders/assertion.rb
@@ -5,7 +5,7 @@ module Saml
include Templatable
extend Forwardable
- def_delegators :@response_builder, :encrypt, :sign, :request, :issuer, :reference_id, :now, :configuration, :user, :version, :destination, :encryption_certificate
+ def_delegators :@response_builder, :encrypt, :embed_signature, :request, :issuer, :reference_id, :now, :configuration, :user, :version, :destination, :encryption_certificate
def initialize(response_builder)
@response_builder = response_builder
lib/saml/kit/builders/identity_provider_metadata.rb
@@ -3,10 +3,13 @@ module Saml
module Builders
class IdentityProviderMetadata
include Saml::Kit::Templatable
- attr_accessor :id, :organization_name, :organization_url, :contact_email, :entity_id, :attributes, :name_id_formats
+ extend Forwardable
+ attr_accessor :attributes, :name_id_formats
attr_accessor :want_authn_requests_signed
attr_reader :logout_urls, :single_sign_on_urls
attr_reader :configuration
+ attr_reader :metadata
+ def_delegators :metadata, :id, :id=, :entity_id, :entity_id=, :organization_name, :organization_name=, :organization_url, :organization_url=, :contact_email, :contact_email=, :to_xml
def initialize(configuration: Saml::Kit.configuration)
@attributes = []
@@ -17,6 +20,8 @@ module Saml
@name_id_formats = [Namespaces::PERSISTENT]
@single_sign_on_urls = []
@want_authn_requests_signed = true
+ @metadata = Saml::Kit::Builders::Metadata.new(configuration: configuration)
+ @metadata.identity_provider = self
end
def add_single_sign_on_service(url, binding: :http_post)
@@ -43,7 +48,7 @@ module Saml
}
end
- def idp_sso_descriptor_options
+ def descriptor_options
{
WantAuthnRequestsSigned: want_authn_requests_signed,
protocolSupportEnumeration: Namespaces::PROTOCOL,
lib/saml/kit/builders/metadata.rb
@@ -0,0 +1,50 @@
+module Saml
+ module Kit
+ module Builders
+ class Metadata
+ include Templatable
+
+ attr_accessor :entity_id
+ attr_accessor :id
+ attr_accessor :identity_provider
+ attr_accessor :organization_name, :organization_url, :contact_email
+ attr_accessor :service_provider
+ attr_reader :configuration
+
+ def initialize(configuration: Saml::Kit.configuration)
+ @id = Id.generate
+ @entity_id = configuration.issuer
+ @configuration = configuration
+ end
+
+ def build_service_provider
+ @service_provider = Saml::Kit::ServiceProviderMetadata.builder(configuration: configuration) do |x|
+ yield x if block_given?
+ end
+ end
+
+ def build_identity_provider
+ @identity_provider = Saml::Kit::IdentityProviderMetadata.builder(configuration: configuration) do |x|
+ yield x if block_given?
+ end
+ end
+
+ def build
+ Saml::Kit::Metadata.from(to_xml)
+ end
+
+ private
+
+ def entity_descriptor_options
+ {
+ 'xmlns': Namespaces::METADATA,
+ 'xmlns:ds': Namespaces::XMLDSIG,
+ 'xmlns:saml': Namespaces::ASSERTION,
+ ID: id,
+ entityID: entity_id,
+ }
+ end
+ end
+ end
+ end
+end
lib/saml/kit/builders/response.rb
@@ -18,7 +18,7 @@ module Saml
@version = "2.0"
@status_code = Namespaces::SUCCESS
@issuer = configuration.issuer
- @sign = want_assertions_signed
+ @embed_signature = want_assertions_signed
@encrypt = encryption_certificate.present?
@configuration = configuration
end
lib/saml/kit/builders/service_provider_metadata.rb
@@ -3,19 +3,21 @@ module Saml
module Builders
class ServiceProviderMetadata
include Saml::Kit::Templatable
- attr_accessor :id, :entity_id, :acs_urls, :logout_urls, :name_id_formats
- attr_accessor :organization_name, :organization_url, :contact_email
+ extend Forwardable
+ attr_accessor :acs_urls, :logout_urls, :name_id_formats
attr_accessor :want_assertions_signed
attr_reader :configuration
+ attr_reader :metadata
+ def_delegators :metadata, :id, :id=, :entity_id, :entity_id=, :organization_name, :organization_name=, :organization_url, :organization_url=, :contact_email, :contact_email=, :to_xml
def initialize(configuration: Saml::Kit.configuration)
@acs_urls = []
@configuration = configuration
- @entity_id = configuration.issuer
- @id = Id.generate
@logout_urls = []
@name_id_formats = [Namespaces::PERSISTENT]
@want_assertions_signed = true
+ @metadata = Saml::Kit::Builders::Metadata.new(configuration: configuration)
+ @metadata.service_provider = self
end
def add_assertion_consumer_service(url, binding: :http_post)
lib/saml/kit/builders/xml_signature.rb
@@ -17,7 +17,7 @@ module Saml
SHA512: "http://www.w3.org/2001/04/xmlenc#sha512",
}.freeze
- attr_reader :sign, :configuration
+ attr_reader :embed_signature, :configuration
attr_reader :reference_id
attr_reader :x509_certificate
lib/saml/kit/authentication_request.rb
@@ -18,7 +18,7 @@ module Saml
def response_for(user, binding:, relay_state: nil)
response_binding = provider.assertion_consumer_service_for(binding: binding)
builder = Saml::Kit::Response.builder(user, self) do |x|
- x.sign = provider.want_assertions_signed
+ x.embed_signature = provider.want_assertions_signed
yield x if block_given?
end
response_binding.serialize(builder, relay_state: relay_state)
lib/saml/kit/builders.rb
@@ -3,6 +3,7 @@ require 'saml/kit/builders/authentication_request'
require 'saml/kit/builders/identity_provider_metadata'
require 'saml/kit/builders/logout_request'
require 'saml/kit/builders/logout_response'
+require 'saml/kit/builders/metadata'
require 'saml/kit/builders/response'
require 'saml/kit/builders/service_provider_metadata'
require 'saml/kit/builders/xml_encryption'
lib/saml/kit/document.rb
@@ -64,16 +64,16 @@ module Saml
end
class << self
- def to_saml_document(xml)
+ def to_saml_document(xml, configuration: Saml::Kit.configuration)
hash = Hash.from_xml(xml)
if hash['Response'].present?
- Response.new(xml)
+ Response.new(xml, configuration: configuration)
elsif hash['LogoutResponse'].present?
- LogoutResponse.new(xml)
+ LogoutResponse.new(xml, configuration: configuration)
elsif hash['AuthnRequest'].present?
- AuthenticationRequest.new(xml)
+ AuthenticationRequest.new(xml, configuration: configuration)
elsif hash['LogoutRequest'].present?
- LogoutRequest.new(xml)
+ LogoutRequest.new(xml, configuration: configuration)
end
rescue => error
Saml::Kit.logger.error(error)
lib/saml/kit/identity_provider_metadata.rb
@@ -31,7 +31,7 @@ module Saml
def login_request_for(binding:, relay_state: nil)
builder = Saml::Kit::AuthenticationRequest.builder do |x|
- x.sign = want_authn_requests_signed
+ x.embed_signature = want_authn_requests_signed
yield x if block_given?
end
request_binding = single_sign_on_service_for(binding: binding)
lib/saml/kit/logout_response.rb
@@ -3,9 +3,9 @@ module Saml
class LogoutResponse < Document
include Respondable
- def initialize(xml, request_id: nil)
+ def initialize(xml, request_id: nil, configuration: Saml::Kit.configuration)
@request_id = request_id
- super(xml, name: "LogoutResponse")
+ super(xml, name: "LogoutResponse", configuration: configuration)
end
Builder = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Saml::Kit::LogoutResponse::Builder', 'Saml::Kit::Builders::LogoutResponse')
lib/saml/kit/metadata.rb
@@ -109,6 +109,10 @@ module Saml
end
end
+ def self.builder_class
+ Saml::Kit::Builders::Metadata
+ end
+
private
def document
lib/saml/kit/templatable.rb
@@ -1,7 +1,12 @@
module Saml
module Kit
module Templatable
- attr_accessor :sign
+ attr_accessor :embed_signature
+
+ def sign=(value)
+ Saml::Kit.deprecate("sign= is deprecated. Use embed_signature= instead")
+ self.embed_signature = value
+ end
def to_xml(xml: ::Builder::XmlMarkup.new)
signatures.complete(render(self, xml: xml))
@@ -13,7 +18,7 @@ module Saml
end
def sign?
- sign.nil? ? configuration.sign? : sign && configuration.sign?
+ embed_signature.nil? ? configuration.sign? : embed_signature && configuration.sign?
end
def signatures
lib/saml/kit/version.rb
@@ -1,5 +1,5 @@
module Saml
module Kit
- VERSION = "0.2.6"
+ VERSION = "0.2.7"
end
end
lib/saml/kit.rb
@@ -74,7 +74,7 @@ module Saml
end
def deprecate(message)
- @deprecation ||= ActiveSupport::Deprecation.new('next-release', 'saml-kit')
+ @deprecation ||= ActiveSupport::Deprecation.new('1.0.0', 'saml-kit')
@deprecation.deprecation_warning(message)
end
end
spec/saml/builders/logout_request_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe Saml::Kit::Builders::LogoutRequest do
end
it 'excludes a signature' do
- subject.sign = false
+ subject.embed_signature = false
xml_hash = Hash.from_xml(subject.to_xml)
expect(xml_hash['LogoutRequest']['Signature']).to be_nil
end
spec/saml/builders/metadata_spec.rb
@@ -0,0 +1,56 @@
+RSpec.describe Saml::Kit::Builders::Metadata do
+ describe ".build" do
+ subject { Saml::Kit::Metadata }
+ let(:url) { FFaker::Internet.uri("https") }
+
+ it 'builds metadata for a service provider' do
+ result = subject.build do |builder|
+ builder.build_service_provider do |x|
+ x.add_assertion_consumer_service(url, binding: :http_post)
+ end
+ end
+
+ hash_result = Hash.from_xml(result.to_xml)
+ expect(hash_result['EntityDescriptor']).to be_present
+ expect(hash_result['EntityDescriptor']['SPSSODescriptor']).to be_present
+ expect(hash_result['EntityDescriptor']['SPSSODescriptor']['AssertionConsumerService']).to be_present
+ expect(hash_result['EntityDescriptor']['SPSSODescriptor']['AssertionConsumerService']['Location']).to eql(url)
+ end
+
+ it 'builds metadata for an identity provider' do
+ result = subject.build do |builder|
+ builder.build_identity_provider do |x|
+ x.add_single_sign_on_service(url, binding: :http_post)
+ end
+ end
+
+ hash_result = Hash.from_xml(result.to_xml)
+ expect(hash_result['EntityDescriptor']).to be_present
+ expect(hash_result['EntityDescriptor']['IDPSSODescriptor']).to be_present
+ expect(hash_result['EntityDescriptor']['IDPSSODescriptor']['SingleSignOnService']).to be_present
+ expect(hash_result['EntityDescriptor']['IDPSSODescriptor']['SingleSignOnService']['Location']).to eql(url)
+ end
+
+ it 'builds metadata for both IDP and SP' do
+ result = subject.build do |builder|
+ builder.build_service_provider do |x|
+ x.add_assertion_consumer_service(url, binding: :http_post)
+ end
+ builder.build_identity_provider do |x|
+ x.add_single_sign_on_service(url, binding: :http_post)
+ end
+ end
+
+ hash_result = Hash.from_xml(result.to_xml)
+ expect(hash_result['EntityDescriptor']).to be_present
+ expect(hash_result['EntityDescriptor']['IDPSSODescriptor']).to be_present
+ expect(hash_result['EntityDescriptor']['SPSSODescriptor']).to be_present
+
+ expect(hash_result['EntityDescriptor']['IDPSSODescriptor']['SingleSignOnService']).to be_present
+ expect(hash_result['EntityDescriptor']['IDPSSODescriptor']['SingleSignOnService']['Location']).to eql(url)
+ expect(hash_result['EntityDescriptor']['SPSSODescriptor']['AssertionConsumerService']).to be_present
+ expect(hash_result['EntityDescriptor']['SPSSODescriptor']['AssertionConsumerService']['Location']).to eql(url)
+ end
+
+ end
+end
spec/saml/builders/response_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe Saml::Kit::Builders::Response do
allow(configuration.registry).to receive(:metadata_for).with(issuer).and_return(provider)
allow(provider).to receive(:matches?).and_return(true)
- subject.sign = true
+ subject.embed_signature = true
subject.encrypt = true
result = subject.build
expect(result).to be_valid
@@ -111,7 +111,7 @@ RSpec.describe Saml::Kit::Builders::Response do
it 'generates a signed response and encrypted assertion' do
subject.encrypt = true
- subject.sign = true
+ subject.embed_signature = true
result = Hash.from_xml(subject.to_xml)
expect(result['Response']['Signature']).to be_present
expect(result['Response']['EncryptedAssertion']).to be_present
@@ -119,7 +119,7 @@ RSpec.describe Saml::Kit::Builders::Response do
it 'generates a signed response and assertion' do
subject.encrypt = false
- subject.sign = true
+ subject.embed_signature = true
result = Hash.from_xml(subject.to_xml)
expect(result['Response']['Signature']).to be_present
expect(result['Response']['Assertion']['Signature']).to be_present
@@ -127,7 +127,7 @@ RSpec.describe Saml::Kit::Builders::Response do
it 'generates a signed response and signed and encrypted assertion' do
subject.encrypt = true
- subject.sign = true
+ subject.embed_signature = true
result = Saml::Kit::Response.new(subject.to_xml, configuration: configuration)
expect(result).to be_signed
@@ -137,7 +137,7 @@ RSpec.describe Saml::Kit::Builders::Response do
it 'generates an encrypted assertion' do
subject.encrypt = true
- subject.sign = false
+ subject.embed_signature = false
result = Saml::Kit::Response.new(subject.to_xml, configuration: configuration)
expect(result).to_not be_signed