saml2 3.1.2 → 3.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +6 -4
  3. data/exe/bulk_verify_responses +94 -0
  4. data/lib/saml2/assertion.rb +7 -7
  5. data/lib/saml2/attribute/x500.rb +31 -28
  6. data/lib/saml2/attribute.rb +53 -49
  7. data/lib/saml2/attribute_consuming_service.rb +29 -31
  8. data/lib/saml2/authn_request.rb +54 -47
  9. data/lib/saml2/authn_statement.rb +31 -20
  10. data/lib/saml2/base.rb +72 -63
  11. data/lib/saml2/bindings/http_post.rb +7 -7
  12. data/lib/saml2/bindings/http_redirect.rb +37 -33
  13. data/lib/saml2/bindings.rb +1 -1
  14. data/lib/saml2/conditions.rb +19 -16
  15. data/lib/saml2/contact.rb +19 -18
  16. data/lib/saml2/endpoint.rb +14 -11
  17. data/lib/saml2/entity.rb +27 -27
  18. data/lib/saml2/identity_provider.rb +13 -10
  19. data/lib/saml2/indexed_object.rb +15 -12
  20. data/lib/saml2/key.rb +43 -34
  21. data/lib/saml2/localized_name.rb +11 -10
  22. data/lib/saml2/logout_request.rb +8 -8
  23. data/lib/saml2/logout_response.rb +4 -4
  24. data/lib/saml2/message.rb +24 -20
  25. data/lib/saml2/name_id.rb +45 -41
  26. data/lib/saml2/namespaces.rb +8 -8
  27. data/lib/saml2/organization.rb +11 -10
  28. data/lib/saml2/organization_and_contacts.rb +5 -5
  29. data/lib/saml2/request.rb +3 -3
  30. data/lib/saml2/requested_authn_context.rb +4 -4
  31. data/lib/saml2/response.rb +45 -33
  32. data/lib/saml2/role.rb +11 -11
  33. data/lib/saml2/schemas.rb +13 -10
  34. data/lib/saml2/service_provider.rb +11 -12
  35. data/lib/saml2/signable.rb +23 -18
  36. data/lib/saml2/sso.rb +5 -5
  37. data/lib/saml2/status.rb +9 -7
  38. data/lib/saml2/status_response.rb +5 -5
  39. data/lib/saml2/subject.rb +28 -28
  40. data/lib/saml2/version.rb +1 -1
  41. data/lib/saml2.rb +7 -7
  42. metadata +78 -122
  43. data/spec/fixtures/FederationMetadata.xml +0 -670
  44. data/spec/fixtures/authnrequest.xml +0 -12
  45. data/spec/fixtures/certificate.pem +0 -24
  46. data/spec/fixtures/entities.xml +0 -13
  47. data/spec/fixtures/external-uri-reference-response.xml +0 -48
  48. data/spec/fixtures/identity_provider.xml +0 -46
  49. data/spec/fixtures/noconditions_response.xml +0 -1
  50. data/spec/fixtures/othercertificate.pem +0 -25
  51. data/spec/fixtures/privatekey.key +0 -27
  52. data/spec/fixtures/response_assertion_signed_reffed_from_response.xml +0 -6
  53. data/spec/fixtures/response_signed.xml +0 -46
  54. data/spec/fixtures/response_tampered_certificate.xml +0 -25
  55. data/spec/fixtures/response_tampered_signature.xml +0 -46
  56. data/spec/fixtures/response_with_attribute_signed.xml +0 -46
  57. data/spec/fixtures/response_with_encrypted_assertion.xml +0 -58
  58. data/spec/fixtures/response_with_rsa_key_value.xml +0 -1
  59. data/spec/fixtures/response_with_signed_assertion_and_encrypted_subject.xml +0 -116
  60. data/spec/fixtures/response_without_keyinfo.xml +0 -1
  61. data/spec/fixtures/service_provider.xml +0 -79
  62. data/spec/fixtures/test3-response.xml +0 -9
  63. data/spec/fixtures/test6-response.xml +0 -10
  64. data/spec/fixtures/test7-response.xml +0 -10
  65. data/spec/fixtures/xml_missigned_assertion.xml +0 -84
  66. data/spec/fixtures/xml_signature_wrapping_attack_duplicate_ids.xml +0 -11
  67. data/spec/fixtures/xml_signature_wrapping_attack_response_attributes.xml +0 -45
  68. data/spec/fixtures/xml_signature_wrapping_attack_response_nameid.xml +0 -44
  69. data/spec/fixtures/xslt-transform-response.xml +0 -57
  70. data/spec/lib/attribute_consuming_service_spec.rb +0 -129
  71. data/spec/lib/attribute_spec.rb +0 -149
  72. data/spec/lib/authn_request_spec.rb +0 -52
  73. data/spec/lib/bindings/http_redirect_spec.rb +0 -183
  74. data/spec/lib/conditions_spec.rb +0 -74
  75. data/spec/lib/entity_spec.rb +0 -58
  76. data/spec/lib/identity_provider_spec.rb +0 -43
  77. data/spec/lib/indexed_object_spec.rb +0 -71
  78. data/spec/lib/key_spec.rb +0 -23
  79. data/spec/lib/logout_request_spec.rb +0 -33
  80. data/spec/lib/logout_response_spec.rb +0 -33
  81. data/spec/lib/message_spec.rb +0 -23
  82. data/spec/lib/response_spec.rb +0 -293
  83. data/spec/lib/service_provider_spec.rb +0 -76
  84. data/spec/lib/signable_spec.rb +0 -15
  85. data/spec/spec_helper.rb +0 -8
@@ -1,20 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'saml2/base'
4
- require 'saml2/namespaces'
3
+ require "saml2/base"
4
+ require "saml2/namespaces"
5
5
 
6
6
  module SAML2
7
7
  class LocalizedName < Hash
8
8
  attr_reader :element
9
9
 
10
10
  def initialize(element, name = nil)
11
+ super()
11
12
  @element = element
12
- unless name.nil?
13
- if name.is_a?(Hash)
14
- replace(name)
15
- else
16
- self[nil] = name
17
- end
13
+ return if name.nil?
14
+
15
+ if name.is_a?(Hash)
16
+ replace(name)
17
+ else
18
+ self[nil] = name
18
19
  end
19
20
  end
20
21
 
@@ -42,14 +43,14 @@ module SAML2
42
43
  def from_xml(nodes)
43
44
  clear
44
45
  nodes.each do |node|
45
- self[node['xml:lang'].to_sym] = node.content && node.content.strip
46
+ self[node["xml:lang"].to_sym] = node.content && node.content.strip
46
47
  end
47
48
  self
48
49
  end
49
50
 
50
51
  def build(builder)
51
52
  each do |lang, value|
52
- builder['md'].__send__(element, value, 'xml:lang' => lang)
53
+ builder["md"].__send__(element, value, "xml:lang" => lang)
53
54
  end
54
55
  end
55
56
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'saml2/name_id'
4
- require 'saml2/request'
3
+ require "saml2/name_id"
4
+ require "saml2/request"
5
5
 
6
6
  module SAML2
7
7
  class LogoutRequest < Request
@@ -24,27 +24,27 @@ module SAML2
24
24
 
25
25
  # @return [NameID]
26
26
  def name_id
27
- @name_id ||= (NameID.from_xml(xml.at_xpath('saml:NameID', Namespaces::ALL)) if xml)
27
+ @name_id ||= (NameID.from_xml(xml.at_xpath("saml:NameID", Namespaces::ALL)) if xml)
28
28
  end
29
29
 
30
30
  # @return [String, Array<String>]
31
31
  def session_index
32
- @session_index ||= (load_string_array(xml,'samlp:SessionIndex') if xml)
32
+ @session_index ||= (load_string_array(xml, "samlp:SessionIndex") if xml)
33
33
  end
34
34
 
35
35
  private
36
36
 
37
37
  def build(builder)
38
- builder['samlp'].LogoutRequest(
39
- 'xmlns:samlp' => Namespaces::SAMLP,
40
- 'xmlns:saml' => Namespaces::SAML
38
+ builder["samlp"].LogoutRequest(
39
+ "xmlns:samlp" => Namespaces::SAMLP,
40
+ "xmlns:saml" => Namespaces::SAML
41
41
  ) do |logout_request|
42
42
  super(logout_request)
43
43
 
44
44
  name_id.build(logout_request)
45
45
 
46
46
  Array(session_index).each do |session_index_instance|
47
- logout_request['samlp'].SessionIndex(session_index_instance)
47
+ logout_request["samlp"].SessionIndex(session_index_instance)
48
48
  end
49
49
  end
50
50
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'saml2/status_response'
3
+ require "saml2/status_response"
4
4
 
5
5
  module SAML2
6
6
  class LogoutResponse < StatusResponse
@@ -21,9 +21,9 @@ module SAML2
21
21
  private
22
22
 
23
23
  def build(builder)
24
- builder['samlp'].LogoutResponse(
25
- 'xmlns:samlp' => Namespaces::SAMLP,
26
- 'xmlns:saml' => Namespaces::SAML
24
+ builder["samlp"].LogoutResponse(
25
+ "xmlns:samlp" => Namespaces::SAMLP,
26
+ "xmlns:saml" => Namespaces::SAML
27
27
  ) do |logout_response|
28
28
  super(logout_response)
29
29
  end
data/lib/saml2/message.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
4
- require 'time'
3
+ require "securerandom"
4
+ require "time"
5
5
 
6
- require 'saml2/base'
7
- require 'saml2/signable'
6
+ require "saml2/base"
7
+ require "saml2/signable"
8
8
 
9
9
  module SAML2
10
10
  class InvalidMessage < RuntimeError
@@ -59,8 +59,10 @@ module SAML2
59
59
  # SAML message type.
60
60
  def from_xml(node)
61
61
  return super unless self == Message
62
+
62
63
  klass = Message.known_messages[node.name]
63
- raise UnknownMessage.new("Unknown message #{node.name}") unless klass
64
+ raise UnknownMessage, "Unknown message #{node.name}" unless klass
65
+
64
66
  klass.from_xml(node)
65
67
  end
66
68
 
@@ -72,8 +74,12 @@ module SAML2
72
74
  # If called on a subclass, will raise if the parsed message does not
73
75
  # match the class is was called on.
74
76
  def parse(xml)
75
- result = Message.from_xml(Nokogiri::XML(xml) { |config| config.strict }.root)
76
- raise UnexpectedMessage.new("Expected a #{self.name}, but got a #{result.class.name}") unless self == Message || result.class == self
77
+ result = Message.from_xml(Nokogiri::XML(xml, &:strict).root)
78
+ unless self == Message || result.instance_of?(self)
79
+ raise UnexpectedMessage,
80
+ "Expected a #{name}, but got a #{result.class.name}"
81
+ end
82
+
77
83
  result
78
84
  rescue Nokogiri::XML::SyntaxError
79
85
  raise CorruptMessage
@@ -86,10 +92,10 @@ module SAML2
86
92
  end
87
93
 
88
94
  def inherited(klass)
95
+ super
89
96
  # explicitly keep track of all messages in this base class
90
- Message.known_messages[klass.name.sub(/^SAML2::/, '')] = klass
97
+ Message.known_messages[klass.name.sub(/^SAML2::/, "")] = klass
91
98
  end
92
-
93
99
  end
94
100
 
95
101
  def initialize
@@ -133,37 +139,35 @@ module SAML2
133
139
 
134
140
  # @return [String]
135
141
  def id
136
- @id ||= xml['ID']
142
+ @id ||= xml["ID"]
137
143
  end
138
144
 
139
145
  # @return [Time]
140
146
  def issue_instant
141
- @issue_instant ||= Time.parse(xml['IssueInstant'])
147
+ @issue_instant ||= Time.parse(xml["IssueInstant"])
142
148
  end
143
149
 
144
150
  # @return [String, nil]
145
151
  def destination
146
- if xml && !instance_variable_defined?(:@destination)
147
- @destination = xml['Destination']
148
- end
152
+ @destination = xml["Destination"] if xml && !instance_variable_defined?(:@destination)
149
153
  @destination
150
154
  end
151
155
 
152
156
  # @return [NameID, nil]
153
157
  def issuer
154
- @issuer ||= NameID.from_xml(xml.at_xpath('saml:Issuer', Namespaces::ALL))
158
+ @issuer ||= NameID.from_xml(xml.at_xpath("saml:Issuer", Namespaces::ALL))
155
159
  end
156
160
 
157
161
  protected
158
162
 
159
163
  # should be called from inside the specific request element
160
164
  def build(message)
161
- message.parent['ID'] = id
162
- message.parent['Version'] = '2.0'
163
- message.parent['IssueInstant'] = issue_instant.iso8601
164
- message.parent['Destination'] = destination if destination
165
+ message.parent["ID"] = id
166
+ message.parent["Version"] = "2.0"
167
+ message.parent["IssueInstant"] = issue_instant.iso8601
168
+ message.parent["Destination"] = destination if destination
165
169
 
166
- issuer.build(message, element: 'Issuer') if issuer
170
+ issuer&.build(message, element: "Issuer")
167
171
  end
168
172
  end
169
173
  end
data/lib/saml2/name_id.rb CHANGED
@@ -1,19 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'saml2/base'
4
- require 'saml2/namespaces'
3
+ require "saml2/base"
4
+ require "saml2/namespaces"
5
5
 
6
6
  module SAML2
7
7
  class NameID < Base
8
8
  module Format
9
- EMAIL_ADDRESS = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
10
- ENTITY = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
11
- KERBEROS = "urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos" # name[/instance]@REALM
12
- PERSISTENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" # opaque, pseudo-random, unique per SP-IdP pair
13
- TRANSIENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" # opaque, will likely change
14
- UNSPECIFIED = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
15
- WINDOWS_DOMAIN_QUALIFIED_NAME = "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName" # [DomainName\]UserName
16
- X509_SUBJECT_NAME = "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName"
9
+ EMAIL_ADDRESS = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
10
+ ENTITY =
11
+ "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
12
+ KERBEROS =
13
+ "urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos" # name[/instance]@REALM
14
+ PERSISTENT =
15
+ "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" # opaque, pseudo-random, unique per SP-IdP pair
16
+ TRANSIENT =
17
+ "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" # opaque, will likely change
18
+ UNSPECIFIED =
19
+ "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
20
+ WINDOWS_DOMAIN_QUALIFIED_NAME =
21
+ "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName" # [DomainName\]UserName
22
+ X509_SUBJECT_NAME = "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName"
17
23
  end
18
24
 
19
25
  class Policy < Base
@@ -25,6 +31,7 @@ module SAML2
25
31
  # @param format optional [String]
26
32
  # @param sp_name_qualifier optional [String]
27
33
  def initialize(allow_create = nil, format = nil, sp_name_qualifier = nil)
34
+ super()
28
35
  @allow_create = allow_create if allow_create
29
36
  @format = format if format
30
37
  @sp_name_qualifier = sp_name_qualifier if sp_name_qualifier
@@ -32,43 +39,37 @@ module SAML2
32
39
 
33
40
  # @return [Boolean, nil]
34
41
  def allow_create?
35
- if xml && !instance_variable_defined?(:@allow_create)
36
- @allow_create = xml['AllowCreate']&.== 'true'
37
- end
42
+ @allow_create = xml["AllowCreate"]&.== "true" if xml && !instance_variable_defined?(:@allow_create)
38
43
  @allow_create
39
44
  end
40
45
 
41
46
  # @see Format
42
47
  # @return [String, nil]
43
48
  def format
44
- if xml && !instance_variable_defined?(:@format)
45
- @format = xml['Format']
46
- end
49
+ @format = xml["Format"] if xml && !instance_variable_defined?(:@format)
47
50
  @format
48
51
  end
49
52
 
50
53
  # @return [String, nil]
51
54
  def sp_name_qualifier
52
- if xml && !instance_variable_defined?(:@sp_name_qualifier)
53
- @sp_name_qualifier = xml['SPNameQualifier']
54
- end
55
+ @sp_name_qualifier = xml["SPNameQualifier"] if xml && !instance_variable_defined?(:@sp_name_qualifier)
55
56
  @sp_name_qualifier
56
57
  end
57
58
 
58
59
  # @param rhs [Policy]
59
60
  # @return [Boolean]
60
- def ==(rhs)
61
- allow_create? == rhs.allow_create? &&
62
- format == rhs.format &&
63
- sp_name_qualifier == rhs.sp_name_qualifier
61
+ def ==(other)
62
+ allow_create? == other.allow_create? &&
63
+ format == other.format &&
64
+ sp_name_qualifier == other.sp_name_qualifier
64
65
  end
65
66
 
66
67
  # (see Base#build)
67
68
  def build(builder)
68
- builder['samlp'].NameIDPolicy do |name_id_policy|
69
- name_id_policy.parent['Format'] = format if format
70
- name_id_policy.parent['SPNameQualifier'] = sp_name_qualifier if sp_name_qualifier
71
- name_id_policy.parent['AllowCreate'] = allow_create? unless allow_create?.nil?
69
+ builder["samlp"].NameIDPolicy do |name_id_policy|
70
+ name_id_policy.parent["Format"] = format if format
71
+ name_id_policy.parent["SPNameQualifier"] = sp_name_qualifier if sp_name_qualifier
72
+ name_id_policy.parent["AllowCreate"] = allow_create? unless allow_create?.nil?
72
73
  end
73
74
  end
74
75
  end
@@ -81,9 +82,9 @@ module SAML2
81
82
  # (see Base#from_xml)
82
83
  def from_xml(node)
83
84
  self.id = node.content.strip
84
- self.format = node['Format']
85
- self.name_qualifier = node['NameQualifier']
86
- self.sp_name_qualifier = node['SPNameQualifier']
85
+ self.format = node["Format"]
86
+ self.name_qualifier = node["NameQualifier"]
87
+ self.sp_name_qualifier = node["SPNameQualifier"]
87
88
  end
88
89
 
89
90
  # @param id [String]
@@ -91,26 +92,29 @@ module SAML2
91
92
  # @param name_qualifier optional [String]
92
93
  # @param sp_name_qualifier optional [String]
93
94
  def initialize(id = nil, format = nil, name_qualifier: nil, sp_name_qualifier: nil)
94
- @id, @format, @name_qualifier, @sp_name_qualifier =
95
- id, format, name_qualifier, sp_name_qualifier
95
+ super()
96
+ @id = id
97
+ @format = format
98
+ @name_qualifier = name_qualifier
99
+ @sp_name_qualifier = sp_name_qualifier
96
100
  end
97
101
 
98
102
  # @param rhs [NameID]
99
103
  # @return [Boolean]
100
- def ==(rhs)
101
- id == rhs.id &&
102
- format == rhs.format &&
103
- name_qualifier == rhs.name_qualifier &&
104
- sp_name_qualifier == rhs.sp_name_qualifier
104
+ def ==(other)
105
+ id == other.id &&
106
+ format == other.format &&
107
+ name_qualifier == other.name_qualifier &&
108
+ sp_name_qualifier == other.sp_name_qualifier
105
109
  end
106
110
 
107
111
  # (see Base#build)
108
112
  def build(builder, element: nil)
109
113
  args = {}
110
- args['Format'] = format if format
111
- args['NameQualifier'] = name_qualifier if name_qualifier
112
- args['SPNameQualifier'] = sp_name_qualifier if sp_name_qualifier
113
- builder['saml'].__send__(element || 'NameID', id, args)
114
+ args["Format"] = format if format
115
+ args["NameQualifier"] = name_qualifier if name_qualifier
116
+ args["SPNameQualifier"] = sp_name_qualifier if sp_name_qualifier
117
+ builder["saml"].__send__(element || "NameID", id, args)
114
118
  end
115
119
  end
116
120
  end
@@ -12,14 +12,14 @@ module SAML2
12
12
  X500 = "urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"
13
13
 
14
14
  ALL = {
15
- 'xmlns:dsig' => DSIG,
16
- 'xmlns:md' => METADATA,
17
- 'xmlns:saml' => SAML,
18
- 'xmlns:samlp' => SAMLP,
19
- 'xmlns:x500' => X500,
20
- 'xmlns:xenc' => XENC,
21
- 'xmlns:xs' => XS,
22
- 'xmlns:xsi' => XSI,
15
+ "xmlns:dsig" => DSIG,
16
+ "xmlns:md" => METADATA,
17
+ "xmlns:saml" => SAML,
18
+ "xmlns:samlp" => SAMLP,
19
+ "xmlns:x500" => X500,
20
+ "xmlns:xenc" => XENC,
21
+ "xmlns:xs" => XS,
22
+ "xmlns:xsi" => XSI
23
23
  }.freeze
24
24
  end
25
25
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'saml2/base'
4
- require 'saml2/localized_name'
5
- require 'saml2/namespaces'
3
+ require "saml2/base"
4
+ require "saml2/localized_name"
5
+ require "saml2/namespaces"
6
6
 
7
7
  module SAML2
8
8
  class Organization < Base
@@ -11,20 +11,21 @@ module SAML2
11
11
 
12
12
  # (see Base#from_xml)
13
13
  def from_xml(node)
14
- name.from_xml(node.xpath('md:OrganizationName', Namespaces::ALL))
15
- display_name.from_xml(node.xpath('md:OrganizationDisplayName', Namespaces::ALL))
16
- url.from_xml(node.xpath('md:OrganizationURL', Namespaces::ALL))
14
+ name.from_xml(node.xpath("md:OrganizationName", Namespaces::ALL))
15
+ display_name.from_xml(node.xpath("md:OrganizationDisplayName", Namespaces::ALL))
16
+ url.from_xml(node.xpath("md:OrganizationURL", Namespaces::ALL))
17
17
  end
18
18
 
19
19
  def initialize(name = nil, display_name = nil, url = nil)
20
- @name = LocalizedName.new('OrganizationName', name)
21
- @display_name = LocalizedName.new('OrganizationDisplayName', display_name)
22
- @url = LocalizedName.new('OrganizationURL', url)
20
+ super()
21
+ @name = LocalizedName.new("OrganizationName", name)
22
+ @display_name = LocalizedName.new("OrganizationDisplayName", display_name)
23
+ @url = LocalizedName.new("OrganizationURL", url)
23
24
  end
24
25
 
25
26
  # (see Base#build)
26
27
  def build(builder)
27
- builder['md'].Organization do |organization|
28
+ builder["md"].Organization do |organization|
28
29
  @name.build(organization)
29
30
  @display_name.build(organization)
30
31
  @url.build(organization)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'saml2/contact'
4
- require 'saml2/organization'
3
+ require "saml2/contact"
4
+ require "saml2/organization"
5
5
 
6
6
  module SAML2
7
7
  module OrganizationAndContacts
@@ -22,20 +22,20 @@ module SAML2
22
22
  # @return [Organization, nil]
23
23
  def organization
24
24
  unless instance_variable_defined?(:@organization)
25
- @organization = Organization.from_xml(xml.at_xpath('md:Organization', Namespaces::ALL))
25
+ @organization = Organization.from_xml(xml.at_xpath("md:Organization", Namespaces::ALL))
26
26
  end
27
27
  @organization
28
28
  end
29
29
 
30
30
  # @return [Array<Contact>]
31
31
  def contacts
32
- @contacts ||= load_object_array(xml, 'md:ContactPerson', Contact)
32
+ @contacts ||= load_object_array(xml, "md:ContactPerson", Contact)
33
33
  end
34
34
 
35
35
  protected
36
36
 
37
37
  def build(builder)
38
- organization.build(builder) if organization
38
+ organization&.build(builder)
39
39
  contacts.each do |contact|
40
40
  contact.build(builder)
41
41
  end
data/lib/saml2/request.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'saml2/message'
4
- require 'saml2/name_id'
5
- require 'saml2/namespaces'
3
+ require "saml2/message"
4
+ require "saml2/name_id"
5
+ require "saml2/namespaces"
6
6
 
7
7
  module SAML2
8
8
  # @abstract
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'saml2/base'
3
+ require "saml2/base"
4
4
 
5
5
  module SAML2
6
6
  class RequestedAuthnContext < Base
@@ -11,10 +11,10 @@ module SAML2
11
11
 
12
12
  # (see Base#build)
13
13
  def build(builder)
14
- builder['samlp'].RequestedAuthnContext do |requested_authn_context|
15
- requested_authn_context.parent['Comparison'] = comparison.to_s if comparison
14
+ builder["samlp"].RequestedAuthnContext do |requested_authn_context|
15
+ requested_authn_context.parent["Comparison"] = comparison.to_s if comparison
16
16
  Array(class_ref).each do |individual_class_ref|
17
- requested_authn_context['saml'].AuthnContextClassRef(individual_class_ref)
17
+ requested_authn_context["saml"].AuthnContextClassRef(individual_class_ref)
18
18
  end
19
19
  end
20
20
  end