main
 1# frozen_string_literal: true
 2
 3module Saml
 4  module Kit
 5    # This module provides the behaviours
 6    # associated with SAML Response documents.
 7    # .e.g. Response, LogoutResponse
 8    module Respondable
 9      extend ActiveSupport::Concern
10      attr_reader :request_id
11
12      included do
13        validates_inclusion_of :status_code, in: [Namespaces::SUCCESS]
14        validate :must_match_request_id
15      end
16
17      # @!visibility private
18      def query_string_parameter
19        'SAMLResponse'
20      end
21
22      # Returns the /Status/StatusCode@Value
23      def status_code
24        at_xpath('./*/samlp:Status/samlp:StatusCode/@Value').try(:value)
25      end
26
27      # Returns the /Status/StatusMessage
28      def status_message
29        at_xpath('./*/samlp:Status/samlp:StatusMessage').try(:text)
30      end
31
32      # Returns the /InResponseTo attribute.
33      def in_response_to
34        at_xpath('./*/@InResponseTo').try(:value)
35      end
36
37      # Returns true if the Status code is #{Saml::Kit::Namespaces::SUCCESS}
38      def success?
39        Namespaces::SUCCESS == status_code
40      end
41
42      private
43
44      def must_match_request_id
45        return if request_id.nil?
46        return if in_response_to == request_id
47
48        errors.add(:in_response_to, error_message(:invalid_response_to))
49      end
50    end
51  end
52end