saml-kit 0.2.4 → 0.2.5
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/lib/saml/kit.rb +1 -0
- data/lib/saml/kit/assertion.rb +33 -5
- data/lib/saml/kit/bindings/url_builder.rb +1 -1
- data/lib/saml/kit/buildable.rb +4 -0
- data/lib/saml/kit/builders/xml_signature.rb +1 -1
- data/lib/saml/kit/certificate.rb +2 -2
- data/lib/saml/kit/document.rb +2 -1
- data/lib/saml/kit/locales/en.yml +2 -1
- data/lib/saml/kit/metadata.rb +2 -1
- data/lib/saml/kit/response.rb +7 -32
- data/lib/saml/kit/signature.rb +12 -11
- data/lib/saml/kit/signatures.rb +20 -1
- data/lib/saml/kit/templatable.rb +5 -1
- data/lib/saml/kit/translatable.rb +9 -0
- data/lib/saml/kit/trustable.rb +7 -12
- data/lib/saml/kit/version.rb +1 -1
- data/lib/saml/kit/xml_decryption.rb +1 -1
- data/lib/saml/kit/xsd_validatable.rb +0 -4
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b98601350af83c7090bc7fead240f7fabb4736f642a262502a96c48e533f3203
|
4
|
+
data.tar.gz: a51e398301b1115654dbe0a8a31bf61b029456c12302bb42512b7dac716d38e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d032fb605d2c62e45e491ddde0e90274f3ae0ddab82c7e4daa72cfcc7c992483abcd5151399c67d7205bcb0de2ebe1fb1e1953fe416c9efac333e1dba86ab56
|
7
|
+
data.tar.gz: d330dc2cc0a7dfd9d7fb29e9ec9da4b9549739160f77bc6de73f1d6bd9ca15851faa595a3ccf7a75064479751b81123beaf4fb0dd6b31f5f193fbc4fd0ce182e
|
data/lib/saml/kit.rb
CHANGED
data/lib/saml/kit/assertion.rb
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
module Saml
|
2
2
|
module Kit
|
3
3
|
class Assertion
|
4
|
+
include ActiveModel::Validations
|
5
|
+
include Translatable
|
6
|
+
|
7
|
+
validate :must_match_issuer
|
8
|
+
validate :must_be_active_session
|
9
|
+
attr_reader :name
|
10
|
+
|
4
11
|
def initialize(xml_hash, configuration:)
|
12
|
+
@name = "Assertion"
|
5
13
|
@xml_hash = xml_hash
|
6
14
|
@configuration = configuration
|
7
15
|
end
|
@@ -11,7 +19,20 @@ module Saml
|
|
11
19
|
end
|
12
20
|
|
13
21
|
def signed?
|
14
|
-
|
22
|
+
signature.present?
|
23
|
+
end
|
24
|
+
|
25
|
+
def signature
|
26
|
+
xml_hash = assertion.fetch('Signature', nil)
|
27
|
+
xml_hash ? Signature.new(xml_hash) : nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def expired?
|
31
|
+
Time.current > expired_at
|
32
|
+
end
|
33
|
+
|
34
|
+
def active?
|
35
|
+
Time.current > started_at && !expired?
|
15
36
|
end
|
16
37
|
|
17
38
|
def attributes
|
@@ -35,10 +56,6 @@ module Saml
|
|
35
56
|
parse_date(assertion.fetch('Conditions', {}).fetch('NotOnOrAfter', nil))
|
36
57
|
end
|
37
58
|
|
38
|
-
def certificate
|
39
|
-
assertion.fetch('Signature', {}).fetch('KeyInfo', {}).fetch('X509Data', {}).fetch('X509Certificate', nil)
|
40
|
-
end
|
41
|
-
|
42
59
|
def audiences
|
43
60
|
Array(assertion['Conditions']['AudienceRestriction']['Audience'])
|
44
61
|
rescue => error
|
@@ -68,6 +85,17 @@ module Saml
|
|
68
85
|
Saml::Kit.logger.error(error)
|
69
86
|
Time.at(0).to_datetime
|
70
87
|
end
|
88
|
+
|
89
|
+
def must_match_issuer
|
90
|
+
unless audiences.include?(@configuration.issuer)
|
91
|
+
errors[:audience] << error_message(:must_match_issuer)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def must_be_active_session
|
96
|
+
return if active?
|
97
|
+
errors[:base] << error_message(:expired)
|
98
|
+
end
|
71
99
|
end
|
72
100
|
end
|
73
101
|
end
|
@@ -21,7 +21,7 @@ module Saml
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def signature_for(payload)
|
24
|
-
private_key = configuration.private_keys(use: :signing).
|
24
|
+
private_key = configuration.private_keys(use: :signing).last
|
25
25
|
encode(private_key.sign(OpenSSL::Digest::SHA256.new, payload))
|
26
26
|
end
|
27
27
|
|
data/lib/saml/kit/buildable.rb
CHANGED
@@ -24,7 +24,7 @@ module Saml
|
|
24
24
|
def initialize(reference_id, configuration:)
|
25
25
|
@configuration = configuration
|
26
26
|
@reference_id = reference_id
|
27
|
-
@x509_certificate = configuration.certificates(use: :signing).
|
27
|
+
@x509_certificate = configuration.certificates(use: :signing).last.stripped
|
28
28
|
end
|
29
29
|
|
30
30
|
def signature_method
|
data/lib/saml/kit/certificate.rb
CHANGED
data/lib/saml/kit/document.rb
CHANGED
@@ -2,8 +2,9 @@ module Saml
|
|
2
2
|
module Kit
|
3
3
|
class Document
|
4
4
|
PROTOCOL_XSD = File.expand_path("./xsd/saml-schema-protocol-2.0.xsd", File.dirname(__FILE__)).freeze
|
5
|
-
include XsdValidatable
|
6
5
|
include ActiveModel::Validations
|
6
|
+
include XsdValidatable
|
7
|
+
include Translatable
|
7
8
|
include Trustable
|
8
9
|
include Buildable
|
9
10
|
validates_presence_of :content
|
data/lib/saml/kit/locales/en.yml
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
en:
|
3
3
|
saml/kit:
|
4
4
|
errors:
|
5
|
+
Assertion:
|
6
|
+
expired: "must not be expired."
|
5
7
|
AuthnRequest:
|
6
8
|
invalid: "must contain AuthnRequest."
|
7
9
|
invalid_fingerprint: "does not match."
|
@@ -17,7 +19,6 @@ en:
|
|
17
19
|
LogoutResponse:
|
18
20
|
unregistered: "is unregistered."
|
19
21
|
Response:
|
20
|
-
expired: "must not be expired."
|
21
22
|
invalid: "must contain Response."
|
22
23
|
invalid_fingerprint: "does not match."
|
23
24
|
invalid_response_to: "must match request id."
|
data/lib/saml/kit/metadata.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module Saml
|
2
2
|
module Kit
|
3
3
|
class Metadata
|
4
|
+
METADATA_XSD = File.expand_path("./xsd/saml-schema-metadata-2.0.xsd", File.dirname(__FILE__)).freeze
|
4
5
|
include ActiveModel::Validations
|
5
6
|
include XsdValidatable
|
7
|
+
include Translatable
|
6
8
|
include Buildable
|
7
|
-
METADATA_XSD = File.expand_path("./xsd/saml-schema-metadata-2.0.xsd", File.dirname(__FILE__)).freeze
|
8
9
|
|
9
10
|
validates_presence_of :metadata
|
10
11
|
validate :must_contain_descriptor
|
data/lib/saml/kit/response.rb
CHANGED
@@ -4,50 +4,25 @@ module Saml
|
|
4
4
|
include Respondable
|
5
5
|
extend Forwardable
|
6
6
|
|
7
|
-
def_delegators :assertion, :name_id, :[], :attributes
|
7
|
+
def_delegators :assertion, :name_id, :[], :attributes
|
8
8
|
|
9
|
-
validate :
|
10
|
-
validate :must_match_issuer
|
9
|
+
validate :must_be_valid_assertion
|
11
10
|
|
12
11
|
def initialize(xml, request_id: nil, configuration: Saml::Kit.configuration)
|
13
12
|
@request_id = request_id
|
14
13
|
super(xml, name: "Response", configuration: configuration)
|
15
14
|
end
|
16
15
|
|
17
|
-
def expired?
|
18
|
-
Time.current > expired_at
|
19
|
-
end
|
20
|
-
|
21
|
-
def active?
|
22
|
-
Time.current > started_at && !expired?
|
23
|
-
end
|
24
|
-
|
25
16
|
def assertion
|
26
|
-
@assertion
|
27
|
-
end
|
28
|
-
|
29
|
-
def signed?
|
30
|
-
super || assertion.signed?
|
31
|
-
end
|
32
|
-
|
33
|
-
def certificate
|
34
|
-
super || assertion.certificate
|
17
|
+
@assertion ||= Saml::Kit::Assertion.new(to_h, configuration: @configuration)
|
35
18
|
end
|
36
19
|
|
37
20
|
private
|
38
21
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def must_match_issuer
|
46
|
-
return unless expected_type?
|
47
|
-
return unless success?
|
48
|
-
|
49
|
-
unless audiences.include?(configuration.issuer)
|
50
|
-
errors[:audience] << error_message(:must_match_issuer)
|
22
|
+
def must_be_valid_assertion
|
23
|
+
assertion.valid?
|
24
|
+
assertion.errors.each do |attribute, error|
|
25
|
+
self.errors[attribute] << error
|
51
26
|
end
|
52
27
|
end
|
53
28
|
|
data/lib/saml/kit/signature.rb
CHANGED
@@ -1,22 +1,23 @@
|
|
1
1
|
module Saml
|
2
2
|
module Kit
|
3
3
|
class Signature
|
4
|
-
|
5
|
-
|
4
|
+
def initialize(xml_hash)
|
5
|
+
@xml_hash = xml_hash
|
6
|
+
end
|
6
7
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
8
|
+
def certificate
|
9
|
+
value = to_h.fetch('KeyInfo', {}).fetch('X509Data', {}).fetch('X509Certificate', nil)
|
10
|
+
return if value.nil?
|
11
|
+
Saml::Kit::Certificate.new(value, use: :signing)
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
13
|
-
|
14
|
+
def trusted?(metadata)
|
15
|
+
return false if metadata.nil?
|
16
|
+
metadata.matches?(certificate.fingerprint, use: :signing)
|
14
17
|
end
|
15
18
|
|
16
|
-
def
|
17
|
-
|
18
|
-
yield xml, new(xml, signatures)
|
19
|
-
signatures.complete(xml.target!)
|
19
|
+
def to_h
|
20
|
+
@xml_hash
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
data/lib/saml/kit/signatures.rb
CHANGED
@@ -14,9 +14,28 @@ module Saml
|
|
14
14
|
|
15
15
|
def complete(raw_xml)
|
16
16
|
return raw_xml unless configuration.sign?
|
17
|
-
private_key = configuration.private_keys(use: :signing).
|
17
|
+
private_key = configuration.private_keys(use: :signing).last
|
18
18
|
Xmldsig::SignedDocument.new(raw_xml).sign(private_key)
|
19
19
|
end
|
20
|
+
|
21
|
+
def self.sign(xml: ::Builder::XmlMarkup.new, configuration: Saml::Kit.configuration)
|
22
|
+
signatures = Saml::Kit::Signatures.new(configuration: configuration)
|
23
|
+
yield xml, XmlSignatureTemplate.new(xml, signatures)
|
24
|
+
signatures.complete(xml.target!)
|
25
|
+
end
|
26
|
+
|
27
|
+
class XmlSignatureTemplate
|
28
|
+
attr_reader :signatures, :xml
|
29
|
+
|
30
|
+
def initialize(xml, signatures)
|
31
|
+
@signatures = signatures
|
32
|
+
@xml = xml
|
33
|
+
end
|
34
|
+
|
35
|
+
def template(reference_id)
|
36
|
+
Template.new(signatures.build(reference_id)).to_xml(xml: xml)
|
37
|
+
end
|
38
|
+
end
|
20
39
|
end
|
21
40
|
end
|
22
41
|
end
|
data/lib/saml/kit/templatable.rb
CHANGED
@@ -21,7 +21,7 @@ module Saml
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def encryption_for(xml:)
|
24
|
-
if encrypt
|
24
|
+
if encrypt?
|
25
25
|
temp = ::Builder::XmlMarkup.new
|
26
26
|
yield temp
|
27
27
|
xml_encryption = Saml::Kit::Builders::XmlEncryption.new(temp.target!, encryption_certificate.public_key)
|
@@ -31,6 +31,10 @@ module Saml
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
def encrypt?
|
35
|
+
encrypt && encryption_certificate
|
36
|
+
end
|
37
|
+
|
34
38
|
def render(model, options)
|
35
39
|
Saml::Kit::Template.new(model).to_xml(options)
|
36
40
|
end
|
data/lib/saml/kit/trustable.rb
CHANGED
@@ -9,24 +9,18 @@ module Saml
|
|
9
9
|
validate :must_be_trusted, unless: :signature_manually_verified
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
to_h.fetch(name, {}).fetch('Signature', {}).fetch('KeyInfo', {}).fetch('X509Data', {}).fetch('X509Certificate', nil)
|
15
|
-
end
|
16
|
-
|
17
|
-
def fingerprint
|
18
|
-
return if certificate.blank?
|
19
|
-
Fingerprint.new(certificate)
|
12
|
+
def signed?
|
13
|
+
signature.present?
|
20
14
|
end
|
21
15
|
|
22
|
-
def
|
23
|
-
to_h.fetch(name, {}).fetch('Signature', nil)
|
16
|
+
def signature
|
17
|
+
xml_hash = to_h.fetch(name, {}).fetch('Signature', nil)
|
18
|
+
xml_hash ? Signature.new(xml_hash) : nil
|
24
19
|
end
|
25
20
|
|
26
21
|
def trusted?
|
27
|
-
return false if provider.nil?
|
28
22
|
return false unless signed?
|
29
|
-
|
23
|
+
signature.trusted?(provider)
|
30
24
|
end
|
31
25
|
|
32
26
|
def provider
|
@@ -59,6 +53,7 @@ module Saml
|
|
59
53
|
|
60
54
|
def must_be_trusted
|
61
55
|
return if trusted?
|
56
|
+
return if provider.present? && !signed?
|
62
57
|
errors[:fingerprint] << error_message(:invalid_fingerprint)
|
63
58
|
end
|
64
59
|
end
|
data/lib/saml/kit/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saml-kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mo khan
|
@@ -246,6 +246,7 @@ files:
|
|
246
246
|
- lib/saml/kit/signatures.rb
|
247
247
|
- lib/saml/kit/templatable.rb
|
248
248
|
- lib/saml/kit/template.rb
|
249
|
+
- lib/saml/kit/translatable.rb
|
249
250
|
- lib/saml/kit/trustable.rb
|
250
251
|
- lib/saml/kit/version.rb
|
251
252
|
- lib/saml/kit/xml.rb
|