spid 0.7.0 → 0.8.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.
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spid
4
- class IdentityProviderConfiguration # :nodoc:
5
- attr_reader :idp_metadata, :idp_metadata_hash
6
-
7
- def initialize(idp_metadata:)
8
- @idp_metadata = idp_metadata
9
- @idp_metadata_hash = idp_metadata_parser.parse_to_hash(idp_metadata)
10
- end
11
-
12
- def entity_id
13
- @entity_id ||= idp_metadata_hash[:idp_entity_id]
14
- end
15
-
16
- def sso_target_url
17
- @sso_target_url ||= idp_metadata_hash[:idp_sso_target_url]
18
- end
19
-
20
- def slo_target_url
21
- @slo_target_url ||= idp_metadata_hash[:idp_slo_target_url]
22
- end
23
-
24
- def cert_fingerprint
25
- @cert_fingerprint ||= idp_metadata_hash[:idp_cert_fingerprint]
26
- end
27
-
28
- private
29
-
30
- def idp_metadata_parser
31
- @idp_metadata_parser ||= ::OneLogin::RubySaml::IdpMetadataParser.new
32
- end
33
- end
34
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "faraday"
4
- require "faraday_middleware"
5
-
6
- module Spid
7
- class IdentityProviders # :nodoc:
8
- class MetadataFetchError < StandardError; end
9
-
10
- def self.fetch_all
11
- new.fetch_all
12
- end
13
-
14
- def fetch_all
15
- spid_idp_entities.map do |idp|
16
- metadata_url = check_for_final_metadata_url(idp["metadata_url"])
17
- {
18
- name: idp["entity_name"].gsub(/ ID$/, "").downcase,
19
- metadata_url: metadata_url,
20
- entity_id: idp["entity_id"]
21
- }
22
- end
23
- end
24
-
25
- private
26
-
27
- def check_for_final_metadata_url(metadata_url)
28
- response = Faraday.get(metadata_url)
29
- case response.status
30
- when 200
31
- metadata_url
32
- when 301, 302
33
- response["Location"]
34
- end
35
- end
36
-
37
- def spid_idp_entities
38
- return [] if response.body["spidFederationRegistry"].nil?
39
- response.body["spidFederationRegistry"]["entities"]
40
- end
41
-
42
- def response
43
- connection.get do |req|
44
- req.url "/api/identity-providers"
45
- req.headers["Accept"] = "application/json"
46
- end
47
- end
48
-
49
- def connection
50
- Faraday.new("https://registry.spid.gov.it") do |conn|
51
- conn.response :json, content_type: /\bjson$/
52
-
53
- conn.adapter Faraday.default_adapter
54
- end
55
- end
56
- end
57
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "singleton"
4
- require "onelogin/ruby-saml/idp_metadata_parser"
5
-
6
- module Spid
7
- class IdpMetadata # :nodoc:
8
- include Singleton
9
-
10
- def initialize
11
- @identity_providers = Spid::IdentityProviders.fetch_all
12
- @metadata = {}
13
- end
14
-
15
- def [](idp_name)
16
- return @metadata[idp_name] unless @metadata[idp_name].nil?
17
- idp_hash = identity_provider_hash(idp_name)
18
-
19
- @metadata[idp_name] = parser.parse_remote_to_hash(
20
- idp_hash[:metadata_url],
21
- idp_hash[:metadata_url].start_with?("https://")
22
- )
23
- @metadata[idp_name]
24
- end
25
-
26
- def identity_provider_hash(idp_name)
27
- @identity_providers.find do |idp|
28
- idp[:name] == idp_name.to_s
29
- end
30
- end
31
-
32
- private
33
-
34
- def parser
35
- @parser ||= ::OneLogin::RubySaml::IdpMetadataParser.new
36
- end
37
- end
38
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "uri"
4
-
5
- module Spid
6
- class ServiceProviderConfiguration # :nodoc:
7
- attr_reader :host,
8
- :sso_path,
9
- :slo_path,
10
- :metadata_path,
11
- :private_key_file_path,
12
- :certificate_file_path,
13
- :digest_method,
14
- :signature_method
15
-
16
- # rubocop:disable Metrics/ParameterLists
17
- def initialize(
18
- host:,
19
- sso_path:,
20
- slo_path:,
21
- metadata_path:,
22
- private_key_file_path:,
23
- certificate_file_path:,
24
- digest_method:,
25
- signature_method:
26
- )
27
- @host = host
28
- @sso_path = sso_path
29
- @slo_path = slo_path
30
- @metadata_path = metadata_path
31
- @private_key_file_path = private_key_file_path
32
- @certificate_file_path = certificate_file_path
33
- @digest_method = digest_method
34
- @signature_method = signature_method
35
- validate_attributes
36
- end
37
- # rubocop:enable Metrics/ParameterLists
38
-
39
- def sso_url
40
- @sso_url ||= URI.join(host, sso_path).to_s
41
- end
42
-
43
- def slo_url
44
- @slo_url ||= URI.join(host, slo_path).to_s
45
- end
46
-
47
- def metadata_url
48
- @metadata_url ||= URI.join(host, metadata_path).to_s
49
- end
50
-
51
- def private_key
52
- @private_key ||= File.read(private_key_file_path)
53
- end
54
-
55
- def certificate
56
- @certificate ||= File.read(certificate_file_path)
57
- end
58
-
59
- private
60
-
61
- def validate_attributes
62
- if !DIGEST_METHODS.include?(digest_method)
63
- raise UnknownDigestMethodError,
64
- "Provided digest method is not valid:" \
65
- " use one of #{DIGEST_METHODS.join(', ')}"
66
- elsif !SIGNATURE_METHODS.include?(signature_method)
67
- raise UnknownSignatureMethodError,
68
- "Provided digest method is not valid:" \
69
- " use one of #{SIGNATURE_METHODS.join(', ')}"
70
- end
71
- end
72
- end
73
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spid/logout_request"
4
- require "onelogin/ruby-saml/settings"
5
-
6
- module Spid
7
- class SloRequest # :nodoc:
8
- attr_reader :slo_settings
9
-
10
- def initialize(slo_settings:)
11
- @slo_settings = slo_settings
12
- end
13
-
14
- def to_saml
15
- logout_request.create(slo_settings)
16
- end
17
-
18
- private
19
-
20
- def logout_request
21
- LogoutRequest.new
22
- end
23
- end
24
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "onelogin/ruby-saml/logoutresponse"
4
-
5
- module Spid
6
- class SloResponse # :nodoc:
7
- attr_reader :body, :slo_settings
8
-
9
- def initialize(body:, slo_settings:)
10
- @body = body
11
- @slo_settings = slo_settings
12
- end
13
-
14
- def valid?
15
- saml_response.validate
16
- end
17
-
18
- private
19
-
20
- def saml_response
21
- @saml_response ||= ::OneLogin::RubySaml::Logoutresponse.new(
22
- body,
23
- slo_settings
24
- )
25
- end
26
- end
27
- end
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "onelogin/ruby-saml/settings"
4
-
5
- module Spid
6
- class SloSettings < ::OneLogin::RubySaml::Settings # :nodoc:
7
- attr_reader :service_provider_configuration,
8
- :identity_provider_configuration,
9
- :session_index
10
-
11
- def initialize(
12
- service_provider_configuration:,
13
- identity_provider_configuration:,
14
- session_index:
15
- )
16
- @service_provider_configuration = service_provider_configuration
17
- @identity_provider_configuration = identity_provider_configuration
18
- @session_index = session_index
19
-
20
- super(slo_attributes)
21
- end
22
-
23
- # rubocop:disable Metrics/MethodLength
24
- # rubocop:disable Metrics/AbcSize
25
- def slo_attributes
26
- return @slo_attributes if @slo_attributes.present?
27
- @slo_attributes = {
28
- idp_slo_target_url: identity_provider_configuration.slo_target_url,
29
- issuer: service_provider_configuration.host,
30
- idp_name_qualifier: identity_provider_configuration.entity_id,
31
- name_identifier_value: generated_name_identifier_value,
32
- name_identifier_format: name_identifier_format_value,
33
- private_key: service_provider_configuration.private_key,
34
- certificate: service_provider_configuration.certificate,
35
- idp_cert_fingerprint: identity_provider_configuration.cert_fingerprint,
36
- sessionindex: session_index,
37
- security: {
38
- logout_requests_signed: true,
39
- embed_sign: true,
40
- digest_method: service_provider_configuration.digest_method,
41
- signature_method: service_provider_configuration.signature_method
42
- }
43
- }
44
- @slo_attributes
45
- end
46
- # rubocop:enable Metrics/AbcSize
47
- # rubocop:enable Metrics/MethodLength
48
-
49
- private
50
-
51
- def generated_name_identifier_value
52
- ::OneLogin::RubySaml::Utils.uuid
53
- end
54
-
55
- def name_identifier_format_value
56
- "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
57
- end
58
- end
59
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spid/authn_request"
4
- require "onelogin/ruby-saml/settings"
5
-
6
- module Spid
7
- class SsoRequest # :nodoc:
8
- attr_reader :sso_settings
9
-
10
- def initialize(sso_settings:)
11
- @sso_settings = sso_settings
12
- end
13
-
14
- def to_saml
15
- authn_request.create(sso_settings)
16
- end
17
-
18
- private
19
-
20
- def authn_request
21
- AuthnRequest.new
22
- end
23
- end
24
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "onelogin/ruby-saml/response"
4
- require "active_support/inflector/methods"
5
-
6
- module Spid
7
- class SsoResponse # :nodoc:
8
- attr_reader :body, :sso_settings
9
-
10
- def initialize(body:, sso_settings:)
11
- @body = body
12
- @sso_settings = sso_settings
13
- end
14
-
15
- def valid?
16
- saml_response.is_valid?
17
- end
18
-
19
- def attributes
20
- raw_attributes.each_with_object({}) do |(key, value), acc|
21
- acc[normalize_key(key)] = value
22
- end
23
- end
24
-
25
- def session_index
26
- saml_response.sessionindex
27
- end
28
-
29
- def raw_attributes
30
- saml_response.attributes.attributes
31
- end
32
-
33
- private
34
-
35
- def normalize_key(key)
36
- ActiveSupport::Inflector.underscore(
37
- key.to_s
38
- ).to_sym
39
- end
40
-
41
- def saml_response
42
- @saml_response ||= ::OneLogin::RubySaml::Response.new(
43
- body,
44
- settings: sso_settings
45
- )
46
- end
47
- end
48
- end
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spid
4
- class SsoSettings < ::OneLogin::RubySaml::Settings # :nodoc:
5
- attr_reader :service_provider_configuration,
6
- :identity_provider_configuration,
7
- :authn_context,
8
- :authn_context_comparison
9
-
10
- # rubocop:disable Metrics/MethodLength
11
- def initialize(
12
- service_provider_configuration:,
13
- identity_provider_configuration:,
14
- authn_context: Spid::L1,
15
- authn_context_comparison: Spid::EXACT_COMPARISON
16
- )
17
-
18
- unless AUTHN_CONTEXTS.include?(authn_context)
19
- raise Spid::UnknownAuthnContextError,
20
- "Provided authn_context is not valid:" \
21
- " use one of #{AUTHN_CONTEXTS.join(', ')}"
22
- end
23
-
24
- unless COMPARISON_METHODS.include?(authn_context_comparison)
25
- raise Spid::UnknownAuthnComparisonMethodError,
26
- "Provided authn_context_comparison_method is not valid:" \
27
- " use one of #{COMPARISON_METHODS.join(', ')}"
28
- end
29
-
30
- @service_provider_configuration = service_provider_configuration
31
- @identity_provider_configuration = identity_provider_configuration
32
- @authn_context = authn_context
33
- @authn_context_comparison = authn_context_comparison
34
-
35
- super(sso_attributes)
36
- end
37
- # rubocop:enable Metrics/MethodLength
38
-
39
- # rubocop:disable Metrics/MethodLength
40
- # rubocop:disable Metrics/AbcSize
41
- def sso_attributes
42
- return @sso_attributes if @sso_attributes.present?
43
- @sso_attributes = {
44
- idp_sso_target_url: identity_provider_configuration.sso_target_url,
45
- assertion_consumer_service_url: service_provider_configuration.sso_url,
46
- protocol_binding: protocol_binding_value,
47
- issuer: service_provider_configuration.host,
48
- private_key: service_provider_configuration.private_key,
49
- certificate: service_provider_configuration.certificate,
50
- name_identifier_format: name_identifier_format_value,
51
- authn_context: authn_context,
52
- authn_context_comparison: authn_context_comparison,
53
- idp_cert_fingerprint: identity_provider_configuration.cert_fingerprint,
54
- security: {
55
- authn_requests_signed: true,
56
- embed_sign: true,
57
- digest_method: service_provider_configuration.digest_method,
58
- signature_method: service_provider_configuration.signature_method
59
- }
60
- }
61
- @sso_attributes[:force_authn] = true if authn_context > Spid::L1
62
- @sso_attributes
63
- end
64
- # rubocop:enable Metrics/AbcSize
65
- # rubocop:enable Metrics/MethodLength
66
-
67
- private
68
-
69
- def protocol_binding_value
70
- "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
71
- end
72
-
73
- def name_identifier_format_value
74
- "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
75
- end
76
- end
77
- end