Comparing changes
v1.0.31
→
v1.1.0
12 commits
20 files changed
Commits
Changed files (20)
bin
lib
saml
kit
spec
fixtures
saml
bin/cibuild
@@ -17,5 +17,5 @@ export RUBY_HEAP_SLOTS_INCREMENT=400000
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
ruby -v
-gem install bundler --conservative
+gem install bundler --conservative -v '~> 2.0'
bin/test
lib/saml/kit/builders/authentication_request.rb
@@ -10,6 +10,7 @@ module Saml
attr_accessor :id, :now, :issuer, :assertion_consumer_service_url
attr_accessor :name_id_format, :destination
attr_accessor :version
+ attr_accessor :force_authn
attr_reader :configuration
def initialize(configuration: Saml::Kit.configuration)
@@ -36,10 +37,8 @@ module Saml
IssueInstant: now.utc.iso8601,
Destination: destination,
}
- if assertion_consumer_service_url.present?
- options[:AssertionConsumerServiceURL] =
- assertion_consumer_service_url
- end
+ options[:ForceAuthn] = force_authn unless force_authn.nil?
+ options[:AssertionConsumerServiceURL] = assertion_consumer_service_url if assertion_consumer_service_url.present?
options
end
end
lib/saml/kit/deprecated/metadata.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module Saml
module Kit
class Metadata
lib/saml/kit/authentication_request.rb
@@ -47,6 +47,11 @@ module Saml
at_xpath('./*/@AssertionConsumerServiceURL').try(:value)
end
+ # Returns the ForceAuthn attribute as a boolean.
+ def force_authn
+ at_xpath('./*/@ForceAuthn').try(:value) == 'true'
+ end
+
def name_id_format
name_id_policy
end
lib/saml/kit/bindings.rb
@@ -11,10 +11,10 @@ module Saml
# the different SAML bindings that are
# supported by this gem.
module Bindings
- BINDINGS_2_0 = 'urn:oasis:names:tc:SAML:2.0:bindings'.freeze
- HTTP_ARTIFACT = "#{BINDINGS_2_0}:HTTP-Artifact".freeze
- HTTP_POST = "#{BINDINGS_2_0}:HTTP-POST".freeze
- HTTP_REDIRECT = "#{BINDINGS_2_0}:HTTP-Redirect".freeze
+ BINDINGS_2_0 = 'urn:oasis:names:tc:SAML:2.0:bindings'
+ HTTP_ARTIFACT = "#{BINDINGS_2_0}:HTTP-Artifact"
+ HTTP_POST = "#{BINDINGS_2_0}:HTTP-POST"
+ HTTP_REDIRECT = "#{BINDINGS_2_0}:HTTP-Redirect"
ALL = {
http_post: HTTP_POST,
http_redirect: HTTP_REDIRECT,
lib/saml/kit/namespaces.rb
@@ -3,33 +3,33 @@
module Saml
module Kit
module Namespaces
- SAML_2_0 = 'urn:oasis:names:tc:SAML:2.0'.freeze
- SAML_1_1 = 'urn:oasis:names:tc:SAML:1.1'.freeze
- ATTR_NAME_FORMAT = "#{SAML_2_0}:attrname-format".freeze
- NAME_ID_FORMAT_1_1 = "#{SAML_1_1}:nameid-format".freeze
- NAME_ID_FORMAT_2_0 = "#{SAML_2_0}:nameid-format".freeze
- STATUS = "#{SAML_2_0}:status".freeze
+ SAML_2_0 = 'urn:oasis:names:tc:SAML:2.0'
+ SAML_1_1 = 'urn:oasis:names:tc:SAML:1.1'
+ ATTR_NAME_FORMAT = "#{SAML_2_0}:attrname-format"
+ NAME_ID_FORMAT_1_1 = "#{SAML_1_1}:nameid-format"
+ NAME_ID_FORMAT_2_0 = "#{SAML_2_0}:nameid-format"
+ STATUS = "#{SAML_2_0}:status"
- ASSERTION = "#{SAML_2_0}:assertion".freeze
- ATTR_SPLAT = "#{ATTR_NAME_FORMAT}:*".freeze
- BASIC = "#{ATTR_NAME_FORMAT}:basic".freeze
- BEARER = "#{SAML_2_0}:cm:bearer".freeze
- EMAIL_ADDRESS = "#{NAME_ID_FORMAT_1_1}:emailAddress".freeze
- INVALID_NAME_ID_POLICY = "#{STATUS}:InvalidNameIDPolicy".freeze
- METADATA = "#{SAML_2_0}:metadata".freeze
- PASSWORD = "#{SAML_2_0}:ac:classes:Password".freeze
+ ASSERTION = "#{SAML_2_0}:assertion"
+ ATTR_SPLAT = "#{ATTR_NAME_FORMAT}:*"
+ BASIC = "#{ATTR_NAME_FORMAT}:basic"
+ BEARER = "#{SAML_2_0}:cm:bearer"
+ EMAIL_ADDRESS = "#{NAME_ID_FORMAT_1_1}:emailAddress"
+ INVALID_NAME_ID_POLICY = "#{STATUS}:InvalidNameIDPolicy"
+ METADATA = "#{SAML_2_0}:metadata"
+ PASSWORD = "#{SAML_2_0}:ac:classes:Password"
PASSWORD_PROTECTED =
- "#{SAML_2_0}:ac:classes:PasswordProtectedTransport".freeze
- PERSISTENT = "#{NAME_ID_FORMAT_2_0}:persistent".freeze
- PROTOCOL = "#{SAML_2_0}:protocol".freeze
- REQUESTER_ERROR = "#{STATUS}:Requester".freeze
- RESPONDER_ERROR = "#{STATUS}:Responder".freeze
- SUCCESS = "#{STATUS}:Success".freeze
- TRANSIENT = "#{NAME_ID_FORMAT_2_0}:transient".freeze
- UNSPECIFIED = "#{SAML_2_0}:consent:unspecified".freeze
- UNSPECIFIED_NAMEID = "#{NAME_ID_FORMAT_1_1}:unspecified".freeze
- URI = "#{ATTR_NAME_FORMAT}:uri".freeze
- VERSION_MISMATCH_ERROR = "#{STATUS}:VersionMismatch".freeze
+ "#{SAML_2_0}:ac:classes:PasswordProtectedTransport"
+ PERSISTENT = "#{NAME_ID_FORMAT_2_0}:persistent"
+ PROTOCOL = "#{SAML_2_0}:protocol"
+ REQUESTER_ERROR = "#{STATUS}:Requester"
+ RESPONDER_ERROR = "#{STATUS}:Responder"
+ SUCCESS = "#{STATUS}:Success"
+ TRANSIENT = "#{NAME_ID_FORMAT_2_0}:transient"
+ UNSPECIFIED = "#{SAML_2_0}:consent:unspecified"
+ UNSPECIFIED_NAMEID = "#{NAME_ID_FORMAT_1_1}:unspecified"
+ URI = "#{ATTR_NAME_FORMAT}:uri"
+ VERSION_MISMATCH_ERROR = "#{STATUS}:VersionMismatch"
end
end
end
lib/saml/kit/organization.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module Saml
module Kit
class Organization
lib/saml/kit/signature.rb
@@ -105,7 +105,7 @@ module Saml
dsignature.errors.each do |attribute|
errors.add(attribute, error_message(attribute))
end
- rescue Xmldsig::SchemaError => error
+ rescue StandardError => error
errors.add(:base, error.message)
end
lib/saml/kit/version.rb
@@ -2,6 +2,6 @@
module Saml
module Kit
- VERSION = '1.0.31'.freeze
+ VERSION = '1.1.0'
end
end
spec/fixtures/unsigned_response_two_assertions.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0"?>
+<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" Destination="https://portal.dev/sessions/acs" ID="_f6a486e0-29e2-0135-23c6-20999b09e5e7" InResponseTo="_0890e87d-1b33-4d0d-8875-776b50bf3359" IssueInstant="2017-06-02T17:00:54Z" Version="2.0">
+ <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://portal/sessions/metadata</Issuer>
+ <samlp:Status>
+ <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+ </samlp:Status>
+ <Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ID="_03c49290-29e5-0135-23c7-20999b09e5e7" IssueInstant="2017-06-02T17:15:35Z" Version="2.0">
+ <Issuer>http://auth.dev/auth/metadata</Issuer>
+ <Subject>
+ <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">mokha@cisco.com</NameID>
+ <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+ <SubjectConfirmationData InResponseTo="_e2d943d8-8c0f-4de6-b58a-0ded2d016b85" NotOnOrAfter="2017-06-02T17:18:35Z" Recipient="https://portal.dev/sessions/acs"/>
+ </SubjectConfirmation>
+ </Subject>
+ <Conditions NotBefore="2017-06-02T17:15:30Z" NotOnOrAfter="2017-06-02T18:15:35Z">
+ <AudienceRestriction>
+ <Audience>https://portal.dev/sessions/metadata</Audience>
+ </AudienceRestriction>
+ </Conditions>
+ <AttributeStatement>
+ <Attribute FriendlyName="user_id" Name="user_id" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue>a44550cf-9839-49fb-a101-10a741afe16b</AttributeValue>
+ </Attribute>
+ <Attribute FriendlyName="success_notice" Name="success_notice" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <Attribute FriendlyName="business_guid" Name="business_guid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue>4198398a-8cd3-4539-a936-5b34e35513ac</AttributeValue>
+ </Attribute>
+ <Attribute FriendlyName="event_intake_url" Name="event_intake_url" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue/>
+ </Attribute>
+ <Attribute FriendlyName="console_base_url" Name="console_base_url" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue/>
+ </Attribute>
+ <Attribute FriendlyName="auth_token" Name="auth_token" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue>8185b86b3e19fe9782fd69c790b2d185627e9b68bff229fb</AttributeValue>
+ </Attribute>
+ <Attribute FriendlyName="amp_user_role" Name="amp_user_admin" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue>true</AttributeValue>
+ </Attribute>
+ <Attribute FriendlyName="amp_business_name" Name="amp_business_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue>Business for mokha@cisco.com</AttributeValue>
+ </Attribute>
+ </AttributeStatement>
+ <AuthnStatement AuthnInstant="2017-06-02T17:15:35Z" SessionIndex="_03c49290-29e5-0135-23c7-20999b09e5e7">
+ <AuthnContext>
+ <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
+ </AuthnContext>
+ </AuthnStatement>
+ </Assertion>
+ <Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ID="_03c49290-29e5-0135-23c7-20999b09e5e7" IssueInstant="2017-06-02T17:15:35Z" Version="2.0">
+ <Issuer>http://auth.dev/auth/metadata</Issuer>
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+ <ds:Reference URI="#_03c49290-29e5-0135-23c7-20999b09e5e7">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+ <ds:DigestValue>00HKo34VqiMWtfJC6V2ZECp/gGCyXpmsoAJ7d1ApBlI=</ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue>WsM5KurVpKx9ewETIoWM9hrXKbDGybwCA7mgp0v4bUuq4njpGCDVwfLyOvc7zGbeJ2KIZ3IRF5fra3y97xlXXnEbwUth1b43liXi/SvOawkI38AGyu9CVqu2PgX+tt73in81Z1n8w0esZpy1L1mdgZqLLTpgVee+feEO6fd4TfPqy2VdLJJaSWWdIhyIEsK2pN7sO8476KS+PMcazhy15lGXR8/NEtzSC39t7NpfYg4CHHOypOHLnkiuY3sOC9Y3DLK/vUG/yx/43BCMDksW4mPNXFMQEoRb3+Hc0yEN5liz73oZa02wSwUYioj2FTCU2Ll003pgY/+E0kIV5hIzpg==</ds:SignatureValue>
+ <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>MIID2zCCAsOgAwIBAgIJANEwdtPv2CcfMA0GCSqGSIb3DQEBCwUAMIGDMQswCQYDVQQGEwJDQTEQMA4GA1UECAwHQWxiZXJ0YTEQMA4GA1UEBwwHQ2FsZ2FyeTEOMAwGA1UECgwFQ2lzY28xDDAKBgNVBAsMA0FNUDESMBAGA1UEAwwJY2lzY28uY29tMR4wHAYJKoZIhvcNAQkBFg9wamlzbEBjaXNjby5jb20wHhcNMTYwMjIzMTgyMDEzWhcNMjYwMjIyMTgyMDEzWjCBgzELMAkGA1UEBhMCQ0ExEDAOBgNVBAgMB0FsYmVydGExEDAOBgNVBAcMB0NhbGdhcnkxDjAMBgNVBAoMBUNpc2NvMQwwCgYDVQQLDANBTVAxEjAQBgNVBAMMCWNpc2NvLmNvbTEeMBwGCSqGSIb3DQEJARYPcGppc2xAY2lzY28uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApY6BaL1HZn3OQM0zPV+5+KkpJc90fUKGI0mf4WmbPB3NPF1qKhoFVS9cZclyL4y6vRhL88lZBp87xkz3M1pz14HLTdls4NsOGzw1xKMizFzP/sEBmn5gL2fWHkkb5mFtrWa1PqEM5cTWPYvej/5fKM4qdQtW3kZFuMghacCV9Y9xGObkucZMRov1Yy8Hea3vEH/SQ5a/7NJNFiHzCQ2109OCkxpTV0njcYeIBQxUFkR2UKWID1wbiEqvjAurtA8siq/CPpwMjkAGiqiaRMDroHCRpyc3ZIDiew49es3txwqJrZJPgiXy7HdIdCAaigFsWAvi6YdVEEyNExeb3giObwIDAQABo1AwTjAdBgNVHQ4EFgQUbpy9sDuGyct0uIu3OYkyI7GVd4EwHwYDVR0jBBgwFoAUbpy9sDuGyct0uIu3OYkyI7GVd4EwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXTUOqaz1a7McsgiU6u09iQ4HUZKk5WgsoIjkMJY/jE1I8GsOlhly1tHgPmOVHe/0QxZg+YB4MV/d83708NpBiK+qGzE9mjCC457tcfzd762VcpexmLo5SR+JWOBFXSFgddrEhBy8eWXk075vdQt/fmB8S4MwWSiICcwY4rTddwy4LBQ4yqsLh7u7y1XptZG20jd1VIBsFP1kcrxlPTDxhulHJkgADWf+N/nyhUOTSOmFlaXK7LJFJDjqL4uslP85iPnEzjCRrNRCrI6eQleTrrTdev1u32RMj5nyrcp1h9G3Jt5/gyJChM7Bar3bwJMZpv7cmdGmYa3Lsx6mRgO6Gg==</ds:X509Certificate>
+ </ds:X509Data>
+ </KeyInfo>
+ </ds:Signature>
+ <Subject>
+ <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">mokha@cisco.com</NameID>
+ <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+ <SubjectConfirmationData InResponseTo="_e2d943d8-8c0f-4de6-b58a-0ded2d016b85" NotOnOrAfter="2017-06-02T17:18:35Z" Recipient="https://portal.dev/sessions/acs"/>
+ </SubjectConfirmation>
+ </Subject>
+ <Conditions NotBefore="2017-06-02T17:15:30Z" NotOnOrAfter="2017-06-02T18:15:35Z">
+ <AudienceRestriction>
+ <Audience>https://portal.dev/sessions/metadata</Audience>
+ </AudienceRestriction>
+ </Conditions>
+ <AttributeStatement>
+ <Attribute FriendlyName="user_id" Name="user_id" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue>a44550cf-9839-49fb-a101-10a741afe16b</AttributeValue>
+ </Attribute>
+ <Attribute FriendlyName="success_notice" Name="success_notice" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+ <Attribute FriendlyName="business_guid" Name="business_guid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue>4198398a-8cd3-4539-a936-5b34e35513ac</AttributeValue>
+ </Attribute>
+ <Attribute FriendlyName="event_intake_url" Name="event_intake_url" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue/>
+ </Attribute>
+ <Attribute FriendlyName="console_base_url" Name="console_base_url" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue/>
+ </Attribute>
+ <Attribute FriendlyName="auth_token" Name="auth_token" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue>8185b86b3e19fe9782fd69c790b2d185627e9b68bff229fb</AttributeValue>
+ </Attribute>
+ <Attribute FriendlyName="amp_user_role" Name="amp_user_admin" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue>true</AttributeValue>
+ </Attribute>
+ <Attribute FriendlyName="amp_business_name" Name="amp_business_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+ <AttributeValue>Business for mokha@cisco.com</AttributeValue>
+ </Attribute>
+ </AttributeStatement>
+ <AuthnStatement AuthnInstant="2017-06-02T17:15:35Z" SessionIndex="_03c49290-29e5-0135-23c7-20999b09e5e7">
+ <AuthnContext>
+ <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
+ </AuthnContext>
+ </AuthnStatement>
+ </Assertion>
+</samlp:Response>
spec/saml/kit/bindings/url_builder_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
RSpec.describe Saml::Kit::Bindings::UrlBuilder do
describe '#build' do
let(:xml) { '<xml></xml>' }
@@ -57,9 +59,9 @@ RSpec.describe Saml::Kit::Bindings::UrlBuilder do
query_params = to_query_params(result)
expect(query_params['SigAlg']).to eql(CGI.escape(::Xml::Kit::Namespaces::SHA256))
- payload = "#{query_string_parameter}=#{query_params[query_string_parameter]}"
- payload << "&RelayState=#{query_params['RelayState']}"
- payload << "&SigAlg=#{query_params['SigAlg']}"
+ payload = "#{query_string_parameter}=#{query_params[query_string_parameter]}" \
+ "&RelayState=#{query_params['RelayState']}" \
+ "&SigAlg=#{query_params['SigAlg']}"
private_key = configuration.private_keys(use: :signing).last
expected_signature = Base64.strict_encode64(private_key.sign(OpenSSL::Digest::SHA256.new, payload))
expect(query_params['Signature']).to eql(expected_signature)
@@ -70,8 +72,8 @@ RSpec.describe Saml::Kit::Bindings::UrlBuilder do
query_params = to_query_params(result)
expect(query_params['SigAlg']).to eql(CGI.escape(::Xml::Kit::Namespaces::SHA256))
- payload = "#{query_string_parameter}=#{query_params[query_string_parameter]}"
- payload << "&SigAlg=#{query_params['SigAlg']}"
+ payload = "#{query_string_parameter}=#{query_params[query_string_parameter]}" \
+ "&SigAlg=#{query_params['SigAlg']}"
private_key = configuration.private_keys(use: :signing).last
expected_signature = Base64.strict_encode64(private_key.sign(OpenSSL::Digest::SHA256.new, payload))
expect(query_params['Signature']).to eql(expected_signature)
spec/saml/kit/builders/assertion_builder_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
RSpec.describe Saml::Kit::Builders::Assertion do
spec/saml/kit/builders/authentication_request_spec.rb
@@ -25,5 +25,13 @@ RSpec.describe Saml::Kit::Builders::AuthenticationRequest do
expect(result['AuthnRequest']['Issuer']).to eql(issuer)
expect(result['AuthnRequest']['NameIDPolicy']['Format']).to eql(Saml::Kit::Namespaces::PERSISTENT)
end
+
+ context 'when force authn is enabled' do
+ before { subject.force_authn = true }
+
+ let(:result) { Hash.from_xml(subject.to_xml) }
+
+ specify { expect(result['AuthnRequest']['ForceAuthn']).to eql('true') }
+ end
end
end
spec/saml/kit/authentication_request_spec.rb
@@ -30,6 +30,7 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
specify { expect(subject.assertion_consumer_service_url).to eql(assertion_consumer_service_url) }
specify { expect(subject.name_id_format).to eql(name_id_format) }
specify { expect(subject.destination).to eql(destination) }
+ specify { expect(subject.force_authn).to be(false) }
describe '#valid?' do
let(:registry) { instance_double(Saml::Kit::DefaultRegistry) }
@@ -186,6 +187,26 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
end
end
+ describe '#force_authn' do
+ context 'when set to true' do
+ subject { described_class.build { |x| x.force_authn = true } }
+
+ specify { expect(subject.force_authn).to be(true) }
+ end
+
+ context 'when set to false' do
+ subject { described_class.build { |x| x.force_authn = false } }
+
+ specify { expect(subject.force_authn).to be(false) }
+ end
+
+ context 'when not specified' do
+ subject { described_class.build { |x| x.force_authn = nil } }
+
+ specify { expect(subject.force_authn).to be(false) }
+ end
+ end
+
describe '.build' do
let(:url) { FFaker::Internet.uri('https') }
let(:entity_id) { FFaker::Internet.uri('https') }
spec/saml/kit/response_spec.rb
@@ -241,6 +241,13 @@ RSpec.describe Saml::Kit::Response do
expect(subject.errors.full_messages).to include('must contain a single Assertion.')
end
+ it 'is invalid if there are two assertions (one signed and the other unsigned)' do
+ raw_xml = IO.read('spec/fixtures/unsigned_response_two_assertions.xml')
+ subject = described_class.new(raw_xml)
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages).to include('must contain a single Assertion.')
+ end
+
it 'is invalid when the assertion has a signature and has been tampered with' do
user = User.new(attributes: { token: SecureRandom.uuid })
request = Saml::Kit::AuthenticationRequest.build
.rubocop.yml
@@ -12,7 +12,7 @@ AllCops:
- 'spec/examples/**/*'
- 'tmp/**/*'
- 'vendor/**/*'
- TargetRubyVersion: 2.2
+ TargetRubyVersion: 2.4
Layout/AlignParameters:
Enabled: true
.travis.yml
@@ -3,13 +3,12 @@ env:
- CC_TEST_REPORTER_ID=256cf27053220ac6b8962d6aef566e28753bc58633348ffef9274d3e1a48b31c
language: ruby
rvm:
- - 2.2.10
- - 2.3.8
- 2.4.6
- 2.5.5
- - 2.6.2
+ - 2.6.3
before_install:
- - "gem install bundler -v '~> 1.0'"
+ - gem update --system
+ - gem install bundler -v '~> 2.0'
before_script:
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
- chmod +x ./cc-test-reporter
CHANGELOG.md
@@ -1,4 +1,5 @@
-Version 1.0.31
+Version 1.1.0
+
# Changelog
All notable changes to this project will be documented in this file.
@@ -8,6 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
- nil
+## [1.1.0] - 2019-04-30
+### Added
+- Add support for ForceAuthn attribute on AuthnRequest
+
+### Removed
+- Drop support for ruby 2.2
+- Drop support for ruby 2.3
+
+### Changed
+- Rescue from invalid signature validation
+- Change minimum ruby version to 2.4
+- Change minimum bundler to 2.0
+
## [1.0.31] - 2019-04-17
### Changed
- Rescue from all decryption errors
@@ -69,7 +83,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed
- Removed optional SessionNotOnOrAfter attribute from AuthnStatement.
-[Unreleased]: https://github.com/saml-kit/saml-kit/compare/v1.0.31...HEAD
+[Unreleased]: https://github.com/saml-kit/saml-kit/compare/v1.1.0...HEAD
+[1.1.0]: https://github.com/saml-kit/saml-kit/compare/v1.0.31...v1.1.0
[1.0.31]: https://github.com/saml-kit/saml-kit/compare/v1.0.30...v1.0.31
[1.0.30]: https://github.com/saml-kit/saml-kit/compare/v1.0.29...v1.0.30
[1.0.29]: https://github.com/saml-kit/saml-kit/compare/v1.0.28...v1.0.29
Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- saml-kit (1.0.31)
+ saml-kit (1.1.0)
activemodel (>= 4.2.0)
net-hippie (~> 0.1)
xml-kit (>= 0.3.0, < 1.0.0)
@@ -19,8 +19,9 @@ GEM
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
ast (2.4.0)
- benchmark-perf (0.4.0)
- benchmark-trend (0.2.0)
+ benchmark-malloc (0.1.0)
+ benchmark-perf (0.5.0)
+ benchmark-trend (0.3.0)
builder (3.2.3)
bundler-audit (0.6.1)
bundler (>= 1.2.0, < 3)
@@ -31,15 +32,15 @@ GEM
diff-lcs (1.3)
docile (1.3.1)
ffaker (2.11.0)
- hashdiff (0.3.8)
- i18n (1.5.1)
+ hashdiff (0.3.9)
+ i18n (1.6.0)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.2)
json (2.2.0)
mini_portile2 (2.4.0)
minitest (5.11.3)
net-hippie (0.2.5)
- nokogiri (1.9.1)
+ nokogiri (1.10.3)
mini_portile2 (~> 2.4.0)
parallel (1.17.0)
parser (2.6.2.1)
@@ -52,13 +53,14 @@ GEM
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
- rspec-benchmark (0.4.0)
- benchmark-perf (~> 0.4.0)
- benchmark-trend (~> 0.2.0)
+ rspec-benchmark (0.5.0)
+ benchmark-malloc (~> 0.1.0)
+ benchmark-perf (~> 0.5.0)
+ benchmark-trend (~> 0.3.0)
rspec (>= 3.0.0, < 4.0.0)
rspec-core (3.8.0)
rspec-support (~> 3.8.0)
- rspec-expectations (3.8.2)
+ rspec-expectations (3.8.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.0)
@@ -106,7 +108,7 @@ PLATFORMS
ruby
DEPENDENCIES
- bundler (~> 1.17)
+ bundler (~> 2.0)
bundler-audit (~> 0.6)
ffaker (~> 2.7)
rake (~> 10.0)
@@ -120,4 +122,4 @@ DEPENDENCIES
webmock (~> 3.1)
BUNDLED WITH
- 1.17.3
+ 2.0.1
saml-kit.gemspec
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
spec.description = 'A simple toolkit for working with SAML.'
spec.homepage = 'https://github.com/saml-kit/saml-kit'
spec.license = 'MIT'
- spec.required_ruby_version = '>= 2.2.0'
+ spec.required_ruby_version = '~> 2.4'
spec.files = `git ls-files -z`.split("\x0").reject do |f|
(
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
spec.add_dependency 'activemodel', '>= 4.2.0'
spec.add_dependency 'net-hippie', '~> 0.1'
spec.add_dependency 'xml-kit', '>= 0.3.0', '< 1.0.0'
- spec.add_development_dependency 'bundler', '~> 1.17'
+ spec.add_development_dependency 'bundler', '~> 2.0'
spec.add_development_dependency 'bundler-audit', '~> 0.6'
spec.add_development_dependency 'ffaker', '~> 2.7'
spec.add_development_dependency 'rake', '~> 10.0'