Comparing changes

v1.0.25 v1.0.26
7 commits 7 files changed
lib/saml/kit/builders/encrypted_assertion.rb
@@ -10,13 +10,18 @@ module Saml
         extend Forwardable
 
         attr_reader :assertion
+        attr_accessor :destination
         def_delegators :@response_builder,
           :configuration,
           :encryption_certificate
 
         def_delegators :@assertion,
           :default_name_id_format,
-          :default_name_id_format=
+          :default_name_id_format=,
+          :destination=,
+          :embed_signature,
+          :issuer=,
+          :now=
 
         def initialize(response_builder, assertion)
           @response_builder = response_builder
lib/saml/kit/builders/response.rb
@@ -7,11 +7,8 @@ module Saml
       # {include:file:spec/saml/kit/builders/response_spec.rb}
       class Response
         include XmlTemplatable
-        attr_reader :user, :request
-        attr_accessor :id, :now
-        attr_accessor :version, :status_code, :status_message
-        attr_accessor :issuer, :destination
-        attr_reader :configuration
+        attr_reader :user, :request, :issuer, :destination, :now, :configuration
+        attr_accessor :id, :version, :status_code, :status_message
 
         def initialize(
           user, request = nil, configuration: Saml::Kit.configuration
@@ -55,6 +52,37 @@ module Saml
             end
         end
 
+        def encrypt=(value)
+          super(value)
+          return if @assertion.nil?
+
+          if value
+            @assertion = EncryptedAssertion.new(self, assertion) if assertion.is_a?(Assertion)
+          elsif assertion.is_a?(EncryptedAssertion)
+            @assertion = assertion.assertion if assertion.is_a?(EncryptedAssertion)
+          end
+        end
+
+        def destination=(value)
+          @destination = value
+          assertion.destination = value
+        end
+
+        def issuer=(value)
+          @issuer = value
+          assertion.issuer = value
+        end
+
+        def now=(value)
+          @now = value
+          assertion.now = value
+        end
+
+        def embed_signature=(value)
+          @embed_signature = value
+          assertion.embed_signature = value
+        end
+
         private
 
         def response_options
lib/saml/kit/version.rb
@@ -2,6 +2,6 @@
 
 module Saml
   module Kit
-    VERSION = '1.0.25'.freeze
+    VERSION = '1.0.26'.freeze
   end
 end
spec/saml/kit/builders/response_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Saml::Kit::Builders::Response do
   end
   let(:email) { FFaker::Internet.email }
   let(:assertion_consumer_service_url) { FFaker::Internet.uri('https') }
-  let(:user) { User.new(attributes: { email: email, created_at: Time.now.utc.iso8601, roles: ['husband', 'father', 'programmer'] }) }
+  let(:user) { User.new(attributes: { email: email, created_at: Time.now.utc.iso8601, roles: %w[husband father programmer] }) }
   let(: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') }
@@ -76,6 +76,8 @@ RSpec.describe Saml::Kit::Builders::Response do
       allow(Saml::Kit.configuration).to receive(:entity_id).and_return(issuer)
       subject.destination = assertion_consumer_service_url
       subject.encrypt = false
+      subject.encrypt = true
+      subject.encrypt = false
       hash = Hash.from_xml(subject.to_xml)
 
       expect(hash['Response']['ID']).to be_present
@@ -112,7 +114,7 @@ RSpec.describe Saml::Kit::Builders::Response do
       expect(hash['Response']['Assertion']['AttributeStatement']['Attribute'][1]['AttributeValue']).to be_present
 
       expect(hash['Response']['Assertion']['AttributeStatement']['Attribute'][2]['Name']).to eql('roles')
-      expect(hash['Response']['Assertion']['AttributeStatement']['Attribute'][2]['AttributeValue']).to match_array(['husband', 'father', 'programmer'])
+      expect(hash['Response']['Assertion']['AttributeStatement']['Attribute'][2]['AttributeValue']).to match_array(%w[husband father programmer])
     end
 
     it 'does not add a signature when the SP does not want assertions signed' do
@@ -218,5 +220,36 @@ RSpec.describe Saml::Kit::Builders::Response do
       expect(result).to be_signed
       expect(result.signature.certificate).to eql(key_pair.certificate)
     end
+
+    it 'specifies the recipient on the subject confirmation data' do
+      acs_url = FFaker::Internet.uri('https')
+      subject.assertion # force memoization the assertion
+      subject.destination = acs_url
+      result = subject.build
+      expect(result.assertion.at_xpath('/samlp:Response/saml:Assertion/saml:Subject/saml:SubjectConfirmation/saml:SubjectConfirmationData').attribute('Recipient').value).to eql(acs_url)
+    end
+
+    it 'uses the updated issuer on the assertion' do
+      issuer = FFaker::Internet.uri('https')
+      subject.assertion # force memoization the assertion
+      subject.issuer = issuer
+      result = subject.build
+      expect(result.assertion.issuer).to eql(issuer)
+    end
+
+    it 'uses the `now` on the assertion' do
+      now = 5.minutes.from_now
+      subject.assertion # force memoization the assertion
+      subject.now = now
+      result = subject.build
+      expect(result.assertion.started_at.to_i).to eql(now.to_i)
+    end
+
+    it 'does not embed the signature' do
+      subject.assertion # force memoization the assertion
+      subject.embed_signature = false
+      result = subject.build
+      expect(result.assertion).not_to be_signed
+    end
   end
 end
spec/saml/kit/metadata_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Saml::Kit::Metadata do
           x.build_identity_provider
           x.build_service_provider
         end
-      end.to perform_under(10).ms
+      end.to perform_under(50).ms
     end
 
     it 'returns a composite' do
.gitlab-ci.yml
@@ -1,4 +1,4 @@
-image: ruby:2.2
+image: ruby:2.5
 
 before_script:
   - apt-get update && apt-get install -y locales
.travis.yml
@@ -5,7 +5,7 @@ rvm:
   - 2.2.10
   - 2.3.7
   - 2.4.4
-  - 2.5.1
+  - 2.5.3
 script:
   - bin/cibuild
   - bin/lint