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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a115dcdaeda82006ef3ffa4203bf6d4635d0a15e8b435f39429516f7cc931e7
4
- data.tar.gz: bcb065ec6ea653a8745680ef8805bb756deef2410d56aa91ce9b24a51673b851
3
+ metadata.gz: 2f0ea1fc4ad96eb6348fdeec0d727966d6ed6c10673805c00753c14e07c8a32e
4
+ data.tar.gz: 272888b9072bfd42f7cc714d26c27f0548210d62ddf452797d6b25c8ebc81108
5
5
  SHA512:
6
- metadata.gz: c731db6ddea64286e5543a07aee532eedaad1d0df79ca9b7b03555ba5e34864a17fa6ed9f81dc35ed21e7526acf41b6847e2476164edd147468008935f136772
7
- data.tar.gz: 813bd1abdc555ce0d54c9376d06d7b3e31e0908296ec343691e4ef8f7a08c4fa8d04fc0fdec8d7f1d6ecd4b6b8918c7ac6c890291ace8adec4348b099d6090ad
6
+ metadata.gz: 7d0c70aa33cd6c31bee3f306394c6f3c22d1b939bd60d694c701d561e02977305ed931bee5aa815ebc9d00ab1b54ed290f4fb901337b232ebdb79948d95aaa83
7
+ data.tar.gz: b732ec284055e6f602601285cbb51f9db450f8b294217b57f491dcf0e5f8d5cc9037a3fcd5fc3ce80aa98856286db76ab71ecfb4328593b6ce003b5b007f184d
@@ -14,8 +14,16 @@ Metrics/BlockLength:
14
14
  Metrics/LineLength:
15
15
  Exclude:
16
16
  - spid.gemspec
17
+ RSpec/DescribeClass:
18
+ Exclude:
19
+ - spec/integration/**/*.rb
20
+ RSpec/FilePath:
21
+ Exclude:
22
+ - spec/integration/**/*.rb
17
23
  RSpec/NestedGroups:
18
24
  Enabled: false
25
+ RSpec/SubjectStub:
26
+ Enabled: false
19
27
  Style/EmptyMethod:
20
28
  EnforcedStyle: expanded
21
29
  Style/StringLiterals:
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.8.0]
6
+ ### Added
7
+ - Spid configuration singleton class
8
+
9
+ ### Changed
10
+ - Slo prefixed classes moved to Slo:: Namespace
11
+ - Sso prefixed classes moved to Sso:: Namespace
12
+ - Request and Response classes generate themselves setting objects
13
+
5
14
  ## [0.7.0] - 2018-07-18
6
15
  ### Added
7
16
  - SloResponse class in order to validate saml response
@@ -56,7 +65,8 @@
56
65
  - Coveralls Integration
57
66
  - Rubygems version badge in README
58
67
 
59
- [Unreleased]: https://github.com/italia/spid-ruby/compare/v0.7.0...HEAD
68
+ [Unreleased]: https://github.com/italia/spid-ruby/compare/v0.8.0...HEAD
69
+ [0.8.0]: https://github.com/italia/spid-ruby/compare/v0.7.0...v0.8.0
60
70
  [0.7.0]: https://github.com/italia/spid-ruby/compare/v0.6.0...v0.7.0
61
71
  [0.6.0]: https://github.com/italia/spid-ruby/compare/v0.5.0...v0.6.0
62
72
  [0.5.0]: https://github.com/italia/spid-ruby/compare/v0.4.0...v0.5.0
data/README.md CHANGED
@@ -6,7 +6,7 @@ Ruby library for SPID authentication
6
6
  | Project | Spid Ruby |
7
7
  | ---------------------- | ------------ |
8
8
  | Gem name | spid |
9
- | License | [MIT](https://github.com/italia/spid-ruby/blob/master/LICENSE) |
9
+ | License | [BSD 3](https://github.com/italia/spid-ruby/blob/master/LICENSE) |
10
10
  | Version | [![Gem Version](https://badge.fury.io/rb/spid.svg)](http://badge.fury.io/rb/spid) |
11
11
  | Continuous integration | [![Build Status](https://secure.travis-ci.org/italia/spid-ruby.svg?branch=master)](https://travis-ci.org/italia/spid-ruby) |
12
12
  | 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) |
@@ -2,18 +2,14 @@
2
2
 
3
3
  require "spid/authn_request"
4
4
  require "spid/logout_request"
5
- require "spid/sso_request"
6
- require "spid/sso_response"
7
- require "spid/slo_request"
8
- require "spid/slo_response"
9
- require "spid/identity_providers"
5
+ require "spid/sso"
6
+ require "spid/slo"
10
7
  require "spid/metadata"
11
- require "spid/idp_metadata"
12
8
  require "spid/version"
13
- require "spid/identity_provider_configuration"
14
- require "spid/service_provider_configuration"
15
- require "spid/sso_settings"
16
- require "spid/slo_settings"
9
+ require "spid/configuration"
10
+ require "spid/identity_provider"
11
+ require "spid/service_provider"
12
+ require "spid/identity_provider_manager"
17
13
 
18
14
  module Spid # :nodoc:
19
15
  class UnknownAuthnComparisonMethodError < StandardError; end
@@ -22,13 +18,13 @@ module Spid # :nodoc:
22
18
  class UnknownSignatureMethodError < StandardError; end
23
19
 
24
20
  EXACT_COMPARISON = :exact
25
- MININUM_COMPARISON = :minumum
21
+ MINIMUM_COMPARISON = :minumum
26
22
  BETTER_COMPARISON = :better
27
23
  MAXIMUM_COMPARISON = :maximum
28
24
 
29
25
  COMPARISON_METHODS = [
30
26
  EXACT_COMPARISON,
31
- MININUM_COMPARISON,
27
+ MINIMUM_COMPARISON,
32
28
  BETTER_COMPARISON,
33
29
  MAXIMUM_COMPARISON
34
30
  ].freeze
@@ -62,4 +58,20 @@ module Spid # :nodoc:
62
58
  L2,
63
59
  L3
64
60
  ].freeze
61
+
62
+ class << self
63
+ attr_writer :configuration
64
+ end
65
+
66
+ def self.configuration
67
+ @configuration ||= Configuration.new
68
+ end
69
+
70
+ def self.reset_configuration!
71
+ @configuration = Configuration.new
72
+ end
73
+
74
+ def self.configure
75
+ yield configuration
76
+ end
65
77
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spid
4
+ class Configuration # :nodoc:
5
+ attr_accessor :idp_metadata_dir_path
6
+ attr_accessor :hostname
7
+ attr_accessor :metadata_path
8
+ attr_accessor :start_sso_path
9
+ attr_accessor :start_slo_path
10
+ attr_accessor :acs_path
11
+ attr_accessor :slo_path
12
+ attr_accessor :digest_method
13
+ attr_accessor :signature_method
14
+ attr_accessor :private_key
15
+ attr_accessor :certificate
16
+ attr_accessor :attribute_service_name
17
+
18
+ # rubocop:disable Metrics/MethodLength
19
+ def initialize
20
+ @idp_metadata_dir_path = "idp_metadata"
21
+ @metadata_path = "/spid/metadata"
22
+ @start_sso_path = "/spid/login"
23
+ @start_slo_path = "/spid/logout"
24
+ @acs_path = "/spid/sso"
25
+ @slo_path = "/spid/slo"
26
+ @digest_method = Spid::SHA256
27
+ @signature_method = Spid::RSA_SHA256
28
+ @attribute_service_name = attribute_service_name
29
+ @hostname = nil
30
+ @private_key = nil
31
+ @certificate = nil
32
+ end
33
+ # rubocop:enable Metrics/MethodLength
34
+
35
+ # rubocop:disable Metrics/MethodLength
36
+ def service_provider
37
+ @service_provider ||=
38
+ begin
39
+ Spid::ServiceProvider.new(
40
+ host: hostname,
41
+ acs_path: acs_path,
42
+ slo_path: slo_path,
43
+ metadata_path: metadata_path,
44
+ private_key: private_key,
45
+ certificate: certificate,
46
+ digest_method: digest_method,
47
+ signature_method: signature_method,
48
+ attribute_service_name: attribute_service_name
49
+ )
50
+ end
51
+ end
52
+ # rubocop:enable Metrics/MethodLength
53
+ end
54
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "onelogin/ruby-saml/idp_metadata_parser"
4
+
5
+ module Spid
6
+ class IdentityProvider # :nodoc:
7
+ attr_reader :name,
8
+ :entity_id,
9
+ :sso_target_url,
10
+ :slo_target_url,
11
+ :cert_fingerprint
12
+
13
+ def initialize(
14
+ name:,
15
+ entity_id:,
16
+ sso_target_url:,
17
+ slo_target_url:,
18
+ cert_fingerprint:
19
+ )
20
+ @name = name
21
+ @entity_id = entity_id
22
+ @sso_target_url = sso_target_url
23
+ @slo_target_url = slo_target_url
24
+ @cert_fingerprint = cert_fingerprint
25
+ end
26
+
27
+ def sso_attributes
28
+ @sso_attributes ||=
29
+ begin
30
+ {
31
+ idp_sso_target_url: sso_target_url,
32
+ idp_cert_fingerprint: cert_fingerprint
33
+ }
34
+ end
35
+ end
36
+
37
+ def slo_attributes
38
+ @slo_attributes ||=
39
+ begin
40
+ {
41
+ idp_slo_target_url: slo_target_url,
42
+ idp_name_qualifier: entity_id,
43
+ idp_cert_fingerprint: cert_fingerprint
44
+ }
45
+ end
46
+ end
47
+
48
+ def self.parse_from_xml(name:, metadata:)
49
+ idp_metadata_parser = ::OneLogin::RubySaml::IdpMetadataParser.new
50
+ idp_settings = idp_metadata_parser.parse_to_hash(metadata)
51
+ new(
52
+ name: name,
53
+ entity_id: idp_settings[:idp_entity_id],
54
+ sso_target_url: idp_settings[:idp_sso_target_url],
55
+ slo_target_url: idp_settings[:idp_slo_target_url],
56
+ cert_fingerprint: idp_settings[:idp_cert_fingerprint]
57
+ )
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spid
4
+ class IdentityProviderManager # :nodoc:
5
+ include Singleton
6
+
7
+ def identity_providers
8
+ @identity_providers ||=
9
+ begin
10
+ Dir.chdir(Spid.configuration.idp_metadata_dir_path) do
11
+ Dir.glob("*.xml").map do |metadata_filepath|
12
+ generate_identity_provider_from_file(
13
+ File.expand_path(metadata_filepath)
14
+ )
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def self.find_by_name(idp_name)
21
+ instance.identity_providers.find do |idp|
22
+ idp.name == idp_name
23
+ end
24
+ end
25
+
26
+ def self.find_by_entity(entity_id)
27
+ instance.identity_providers.find do |idp|
28
+ idp.entity_id == entity_id
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def generate_identity_provider_from_file(metadata_filepath)
35
+ idp_name = File.basename(metadata_filepath, "-metadata.xml")
36
+ metadata = File.read(metadata_filepath)
37
+ IdentityProvider.parse_from_xml(
38
+ metadata: metadata,
39
+ name: idp_name
40
+ )
41
+ end
42
+ end
43
+ end
@@ -5,19 +5,13 @@ require "onelogin/ruby-saml/settings"
5
5
 
6
6
  module Spid
7
7
  class Metadata # :nodoc:
8
- attr_reader :metadata_attributes,
9
- :service_provider_configuration,
10
- :attribute_service_name
8
+ attr_reader :metadata_attributes
11
9
 
12
10
  # rubocop:disable Metrics/MethodLength
13
11
  def initialize(
14
- service_provider_configuration:,
15
- attribute_service_name:,
16
12
  digest_method: Spid::SHA256,
17
13
  signature_method: Spid::RSA_SHA256
18
14
  )
19
- @service_provider_configuration = service_provider_configuration
20
- @attribute_service_name = attribute_service_name
21
15
  @metadata_attributes = {
22
16
  issuer: issuer,
23
17
  private_key: private_key_content,
@@ -45,23 +39,31 @@ module Spid
45
39
  end
46
40
 
47
41
  def issuer
48
- service_provider_configuration.host
42
+ service_provider.host
49
43
  end
50
44
 
51
45
  def private_key_content
52
- service_provider_configuration.private_key
46
+ service_provider.private_key
53
47
  end
54
48
 
55
49
  def certificate_content
56
- service_provider_configuration.certificate
50
+ service_provider.certificate
57
51
  end
58
52
 
59
53
  def assertion_consumer_service_url
60
- service_provider_configuration.sso_url
54
+ service_provider.acs_url
61
55
  end
62
56
 
63
57
  def single_logout_service_url
64
- service_provider_configuration.slo_url
58
+ service_provider.slo_url
59
+ end
60
+
61
+ def attribute_service_name
62
+ service_provider.attribute_service_name
63
+ end
64
+
65
+ def service_provider
66
+ @service_provider ||= Spid.configuration.service_provider
65
67
  end
66
68
 
67
69
  private
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+
5
+ module Spid
6
+ class ServiceProvider # :nodoc:
7
+ attr_reader :host,
8
+ :acs_path,
9
+ :slo_path,
10
+ :metadata_path,
11
+ :private_key,
12
+ :certificate,
13
+ :digest_method,
14
+ :signature_method,
15
+ :attribute_service_name
16
+
17
+ # rubocop:disable Metrics/ParameterLists
18
+ def initialize(
19
+ host:,
20
+ acs_path:,
21
+ slo_path:,
22
+ metadata_path:,
23
+ private_key:,
24
+ certificate:,
25
+ digest_method:,
26
+ signature_method:,
27
+ attribute_service_name:
28
+ )
29
+ @host = host
30
+ @acs_path = acs_path
31
+ @slo_path = slo_path
32
+ @metadata_path = metadata_path
33
+ @private_key = private_key
34
+ @certificate = certificate
35
+ @digest_method = digest_method
36
+ @signature_method = signature_method
37
+ @attribute_service_name = attribute_service_name
38
+ validate_attributes
39
+ end
40
+ # rubocop:enable Metrics/ParameterLists
41
+
42
+ def acs_url
43
+ @acs_url ||= URI.join(host, acs_path).to_s
44
+ end
45
+
46
+ def slo_url
47
+ @slo_url ||= URI.join(host, slo_path).to_s
48
+ end
49
+
50
+ def metadata_url
51
+ @metadata_url ||= URI.join(host, metadata_path).to_s
52
+ end
53
+
54
+ # rubocop:disable Metrics/MethodLength
55
+ def sso_attributes
56
+ @sso_attributes ||=
57
+ begin
58
+ {
59
+ assertion_consumer_service_url: acs_url,
60
+ issuer: host,
61
+ private_key: private_key,
62
+ certificate: certificate,
63
+ security: {
64
+ authn_requests_signed: true,
65
+ embed_sign: true,
66
+ digest_method: digest_method,
67
+ signature_method: signature_method
68
+ }
69
+ }
70
+ end
71
+ end
72
+ # rubocop:enable Metrics/MethodLength
73
+
74
+ # rubocop:disable Metrics/MethodLength
75
+ def slo_attributes
76
+ @slo_attributes ||=
77
+ begin
78
+ {
79
+ issuer: host,
80
+ private_key: private_key,
81
+ certificate: certificate,
82
+ security: {
83
+ logout_requests_signed: true,
84
+ embed_sign: true,
85
+ digest_method: digest_method,
86
+ signature_method: signature_method
87
+ }
88
+ }
89
+ end
90
+ end
91
+ # rubocop:enable Metrics/MethodLength
92
+
93
+ private
94
+
95
+ def validate_attributes
96
+ if !DIGEST_METHODS.include?(digest_method)
97
+ raise UnknownDigestMethodError,
98
+ "Provided digest method is not valid:" \
99
+ " use one of #{DIGEST_METHODS.join(', ')}"
100
+ elsif !SIGNATURE_METHODS.include?(signature_method)
101
+ raise UnknownSignatureMethodError,
102
+ "Provided digest method is not valid:" \
103
+ " use one of #{SIGNATURE_METHODS.join(', ')}"
104
+ end
105
+ end
106
+ end
107
+ end