Commit 7a63f10

mo <mo.khan@gmail.com>
2017-11-04 21:08:13
validate the status code..
1 parent 2dbf9bf
Changed files (3)
lib/saml/kit/namespaces.rb
@@ -14,6 +14,9 @@ module Saml
       POST = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
       PROTOCOL = "urn:oasis:names:tc:SAML:2.0:protocol"
       SUCCESS = "urn:oasis:names:tc:SAML:2.0:status:Success"
+      REQUESTER_ERROR = "urn:oasis:names:tc:SAML:2.0:status:Requester"
+      RESPONDER_ERROR = "urn:oasis:names:tc:SAML:2.0:status:Responder"
+      VERSION_MISMATCH_ERROR = "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch"
       TRANSIENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
       UNSPECIFIED = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
       URI = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
lib/saml/kit/response.rb
@@ -13,6 +13,7 @@ module Saml
       validate :must_be_registered
       validate :must_match_xsd
       validate :must_be_valid_version
+      validate :must_be_successful
 
       def initialize(xml)
         @content = xml
@@ -32,6 +33,10 @@ module Saml
         @xml_hash.dig(name, 'Issuer')
       end
 
+      def status_code
+        @xml_hash.dig(name, 'Status', 'StatusCode', 'Value')
+      end
+
       def [](key)
         attributes[key]
       end
@@ -114,6 +119,11 @@ module Saml
         errors[:base] << error_message(:invalid)
       end
 
+      def must_be_successful
+        return if Namespaces::SUCCESS == status_code
+        errors[:base] << error_message(:invalid)
+      end
+
       def login_response?
         return false if to_xml.blank?
         @xml_hash[name].present?
@@ -122,7 +132,7 @@ module Saml
       class Builder
         attr_reader :user, :request
         attr_accessor :id, :reference_id, :now, :name_id_format
-        attr_accessor :version
+        attr_accessor :version, :status_code
 
         def initialize(user, request)
           @user = user
@@ -132,6 +142,7 @@ module Saml
           @now = Time.now.utc
           @name_id_format = Namespaces::PERSISTENT
           @version = "2.0"
+          @status_code = Namespaces::SUCCESS
         end
 
         def to_xml
@@ -141,7 +152,7 @@ module Saml
             xml.Issuer(configuration.issuer, xmlns: Namespaces::ASSERTION)
             signature.template(xml)
             xml.Status do
-              xml.StatusCode Value: Namespaces::SUCCESS
+              xml.StatusCode Value: status_code
             end
             xml.Assertion(assertion_options) do
               xml.Issuer configuration.issuer
spec/saml/response_spec.rb
@@ -208,5 +208,12 @@ RSpec.describe Saml::Kit::Response do
       builder.id = nil
       expect(described_class.new(builder.to_xml)).to_not be_valid
     end
+
+    it 'validates the status code' do
+      allow(registry).to receive(:metadata_for).and_return(metadata)
+      allow(metadata).to receive(:matches?).and_return(true)
+      builder.status_code = Saml::Kit::Namespaces::REQUESTER_ERROR
+      expect(described_class.new(builder.to_xml)).to_not be_valid
+    end
   end
 end