Skip to content

Commit d175b9f

Browse files
committed
More fixes, remove REXML
1 parent 6449654 commit d175b9f

File tree

11 files changed

+42
-82
lines changed

11 files changed

+42
-82
lines changed

lib/ruby_saml/idp_metadata_parser.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,14 +348,14 @@ def certificates
348348
unless signing_nodes.empty?
349349
certs['signing'] = []
350350
signing_nodes.each do |cert_node|
351-
certs['signing'] << cert_node.content
351+
certs['signing'] << cert_node.text
352352
end
353353
end
354354

355355
unless encryption_nodes.empty?
356356
certs['encryption'] = []
357357
encryption_nodes.each do |cert_node|
358-
certs['encryption'] << cert_node.content
358+
certs['encryption'] << cert_node.text
359359
end
360360
end
361361
certs

lib/ruby_saml/logoutresponse.rb

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,10 @@ def in_response_to
6969
# @return [String] Gets the Issuer from the Logout Response.
7070
#
7171
def issuer
72-
@issuer ||= begin
73-
node = document.at_xpath(
74-
"/p:LogoutResponse/a:Issuer",
75-
{ "p" => RubySaml::XML::NS_PROTOCOL, "a" => RubySaml::XML::NS_ASSERTION }
76-
)
77-
Utils.element_text(node)
78-
end
72+
@issuer ||=document.at_xpath(
73+
"/p:LogoutResponse/a:Issuer",
74+
{ "p" => RubySaml::XML::NS_PROTOCOL, "a" => RubySaml::XML::NS_ASSERTION }
75+
)&.text
7976
end
8077

8178
# @return [String] Gets the StatusCode from a Logout Response.
@@ -88,13 +85,10 @@ def status_code
8885
end
8986

9087
def status_message
91-
@status_message ||= begin
92-
node = document.at_xpath(
93-
"/p:LogoutResponse/p:Status/p:StatusMessage",
94-
{ "p" => RubySaml::XML::NS_PROTOCOL }
95-
)
96-
Utils.element_text(node)
97-
end
88+
@status_message ||= document.at_xpath(
89+
"/p:LogoutResponse/p:Status/p:StatusMessage",
90+
{ "p" => RubySaml::XML::NS_PROTOCOL }
91+
)&.text
9892
end
9993

10094
# Aux function to validate the Logout Response

lib/ruby_saml/response.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def is_valid?(collect_errors = false)
8080
# @return [String] the NameID provided by the SAML response from the IdP.
8181
#
8282
def name_id
83-
@name_id ||= name_id_node&.content
83+
@name_id ||= name_id_node&.text
8484
end
8585

8686
alias_method :nameid, :name_id
@@ -162,14 +162,14 @@ def handle_nokogiri_attribute(node, attributes)
162162
if e.elements.empty?
163163
# SAMLCore requires that nil AttributeValues MUST contain xsi:nil XML attribute set to "true" or "1"
164164
# otherwise the value is to be regarded as empty.
165-
%w[true 1].include?(e['xsi:nil']) ? nil : e&.content
165+
%w[true 1].include?(e['xsi:nil']) ? nil : e&.text
166166
else
167167
# Explicitly support saml2:NameID with saml2:NameQualifier if supplied in attributes
168168
# this is useful for allowing eduPersonTargetedId to be passed as an opaque identifier to use to
169169
# identify the subject in an SP rather than email or other less opaque attributes
170170
# NameQualifier, if present is prefixed with a "/" to the value
171171
e.xpath('a:NameID', { "a" => RubySaml::XML::NS_ASSERTION }).map do |n|
172-
next unless (value = n&.content)
172+
next unless (value = n&.text)
173173
base_path = n['NameQualifier'] ? "#{n['NameQualifier']}/" : ''
174174
"#{base_path}#{value}"
175175
end

lib/ruby_saml/saml_message.rb

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,10 @@ def id(document)
2929
end
3030

3131
def root_attribute(document, attribute)
32-
if document.is_a?(Nokogiri::XML::Document)
33-
node = document.at_xpath(
34-
"/p:AuthnRequest | /p:Response | /p:LogoutResponse | /p:LogoutRequest",
35-
{ "p" => RubySaml::XML::NS_PROTOCOL }
36-
)
37-
node.nil? ? nil : node[attribute]
38-
else
39-
node = REXML::XPath.first(
40-
document,
41-
"/p:AuthnRequest | /p:Response | /p:LogoutResponse | /p:LogoutRequest",
42-
{ "p" => RubySaml::XML::NS_PROTOCOL }
43-
)
44-
node.nil? ? nil : node.attributes[attribute]
45-
end
32+
document.at_xpath(
33+
"/p:AuthnRequest | /p:Response | /p:LogoutResponse | /p:LogoutRequest",
34+
{ "p" => RubySaml::XML::NS_PROTOCOL }
35+
)&.[](attribute)
4636
end
4737

4838
# Validates the SAML Message against the specified schema.

lib/ruby_saml/slo_logoutrequest.rb

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def is_valid?(collect_errors = false)
5858

5959
# @return [String] The NameID of the Logout Request.
6060
def name_id
61-
@name_id ||= name_id_node&.content
61+
@name_id ||= name_id_node&.text
6262
end
6363
alias_method :nameid, :name_id
6464

@@ -88,13 +88,10 @@ def id
8888
# @return [String] Gets the Issuer from the Logout Request.
8989
#
9090
def issuer
91-
@issuer ||= begin
92-
node = document.at_xpath(
93-
"/p:LogoutRequest/a:Issuer",
94-
{ "p" => RubySaml::XML::NS_PROTOCOL, "a" => RubySaml::XML::NS_ASSERTION }
95-
)
96-
Utils.element_text(node)
97-
end
91+
@issuer ||= document.at_xpath(
92+
"/p:LogoutRequest/a:Issuer",
93+
{ "p" => RubySaml::XML::NS_PROTOCOL, "a" => RubySaml::XML::NS_ASSERTION }
94+
)&.text
9895
end
9996

10097
# @return [Time|nil] Gets the NotOnOrAfter Attribute value if exists.
@@ -115,12 +112,10 @@ def not_on_or_after
115112
# @return [Array] Gets the SessionIndex if exists (Supported multiple values). Empty Array if none found
116113
#
117114
def session_indexes
118-
nodes = document.xpath(
115+
document.xpath(
119116
"/p:LogoutRequest/p:SessionIndex",
120117
{ "p" => RubySaml::XML::NS_PROTOCOL }
121-
)
122-
123-
nodes.map { |node| Utils.element_text(node) }
118+
).map { |node| node.text }
124119
end
125120

126121
private

lib/ruby_saml/utils.rb

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -295,17 +295,6 @@ def original_uri_match?(destination_url, settings_url)
295295
destination_url == settings_url
296296
end
297297

298-
# Given a REXML::Element instance, return the concatenation of all child text nodes. Assumes
299-
# that there all children other than text nodes can be ignored (e.g. comments). If nil is
300-
# passed, nil will be returned.
301-
def element_text(element)
302-
if element.is_a?(REXML::Element)
303-
element.texts.map(&:value).join
304-
else
305-
element&.content
306-
end
307-
end
308-
309298
# Given a private key PEM string, return an array of OpenSSL::PKey::PKey classes
310299
# that can be used to parse it, with the most likely match first.
311300
def private_key_classes(pem)

lib/ruby_saml/xml.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# frozen_string_literal: true
22

3-
require 'rexml/element'
43
require 'openssl'
54
require 'nokogiri'
65
require 'digest/sha1'
@@ -51,9 +50,9 @@ module XML
5150
Nokogiri::XML::ParseOptions::NONET
5251

5352
# Safely load the SAML Message XML.
54-
# @param document [REXML::Document] The message to be loaded
53+
# @param document [String | Nokogiri::XML::Document] The message to be loaded
5554
# @param check_malformed_doc [Boolean] check_malformed_doc Enable or Disable the check for malformed XML
56-
# @return [Nokogiri::XML] The nokogiri document
55+
# @return [Nokogiri::XML::Document] The nokogiri document
5756
# @raise [ValidationError] If there was a problem loading the SAML Message XML
5857
def safe_load_nokogiri(document, check_malformed_doc: true)
5958
doc_str = document.to_s
@@ -72,7 +71,7 @@ def safe_load_nokogiri(document, check_malformed_doc: true)
7271
end
7372
end
7473

75-
# TODO: This is messy, its shims how the old work REXML parser
74+
# TODO: This is messy, its shims how the old REXML parser works
7675
if xml
7776
error ||= StandardError.new('Dangerous XML detected. No Doctype nodes allowed') if xml.internal_subset
7877
error ||= StandardError.new("There were XML errors when parsing: #{xml.errors}") if check_malformed_doc && !xml.errors.empty?

lib/ruby_saml/xml/decryptor.rb

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,6 @@ def decrypt_attribute(encrypted_attribute_node, decryption_keys)
7272
def decrypt_node(encrypted_node, regexp, decryption_keys)
7373
validate_decryption_keys!(decryption_keys)
7474

75-
# TODO: Remove this
76-
encrypted_node = Nokogiri::XML(encrypted_node.to_s).root if encrypted_node.is_a?(REXML::Element)
77-
7875
node_header = if encrypted_node.name == 'EncryptedAttribute'
7976
%(<node xmlns:saml="#{RubySaml::XML::NS_ASSERTION}" xmlns:xsi="#{RubySaml::XML::XSI}">)
8077
else

lib/ruby_saml/xml/signed_document_info.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def certificate_text
178178
cert = noko.at_xpath(
179179
'//ds:X509Certificate',
180180
{ 'ds' => RubySaml::XML::DSIG }
181-
)&.content&.strip
181+
)&.text&.strip
182182
Base64.decode64(cert) if cert && !cert.empty?
183183
end
184184

test/utils_test.rb

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -325,39 +325,35 @@ def result(duration, reference = 0)
325325
end
326326
end
327327

328-
describe '.element_text' do
328+
describe 'Nokogiri::XML::Node#text' do
329329
it 'returns the element text' do
330-
element = REXML::Document.new('<element>element text</element>').elements.first
331-
assert_equal 'element text', RubySaml::Utils.element_text(element)
330+
element = Nokogiri::XML('<element>element text</element>').root
331+
assert_equal 'element text', element.text
332332
end
333333

334334
it 'returns all segments of the element text' do
335-
element = REXML::Document.new('<element>element <!-- comment -->text</element>').elements.first
336-
assert_equal 'element text', RubySaml::Utils.element_text(element)
335+
element = Nokogiri::XML('<element>element <!-- comment -->text</element>').root
336+
assert_equal 'element text', element.text
337337
end
338338

339339
it 'returns normalized element text' do
340-
element = REXML::Document.new('<element>element &amp; text</element>').elements.first
341-
assert_equal 'element & text', RubySaml::Utils.element_text(element)
340+
element = Nokogiri::XML('<element>element &amp; text</element>').root
341+
assert_equal 'element & text', element.text
342342
end
343343

344344
it 'returns the CDATA element text' do
345-
element = REXML::Document.new('<element><![CDATA[element & text]]></element>').elements.first
346-
assert_equal 'element & text', RubySaml::Utils.element_text(element)
345+
element = Nokogiri::XML('<element><![CDATA[element & text]]></element>').root
346+
assert_equal 'element & text', element.text
347347
end
348348

349349
it 'returns the element text with newlines and additional whitespace' do
350-
element = REXML::Document.new("<element> element \n text </element>").elements.first
351-
assert_equal " element \n text ", RubySaml::Utils.element_text(element)
352-
end
353-
354-
it 'returns nil when element is nil' do
355-
assert_nil RubySaml::Utils.element_text(nil)
350+
element = Nokogiri::XML("<element> element \n text </element>").root
351+
assert_equal " element \n text ", element.text
356352
end
357353

358354
it 'returns empty string when element has no text' do
359-
element = REXML::Document.new('<element></element>').elements.first
360-
assert_equal '', RubySaml::Utils.element_text(element)
355+
element = Nokogiri::XML('<element></element>').root
356+
assert_equal '', element.text
361357
end
362358
end
363359
end

0 commit comments

Comments
 (0)