spid 0.15.2 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4866af87e0c8823162483e64a14afda3d325d3791c69f5e7678c9fdc2f29c65d
4
- data.tar.gz: e437a860f4dc46efddb947ce55982c2b0d1b3bc09831d3298f537b574ae99274
3
+ metadata.gz: 7ba07f30c0e0a0f5a7e810dd65f1fa640c7c44be9821d80d3e66aa9beacd96f3
4
+ data.tar.gz: 51bdce6a6796d79c084ae3c0c4ef590fee8fa09407282a083730d851f20087a4
5
5
  SHA512:
6
- metadata.gz: ef442a357be9ddb4781dad1a90addce249db283e1f9fa38890d24da8b22e176b81bdfe16c59cf4e18f3dfb192888479e1d911db33064a58b34795cb611b65fe7
7
- data.tar.gz: 586d5a07cc351d555fd42d03857e4f8f803ef58e3c4334cbc9cdbfc84a242079c6216b69e05defea9cf34516230c97c49dff16439eb06c1729bbde8c1b0982c2
6
+ metadata.gz: 0e9bb862aa5e52e2bc9322a599f1f52905b0bfc91ac754aed5962134eeab1f4f87db3146e43a7788f5e46c34d73c0d9697c61d3e49eab81d30bd934f3f59ec11
7
+ data.tar.gz: 75f930de84a75db8ea97e7651a96a6116bd2e29b8e3903e39c24d98074c952d6936700a08267605a747f97956d703acab408db4ec5875bfea98cb8b4cf1ae3db
data/.rubocop.yml CHANGED
@@ -12,6 +12,7 @@ Metrics/BlockLength:
12
12
  Exclude:
13
13
  - spec/**/*.rb
14
14
  - spid.gemspec
15
+ - lib/**/*.rake
15
16
  Metrics/LineLength:
16
17
  Exclude:
17
18
  - spid.gemspec
data/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.16.0] - 2018-09-05
6
+ ### Added
7
+ - Task rake for IdPs metadata fetching
8
+ - Rails installer
9
+
5
10
  ## [0.15.2] - 2018-08-31
6
11
  ### Fixed
7
12
  - Now response doesn't fail if status code is not success
@@ -118,7 +123,8 @@
118
123
  - Coveralls Integration
119
124
  - Rubygems version badge in README
120
125
 
121
- [Unreleased]: https://github.com/italia/spid-ruby/compare/v0.15.2...HEAD
126
+ [Unreleased]: https://github.com/italia/spid-ruby/compare/v0.16.0...HEAD
127
+ [0.16.0]: https://github.com/italia/spid-ruby/compare/v0.15.2...v0.16.0
122
128
  [0.15.2]: https://github.com/italia/spid-ruby/compare/v0.15.1...v0.15.2
123
129
  [0.15.1]: https://github.com/italia/spid-ruby/compare/v0.15.0...v0.15.1
124
130
  [0.15.0]: https://github.com/italia/spid-ruby/compare/v0.14.0...v0.15.0
data/README.md CHANGED
@@ -1,8 +1,5 @@
1
1
  # spid-ruby
2
2
 
3
- Ruby library for SPID authentication
4
-
5
-
6
3
  | Project | Spid Ruby |
7
4
  | ---------------------- | ------------ |
8
5
  | Gem name | spid |
@@ -12,14 +9,103 @@ Ruby library for SPID authentication
12
9
  | Test coverate | [![Coverage Status](https://coveralls.io/repos/github/italia/spid-ruby/badge.svg?branch=master)](https://coveralls.io/github/italia/spid-ruby?branch=master) |
13
10
  | Credits | [Contributors](https://github.com/italia/spid-ruby/graphs/contributors) |
14
11
 
15
- ## Installation
16
-
17
- Add into your Gemfile
12
+ ## Installazione & Configurazione
18
13
 
14
+ ### Installazione
15
+ Aggiungi al tuo Gemfile
19
16
  ```ruby
20
17
  gem "spid"
21
18
  ```
19
+ ed esegui nel terminale
20
+ ```bash
21
+ $ bundle install
22
+ ```
23
+
24
+ ### Configurazione
25
+ A questo punto è necessario aggiungere il middleware `Spid::Rack` nello stack dell'applicazione, avendo cura di inserirlo **dopo** un middleware per la gestione della sessione, ad esempio `Rack::Session::Cookie`
26
+
27
+ ```ruby
28
+ use Rack::Session::Cookie
29
+ use Spid::Rack
30
+ ```
31
+
32
+ E configurare il parametri spid tramite il seguente codice
33
+ ```ruby
34
+ Spid.configure do |config|
35
+ #config ...
36
+ end
37
+ ```
38
+ tramite il quale potete accedere alle seguenti configurazioni:
39
+
40
+ |Nome|valore default||Obbligatorio?|
41
+ |:---|:---|:---|:---|
42
+ |config.hostname||Hostname dell'applicazione, che verrà utilizzato come entity_id del service provider|✓|
43
+ |config.idp_metadata_dir_path||Directory dove si troveranno copia dei metadata degli Identity Provider del sistema SPID|✓|
44
+ |config.private_key_pem||Chiave privata del Service Provider in rappresentazione pem|✓|
45
+ |config.certificate_pem||Certificato X509 del Service Provider in rappresentazione pem|✓|
46
+ |config.attribute_services||Array degli attribute service indexes richiesti dal Service Provider all'Identity Provider (vedi sotto)|✓|
47
+ |config.metadata_path|`/spid/metadata`|Path per la fornitura del metadata del Service Provider||
48
+ |config.login_path|`/spid/login`|Path per la generazione ed invio dell'AuthnRequest all'Identity Provider||
49
+ |config.acs_path|`/spid/sso`|Path per la ricezione dell'Assertion di autenticazione||
50
+ |config.logout_path|`/spid/logout`|Path per la generazione ed invio della LogoutRequest all'Identity Provider||
51
+ |config.slo_path|`/spid/slo`|Path per la ricezione dell'Assertion di chiusura della sessione||
52
+ |config.default_relay_state_path|`/`|Indirizzo di ritorno dopo aver ricevuto un Assertion||
53
+ |config.digest_method|Spid::SHA256|Algoritmo utilizzato per la generazione del digest per le firme||
54
+ |config.signature_method|Spid::RSA_SHA256|Algoritmo utilizzato per la generazione della signature XML||
55
+ |config.acs_binding|Spid::BINDINGS_HTTP_POST|Binding method utilizzato per la ricezione dell'Assertion di autenticazione||
56
+ |config.slo_binding|Spid::BINDINGS_HTTP_REDIRECT|Binding method utilizzato ler la ricezione dell'Assertion di chiusura della sessione||
57
+
58
+ #### Attribute Services
59
+ Il protocollo SPID prevede la possibilità di specificare almeno un servizio di attributi. Ogni servizio ha un nome e un elenco di attributi richiesti.
60
+
61
+ Per configurare dei servizi bisogna utilizzare questa configurazione
62
+ ```ruby
63
+ Spid.configure do |config|
64
+ ...
65
+ config.attribute_services = [
66
+ { name: "Service 1 name", fields: [ elenco_attributi_servizio_1 ] },
67
+ { name: "Service 2 name", fields: [ elenco_attributi_servizio_2] }
68
+ ]
69
+ ```
70
+ Gli attributi disponibili sono
71
+ ```
72
+ :spid_code, :name, :family_name, :place_of_birth, :date_of_birth, :gender, :company_name, :registered_office, :fiscal_number, :iva_code, :id_card, :mobile_phone, :email, :address, :digital_address
73
+ ```
74
+ ### Scaricamento metadata degli Identity Providers
75
+ Per motivi di sicurezza il sistema SPID prevede che un Service Provider abbia una copia 'sicura' dei metadata degli Identity Providers.
76
+
77
+ Al fine di facilitarne lo scaricamento la gemma `spid-ruby` prevede un task rake che li installa nella directory `config.idp_metadata_dir_path`.
78
+
79
+ A questo punto è possibile lanciare
80
+
81
+ ```bash
82
+ $ rake spid:fetch_idp_metadata
83
+ ```
84
+
85
+ #### Sinatra
86
+ Occorre modificare il `Rakefile` dell'applicazione aggiungendo
87
+ ```ruby
88
+ # qui è necessario caricare preventivamente la configurazione SPID
89
+ # require "sinatra-app.rb"
90
+ require "spid/tasks"
91
+ ```
92
+
93
+ ## Funzionamento
94
+ ### Login
95
+
96
+ Per iniziare un login con SPID è necessario utilizzare un url in questo formato `/spid/login?idp_name=posteid&relay_state=/path/to/return&attribute_index=0`, dove
97
+
98
+ * **/spid/login**: è il path configurato nel parametro `config.login_path`
99
+ * **idp_name**: rappresenta l'identificativo dell'Identity Provider con cui si vuole autenticarsi
100
+ * **relay_state**: rappresenta l'url dove deve essere fatto il redirect a seguito della ricezione della response di autenticazione
101
+ * **attribute_index**: rappresenta l'indice del servizio di attributi che vogliano vengano forniti dall'Identity Provider in caso di autenticazione riuscita
102
+
103
+ ### Logout
104
+ Per iniziare un logout con SPID l'url da utilizzare è `/spid/logout?idp_name=posteid&relay_state=/path/to/return`, dove
22
105
 
106
+ * **/spid/logout**: è il path configurato nel parametro `config.logout_path`
107
+ * **idp_name**: rappresenta l'identificativo dell'Identity Provider dove vogliamo terminare la sessione di autenticazione
108
+ * **relay_state**: rappresenta l'url dove deve essere fatto il redirect a seguito della ricezione della response di logout
23
109
 
24
110
  ## Features
25
111
 
@@ -15,8 +15,8 @@ module Spid
15
15
  attr_accessor :acs_binding
16
16
  attr_accessor :slo_binding
17
17
  attr_accessor :attribute_services
18
- attr_writer :private_key
19
- attr_writer :certificate
18
+ attr_accessor :private_key_pem
19
+ attr_accessor :certificate_pem
20
20
 
21
21
  def initialize
22
22
  @idp_metadata_dir_path = "idp_metadata"
@@ -53,11 +53,13 @@ module Spid
53
53
  end
54
54
 
55
55
  def certificate
56
- OpenSSL::X509::Certificate.new(@certificate) unless @certificate.nil?
56
+ return nil if certificate_pem.nil?
57
+ @certificate ||= OpenSSL::X509::Certificate.new(certificate_pem)
57
58
  end
58
59
 
59
60
  def private_key
60
- OpenSSL::PKey::RSA.new(@private_key) unless @private_key.nil?
61
+ return nil if private_key_pem.nil?
62
+ @private_key ||= OpenSSL::PKey::RSA.new(private_key_pem)
61
63
  end
62
64
 
63
65
  def service_provider
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spid
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base # :nodoc:
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ def code_that_runs
9
+ copy_file "spid.rb", "config/initializers/spid.rb"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ Spid.configure do |config|
4
+ config.hostname = ENV.fetch("HOST")
5
+
6
+ config.idp_metadata_dir_path = Rails.root.join("config/idp_metadata")
7
+ config.private_key_pem = ENV.fetch("PRIVATE_KEY")
8
+ config.certificate_pem = ENV.fetch("CERTIFICATE")
9
+
10
+ config.metadata_path = "/spid/metadata"
11
+ config.start_sso_path = "/spid/login"
12
+ config.start_slo_path = "/spid/logout"
13
+ config.acs_path = "/spid/sso"
14
+ config.slo_path = "/spid/slo"
15
+ config.default_relay_state_path = "/"
16
+
17
+ config.digest_method = Spid::SHA512
18
+ config.signature_method = Spid::RSA_SHA512
19
+ config.acs_binding = Spid::BINDINGS_HTTP_POST
20
+ config.slo_binding = Spid::BINDINGS_HTTP_REDIRECT
21
+ config.attribute_services = [
22
+ { name: "Service1", fields: ["email"] }
23
+ ]
24
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "spid/generators/install_generator"
5
+
6
+ module Spid
7
+ module Generators # :nodoc:
8
+ end
9
+ end
data/lib/spid/rack/sso.rb CHANGED
@@ -34,10 +34,14 @@ module Spid
34
34
  session["attributes"] = responser.attributes
35
35
  session["session_index"] = responser.session_index
36
36
  session.delete("sso_request_uuid")
37
+ session.delete("errors")
37
38
  end
38
39
 
39
40
  def store_session_failure
40
41
  session["errors"] = responser.errors
42
+ session.delete("attributes")
43
+ session.delete("sso_request_uuid")
44
+ session.delete("session_index")
41
45
  end
42
46
 
43
47
  def response
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spid/generators"
4
+
5
+ module Spid
6
+ class Railtie < ::Rails::Railtie # :nodoc:
7
+ rake_tasks do |_app|
8
+ require "spid/tasks"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "net/http"
5
+
6
+ module Spid
7
+ class SynchronizeIdpMetadata # :nodoc:
8
+ def initialize
9
+ FileUtils.mkdir_p(Spid.configuration.idp_metadata_dir_path)
10
+ end
11
+
12
+ def call
13
+ idp_list.map do |name, url|
14
+ metadata_name = "#{name.delete(' ').downcase}-metadata.xml"
15
+ metadata = get_metadata_from_url(url)
16
+
17
+ File.open(metadata_path(metadata_name), "wb") { |f| f.write metadata }
18
+ end
19
+ end
20
+
21
+ def idp_list
22
+ metadata_list.each.with_object({}) do |(name, url), acc|
23
+ uri = URI(url)
24
+ res = Net::HTTP.get_response(uri)
25
+ acc[name] = if res.code == "302"
26
+ res["Location"]
27
+ else
28
+ url
29
+ end
30
+ end
31
+ end
32
+
33
+ def metadata_list
34
+ entities.each.with_object({}) do |entity, acc|
35
+ entity_name = entity["entity_name"]
36
+ entity_name = "SPIDItalia" if entity_name =~ /SPIDItalia/
37
+ acc[entity_name] = entity["metadata_url"]
38
+ end
39
+ end
40
+
41
+ def metadata_path(name)
42
+ File.join(
43
+ Spid.configuration.idp_metadata_dir_path,
44
+ name
45
+ )
46
+ end
47
+
48
+ def entities
49
+ return [] if idp_list_raw.nil?
50
+
51
+ JSON.parse(idp_list_raw)["spidFederationRegistry"]["entities"]
52
+ end
53
+
54
+ def get_metadata_from_url(url)
55
+ uri = URI(url)
56
+ req = Net::HTTP::Get.new(uri)
57
+
58
+ res = Net::HTTP.start(
59
+ uri.host, uri.port, use_ssl: uri.scheme == "https"
60
+ ) do |http|
61
+ http.request(req)
62
+ end
63
+
64
+ res.body
65
+ end
66
+
67
+ def idp_list_raw
68
+ uri = URI(registry_url)
69
+
70
+ req = Net::HTTP::Get.new(uri)
71
+ req["Accept"] = "application/json"
72
+
73
+ res = Net::HTTP.start(
74
+ uri.host, uri.port, use_ssl: uri.scheme == "https"
75
+ ) do |http|
76
+ http.request(req)
77
+ end
78
+
79
+ res.body
80
+ end
81
+
82
+ def registry_url
83
+ "https://registry.spid.gov.it/api/identity-providers"
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :spid do
4
+ task :certificate do
5
+ Rake::Task["environment"].invoke if defined?(Rails)
6
+
7
+ if File.exist?(Spid.configuration.certificate_path) &&
8
+ File.exist?(Spid.configuration.private_key_path)
9
+ puts "A certificate and a private key already exists!"
10
+ exit
11
+ end
12
+
13
+ private_key = OpenSSL::PKey::RSA.new(4096)
14
+ public_key = private_key.public_key
15
+
16
+ subject = {}
17
+
18
+ print "Insert the certificate Country (default IT): "
19
+ subject[:C] = $stdin.gets.chomp
20
+ subject[:C] = "IT" if subject[:C] == ""
21
+
22
+ print "Insert the Organization name: "
23
+ subject[:O] = $stdin.gets.chomp
24
+
25
+ print "Insert the Organization Unit name: "
26
+ subject[:OU] = $stdin.gets.chomp
27
+
28
+ print "Insert the Common Name: "
29
+ subject[:CN] = $stdin.gets.chomp
30
+
31
+ print "Insert the Domain Component: "
32
+ subject[:DC] = $stdin.gets.chomp
33
+
34
+ print "Insert the State or Province name: "
35
+ subject[:ST] = $stdin.gets.chomp
36
+
37
+ subject = subject.map do |key, value|
38
+ "/#{key}=#{value}" if !value.nil? && value != ""
39
+ end.join
40
+
41
+ certificate = OpenSSL::X509::Certificate.new
42
+ name = OpenSSL::X509::Name.parse(subject)
43
+ certificate.issuer = certificate.subject = name
44
+ certificate.not_before = Time.now
45
+ certificate.not_after = Time.now + (30 * 365 * 24 * 60 * 60)
46
+ certificate.public_key = public_key
47
+ certificate.serial = 0x0
48
+ certificate.version = 2
49
+
50
+ certificate.sign private_key, OpenSSL::Digest::SHA512.new
51
+
52
+ File.open(Spid.configuration.certificate_path, "w") do |f|
53
+ f.write certificate.to_pem
54
+ end
55
+
56
+ File.open(Spid.configuration.private_key_path, "w") do |f|
57
+ f.write private_key.to_pem
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spid/synchronize_idp_metadata"
4
+
5
+ namespace :spid do
6
+ desc "Synchronize IDP metadata"
7
+ task :fetch_idp_metadata do
8
+ Rake::Task["environment"].invoke if defined?(Rails)
9
+ Spid::SynchronizeIdpMetadata.new.call
10
+ end
11
+ end
data/lib/spid/tasks.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rake"
4
+
5
+ ["fetch_idp_metadata", "certificate"].each do |task|
6
+ load "spid/tasks/#{task}.rake"
7
+ end
data/lib/spid/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spid
4
- VERSION = "0.15.2"
4
+ VERSION = "0.16.0"
5
5
  end
data/lib/spid.rb CHANGED
@@ -8,6 +8,8 @@ require "spid/metadata"
8
8
  require "spid/version"
9
9
  require "spid/configuration"
10
10
  require "spid/identity_provider_manager"
11
+ require "spid/synchronize_idp_metadata"
12
+ require "spid/railtie" if defined?(Rails)
11
13
 
12
14
  module Spid # :nodoc:
13
15
  class UnknownAuthnComparisonMethodError < StandardError; end
data/spid.gemspec CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_runtime_dependency "activesupport", ">= 3.0.0", "< 5.3"
28
28
  spec.add_runtime_dependency "rack", ">= 1", "< 3"
29
+ spec.add_runtime_dependency "rake", ">= 10.0", "< 13"
29
30
  spec.add_runtime_dependency "xmldsig", ">= 0.6.6"
30
31
 
31
32
  spec.add_development_dependency "bundler", "~> 1.16"
@@ -36,7 +37,6 @@ Gem::Specification.new do |spec|
36
37
  spec.add_development_dependency "nokogiri", "~> 1.8", ">= 1.8.3"
37
38
  spec.add_development_dependency "pry", "~> 0"
38
39
  spec.add_development_dependency "pry-doc", "~> 0"
39
- spec.add_development_dependency "rake", "~> 10.0"
40
40
  spec.add_development_dependency "rspec", "~> 3.0"
41
41
  spec.add_development_dependency "rubocop", "0.57.2"
42
42
  spec.add_development_dependency "rubocop-rspec", "1.27.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.2
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Librera
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-31 00:00:00.000000000 Z
11
+ date: 2018-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -50,6 +50,26 @@ dependencies:
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '3'
53
+ - !ruby/object:Gem::Dependency
54
+ name: rake
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '10.0'
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '13'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '10.0'
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '13'
53
73
  - !ruby/object:Gem::Dependency
54
74
  name: xmldsig
55
75
  requirement: !ruby/object:Gem::Requirement
@@ -182,20 +202,6 @@ dependencies:
182
202
  - - "~>"
183
203
  - !ruby/object:Gem::Version
184
204
  version: '0'
185
- - !ruby/object:Gem::Dependency
186
- name: rake
187
- requirement: !ruby/object:Gem::Requirement
188
- requirements:
189
- - - "~>"
190
- - !ruby/object:Gem::Version
191
- version: '10.0'
192
- type: :development
193
- prerelease: false
194
- version_requirements: !ruby/object:Gem::Requirement
195
- requirements:
196
- - - "~>"
197
- - !ruby/object:Gem::Version
198
- version: '10.0'
199
205
  - !ruby/object:Gem::Dependency
200
206
  name: rspec
201
207
  requirement: !ruby/object:Gem::Requirement
@@ -312,6 +318,9 @@ files:
312
318
  - idp_metadata/.gitkeep
313
319
  - lib/spid.rb
314
320
  - lib/spid/configuration.rb
321
+ - lib/spid/generators.rb
322
+ - lib/spid/generators/install_generator.rb
323
+ - lib/spid/generators/templates/spid.rb
315
324
  - lib/spid/identity_provider_manager.rb
316
325
  - lib/spid/metadata.rb
317
326
  - lib/spid/rack.rb
@@ -321,6 +330,7 @@ files:
321
330
  - lib/spid/rack/session.rb
322
331
  - lib/spid/rack/slo.rb
323
332
  - lib/spid/rack/sso.rb
333
+ - lib/spid/railtie.rb
324
334
  - lib/spid/saml2.rb
325
335
  - lib/spid/saml2/authn_request.rb
326
336
  - lib/spid/saml2/identity_provider.rb
@@ -345,6 +355,10 @@ files:
345
355
  - lib/spid/sso.rb
346
356
  - lib/spid/sso/request.rb
347
357
  - lib/spid/sso/response.rb
358
+ - lib/spid/synchronize_idp_metadata.rb
359
+ - lib/spid/tasks.rb
360
+ - lib/spid/tasks/certificate.rake
361
+ - lib/spid/tasks/fetch_idp_metadata.rake
348
362
  - lib/spid/version.rb
349
363
  - spid.gemspec
350
364
  homepage: https://github.com/italia/spid-ruby