22
33require "ruby_saml/xml"
44require "ruby_saml/attributes"
5-
65require "time"
76require "nokogiri"
87
@@ -166,16 +165,16 @@ def attributes
166165 raise ValidationError . new ( "Found an Attribute element with duplicated Name" )
167166 end
168167
169- values = node . elements . collect do |e |
168+ values = node . elements . map do |e |
170169 if e . elements . nil? || e . elements . empty?
171170 # SAMLCore requires that nil AttributeValues MUST contain xsi:nil XML attribute set to "true" or "1"
172171 # otherwise the value is to be regarded as empty.
173172 %w[ true 1 ] . include? ( e . attributes [ 'xsi:nil' ] ) ? nil : Utils . element_text ( e )
174- # explicitly support saml2:NameID with saml2:NameQualifier if supplied in attributes
175- # this is useful for allowing eduPersonTargetedId to be passed as an opaque identifier to use to
176- # identify the subject in an SP rather than email or other less opaque attributes
177- # NameQualifier, if present is prefixed with a "/" to the value
178173 else
174+ # Explicitly support saml2:NameID with saml2:NameQualifier if supplied in attributes
175+ # this is useful for allowing eduPersonTargetedId to be passed as an opaque identifier to use to
176+ # identify the subject in an SP rather than email or other less opaque attributes
177+ # NameQualifier, if present is prefixed with a "/" to the value
179178 REXML ::XPath . match ( e , 'a:NameID' , { "a" => ASSERTION } ) . collect do |n |
180179 base_path = n . attributes [ 'NameQualifier' ] ? "#{ n . attributes [ 'NameQualifier' ] } /" : ''
181180 "#{ base_path } #{ Utils . element_text ( n ) } "
@@ -186,6 +185,7 @@ def attributes
186185 attributes . add ( name , values . flatten )
187186 end
188187 end
188+
189189 attributes
190190 end
191191 end
@@ -594,7 +594,7 @@ def validate_signed_elements
594594 signed_elements << signed_element
595595 end
596596
597- unless signature_nodes . length < 3 && !signed_elements . empty?
597+ unless signature_nodes . size < 3 && !signed_elements . empty?
598598 return append_error ( "Found an unexpected number of Signature Element. SAML Response rejected" )
599599 end
600600
@@ -619,10 +619,10 @@ def validate_in_response_to
619619 append_error ( error_msg )
620620 end
621621
622- # Validates the Audience, (If the Audience match the Service Provider EntityID)
622+ # Validates the Audience, (If the Audience matches the Service Provider EntityID)
623623 # If the response was initialized with the :skip_audience option, this validation is skipped,
624624 # If fails, the error is added to the errors array
625- # @return [Boolean] True if there is an Audience Element that match the Service Provider EntityID, otherwise False if soft=True
625+ # @return [Boolean] True if there is an Audience Element that matches the Service Provider EntityID, otherwise False if soft=True
626626 # @raise [ValidationError] if soft == false and validation fails
627627 #
628628 def validate_audience
@@ -726,7 +726,7 @@ def validate_conditions
726726
727727 # Validates the Issuer (Of the SAML Response and the SAML Assertion)
728728 # @param soft [Boolean] soft Enable or Disable the soft mode (In order to raise exceptions when the response is invalid or not)
729- # @return [Boolean] True if the Issuer matchs the IdP entityId, otherwise False if soft=True
729+ # @return [Boolean] True if the Issuer matches the IdP entityId, otherwise False if soft=True
730730 # @raise [ValidationError] if soft == false and validation fails
731731 #
732732 def validate_issuer
@@ -863,9 +863,9 @@ def validate_signature
863863
864864 if sig_elements . size != 1
865865 if sig_elements . empty?
866- append_error ( "Signed element id ##{ doc . signed_element_id } is not found" )
866+ append_error ( "Signed element id ##{ doc . signed_element_id } is not found" )
867867 else
868- append_error ( "Signed element id ##{ doc . signed_element_id } is found more than once" )
868+ append_error ( "Signed element id ##{ doc . signed_element_id } is found more than once" )
869869 end
870870 return append_error ( error_msg )
871871 end
@@ -874,16 +874,16 @@ def validate_signature
874874
875875 idp_certs = settings . get_idp_cert_multi
876876 if idp_certs . nil? || idp_certs [ :signing ] . empty?
877- opts = { }
878- opts [ :fingerprint_alg ] = settings . idp_cert_fingerprint_algorithm
879877 idp_cert = settings . get_idp_cert
880878 fingerprint = settings . get_fingerprint
881- opts [ :cert ] = idp_cert
879+ opts = {
880+ cert : idp_cert ,
881+ fingerprint_alg : settings . idp_cert_fingerprint_algorithm
882+ }
882883
883884 if fingerprint && doc . validate_document ( fingerprint , @soft , opts )
884885 if settings . security [ :check_idp_cert_expiration ] && RubySaml ::Utils . is_cert_expired ( idp_cert )
885- error_msg = "IdP x509 certificate expired"
886- return append_error ( error_msg )
886+ return append_error ( "IdP x509 certificate expired" )
887887 end
888888 else
889889 return append_error ( error_msg )
@@ -894,18 +894,20 @@ def validate_signature
894894 idp_certs [ :signing ] . each do |idp_cert |
895895 valid = doc . validate_document_with_cert ( idp_cert , true )
896896 next unless valid
897+
897898 if settings . security [ :check_idp_cert_expiration ] && RubySaml ::Utils . is_cert_expired ( idp_cert )
898- expired = true
899+ expired = true
899900 end
900901
901902 # At least one certificate is valid, restore the old accumulated errors
902903 @errors = old_errors
903904 break
904905 end
906+
905907 if expired
906- error_msg = "IdP x509 certificate expired"
907- return append_error ( error_msg )
908+ return append_error ( "IdP x509 certificate expired" )
908909 end
910+
909911 unless valid
910912 # Remove duplicated errors
911913 @errors = @errors . uniq
@@ -933,7 +935,7 @@ def name_id_node
933935 # @param subelt [String] The XPath pattern
934936 # @return [REXML::Element | nil] If any matches, return the Element
935937 #
936- def xpath_first_from_signed_assertion ( subelt = nil )
938+ def xpath_first_from_signed_assertion ( subelt = nil )
937939 doc = decrypted_document . nil? ? document : decrypted_document
938940 node = REXML ::XPath . first (
939941 doc ,
@@ -1035,14 +1037,14 @@ def decrypt_attribute(encrypted_attribute_node)
10351037 #
10361038 def decrypt_element ( encrypt_node , regexp )
10371039 if settings . nil? || settings . get_sp_decryption_keys . empty?
1038- raise ValidationError . new ( ' An ' + encrypt_node . name + ' found and no SP private key found on the settings to decrypt it' )
1040+ raise ValidationError . new ( " An #{ encrypt_node . name } found and no SP private key found on the settings to decrypt it." )
10391041 end
10401042
1041- if encrypt_node . name == 'EncryptedAttribute'
1042- node_header = '<node xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
1043- else
1044- node_header = '<node xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">'
1045- end
1043+ node_header = if encrypt_node . name == 'EncryptedAttribute'
1044+ '<node xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
1045+ else
1046+ '<node xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">'
1047+ end
10461048
10471049 elem_plaintext = RubySaml ::Utils . decrypt_multi ( encrypt_node , settings . get_sp_decryption_keys )
10481050
@@ -1063,8 +1065,9 @@ def decrypt_element(encrypt_node, regexp)
10631065 # @return [Time|nil] The parsed value
10641066 #
10651067 def parse_time ( node , attribute )
1066- return unless node && node . attributes [ attribute ]
1067- Time . parse ( node . attributes [ attribute ] )
1068+ return unless ( value = node &.attributes &.[]( attribute ) )
1069+
1070+ Time . parse ( value )
10681071 end
10691072 end
10701073end
0 commit comments