ciam-es 0.0.1 → 0.0.6

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: 4e95196cb69850d66b4ad960fcf279885cb600448b39548e22b627998da49363
4
- data.tar.gz: 53895057eaafde1db9a846ca1f885219348bdeb0dcaffffb29c39c74e78bd20c
3
+ metadata.gz: 3dad8a3cc1881093b5b571a3a6ff5ef017a580efd63eabe3a40551c365b2ed06
4
+ data.tar.gz: a5f904d9fb491a5fa3e916f81ff3a85b86f93536fb32546e35605ca09a3b3530
5
5
  SHA512:
6
- metadata.gz: 12312ab615271d5e7213a49528de7a286ffd3a103bdd7cf4ff810c2f146fe5bd7fba0bb10df24a37a7c9d3c74be0c875d43fdaaa3e05bead86c1366545278918
7
- data.tar.gz: 2f46ce928a88d79369d7b22d8ef29f4490b0a6a8c600c2927b511e539d8b62a189c3c81ff56a3276b965d907d2f0ea78890c28594c9a71a98c092fd6a5749f85
6
+ metadata.gz: f15050be6418bf31b9b680e16de3646cd987d5142db14a9a07656e62b2916d0dd21c891d594cbf8ded5a288ab03162126480318c5fa0cc130ccc1483e03bfd48
7
+ data.tar.gz: 5e49de6e43c66d2823efc1a472be655edca69deebec364d595aea1577eedd203ed272846ab76e252474502f28addd9b3dcc36949a8e51478aa8a6b46dff02a02
@@ -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.1'
5
+ s.version = '0.0.6'
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"]
@@ -19,5 +19,5 @@ Gem::Specification.new do |s|
19
19
  s.add_runtime_dependency("canonix", ["0.1.1"])
20
20
  s.add_runtime_dependency("uuid", ["~> 2.3"])
21
21
  s.add_runtime_dependency("nokogiri", '>= 1.6.7.2')
22
- s.add_runtime_dependency("addressable", ["2.7.0"])
22
+ s.add_runtime_dependency("addressable", [">= 2.4.0"])
23
23
  end
@@ -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
@@ -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|
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.1
4
+ version: 0.0.6
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-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: canonix
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: addressable
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 2.7.0
61
+ version: 2.4.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 2.7.0
68
+ version: 2.4.0
69
69
  description: 'SAML toolkit for Ruby programs to integrate with CIAM Milano '
70
70
  email: fabiano.pavan@soluzionipa.it
71
71
  executables: []
@@ -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