|
1 | 1 | # frozen_string_literal: true |
2 | 2 |
|
| 3 | + |
| 4 | +require "ruby_saml/settings" |
3 | 5 | require "ruby_saml/xml" |
4 | 6 | require "ruby_saml/attributes" |
5 | 7 | require "time" |
@@ -52,18 +54,29 @@ def initialize(response, options = {}) |
52 | 54 |
|
53 | 55 | @options = options |
54 | 56 | @soft = true |
| 57 | + message_max_bytesize = nil |
55 | 58 | unless options[:settings].nil? |
56 | 59 | @settings = options[:settings] |
57 | | - unless @settings.soft.nil? |
58 | | - @soft = @settings.soft |
59 | | - end |
| 60 | + |
| 61 | + raise ValidationError.new("Invalid settings type: expected RubySaml::Settings, got #{@settings. class. name}") if !@settings.is_a?(Settings) && !@settings.nil? |
| 62 | + |
| 63 | + @soft = @settings&.respond_to?(:soft) && !@settings.soft.nil? ? @settings.soft : true |
| 64 | + message_max_bytesize = @settings.message_max_bytesize if @settings.respond_to?(:message_max_bytesize) |
60 | 65 | end |
61 | 66 |
|
62 | | - @response = RubySaml::XML::Decoder.decode_message(response, @settings&.message_max_bytesize) |
63 | | - @document = RubySaml::XML.safe_load_nokogiri(@response) |
| 67 | + @response = RubySaml::XML::Decoder.decode_message(response, message_max_bytesize) |
| 68 | + begin |
| 69 | + @document = RubySaml::XML.safe_load_xml(@response, check_malformed_doc: @soft) |
| 70 | + rescue StandardError => e |
| 71 | + @errors << "XML load failed: #{e.message}" if e.message != "Empty document" |
| 72 | + return false if @soft |
| 73 | + raise ValidationError.new("XML load failed: #{e.message}") if e.message != "Empty document" |
| 74 | + end |
64 | 75 |
|
65 | | - if assertion_encrypted? |
66 | | - @decrypted_document = generate_decrypted_document |
| 76 | + unless @document.nil? |
| 77 | + if assertion_encrypted? |
| 78 | + @decrypted_document = generate_decrypted_document |
| 79 | + end |
67 | 80 | end |
68 | 81 |
|
69 | 82 | super() |
@@ -131,6 +144,8 @@ def sessionindex |
131 | 144 | # @raise [ValidationError] if there are 2+ Attribute with the same Name |
132 | 145 | # |
133 | 146 | def attributes |
| 147 | + return nil if @document.nil? |
| 148 | + |
134 | 149 | @attr_statements ||= begin |
135 | 150 | attributes = Attributes.new |
136 | 151 |
|
@@ -367,6 +382,9 @@ def assertion_id |
367 | 382 | # |
368 | 383 | def validate(collect_errors = false) |
369 | 384 | reset_errors! |
| 385 | + |
| 386 | + return append_error("Blank response") if @document.nil? |
| 387 | + |
370 | 388 | return false unless validate_response_state |
371 | 389 |
|
372 | 390 | validations = %i[ |
@@ -417,8 +435,10 @@ def validate_success_status |
417 | 435 | def validate_structure |
418 | 436 | structure_error_msg = "Invalid SAML Response. Not match the saml-schema-protocol-2.0.xsd" |
419 | 437 |
|
| 438 | + doc_to_analize = @document.nil? ? @response : @document |
| 439 | + |
420 | 440 | check_malformed_doc = check_malformed_doc_enabled? |
421 | | - unless valid_saml?(document, soft, check_malformed_doc: check_malformed_doc) |
| 441 | + unless valid_saml?(doc_to_analize, soft, check_malformed_doc: check_malformed_doc) |
422 | 442 | return append_error(structure_error_msg) |
423 | 443 | end |
424 | 444 |
|
@@ -900,6 +920,8 @@ def validate_signature |
900 | 920 | end |
901 | 921 |
|
902 | 922 | def name_id_node |
| 923 | + return nil if @document.nil? |
| 924 | + |
903 | 925 | @name_id_node ||= |
904 | 926 | begin |
905 | 927 | encrypted_node = xpath_first_from_signed_assertion('/a:Subject/a:EncryptedID') |
|
0 commit comments