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 +4 -4
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +11 -1
- data/README.md +1 -1
- data/lib/spid.rb +24 -12
- data/lib/spid/configuration.rb +54 -0
- data/lib/spid/identity_provider.rb +60 -0
- data/lib/spid/identity_provider_manager.rb +43 -0
- data/lib/spid/metadata.rb +14 -12
- data/lib/spid/service_provider.rb +107 -0
- data/lib/spid/slo.rb +10 -0
- data/lib/spid/slo/request.rb +50 -0
- data/lib/spid/slo/response.rb +72 -0
- data/lib/spid/slo/settings.rb +53 -0
- data/lib/spid/sso.rb +10 -0
- data/lib/spid/sso/request.rb +53 -0
- data/lib/spid/sso/response.rb +80 -0
- data/lib/spid/sso/settings.rb +78 -0
- data/lib/spid/version.rb +1 -1
- metadata +14 -12
- data/lib/spid/identity_provider_configuration.rb +0 -34
- data/lib/spid/identity_providers.rb +0 -57
- data/lib/spid/idp_metadata.rb +0 -38
- data/lib/spid/service_provider_configuration.rb +0 -73
- data/lib/spid/slo_request.rb +0 -24
- data/lib/spid/slo_response.rb +0 -27
- data/lib/spid/slo_settings.rb +0 -59
- data/lib/spid/sso_request.rb +0 -24
- data/lib/spid/sso_response.rb +0 -48
- data/lib/spid/sso_settings.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f0ea1fc4ad96eb6348fdeec0d727966d6ed6c10673805c00753c14e07c8a32e
|
4
|
+
data.tar.gz: 272888b9072bfd42f7cc714d26c27f0548210d62ddf452797d6b25c8ebc81108
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d0c70aa33cd6c31bee3f306394c6f3c22d1b939bd60d694c701d561e02977305ed931bee5aa815ebc9d00ab1b54ed290f4fb901337b232ebdb79948d95aaa83
|
7
|
+
data.tar.gz: b732ec284055e6f602601285cbb51f9db450f8b294217b57f491dcf0e5f8d5cc9037a3fcd5fc3ce80aa98856286db76ab71ecfb4328593b6ce003b5b007f184d
|
data/.rubocop.yml
CHANGED
@@ -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:
|
data/CHANGELOG.md
CHANGED
@@ -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.
|
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 | [
|
9
|
+
| License | [BSD 3](https://github.com/italia/spid-ruby/blob/master/LICENSE) |
|
10
10
|
| Version | [](http://badge.fury.io/rb/spid) |
|
11
11
|
| Continuous integration | [](https://travis-ci.org/italia/spid-ruby) |
|
12
12
|
| Test coverate | [](https://coveralls.io/github/italia/spid-ruby?branch=master) |
|
data/lib/spid.rb
CHANGED
@@ -2,18 +2,14 @@
|
|
2
2
|
|
3
3
|
require "spid/authn_request"
|
4
4
|
require "spid/logout_request"
|
5
|
-
require "spid/
|
6
|
-
require "spid/
|
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/
|
14
|
-
require "spid/
|
15
|
-
require "spid/
|
16
|
-
require "spid/
|
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
|
-
|
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
|
-
|
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
|
data/lib/spid/metadata.rb
CHANGED
@@ -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
|
-
|
42
|
+
service_provider.host
|
49
43
|
end
|
50
44
|
|
51
45
|
def private_key_content
|
52
|
-
|
46
|
+
service_provider.private_key
|
53
47
|
end
|
54
48
|
|
55
49
|
def certificate_content
|
56
|
-
|
50
|
+
service_provider.certificate
|
57
51
|
end
|
58
52
|
|
59
53
|
def assertion_consumer_service_url
|
60
|
-
|
54
|
+
service_provider.acs_url
|
61
55
|
end
|
62
56
|
|
63
57
|
def single_logout_service_url
|
64
|
-
|
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
|