Commit 56d8f0f
Changed files (6)
lib
saml
kit
spec
saml
kit
lib/saml/kit/concerns/xsd_validatable.rb
@@ -19,7 +19,7 @@ module Saml
Dir.chdir(File.dirname(xsd)) do
xsd = Nokogiri::XML::Schema(IO.read(xsd))
- xsd.validate(to_nokogiri).each do |error|
+ xsd.validate(to_nokogiri.document).each do |error|
errors[:base] << error.message
end
end
lib/saml/kit/locales/en.yml
@@ -5,8 +5,12 @@ en:
Assertion:
cannot_decrypt: "cannot be decrypted."
expired: "must not be expired."
- must_match_issuer: "must match entityId."
+ invalid: "must contain Assertion."
+ invalid_fingerprint: "is not registered."
+ invalid_version: "must be 2.0."
must_contain_single_assertion: "must contain single Assertion."
+ must_match_issuer: "must match entityId."
+ unregistered: "is unregistered."
AuthnRequest:
invalid: "must contain AuthnRequest."
invalid_fingerprint: "is not registered."
lib/saml/kit/assertion.rb
@@ -5,11 +5,7 @@ module Saml
# This class validates the Assertion
# element nested in a Response element
# of a SAML document.
- class Assertion
- include ActiveModel::Validations
- include Buildable
- include Translatable
- include XmlParseable
+ class Assertion < Document
extend Forwardable
XPATH = [
'/samlp:Response/saml:Assertion',
@@ -36,12 +32,21 @@ module Saml
@encrypted = false
keys = configuration.private_keys(use: :encryption) + private_keys
decrypt(::Xml::Kit::Decryption.new(private_keys: keys.uniq))
+ super(to_s, name: 'Assertion', configuration: configuration)
+ end
+
+ def id
+ at_xpath('./@ID').try(:value)
end
def issuer
at_xpath('./saml:Issuer').try(:text)
end
+ def version
+ at_xpath('./@Version').try(:value)
+ end
+
def name_id
at_xpath('./saml:Subject/saml:NameID').try(:text)
end
@@ -67,6 +72,10 @@ module Saml
now > drifted_started_at && !expired?(now)
end
+ def expected_type?
+ at_xpath("//saml:Assertion|//saml:EncryptedAssertion").present?
+ end
+
def attribute_statement
@attribute_statement ||=
AttributeStatement.new(search('./saml:AttributeStatement'))
@@ -89,12 +98,6 @@ module Saml
@to_nokogiri.to_s
end
- class << self
- def builder_class
- Saml::Kit::Builders::Assertion
- end
- end
-
private
attr_reader :configuration
lib/saml/kit/document.rb
@@ -83,10 +83,11 @@ module Saml
# @!visibility private
def builder_class # :nodoc:
{
- Response.to_s => Saml::Kit::Builders::Response,
- LogoutResponse.to_s => Saml::Kit::Builders::LogoutResponse,
+ Assertion.to_s => Saml::Kit::Builders::Assertion,
AuthenticationRequest.to_s => Saml::Kit::Builders::AuthenticationRequest,
LogoutRequest.to_s => Saml::Kit::Builders::LogoutRequest,
+ LogoutResponse.to_s => Saml::Kit::Builders::LogoutResponse,
+ Response.to_s => Saml::Kit::Builders::Response,
}[name] || (raise ArgumentError, "Unknown SAML Document #{name}")
end
end
spec/saml/kit/builders/assertion_builder_spec.rb
@@ -10,13 +10,21 @@ RSpec.describe Saml::Kit::Builders::Assertion do
let(:authn_request) { instance_double(Saml::Kit::AuthenticationRequest, id: Xml::Kit::Id.generate, assertion_consumer_service_url: assertion_consumer_service_url, issuer: issuer, name_id_format: Saml::Kit::Namespaces::EMAIL_ADDRESS, provider: provider, trusted?: true, signed?: true) }
let(:provider) { instance_double(Saml::Kit::ServiceProviderMetadata, want_assertions_signed: false, encryption_certificates: [configuration.certificates(use: :encryption).last]) }
let(:issuer) { FFaker::Internet.uri('https') }
+ let(:registry) { instance_double(Saml::Kit::DefaultRegistry) }
let(:configuration) do
Saml::Kit::Configuration.new do |config|
config.entity_id = issuer
+ config.registry = registry
config.generate_key_pair_for(use: :signing)
config.generate_key_pair_for(use: :encryption)
end
end
+ let(:metadata) do
+ Saml::Kit::Metadata.build(configuration: configuration) do |x|
+ x.build_identity_provider
+ end
+ end
+ before { allow(registry).to receive(:metadata_for).and_return(metadata) }
specify { expect(subject.build).to be_valid }
specify { expect(subject.build.issuer).to eql(issuer) }
spec/saml/kit/assertion_spec.rb
@@ -243,12 +243,21 @@ RSpec.describe Saml::Kit::Assertion do
describe '.new' do
let(:user) { instance_double(User, name_id_for: SecureRandom.uuid, assertion_attributes_for: {}) }
- let(:saml_request) { double(id: SecureRandom.uuid, issuer: configuration.entity_id) }
+ let(:saml_request) { double(id: Xml::Kit::Id.generate, issuer: configuration.entity_id) }
+ let(:registry) { instance_double(Saml::Kit::DefaultRegistry) }
let(:configuration) do
Saml::Kit::Configuration.new do |x|
x.entity_id = FFaker::Internet.uri('https')
+ x.registry = registry
end
end
+ let(:metadata) do
+ Saml::Kit::Metadata.build(configuration: configuration) do |x|
+ x.build_identity_provider
+ end
+ end
+
+ before { allow(registry).to receive(:metadata_for).with(configuration.entity_id).and_return(metadata) }
it 'parses a raw xml assertion' do
saml = Saml::Kit::Response.build(user, saml_request, configuration: configuration)