ciam-es 0.0.2 → 0.0.7

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: bb8518dd8770087934f1e2c2a660933024bc95cefb2e0236f1d6a6d9978ec261
4
- data.tar.gz: d079efe7ad4bfd58517037d553bd16f206db66c0e4a4ea56d6adeeda62380ac5
3
+ metadata.gz: e1ce973bd3d499cd24750bfc8fbaec35056734fd284a1c2e2cc5e5ad4e97298e
4
+ data.tar.gz: 4d0ec7b507ccbd00422bd868460efeefb358de04ab4b92bb185591b7922bb2c4
5
5
  SHA512:
6
- metadata.gz: 4f6c22bf83eeb57247d65cc83a974ce4b759a850cb18d919e4c6053d450e2ed6cde1dd7178cb5122f81171dcfaa7a50d92fbe403b7eaffe8546238065bf2bdb5
7
- data.tar.gz: 8f76ca315b71604b04432a619b7c835e222a555335775b80445b4e706eda498d0f22eff938b2708935a4fd82f47e7b277fa01e007f1c92eb32c5075d1e2a9b2e
6
+ metadata.gz: 426e3b6ea6bac67c4f25f0ad0636519e8d24f93d5ac87f457ccf7e6a08c7f81d157ece5aa2be393c516c3b9e310edabbe10e8a278b55f68acf65df3295ba7bd8
7
+ data.tar.gz: 98c23881eb82db9f2c790d91347ba2c38e249b9c689dc44db07e1ce166f7db495cde8d4c73dc0d4d13e0ab2647dcf7c46981194de8a7f726371463df486f4d4c
@@ -2,7 +2,7 @@ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'ciam-es'
5
- s.version = '0.0.2'
5
+ s.version = '0.0.7'
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Fabiano Pavan"]
@@ -29,7 +29,7 @@ module Ciam::Saml
29
29
  # Create AuthnRequest root element using REXML
30
30
  request_doc = Ciam::XMLSecurityNew::Document.new
31
31
  request_doc.context[:attribute_quote] = :quote
32
- root = request_doc.add_element "saml2p:AuthnRequest", { "xmlns:saml2p" => "urn:oasis:names:tc:SAML:2.0:protocol",
32
+ root = request_doc.add_element "samlp:AuthnRequest", { "xmlns:samlp" => "urn:oasis:names:tc:SAML:2.0:protocol",
33
33
  "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion"
34
34
  }
35
35
  root.attributes['ID'] = uuid
@@ -72,7 +72,7 @@ module Ciam::Saml
72
72
 
73
73
 
74
74
  if @settings.name_identifier_format != nil
75
- root.add_element "saml2p:NameIDPolicy", {
75
+ root.add_element "samlp:NameIDPolicy", {
76
76
  # Might want to make AllowCreate a setting?
77
77
  #{}"AllowCreate" => "true",
78
78
  "Format" => @settings.name_identifier_format[0]
@@ -83,8 +83,8 @@ module Ciam::Saml
83
83
  # match required for authentication to succeed. If this is not defined,
84
84
  # the IdP will choose default rules for authentication. (Shibboleth IdP)
85
85
  if @settings.authn_context != nil
86
- requested_context = root.add_element "saml2p:RequestedAuthnContext", {
87
- "Comparison" => "minimum"
86
+ requested_context = root.add_element "samlp:RequestedAuthnContext", {
87
+ "Comparison" => "exact"
88
88
  }
89
89
  context_class = []
90
90
  @settings.authn_context.each_with_index{ |context, index|
@@ -95,12 +95,12 @@ module Ciam::Saml
95
95
  end
96
96
 
97
97
  if @settings.requester_identificator != nil
98
- requester_identificator = root.add_element "saml2p:Scoping", {
98
+ requester_identificator = root.add_element "samlp:Scoping", {
99
99
  "ProxyCount" => "0"
100
100
  }
101
101
  identificators = []
102
102
  @settings.requester_identificator.each_with_index{ |requester, index|
103
- identificators[index] = requester_identificator.add_element "saml2p:RequesterID"
103
+ identificators[index] = requester_identificator.add_element "samlp:RequesterID"
104
104
  identificators[index].text = requester
105
105
  }
106
106
 
@@ -109,12 +109,12 @@ module Ciam::Saml
109
109
  request_doc << REXML::XMLDecl.new("1.0", "UTF-8")
110
110
 
111
111
  #LA FIRMA VA MESSA SOLO NEL CASO CON HTTP POST
112
- # cert = @settings.get_sp_cert
113
- # # embed signature
114
- # if @settings.metadata_signed && @settings.sp_private_key && @settings.sp_cert
115
- # private_key = @settings.get_sp_key
116
- # request_doc.sign_document(private_key, cert)
117
- # end
112
+ cert = @settings.get_cert(@settings.sp_cert)
113
+ # embed signature
114
+ if @settings.metadata_signed && @settings.sp_private_key && @settings.sp_cert
115
+ private_key = @settings.get_sp_key
116
+ request_doc.sign_document(private_key, cert)
117
+ end
118
118
 
119
119
  # stampo come stringa semplice i metadata per non avere problemi con validazione firma
120
120
  #ret = request_doc.to_s
@@ -37,85 +37,106 @@ module Ciam::Saml
37
37
  opt = { :name_id => nil, :session_index => nil, :extra_parameters => nil }.merge(options)
38
38
  return nil unless opt[:name_id]
39
39
 
40
- @request = REXML::Document.new
41
- @request.context[:attribute_quote] = :quote
40
+ request_doc = Ciam::XMLSecurityNew::Document.new
41
+ request_doc.context[:attribute_quote] = :quote
42
42
 
43
43
 
44
- root = @request.add_element "saml2p:LogoutRequest", { "xmlns:saml2p" => PROTOCOL }
44
+ root = request_doc.add_element "samlp:LogoutRequest", { "xmlns:samlp" => PROTOCOL, "xmlns:saml" => ASSERTION }
45
45
  root.attributes['ID'] = @transaction_id
46
46
  root.attributes['IssueInstant'] = @issue_instant
47
47
  root.attributes['Version'] = "2.0"
48
48
  root.attributes['Destination'] = @settings.single_logout_destination
49
49
 
50
- issuer = root.add_element "saml2:Issuer", { "xmlns:saml2" => ASSERTION }
51
- issuer.attributes['Format'] = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
52
- #issuer.text = @settings.issuer
53
- #per la federazione trentina qui ci vanno i metadati...
54
- issuer.text = @settings.idp_metadata
50
+ issuer = root.add_element "saml:Issuer"#, { "xmlns:saml2" => ASSERTION }
51
+ #issuer.attributes['Format'] = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
52
+ issuer.text = @settings.issuer
55
53
 
56
- name_id = root.add_element "saml2:NameID", { "xmlns:saml2" => ASSERTION }
54
+ name_id = root.add_element "saml:NameID"#, { "xmlns:saml2" => ASSERTION }
57
55
  name_id.attributes['Format'] = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
58
56
  name_id.attributes['NameQualifier'] = @settings.idp_name_qualifier
59
57
  name_id.text = opt[:name_id]
60
58
  # I believe the rest of these are optional
61
- if @settings && @settings.sp_name_qualifier
62
- name_id.attributes["SPNameQualifier"] = @settings.sp_name_qualifier
63
- end
59
+ # if @settings && @settings.sp_name_qualifier
60
+ # name_id.attributes["SPNameQualifier"] = @settings.sp_name_qualifier
61
+ # end
64
62
  if opt[:session_index]
65
- session_index = root.add_element "saml2p:SessionIndex" #, { "xmlns:samlp" => PROTOCOL }
63
+ session_index = root.add_element "samlp:SessionIndex" #, { "xmlns:samlp" => PROTOCOL }
66
64
  session_index.text = opt[:session_index]
67
65
  end
68
- Logging.debug "Created LogoutRequest: #{@request}"
69
- meta = Metadata.new(@settings)
70
- return meta.create_slo_request( to_s, opt[:extra_parameters] )
66
+
67
+ request_doc << REXML::XMLDecl.new("1.0", "UTF-8")
68
+ #sign logout_request
69
+ cert = @settings.get_cert(@settings.sp_cert)
70
+
71
+ # embed signature
72
+ if @settings.metadata_signed && @settings.sp_private_key && @settings.sp_cert
73
+ private_key = @settings.get_sp_key
74
+ request_doc.sign_document(private_key, cert)
75
+ end
76
+
77
+
78
+ puts "Created LogoutRequest: #{request_doc}"
79
+
80
+ #Logout per binding redirect
81
+ # meta = Metadata.new(@settings)
82
+ # slo_req = meta.create_slo_request( request_doc.to_s, opt[:extra_parameters] )
83
+
84
+
85
+ return request_doc.to_s
86
+
71
87
  #action, content = binding_select("SingleLogoutService")
72
88
  #Logging.debug "action: #{action} content: #{content}"
73
89
  #return [action, content]
74
- end
90
+ end
75
91
 
76
- # function to return the created request as an XML document
92
+ # function to return the created request as an XML document
77
93
  def to_xml
78
- text = ""
79
- @request.write(text, 1)
80
- return text
94
+ text = ""
95
+ @request.write(text, 1)
96
+ return text
97
+ end
98
+
99
+ def to_s
100
+ @request.to_s
81
101
  end
82
- def to_s
83
- @request.to_s
84
- end
102
+
85
103
  # Functions for pulling values out from an IdP initiated LogoutRequest
86
- def name_id
87
- element = REXML::XPath.first(@request, "/p:LogoutRequest/a:NameID", {
88
- "p" => PROTOCOL, "a" => ASSERTION } )
89
- return nil if element.nil?
90
- # Can't seem to get this to work right...
91
- #element.context[:compress_whitespace] = ["NameID"]
92
- #element.context[:compress_whitespace] = :all
93
- str = element.text.gsub(/^\s+/, "")
94
- str.gsub!(/\s+$/, "")
95
- return str
96
- end
104
+ def name_id
105
+ element = REXML::XPath.first(@request, "/p:LogoutRequest/a:NameID", {
106
+ "p" => PROTOCOL, "a" => ASSERTION } )
107
+ return nil if element.nil?
108
+ # Can't seem to get this to work right...
109
+ #element.context[:compress_whitespace] = ["NameID"]
110
+ #element.context[:compress_whitespace] = :all
111
+ str = element.text.gsub(/^\s+/, "")
112
+ str.gsub!(/\s+$/, "")
113
+ return str
114
+ end
97
115
 
98
- def transaction_id
99
- return @transaction_id if @transaction_id
100
- element = REXML::XPath.first(@request, "/p:LogoutRequest", {
101
- "p" => PROTOCOL} )
102
- return nil if element.nil?
103
- return element.attributes["ID"]
104
- end
105
- def is_valid?
106
- validate(soft = true)
107
- end
116
+ def transaction_id
117
+ return @transaction_id if @transaction_id
118
+ element = REXML::XPath.first(@request, "/p:LogoutRequest", {
119
+ "p" => PROTOCOL} )
120
+ return nil if element.nil?
121
+ return element.attributes["ID"]
122
+ end
123
+
124
+ def is_valid?
125
+ validate(soft = true)
126
+ end
108
127
 
109
- def validate!
110
- validate( soft = false )
111
- end
112
- def validate( soft = true )
113
- return false if @request.nil?
114
- return false if @request.validate(@settings, soft) == false
115
-
116
- return true
117
-
118
- end
128
+ def validate!
129
+ validate( soft = false )
130
+ end
131
+
132
+ def validate( soft = true )
133
+ return false if @request.nil?
134
+ return false if @request.validate(@settings, soft) == false
135
+
136
+ return true
137
+
138
+ end
139
+
119
140
  private
120
141
 
121
142
  def self.timestamp
@@ -5,13 +5,15 @@ require "rexml/document"
5
5
  module Ciam
6
6
  module Saml
7
7
  class LogoutResponse
8
- include Coding
9
- include Request
8
+ include Coding
9
+ include Response
10
10
  ASSERTION = "urn:oasis:names:tc:SAML:2.0:assertion"
11
11
  PROTOCOL = "urn:oasis:names:tc:SAML:2.0:protocol"
12
12
  DSIG = "http://www.w3.org/2000/09/xmldsig#"
13
13
 
14
- def initialize( options = { } )
14
+ attr_accessor :settings
15
+
16
+ def initialize( options = { } )
15
17
  opt = { :response => nil, :settings => nil }.merge(options)
16
18
  # We've recieved a LogoutResponse from the IdP
17
19
  if opt[:response]
@@ -32,7 +34,7 @@ module Ciam
32
34
  if opt[:settings]
33
35
  @settings = opt[:settings]
34
36
  end
35
- end
37
+ end
36
38
 
37
39
  # Create a LogoutResponse to to the IdP's LogoutRequest
38
40
  # (For IdP initiated SLO)
@@ -42,11 +44,12 @@ module Ciam
42
44
  :status => "urn:oasis:names:tc:SAML:2.0:status:Success",
43
45
  :extra_parameters => nil }.merge(options)
44
46
  return nil if opt[:transaction_id].nil?
45
- @response = REXML::Document.new
46
- @response.context[:attribute_quote] = :quote
47
+ response_doc = Ciam::XMLSecurityNew::Document.new
48
+ response_doc.context[:attribute_quote] = :quote
49
+
47
50
  uuid = "_" + UUID.new.generate
48
51
  time = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
49
- root = @response.add_element "saml2p:LogoutResponse", { "xmlns:saml2p" => PROTOCOL }
52
+ root = response_doc.add_element "saml2p:LogoutResponse", { "xmlns:saml2p" => PROTOCOL }
50
53
  root.attributes['ID'] = uuid
51
54
  root.attributes['IssueInstant'] = time
52
55
  root.attributes['Version'] = "2.0"
@@ -68,44 +71,56 @@ module Ciam
68
71
  }
69
72
  issuer.text = @settings.issuer
70
73
  end
71
- meta = Metadata.new( @settings )
72
- Logging.debug "Created LogoutResponse:\n#{@response}"
73
- return meta.create_slo_response( to_s, opt[:extra_parameters] )
74
+
75
+ response_doc << REXML::XMLDecl.new("1.0", "UTF-8")
76
+ #sign logout_response
77
+ cert = @settings.get_cert(@settings.sp_cert)
78
+
79
+ # embed signature
80
+ if @settings.metadata_signed && @settings.sp_private_key && @settings.sp_cert
81
+ private_key = @settings.get_sp_key
82
+ response_doc.sign_document(private_key, cert)
83
+ end
74
84
 
75
- #root.attributes['Destination'] = action
85
+ Logging.debug "Created LogoutResponse:\n #{response_doc}"
76
86
 
87
+ return request_doc.to_s
88
+
77
89
  end
90
+
78
91
  # function to return the created request as an XML document
79
92
  def to_xml
80
93
  text = ""
81
94
  @response.write(text, 1)
82
95
  return text
83
96
  end
97
+
84
98
  def to_s
85
99
  @response.to_s
86
100
  end
87
101
 
88
- def issuer
89
- element = REXML::XPath.first(@response, "/p:LogoutResponse/a:Issuer", {
90
- "p" => PROTOCOL, "a" => ASSERTION} )
91
- return nil if element.nil?
92
- element.text
93
- end
102
+ def issuer
103
+ element = REXML::XPath.first(@response, "/p:LogoutResponse/a:Issuer", {
104
+ "p" => PROTOCOL, "a" => ASSERTION} )
105
+ return nil if element.nil?
106
+ element.text
107
+ end
94
108
 
95
- def in_response_to
109
+ def in_response_to
96
110
  element = REXML::XPath.first(@response, "/p:LogoutResponse", {
97
111
  "p" => PROTOCOL })
98
112
  return nil if element.nil?
99
- element.attributes["InResponseTo"]
100
- end
113
+ element.attributes["InResponseTo"]
114
+ end
101
115
 
102
- def success?
116
+ def success?
103
117
  element = REXML::XPath.first(@response, "/p:LogoutResponse/p:Status/p:StatusCode", {
104
118
  "p" => PROTOCOL })
105
119
  return false if element.nil?
106
- element.attributes["Value"] == "urn:oasis:names:tc:SAML:2.0:status:Success"
107
-
108
- end
120
+ element.attributes["Value"] == "urn:oasis:names:tc:SAML:2.0:status:Success"
121
+
122
+ end
123
+
109
124
  def is_valid?
110
125
  validate(soft = true)
111
126
  end
@@ -113,6 +128,7 @@ module Ciam
113
128
  def validate!
114
129
  validate( soft = false )
115
130
  end
131
+
116
132
  def validate( soft = true )
117
133
  return false if @response.nil?
118
134
  # Skip validation with a failed response if we don't have settings
@@ -123,10 +139,12 @@ module Ciam
123
139
 
124
140
  end
125
141
 
126
- protected
142
+ protected
143
+
127
144
  def document
128
145
  REXML::Document.new(@response)
129
146
  end
130
- end
147
+
148
+ end
131
149
  end
132
150
  end
@@ -30,18 +30,10 @@ module Ciam
30
30
  def generate(settings)
31
31
  #meta_doc = REXML::Document.new
32
32
  meta_doc = Ciam::XMLSecurityNew::Document.new
33
- if settings.aggregato
34
- root = meta_doc.add_element "md:EntityDescriptor", {
35
- "xmlns:md" => "urn:oasis:names:tc:SAML:2.0:metadata",
36
- "xmlns:xml" => "http://www.w3.org/XML/1998/namespace",
37
- "xmlns:ciam" => "https://ciam.gov.it/saml-extensions",
38
- }
39
- else
40
- root = meta_doc.add_element "md:EntityDescriptor", {
33
+ root = meta_doc.add_element "md:EntityDescriptor", {
41
34
  "xmlns:md" => "urn:oasis:names:tc:SAML:2.0:metadata",
42
35
  "xmlns:xml" => "http://www.w3.org/XML/1998/namespace"
43
36
  }
44
- end
45
37
 
46
38
  if settings.issuer != nil
47
39
  root.attributes["entityID"] = settings.issuer
@@ -223,53 +215,12 @@ module Ciam
223
215
  "xml:lang" => "it"
224
216
  }
225
217
 
226
- org_display_name.text = settings.organization['org_display_name']+(settings.aggregato ? " tramite #{settings.hash_aggregatore['soggetto_aggregatore']}" : '')
218
+ org_display_name.text = settings.organization['org_display_name']
227
219
  org_url = organization.add_element "md:OrganizationURL", {
228
220
  "xml:lang" => "it"
229
221
  }
230
222
  org_url.text = settings.organization['org_url']
231
223
 
232
- #ContactPerson per sp aggregato
233
- if settings.aggregato
234
- contact_person_aggregatore = root.add_element "md:ContactPerson", {
235
- "contactType" => "other",
236
- "ciam:entityType" => "ciam:aggregator"
237
- }
238
- company = contact_person_aggregatore.add_element "md:Company"
239
- company.text = settings.hash_aggregatore['soggetto_aggregatore']
240
-
241
- extensions_aggregatore = contact_person_aggregatore.add_element "md:Extensions"
242
- vat_number_aggregatore = extensions_aggregatore.add_element "ciam:VATNumber"
243
- vat_number_aggregatore.text = settings.hash_aggregatore['piva_aggregatore']
244
-
245
- ipa_code_aggregatore = extensions_aggregatore.add_element "ciam:IPACode"
246
- ipa_code_aggregatore.text = settings.hash_aggregatore['cipa_aggregatore']
247
-
248
- fiscal_code_aggregatore = extensions_aggregatore.add_element "ciam:FiscalCode"
249
- fiscal_code_aggregatore.text = settings.hash_aggregatore['cf_aggregatore']
250
-
251
- contact_person_aggregato = root.add_element "md:ContactPerson", {
252
- "contactType" => "other",
253
- "ciam:entityType" => "ciam:aggregated"
254
- }
255
- company = contact_person_aggregato.add_element "md:Company"
256
- company.text = settings.organization['org_name']
257
-
258
- extensions_aggregato = contact_person_aggregato.add_element "md:Extensions"
259
- unless settings.hash_aggregatore['soggetto_aggregato']['vat_number'].blank?
260
- vat_number_aggregato = extensions_aggregato.add_element "ciam:VATNumber"
261
- vat_number_aggregato.text = settings.hash_aggregatore['soggetto_aggregato']['vat_number']
262
- end
263
- unless settings.hash_aggregatore['soggetto_aggregato']['ipa_code'].blank?
264
- ipa_code_aggregato = extensions_aggregato.add_element "ciam:IPACode"
265
- ipa_code_aggregato.text = settings.hash_aggregatore['soggetto_aggregato']['ipa_code']
266
- end
267
- unless settings.hash_aggregatore['soggetto_aggregato']['fiscal_code'].blank?
268
- fiscal_code_aggregato = extensions_aggregato.add_element "ciam:FiscalCode"
269
- fiscal_code_aggregato.text = settings.hash_aggregatore['soggetto_aggregato']['fiscal_code']
270
- end
271
- end
272
-
273
224
  #meta_doc << REXML::XMLDecl.new(version='1.0', encoding='UTF-8')
274
225
  meta_doc << REXML::XMLDecl.new("1.0", "UTF-8")
275
226
 
@@ -98,8 +98,13 @@ module Ciam
98
98
  parse_time(node, "SessionNotOnOrAfter")
99
99
  end
100
100
  end
101
-
102
101
 
102
+ def session_index
103
+ @session_index ||= begin
104
+ node = REXML::XPath.first(document, "/p:Response/a:Assertion/a:AuthnStatement", { "p" => PROTOCOL, "a" => ASSERTION })
105
+ node.attributes["SessionIndex"] unless node.blank?
106
+ end
107
+ end
103
108
 
104
109
  # Checks the status of the response for a "Success" code
105
110
  def success?
@@ -166,12 +171,6 @@ module Ciam
166
171
 
167
172
  }
168
173
 
169
- issuer_assertion_nodes.each{ |iss|
170
- #controllo: L'attributo Format di Issuer deve essere presente con il valore urn:oasis:names:tc:SAML:2.0:nameid-format:entity
171
- return (soft ? false : validation_error("Elemento Issuer non ha formato corretto ")) if iss.attributes['Format'] != 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity'
172
-
173
- }
174
-
175
174
  nodes = issuer_response_nodes + issuer_assertion_nodes
176
175
 
177
176
  nodes.map { |node| Utils.element_text(node) }.compact.uniq
@@ -10,7 +10,7 @@ module Ciam
10
10
  attr_accessor :name_identifier_value, :name_identifier_format
11
11
  attr_accessor :sessionindex, :issuer, :destination_service_url, :authn_context, :requester_identificator
12
12
  attr_accessor :single_logout_service_url, :single_logout_service_binding, :single_logout_destination
13
- attr_accessor :skip_validation, :aggregato, :hash_aggregatore
13
+ attr_accessor :skip_validation
14
14
 
15
15
  def initialize(config = {})
16
16
  config.each do |k,v|
@@ -1,5 +1,5 @@
1
1
  module Ciam
2
2
  module Saml
3
- VERSION = '0.6.0'
3
+ VERSION = '0.7.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ciam-es
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabiano Pavan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-31 00:00:00.000000000 Z
11
+ date: 2020-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: canonix
@@ -138,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
138
  - !ruby/object:Gem::Version
139
139
  version: '0'
140
140
  requirements: []
141
- rubygems_version: 3.0.6
141
+ rubygems_version: 3.0.8
142
142
  signing_key:
143
143
  specification_version: 4
144
144
  summary: SAML Ruby Tookit CIAM