saml2 3.1.10 → 3.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 99a6296632edaf74d6fc282ef56d06e94dc71787e02b254b5e366902a487f22d
4
- data.tar.gz: d7ec1d384f710d3276f51114c34a84079eba0051f41af6a5ce1704c595a0b354
3
+ metadata.gz: f582a823ae927adc8355f2c3b294c8d592a108a60995d8e156548fabb2530e7c
4
+ data.tar.gz: 2a596f2b0705d3b9a365a63721b80a0c977a88315cd70c965ac7166913a12948
5
5
  SHA512:
6
- metadata.gz: 00d66610046dd795906a1ea082c2244c4fabb17f92304005d707f60333233a69c76e059bb312171c3f3ee44470818e32686e418693b059fecb1171d7f6fa7745
7
- data.tar.gz: 9ad6721b14a6098c51fa475bd0fec92728e217beb30f7ff314a0abe0765c55d1b3d5343d6e9f661ffda811994f3dc4d45749d603fc23e6303dd92c883ae2bc68
6
+ metadata.gz: e1140328e3e03194e0d6f7b1046abb89525eb0f7151a838fd313c3bd93ae91fe71f6bcc022474c1aba6b674b48e3a09627003248d8040d4a891c05f86ebe99bc
7
+ data.tar.gz: 3d5c8a0f2e35fdb4017f35bea6a547f05cf53d4c8ce4b43672d18a2a7485f373a0accd4cc87322635be6dcae392cec0095bff7ae4e3db0856f70588cb261331a
@@ -5,8 +5,15 @@
5
5
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6
6
  </head>
7
7
  <body onload="document.forms[0].submit();" style="visibility:hidden;">
8
- <%= form_tag(@saml_acs_url) do %>
9
- <%= hidden_field_tag("SAMLResponse", @saml_response) %>
8
+ <%
9
+ target = @saml_destination || @saml_acs_url
10
+ message = @saml_request || @saml_response || @saml_message
11
+ target ||= message.destination if message.is_a?(SAML2::Message)
12
+ message = Base64.encode64(message.to_s) unless message.is_a?(String)
13
+ %>
14
+ <%= form_tag(target) do %>
15
+ <%= hidden_field_tag("SAMLRequest", message) if @saml_request || @saml_message.is_a?(SAML2::Request) %>
16
+ <%= hidden_field_tag("SAMLResponse", message) if @saml_response || @saml_message.is_a?(SAML2::Response) %>
10
17
  <%= hidden_field_tag("RelayState", @relay_state) if @relay_state %>
11
18
  <%= submit_tag "Submit" %>
12
19
  <% end %>
@@ -82,7 +82,7 @@ responses.each_with_index do |response_raw, i|
82
82
  # TODO: ignore audience restrictions
83
83
  errors = response.validate(service_provider: service_provider_entity,
84
84
  identity_provider: idps[response.issuer&.id],
85
- verification_time: verification_time)
85
+ verification_time:)
86
86
  unless errors.empty?
87
87
  bad_counts[response.issuer&.id] += 1
88
88
  warn "#{errors.inspect} for response #{response.id} from #{response.issuer&.id} (index #{i})"
@@ -30,16 +30,23 @@ module SAML2
30
30
  # @todo go over these params, and use kwargs. Maybe pass Entity instead
31
31
  # of ServiceProvider.
32
32
  # @param issuer [NameID]
33
- # @param identity_provider [IdentityProvider]
34
- # @param assertion_consumer_service [Endpoint::Indexed]
35
- # @param service_provider [ServiceProvider]
33
+ # @param identity_provider [IdentityProvider, nil]
34
+ # @param assertion_consumer_service [Endpoint::Indexed, nil]
35
+ # @param service_provider [ServiceProvider, nil]
36
+ # @param binding [String] the binding to use for the request
36
37
  # @return [AuthnRequest]
37
38
  def self.initiate(issuer, identity_provider = nil,
38
39
  assertion_consumer_service: nil,
39
- service_provider: nil)
40
+ service_provider: nil,
41
+ binding: Bindings::HTTPRedirect::URN)
40
42
  authn_request = new
41
43
  authn_request.issuer = issuer
42
- authn_request.destination = identity_provider.single_sign_on_services.first.location if identity_provider
44
+ if identity_provider
45
+ authn_request.destination = identity_provider
46
+ .single_sign_on_services
47
+ .choose_endpoint(binding)
48
+ &.location
49
+ end
43
50
  authn_request.name_id_policy = NameID::Policy.new(true, NameID::Format::UNSPECIFIED)
44
51
  assertion_consumer_service ||= service_provider.assertion_consumer_services.default if service_provider
45
52
  if assertion_consumer_service
data/lib/saml2/base.rb CHANGED
@@ -30,7 +30,10 @@ module SAML2
30
30
  end
31
31
 
32
32
  def load_object_array(node, element, klass = nil)
33
- node.xpath(element, Namespaces::ALL).map do |element_node|
33
+ nodes = node.xpath(element, Namespaces::ALL)
34
+ return klass::Array.from_xml(nodes) if klass.is_a?(Module) && klass&.const_defined?(:Array, false)
35
+
36
+ nodes.map do |element_node|
34
37
  if klass.nil?
35
38
  SAML2.const_get(element_node.name, false).from_xml(element_node)
36
39
  elsif klass.is_a?(Hash)
@@ -107,10 +110,10 @@ module SAML2
107
110
  # @return [String]
108
111
  def inspect
109
112
  "#<#{self.class.name} #{instance_variables.filter_map do |iv|
110
- next if iv == :@xml
113
+ next if IGNORED_IVARS.include?(iv)
111
114
 
112
115
  "#{iv}=#{instance_variable_get(iv).inspect}"
113
- end.join(", ")}>"
116
+ end.join(" ")}>"
114
117
  end
115
118
 
116
119
  # Serialize this object to XML
@@ -174,7 +177,7 @@ module SAML2
174
177
 
175
178
  old_node = node.parent
176
179
  this_nodes_keys.each_with_index do |key, i|
177
- old_node.replace(node.decrypt_with(key: key))
180
+ old_node.replace(node.decrypt_with(key:))
178
181
  rescue XMLSec::DecryptionError
179
182
  # swallow errors on all but the last key
180
183
  raise if i - 1 == this_nodes_keys.length
@@ -185,6 +188,9 @@ module SAML2
185
188
 
186
189
  private
187
190
 
191
+ IGNORED_IVARS = %i[@errors @pretty @xml].freeze
192
+ private_constant :IGNORED_IVARS
193
+
188
194
  def load_string_array(node, element)
189
195
  self.class.load_string_array(node, element)
190
196
  end
@@ -62,8 +62,8 @@ module SAML2
62
62
 
63
63
  # Use validate instead.
64
64
  # @deprecated
65
- def valid?(now: Time.now.utc, **options)
66
- validate(verification_time: now, **options).empty?
65
+ def valid?(now: Time.now.utc, **)
66
+ validate(verification_time: now, **).empty?
67
67
  end
68
68
 
69
69
  # (see Base#build)
@@ -4,21 +4,112 @@ require "saml2/bindings/http_post"
4
4
 
5
5
  module SAML2
6
6
  class Endpoint < Base
7
+ module ChoiceHelpers
8
+ # Choose a binding supported by this list of endpoints
9
+ #
10
+ # @return [String]
11
+ def choose_binding(*bindings)
12
+ (bindings & map(&:binding)).first
13
+ end
14
+
15
+ # Choose an endpoint from this list of endpoints that supports a given binding
16
+ #
17
+ # @param binding [String] the binding that must match
18
+ # @return [Endpoint, nil]
19
+ def choose_endpoint(binding)
20
+ find { |endpoint| endpoint.binding == binding }
21
+ end
22
+ end
23
+
24
+ class Array < ::Array
25
+ include ChoiceHelpers
26
+
27
+ def self.from_xml(nodes)
28
+ new(nodes.map do |node|
29
+ Endpoint.from_xml(node)
30
+ end).freeze
31
+ end
32
+ end
33
+
34
+ class Indexed < Endpoint
35
+ include IndexedObject
36
+
37
+ class Array
38
+ include ChoiceHelpers
39
+
40
+ # Choose a binding supported by this list of endpoints
41
+ #
42
+ # Note that if there is a default endpoint, its binding will be preferred even
43
+ # over the order of the bindings passed in (as long as it is included in the list
44
+ # at all).
45
+ # @return [String]
46
+ def choose_binding(*bindings)
47
+ return default.binding if default && bindings.include?(default.binding)
48
+
49
+ super
50
+ end
51
+
52
+ # Choose an endpoint from this list of endpoints that supports a given binding
53
+ #
54
+ # Note that if there is a default endpoint, it will be returned if its binding matches
55
+ # even over earlier endpoints in the list.
56
+ # @param binding [String] the binding that must match
57
+ # @return [Endpoint, nil]
58
+ def choose_endpoint(binding)
59
+ return default if default && default.binding == binding
60
+
61
+ super
62
+ end
63
+ end
64
+
65
+ # @param location [String]
66
+ # @param index [Integer]
67
+ # @param is_default [true, false, nil]
68
+ # @param binding [String]
69
+ # @param response_location [String, nil]
70
+ def initialize(location = nil,
71
+ index = nil,
72
+ is_default = nil,
73
+ binding = Bindings::HTTP_POST::URN,
74
+ response_location = nil)
75
+ super(location, binding, response_location)
76
+ @index = index
77
+ @is_default = is_default
78
+ end
79
+
80
+ def eql?(other)
81
+ location == other.location &&
82
+ binding == other.binding &&
83
+ response_location == other.response_location &&
84
+ super
85
+ end
86
+
87
+ # @return [String]
88
+ def inspect
89
+ "#<SAML2::Endpoint::Indexed #{endpoint_inspect} #{indexed_object_inspect}>"
90
+ end
91
+ end
92
+
7
93
  # @return [String]
8
- attr_reader :location, :binding
94
+ attr_accessor :location, :binding
95
+ # @return [String, nil]
96
+ attr_accessor :response_location
9
97
 
10
98
  # @param location [String]
11
99
  # @param binding [String]
12
- def initialize(location = nil, binding = Bindings::HTTP_POST::URN)
100
+ # @param response_location [String, nil]
101
+ def initialize(location = nil, binding = Bindings::HTTP_POST::URN, response_location = nil)
13
102
  super()
14
103
  @location = location
15
104
  @binding = binding
105
+ @response_location = response_location
16
106
  end
17
107
 
18
108
  # @param rhs [Endpoint]
19
109
  # @return [Boolean]
20
110
  def ==(other)
21
- location == other.location && binding == other.binding
111
+ other.is_a?(Endpoint) &&
112
+ location == other.location && binding == other.binding && response_location == other.response_location
22
113
  end
23
114
 
24
115
  # (see Base#from_xml)
@@ -26,30 +117,35 @@ module SAML2
26
117
  super
27
118
  @location = node["Location"]
28
119
  @binding = node["Binding"]
120
+ @response_location = node["ResponseLocation"]
29
121
  end
30
122
 
31
123
  # (see Base#build)
32
124
  def build(builder, element)
33
- builder["md"].__send__(element, "Location" => location, "Binding" => binding)
125
+ builder["md"].__send__(element, "Location" => location, "Binding" => binding) do |b|
126
+ b.ResponseLocation = response_location if response_location
127
+ end
34
128
  end
35
129
 
36
- class Indexed < Endpoint
37
- include IndexedObject
130
+ # @!attribute[r]
131
+ # @return [String]
132
+ # The {response_location} if there is one, otherwise the {location}
133
+ def effective_response_location
134
+ response_location || location
135
+ end
38
136
 
39
- # @param location [String]
40
- # @param index [Integer]
41
- # @param is_default [true, false, nil]
42
- # @param binding [String]
43
- def initialize(location = nil, index = nil, is_default = nil, binding = Bindings::HTTP_POST::URN)
44
- super(location, binding)
45
- @index = index
46
- @is_default = is_default
47
- end
137
+ # @return [String]
138
+ def inspect
139
+ "#<SAML2::Endpoint #{endpoint_inspect}>"
140
+ end
48
141
 
49
- def eql?(other)
50
- location == other.location &&
51
- binding == other.binding && super
52
- end
142
+ private
143
+
144
+ def endpoint_inspect
145
+ r = "location=#{location.inspect}"
146
+ r += " binding=#{binding.inspect}" if binding
147
+ r += " response_location=#{response_location.inspect}" if response_location
148
+ r
53
149
  end
54
150
  end
55
151
  end
data/lib/saml2/entity.rb CHANGED
@@ -168,15 +168,15 @@ module SAML2
168
168
  # @param identity_provider [Entity]
169
169
  def valid_response?(message,
170
170
  identity_provider,
171
- **opts)
171
+ **)
172
172
  unless message.is_a?(Response)
173
173
  message.errors << "not a Response object"
174
174
  return false
175
175
  end
176
176
 
177
177
  message.validate(service_provider: self,
178
- identity_provider: identity_provider,
179
- **opts).empty?
178
+ identity_provider:,
179
+ **).empty?
180
180
  end
181
181
  end
182
182
  end
@@ -12,7 +12,7 @@ module SAML2
12
12
  def initialize
13
13
  super
14
14
  @want_authn_requests_signed = nil
15
- @single_sign_on_services = []
15
+ @single_sign_on_services = Endpoint::Array.new
16
16
  @attribute_profiles = []
17
17
  @attributes = []
18
18
  end
@@ -34,7 +34,7 @@ module SAML2
34
34
  @want_authn_requests_signed
35
35
  end
36
36
 
37
- # @return [Array<Endpoint>]
37
+ # @return [Endpoint::Array]
38
38
  def single_sign_on_services
39
39
  @single_sign_on_services ||= load_object_array(xml, "md:SingleSignOnService", Endpoint)
40
40
  end
@@ -4,6 +4,10 @@ require "saml2/base"
4
4
 
5
5
  module SAML2
6
6
  module IndexedObject
7
+ def self.included(klass)
8
+ klass.const_set(:Array, Array.dup)
9
+ end
10
+
7
11
  # @return [Integer]
8
12
  attr_accessor :index
9
13
 
@@ -42,9 +46,7 @@ module SAML2
42
46
 
43
47
  def self.from_xml(nodes)
44
48
  new(nodes.map do |node|
45
- name.split("::")[1..-2].inject(SAML2) do |mod, klass|
46
- mod.const_get(klass)
47
- end.from_xml(node)
49
+ Object.const_get(name.rpartition("::").first, false).from_xml(node)
48
50
  end).freeze
49
51
  end
50
52
 
@@ -88,8 +90,14 @@ module SAML2
88
90
  builder.parent.children.last["isDefault"] = default? if default_defined?
89
91
  end
90
92
 
91
- def self.included(klass)
92
- klass.const_set(:Array, Array.dup)
93
+ private
94
+
95
+ def indexed_object_inspect
96
+ if default_defined?
97
+ "index=#{index}, default=#{default?}"
98
+ else
99
+ "index=#{index}"
100
+ end
93
101
  end
94
102
  end
95
103
  end
@@ -7,15 +7,16 @@ module SAML2
7
7
  class LogoutRequest < Request
8
8
  attr_writer :name_id, :session_index
9
9
 
10
- # @param sso [SSO]
10
+ # @param sso [SSO, nil]
11
11
  # @param issuer [NameID]
12
12
  # @param name_id [NameID]
13
13
  # @param session_index optional [String, Array<String>]
14
+ # @param binding [String] the binding to use for the request
14
15
  # @return [LogoutRequest]
15
- def self.initiate(sso, issuer, name_id, session_index = [])
16
+ def self.initiate(sso, issuer, name_id, session_index = [], binding: Bindings::HTTPRedirect::URN)
16
17
  logout_request = new
17
18
  logout_request.issuer = issuer
18
- logout_request.destination = sso.single_logout_services.first.location
19
+ logout_request.destination = sso.single_logout_services.choose_endpoint(binding)&.location if sso
19
20
  logout_request.name_id = name_id
20
21
  logout_request.session_index = session_index
21
22
 
@@ -5,16 +5,25 @@ require "saml2/status_response"
5
5
  module SAML2
6
6
  class LogoutResponse < StatusResponse
7
7
  # @param logout_request [LogoutRequest]
8
- # @param sso [SSO]
8
+ # @param sso [SSO, nil]
9
9
  # @param issuer [NameID]
10
10
  # @param status_code [String]
11
+ # @param binding [String] the binding to use for the response
11
12
  # @return [LogoutResponse]
12
- def self.respond_to(logout_request, sso, issuer, status_code = Status::SUCCESS)
13
+ def self.respond_to(logout_request,
14
+ sso,
15
+ issuer,
16
+ status_code = Status::SUCCESS,
17
+ binding: Bindings::HTTPRedirect::URN,
18
+ message: nil)
13
19
  logout_response = new
14
20
  logout_response.issuer = issuer
15
- logout_response.destination = sso.single_logout_services.first.location
21
+ if sso
22
+ logout_response.destination = sso.single_logout_services.choose_endpoint(binding)&.effective_response_location
23
+ end
16
24
  logout_response.in_response_to = logout_request.id
17
25
  logout_response.status.code = status_code
26
+ logout_response.status.message = message
18
27
  logout_response
19
28
  end
20
29
 
data/lib/saml2/message.rb CHANGED
@@ -113,13 +113,14 @@ module SAML2
113
113
  end
114
114
 
115
115
  def validate
116
- @errors = Schemas.protocol.validate(xml.document)
116
+ @errors = xml ? Schemas.protocol.validate(xml.document) : []
117
117
  errors
118
118
  end
119
119
 
120
120
  # If the XML is valid according to SAML XSDs.
121
121
  # @return [Boolean]
122
122
  def valid_schema?
123
+ return true if xml.nil? # it didn't come from parsing XML; there's nothing to be invalid
123
124
  return false unless Schemas.protocol.valid?(xml.document)
124
125
 
125
126
  true
data/lib/saml2/name_id.rb CHANGED
@@ -59,7 +59,8 @@ module SAML2
59
59
  # @param rhs [Policy]
60
60
  # @return [Boolean]
61
61
  def ==(other)
62
- allow_create? == other.allow_create? &&
62
+ other.is_a?(Policy) &&
63
+ allow_create? == other.allow_create? &&
63
64
  format == other.format &&
64
65
  sp_name_qualifier == other.sp_name_qualifier
65
66
  end
@@ -102,7 +103,8 @@ module SAML2
102
103
  # @param rhs [NameID]
103
104
  # @return [Boolean]
104
105
  def ==(other)
105
- id == other.id &&
106
+ other.is_a?(NameID) &&
107
+ id == other.id &&
106
108
  format == other.format &&
107
109
  name_qualifier == other.name_qualifier &&
108
110
  sp_name_qualifier == other.sp_name_qualifier
@@ -116,5 +118,18 @@ module SAML2
116
118
  args["SPNameQualifier"] = sp_name_qualifier if sp_name_qualifier
117
119
  builder["saml"].__send__(element || "NameID", id, args)
118
120
  end
121
+
122
+ # @return [String]
123
+ def inspect
124
+ return id.inspect unless format || name_qualifier || sp_name_qualifier
125
+ return "#{id.inspect}@#{format.inspect}" unless name_qualifier || sp_name_qualifier
126
+
127
+ r = "#<SAML2::NameID id=#{id.inspect}"
128
+ r << " format=#{format.inspect}" if format
129
+ r << " name_qualifier=#{name_qualifier.inspect}" if name_qualifier
130
+ r << " sp_name_qualifier=#{sp_name_qualifier.inspect}" if sp_name_qualifier
131
+ r << ">"
132
+ r
133
+ end
119
134
  end
120
135
  end
@@ -35,7 +35,7 @@ module SAML2
35
35
  end
36
36
 
37
37
  # Begin an IdP Initiated login
38
- # @param service_provider [ServiceProvider]
38
+ # @param service_provider [ServiceProvider, nil]
39
39
  # @param issuer [NameID]
40
40
  # @param name_id [NameID] The subject
41
41
  # @param attributes optional [Hash<String => String>, Array<Attribute>]
@@ -43,7 +43,12 @@ module SAML2
43
43
  def self.initiate(service_provider, issuer, name_id, attributes = nil)
44
44
  response = new
45
45
  response.issuer = issuer
46
- response.destination = service_provider.assertion_consumer_services.default.location if service_provider
46
+ if service_provider
47
+ response.destination = service_provider
48
+ .assertion_consumer_services
49
+ .choose_endpoint(Bindings::HTTP_POST::URN)
50
+ &.effective_response_location
51
+ end
47
52
  assertion = Assertion.new
48
53
  assertion.subject = Subject.new
49
54
  assertion.subject.name_id = name_id
@@ -235,9 +240,9 @@ module SAML2
235
240
 
236
241
  if assertion.conditions &&
237
242
  !(condition_errors = assertion.conditions.validate(
238
- verification_time: verification_time,
243
+ verification_time:,
239
244
  audience: service_provider.entity_id,
240
- ignore_audience_condition: ignore_audience_condition
245
+ ignore_audience_condition:
241
246
  )).empty?
242
247
  return errors.concat(condition_errors)
243
248
  end
data/lib/saml2/role.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "set"
4
-
5
3
  require "saml2/base"
6
4
  require "saml2/key"
7
5
  require "saml2/organization_and_contacts"
@@ -44,18 +44,16 @@ module SAML2
44
44
 
45
45
  # @return [Endpoint::Indexed::Array]
46
46
  def assertion_consumer_services
47
- @assertion_consumer_services ||= begin
48
- nodes = xml.xpath("md:AssertionConsumerService", Namespaces::ALL)
49
- Endpoint::Indexed::Array.from_xml(nodes)
50
- end
47
+ @assertion_consumer_services ||= load_object_array(xml,
48
+ "md:AssertionConsumerService",
49
+ Endpoint::Indexed)
51
50
  end
52
51
 
53
52
  # @return [AttributeConsumingService::Array]
54
53
  def attribute_consuming_services
55
- @attribute_consuming_services ||= begin
56
- nodes = xml.xpath("md:AttributeConsumingService", Namespaces::ALL)
57
- AttributeConsumingService::Array.from_xml(nodes)
58
- end
54
+ @attribute_consuming_services ||= load_object_array(xml,
55
+ "md:AttributeConsumingService",
56
+ AttributeConsumingService)
59
57
  end
60
58
 
61
59
  # (see Base#build)
@@ -100,8 +100,8 @@ module SAML2
100
100
  #
101
101
  # @param (see #validate_signature)
102
102
  # @return [Boolean]
103
- def valid_signature?(**kwargs)
104
- validate_signature(**kwargs).empty?
103
+ def valid_signature?(**)
104
+ validate_signature(**).empty?
105
105
  end
106
106
 
107
107
  # Sign this object.
data/lib/saml2/sso.rb CHANGED
@@ -7,7 +7,7 @@ module SAML2
7
7
  class SSO < Role
8
8
  def initialize
9
9
  super
10
- @single_logout_services = []
10
+ @single_logout_services = Endpoint::Array.new
11
11
  @name_id_formats = []
12
12
  end
13
13
 
@@ -18,7 +18,7 @@ module SAML2
18
18
  @name_id_formats = nil
19
19
  end
20
20
 
21
- # @return [Array<Endpoint>]
21
+ # @return [Endpoint::Array]
22
22
  def single_logout_services
23
23
  @single_logout_services ||= load_object_array(xml, "md:SingleLogoutService", Endpoint)
24
24
  end
data/lib/saml2/status.rb CHANGED
@@ -4,7 +4,9 @@ require "saml2/base"
4
4
 
5
5
  module SAML2
6
6
  class Status < Base
7
- SUCCESS = "urn:oasis:names:tc:SAML:2.0:status:Success"
7
+ SUCCESS = "urn:oasis:names:tc:SAML:2.0:status:Success"
8
+ REQUESTER = "urn:oasis:names:tc:SAML:2.0:status:Requester"
9
+ RESPONDER = "urn:oasis:names:tc:SAML:2.0:status:Responder"
8
10
 
9
11
  # @return [String]
10
12
  attr_accessor :code, :message
data/lib/saml2/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SAML2
4
- VERSION = "3.1.10"
4
+ VERSION = "3.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saml2
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.10
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-02-25 00:00:00.000000000 Z
11
+ date: 2025-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -70,90 +70,6 @@ dependencies:
70
70
  - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: 0.9.5
73
- - !ruby/object:Gem::Dependency
74
- name: debug
75
- requirement: !ruby/object:Gem::Requirement
76
- requirements:
77
- - - "~>"
78
- - !ruby/object:Gem::Version
79
- version: '1.10'
80
- type: :development
81
- prerelease: false
82
- version_requirements: !ruby/object:Gem::Requirement
83
- requirements:
84
- - - "~>"
85
- - !ruby/object:Gem::Version
86
- version: '1.10'
87
- - !ruby/object:Gem::Dependency
88
- name: rake
89
- requirement: !ruby/object:Gem::Requirement
90
- requirements:
91
- - - "~>"
92
- - !ruby/object:Gem::Version
93
- version: '13.2'
94
- type: :development
95
- prerelease: false
96
- version_requirements: !ruby/object:Gem::Requirement
97
- requirements:
98
- - - "~>"
99
- - !ruby/object:Gem::Version
100
- version: '13.2'
101
- - !ruby/object:Gem::Dependency
102
- name: rspec
103
- requirement: !ruby/object:Gem::Requirement
104
- requirements:
105
- - - "~>"
106
- - !ruby/object:Gem::Version
107
- version: '3.5'
108
- type: :development
109
- prerelease: false
110
- version_requirements: !ruby/object:Gem::Requirement
111
- requirements:
112
- - - "~>"
113
- - !ruby/object:Gem::Version
114
- version: '3.5'
115
- - !ruby/object:Gem::Dependency
116
- name: rubocop-inst
117
- requirement: !ruby/object:Gem::Requirement
118
- requirements:
119
- - - "~>"
120
- - !ruby/object:Gem::Version
121
- version: '1'
122
- type: :development
123
- prerelease: false
124
- version_requirements: !ruby/object:Gem::Requirement
125
- requirements:
126
- - - "~>"
127
- - !ruby/object:Gem::Version
128
- version: '1'
129
- - !ruby/object:Gem::Dependency
130
- name: rubocop-rake
131
- requirement: !ruby/object:Gem::Requirement
132
- requirements:
133
- - - "~>"
134
- - !ruby/object:Gem::Version
135
- version: '0.6'
136
- type: :development
137
- prerelease: false
138
- version_requirements: !ruby/object:Gem::Requirement
139
- requirements:
140
- - - "~>"
141
- - !ruby/object:Gem::Version
142
- version: '0.6'
143
- - !ruby/object:Gem::Dependency
144
- name: rubocop-rspec
145
- requirement: !ruby/object:Gem::Requirement
146
- requirements:
147
- - - "~>"
148
- - !ruby/object:Gem::Version
149
- version: '3.5'
150
- type: :development
151
- prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- requirements:
154
- - - "~>"
155
- - !ruby/object:Gem::Version
156
- version: '3.5'
157
73
  description: |
158
74
  The saml2 library is yet another SAML library for Ruby, with
159
75
  an emphasis on _not_ re-implementing XML, especially XML Security,
@@ -237,14 +153,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
237
153
  requirements:
238
154
  - - ">="
239
155
  - !ruby/object:Gem::Version
240
- version: '2.7'
156
+ version: '3.2'
241
157
  required_rubygems_version: !ruby/object:Gem::Requirement
242
158
  requirements:
243
159
  - - ">="
244
160
  - !ruby/object:Gem::Version
245
161
  version: '0'
246
162
  requirements: []
247
- rubygems_version: 3.5.11
163
+ rubygems_version: 3.4.10
248
164
  signing_key:
249
165
  specification_version: 4
250
166
  summary: SAML 2.0 Library