saml-kit 1.0.14 → 1.0.15
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/Rakefile +8 -6
- data/lib/saml/kit.rb +4 -0
- data/lib/saml/kit/assertion.rb +13 -4
- data/lib/saml/kit/authentication_request.rb +4 -4
- data/lib/saml/kit/bindings.rb +3 -0
- data/lib/saml/kit/bindings/binding.rb +1 -0
- data/lib/saml/kit/bindings/http_post.rb +5 -0
- data/lib/saml/kit/bindings/http_redirect.rb +19 -14
- data/lib/saml/kit/bindings/url_builder.rb +8 -2
- data/lib/saml/kit/buildable.rb +3 -0
- data/lib/saml/kit/builders.rb +3 -0
- data/lib/saml/kit/builders/assertion.rb +1 -0
- data/lib/saml/kit/builders/encrypted_assertion.rb +1 -0
- data/lib/saml/kit/builders/metadata.rb +4 -4
- data/lib/saml/kit/builders/null.rb +13 -0
- data/lib/saml/kit/builders/response.rb +7 -2
- data/lib/saml/kit/builders/templates/null.builder +1 -0
- data/lib/saml/kit/builders/templates/response.builder +1 -0
- data/lib/saml/kit/composite_metadata.rb +8 -3
- data/lib/saml/kit/configuration.rb +5 -5
- data/lib/saml/kit/default_registry.rb +3 -0
- data/lib/saml/kit/document.rb +5 -4
- data/lib/saml/kit/identity_provider_metadata.rb +3 -3
- data/lib/saml/kit/invalid_document.rb +2 -0
- data/lib/saml/kit/logout_request.rb +2 -2
- data/lib/saml/kit/metadata.rb +7 -7
- data/lib/saml/kit/null_assertion.rb +3 -0
- data/lib/saml/kit/requestable.rb +4 -0
- data/lib/saml/kit/respondable.rb +8 -0
- data/lib/saml/kit/response.rb +2 -0
- data/lib/saml/kit/rspec/have_query_param.rb +1 -1
- data/lib/saml/kit/serializable.rb +1 -0
- data/lib/saml/kit/service_provider_metadata.rb +3 -0
- data/lib/saml/kit/signature.rb +11 -4
- data/lib/saml/kit/translatable.rb +3 -0
- data/lib/saml/kit/trustable.rb +3 -0
- data/lib/saml/kit/version.rb +1 -1
- data/lib/saml/kit/xml_templatable.rb +2 -0
- data/lib/saml/kit/xsd_validatable.rb +2 -0
- data/saml-kit.gemspec +1 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 589e2c267c9eef495616d9ecac88c78b2961baee78ae9d8fa404f566260b3c9c
|
4
|
+
data.tar.gz: f9bbb3af185e370d62ffab5182801a110b436e7c13b93997536f5856642abbd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4931f06f5fc42b83dd0cdcb27485cce1bb85dac1973a97a47be244b7bbcbda9b2ecf33cd7055c7e9f035a00f0d81840cf6e224c1a7d12834bc7d9901de7cc44
|
7
|
+
data.tar.gz: b60f4263ffe6fb7804d5a708dab81e9168b14435929a2c3ec0c338c76854b5e73694bab32b51ef95f84dbecdc231f20a6285a153e15e9346facbf860bb4276cd
|
data/Rakefile
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'bundler/audit/task'
|
3
4
|
require 'bundler/gem_tasks'
|
5
|
+
require 'reek/rake/task'
|
4
6
|
require 'rspec/core/rake_task'
|
7
|
+
require 'rubocop/rake_task'
|
5
8
|
|
6
9
|
RSpec::Core::RakeTask.new(:spec)
|
7
|
-
task default: :spec
|
8
|
-
|
9
|
-
require 'rubocop/rake_task'
|
10
10
|
RuboCop::RakeTask.new(:rubocop)
|
11
|
-
|
12
|
-
require 'bundler/audit/task'
|
13
11
|
Bundler::Audit::Task.new
|
12
|
+
Reek::Rake::Task.new(:reek) do |task|
|
13
|
+
task.config_file = '.reek'
|
14
|
+
end
|
14
15
|
|
15
|
-
task lint: [:rubocop, 'bundle:audit']
|
16
|
+
task lint: [:rubocop, :reek, 'bundle:audit']
|
17
|
+
task default: :spec
|
data/lib/saml/kit.rb
CHANGED
@@ -48,7 +48,11 @@ I18n.load_path +=
|
|
48
48
|
Dir[File.expand_path('kit/locales/*.yml', File.dirname(__FILE__))]
|
49
49
|
|
50
50
|
module Saml
|
51
|
+
# This module is the container for all classes/modules in this gem.
|
51
52
|
module Kit
|
53
|
+
# This class provides a global access to the
|
54
|
+
# default SAML configuration. This is useful
|
55
|
+
# for long running processes.
|
52
56
|
class << self
|
53
57
|
def configuration
|
54
58
|
@configuration ||= Saml::Kit::Configuration.new
|
data/lib/saml/kit/assertion.rb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
module Saml
|
4
4
|
module Kit
|
5
|
+
# This class validates the Assertion
|
6
|
+
# element nested in a Response element
|
7
|
+
# of a SAML document.
|
5
8
|
class Assertion
|
6
9
|
include ActiveModel::Validations
|
7
10
|
include Translatable
|
@@ -22,8 +25,10 @@ module Saml
|
|
22
25
|
@node = node
|
23
26
|
@configuration = configuration
|
24
27
|
@occurred_at = Time.current
|
28
|
+
@cannot_decrypt = false
|
29
|
+
@encrypted = false
|
25
30
|
private_keys = (configuration.private_keys(use: :encryption) + private_keys).uniq
|
26
|
-
decrypt
|
31
|
+
decrypt(::Xml::Kit::Decryption.new(private_keys: private_keys))
|
27
32
|
end
|
28
33
|
|
29
34
|
def issuer
|
@@ -83,15 +88,19 @@ module Saml
|
|
83
88
|
@node.present?
|
84
89
|
end
|
85
90
|
|
86
|
-
def to_xml(pretty:
|
87
|
-
pretty ? @node.to_xml(indent: 2) :
|
91
|
+
def to_xml(pretty: nil)
|
92
|
+
pretty ? @node.to_xml(indent: 2) : to_s
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_s
|
96
|
+
@node.to_s
|
88
97
|
end
|
89
98
|
|
90
99
|
private
|
91
100
|
|
92
101
|
attr_reader :configuration
|
93
102
|
|
94
|
-
def decrypt
|
103
|
+
def decrypt(decryptor)
|
95
104
|
encrypted_assertion = at_xpath('./xmlenc:EncryptedData')
|
96
105
|
@encrypted = encrypted_assertion.present?
|
97
106
|
return unless @encrypted
|
@@ -54,11 +54,11 @@ module Saml
|
|
54
54
|
# @param configuration [Saml::Kit::Configuration] the configuration to use to build the response.
|
55
55
|
def response_for(user, binding:, relay_state: nil, configuration: Saml::Kit.configuration)
|
56
56
|
response_binding = provider.assertion_consumer_service_for(binding: binding)
|
57
|
-
|
58
|
-
|
59
|
-
yield
|
57
|
+
response = Saml::Kit::Response.builder(user, self, configuration: configuration) do |builder|
|
58
|
+
builder.embed_signature = provider.want_assertions_signed
|
59
|
+
yield builder if block_given?
|
60
60
|
end
|
61
|
-
response_binding.serialize(
|
61
|
+
response_binding.serialize(response, relay_state: relay_state)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
data/lib/saml/kit/bindings.rb
CHANGED
@@ -7,6 +7,9 @@ require 'saml/kit/bindings/url_builder'
|
|
7
7
|
|
8
8
|
module Saml
|
9
9
|
module Kit
|
10
|
+
# This module is responsible for exposing
|
11
|
+
# the different SAML bindings that are
|
12
|
+
# supported by this gem.
|
10
13
|
module Bindings
|
11
14
|
HTTP_ARTIFACT = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact'.freeze
|
12
15
|
HTTP_POST = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'.freeze
|
@@ -3,6 +3,11 @@
|
|
3
3
|
module Saml
|
4
4
|
module Kit
|
5
5
|
module Bindings
|
6
|
+
# This class is responsible for
|
7
|
+
# serializing/deserializing SAML
|
8
|
+
# documents using the HTTP Post
|
9
|
+
# binding specification.
|
10
|
+
# https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf
|
6
11
|
# {include:file:spec/saml/kit/bindings/http_post_spec.rb}
|
7
12
|
class HttpPost < Binding
|
8
13
|
include Serializable
|
@@ -3,6 +3,11 @@
|
|
3
3
|
module Saml
|
4
4
|
module Kit
|
5
5
|
module Bindings
|
6
|
+
# This class is responsible for
|
7
|
+
# serializing/deserializing SAML
|
8
|
+
# documents using the HTTP Redirect
|
9
|
+
# binding specification.
|
10
|
+
# https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf
|
6
11
|
# {include:file:spec/saml/kit/bindings/http_redirect_spec.rb}
|
7
12
|
class HttpRedirect < Binding
|
8
13
|
include Serializable
|
@@ -20,31 +25,31 @@ module Saml
|
|
20
25
|
|
21
26
|
def deserialize(params, configuration: Saml::Kit.configuration)
|
22
27
|
parameters = normalize(params_to_hash(params))
|
23
|
-
document = deserialize_document_from
|
24
|
-
ensure_valid_signature
|
28
|
+
document = deserialize_document_from(parameters, configuration)
|
29
|
+
ensure_valid_signature(parameters, document)
|
25
30
|
document
|
26
31
|
end
|
27
32
|
|
28
33
|
private
|
29
34
|
|
30
|
-
def deserialize_document_from
|
35
|
+
def deserialize_document_from(params, configuration)
|
31
36
|
xml = inflate(decode(unescape(saml_param_from(params))))
|
32
37
|
Saml::Kit::Document.to_saml_document(xml, configuration: configuration)
|
33
38
|
end
|
34
39
|
|
35
|
-
def ensure_valid_signature
|
36
|
-
|
37
|
-
|
40
|
+
def ensure_valid_signature(params, document)
|
41
|
+
signature = params[:Signature]
|
42
|
+
algorithm = params[:SigAlg]
|
43
|
+
provider = document.provider
|
44
|
+
return if signature.blank? || algorithm.blank?
|
45
|
+
return if provider.nil?
|
38
46
|
|
39
|
-
|
40
|
-
algorithm_for(
|
41
|
-
decode(
|
47
|
+
return document.signature_verified! if provider.verify(
|
48
|
+
algorithm_for(algorithm),
|
49
|
+
decode(signature),
|
42
50
|
canonicalize(params)
|
43
51
|
)
|
44
|
-
|
45
|
-
else
|
46
|
-
raise ArgumentError, 'Invalid Signature'
|
47
|
-
end
|
52
|
+
raise ArgumentError, 'Invalid Signature'
|
48
53
|
end
|
49
54
|
|
50
55
|
def canonicalize(params)
|
@@ -79,7 +84,7 @@ module Saml
|
|
79
84
|
|
80
85
|
def params_to_hash(value)
|
81
86
|
return value unless value.is_a?(String)
|
82
|
-
Hash[URI.parse(value).query.split('&').map { |
|
87
|
+
Hash[URI.parse(value).query.split('&').map { |xx| xx.split('=', 2) }]
|
83
88
|
end
|
84
89
|
end
|
85
90
|
end
|
@@ -3,6 +3,11 @@
|
|
3
3
|
module Saml
|
4
4
|
module Kit
|
5
5
|
module Bindings
|
6
|
+
# This class is responsible for
|
7
|
+
# generating a url as per the
|
8
|
+
# rules for the HTTP redirect binding
|
9
|
+
# specification.
|
10
|
+
# https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf
|
6
11
|
# {include:file:spec/saml/kit/bindings/url_builder_spec.rb}
|
7
12
|
class UrlBuilder
|
8
13
|
include Serializable
|
@@ -13,15 +18,16 @@ module Saml
|
|
13
18
|
end
|
14
19
|
|
15
20
|
def build(saml_document, relay_state: nil)
|
21
|
+
destination = saml_document.destination
|
16
22
|
if configuration.sign?
|
17
23
|
payload = canonicalize(saml_document, relay_state)
|
18
|
-
"#{
|
24
|
+
"#{destination}?#{payload}&Signature=#{signature_for(payload)}"
|
19
25
|
else
|
20
26
|
payload = to_query_string(
|
21
27
|
saml_document.query_string_parameter => serialize(saml_document.to_xml),
|
22
28
|
'RelayState' => relay_state
|
23
29
|
)
|
24
|
-
"#{
|
30
|
+
"#{destination}?#{payload}"
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
data/lib/saml/kit/buildable.rb
CHANGED
data/lib/saml/kit/builders.rb
CHANGED
@@ -8,11 +8,14 @@ require 'saml/kit/builders/identity_provider_metadata'
|
|
8
8
|
require 'saml/kit/builders/logout_request'
|
9
9
|
require 'saml/kit/builders/logout_response'
|
10
10
|
require 'saml/kit/builders/metadata'
|
11
|
+
require 'saml/kit/builders/null'
|
11
12
|
require 'saml/kit/builders/response'
|
12
13
|
require 'saml/kit/builders/service_provider_metadata'
|
13
14
|
|
14
15
|
module Saml
|
15
16
|
module Kit
|
17
|
+
# This module contains all the builders classes
|
18
|
+
# that are used to create SAML documents.
|
16
19
|
module Builders
|
17
20
|
end
|
18
21
|
end
|
@@ -22,14 +22,14 @@ module Saml
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def build_service_provider
|
25
|
-
@service_provider = Saml::Kit::ServiceProviderMetadata.builder(configuration: configuration) do |
|
26
|
-
yield
|
25
|
+
@service_provider = Saml::Kit::ServiceProviderMetadata.builder(configuration: configuration) do |xx|
|
26
|
+
yield xx if block_given?
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
def build_identity_provider
|
31
|
-
@identity_provider = Saml::Kit::IdentityProviderMetadata.builder(configuration: configuration) do |
|
32
|
-
yield
|
31
|
+
@identity_provider = Saml::Kit::IdentityProviderMetadata.builder(configuration: configuration) do |xx|
|
32
|
+
yield xx if block_given?
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -9,7 +9,7 @@ module Saml
|
|
9
9
|
include XmlTemplatable
|
10
10
|
attr_reader :user, :request
|
11
11
|
attr_accessor :id, :reference_id, :now
|
12
|
-
attr_accessor :version, :status_code
|
12
|
+
attr_accessor :version, :status_code, :status_message
|
13
13
|
attr_accessor :issuer, :destination
|
14
14
|
attr_reader :configuration
|
15
15
|
|
@@ -21,6 +21,7 @@ module Saml
|
|
21
21
|
@now = Time.now.utc
|
22
22
|
@version = '2.0'
|
23
23
|
@status_code = Namespaces::SUCCESS
|
24
|
+
@status_message = nil
|
24
25
|
@issuer = configuration.entity_id
|
25
26
|
@encryption_certificate = request.try(:provider).try(:encryption_certificates).try(:last)
|
26
27
|
@encrypt = encryption_certificate.present?
|
@@ -31,6 +32,10 @@ module Saml
|
|
31
32
|
Saml::Kit::Response.new(to_xml, request_id: request.try(:id), configuration: configuration)
|
32
33
|
end
|
33
34
|
|
35
|
+
def assertion=(value)
|
36
|
+
@assertion = value ? value : Null.new
|
37
|
+
end
|
38
|
+
|
34
39
|
def assertion
|
35
40
|
@assertion ||=
|
36
41
|
begin
|
@@ -54,7 +59,7 @@ module Saml
|
|
54
59
|
xmlns: Namespaces::PROTOCOL,
|
55
60
|
}
|
56
61
|
options[:Destination] = destination if destination.present?
|
57
|
-
options[:InResponseTo] = request.id if request.present?
|
62
|
+
options[:InResponseTo] = request.try(:id) if request.present?
|
58
63
|
options
|
59
64
|
end
|
60
65
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# frozen_string_literal: true
|
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
module Saml
|
4
4
|
module Kit
|
5
|
+
# This class implements the Composite
|
6
|
+
# design pattern to allow client
|
7
|
+
# component to work with a metadata
|
8
|
+
# that provides an IDPSSODescriptor
|
9
|
+
# and SPSSODescriptor element.
|
5
10
|
class CompositeMetadata < Metadata # :nodoc:
|
6
11
|
include Enumerable
|
7
12
|
attr_reader :service_provider, :identity_provider
|
@@ -15,7 +20,7 @@ module Saml
|
|
15
20
|
end
|
16
21
|
|
17
22
|
def services(type)
|
18
|
-
xpath = map { |
|
23
|
+
xpath = map { |xxx| "//md:EntityDescriptor/md:#{xxx.name}/md:#{type}" }.join('|')
|
19
24
|
search(xpath).map do |item|
|
20
25
|
binding = item.attribute('Binding').value
|
21
26
|
location = item.attribute('Location').value
|
@@ -32,7 +37,7 @@ module Saml
|
|
32
37
|
end
|
33
38
|
|
34
39
|
def method_missing(name, *args)
|
35
|
-
if (target = find { |
|
40
|
+
if (target = find { |xxx| xxx.respond_to?(name) })
|
36
41
|
target.public_send(name, *args)
|
37
42
|
else
|
38
43
|
super
|
@@ -40,7 +45,7 @@ module Saml
|
|
40
45
|
end
|
41
46
|
|
42
47
|
def respond_to_missing?(method, *)
|
43
|
-
find { |
|
48
|
+
find { |xxx| xxx.respond_to?(method) }
|
44
49
|
end
|
45
50
|
end
|
46
51
|
end
|
@@ -56,7 +56,7 @@ module Saml
|
|
56
56
|
# @param passphrase [String] the password to decrypt the private key.
|
57
57
|
# @param use [Symbol] the type of key pair, `:signing` or `:encryption`
|
58
58
|
def add_key_pair(certificate, private_key, passphrase: nil, use: :signing)
|
59
|
-
ensure_proper_use
|
59
|
+
ensure_proper_use(use)
|
60
60
|
@key_pairs.push(::Xml::Kit::KeyPair.new(certificate, private_key, passphrase, use.to_sym))
|
61
61
|
end
|
62
62
|
|
@@ -65,7 +65,7 @@ module Saml
|
|
65
65
|
# @param use [Symbol] the type of key pair, `:signing` or `:encryption`
|
66
66
|
# @param passphrase [String] the private key passphrase to use.
|
67
67
|
def generate_key_pair_for(use:, passphrase: SecureRandom.uuid)
|
68
|
-
ensure_proper_use
|
68
|
+
ensure_proper_use(use)
|
69
69
|
certificate, private_key = ::Xml::Kit::SelfSignedCertificate.new.create(passphrase: passphrase)
|
70
70
|
add_key_pair(certificate, private_key, passphrase: passphrase, use: use)
|
71
71
|
end
|
@@ -74,7 +74,7 @@ module Saml
|
|
74
74
|
#
|
75
75
|
# @param use [Symbol] the type of key pair to return `nil`, `:signing` or `:encryption`
|
76
76
|
def key_pairs(use: nil)
|
77
|
-
use.present? ? @key_pairs.find_all { |
|
77
|
+
use.present? ? @key_pairs.find_all { |xxx| xxx.for?(use) } : @key_pairs
|
78
78
|
end
|
79
79
|
|
80
80
|
# Return each certificate for a specific use.
|
@@ -93,12 +93,12 @@ module Saml
|
|
93
93
|
|
94
94
|
# Returns true if there is at least one signing certificate registered.
|
95
95
|
def sign?
|
96
|
-
certificates(use: :signing).any?
|
96
|
+
@sign ||= certificates(use: :signing).any?
|
97
97
|
end
|
98
98
|
|
99
99
|
private
|
100
100
|
|
101
|
-
def ensure_proper_use
|
101
|
+
def ensure_proper_use(use)
|
102
102
|
return if USES.include?(use)
|
103
103
|
|
104
104
|
error_message = 'Use must be either :signing or :encryption'
|
data/lib/saml/kit/document.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module Saml
|
4
4
|
module Kit
|
5
|
+
# This class is a base class for SAML documents.
|
5
6
|
class Document
|
6
7
|
include ActiveModel::Validations
|
7
8
|
include XsdValidatable
|
@@ -65,8 +66,8 @@ module Saml
|
|
65
66
|
# Returns the SAML document as an XML string.
|
66
67
|
#
|
67
68
|
# @param pretty [Boolean] formats the xml or returns the raw xml.
|
68
|
-
def to_xml(pretty:
|
69
|
-
pretty ? to_nokogiri.to_xml(indent: 2) :
|
69
|
+
def to_xml(pretty: nil)
|
70
|
+
pretty ? to_nokogiri.to_xml(indent: 2) : to_s
|
70
71
|
end
|
71
72
|
|
72
73
|
# Returns the SAML document as an XHTML string.
|
@@ -77,7 +78,7 @@ module Saml
|
|
77
78
|
|
78
79
|
# @!visibility private
|
79
80
|
def to_nokogiri
|
80
|
-
@to_nokogiri ||= Nokogiri::XML(
|
81
|
+
@to_nokogiri ||= Nokogiri::XML(to_s)
|
81
82
|
end
|
82
83
|
|
83
84
|
# @!visibility private
|
@@ -91,7 +92,7 @@ module Saml
|
|
91
92
|
end
|
92
93
|
|
93
94
|
def to_s
|
94
|
-
|
95
|
+
content
|
95
96
|
end
|
96
97
|
|
97
98
|
class << self
|
@@ -74,9 +74,9 @@ module Saml
|
|
74
74
|
# @param configuration [Saml::Kit::Configuration] the configuration to use for generating the request.
|
75
75
|
# @return [Array] The url and saml params encoded using the rules for the specified binding.
|
76
76
|
def login_request_for(binding:, relay_state: nil, configuration: Saml::Kit.configuration)
|
77
|
-
builder = Saml::Kit::AuthenticationRequest.builder(configuration: configuration) do |
|
78
|
-
|
79
|
-
yield
|
77
|
+
builder = Saml::Kit::AuthenticationRequest.builder(configuration: configuration) do |xxx|
|
78
|
+
xxx.embed_signature = want_authn_requests_signed
|
79
|
+
yield xxx if block_given?
|
80
80
|
end
|
81
81
|
request_binding = single_sign_on_service_for(binding: binding)
|
82
82
|
request_binding.serialize(builder, relay_state: relay_state)
|
@@ -51,8 +51,8 @@ module Saml
|
|
51
51
|
# @param relay_state [Object] The RelayState to include in the RelayState param.
|
52
52
|
# @return [Array] Returns an array with a url and Hash of parameters to return to the requestor.
|
53
53
|
def response_for(binding:, relay_state: nil)
|
54
|
-
builder = Saml::Kit::LogoutResponse.builder(self) do |
|
55
|
-
yield
|
54
|
+
builder = Saml::Kit::LogoutResponse.builder(self) do |xxx|
|
55
|
+
yield xxx if block_given?
|
56
56
|
end
|
57
57
|
response_binding = provider.single_logout_service_for(binding: binding)
|
58
58
|
response_binding.serialize(builder, relay_state: relay_state)
|
data/lib/saml/kit/metadata.rb
CHANGED
@@ -110,7 +110,7 @@ module Saml
|
|
110
110
|
# @param type [Symbol] can be on the service element like `AssertionConsumerServiceURL`, `SingleSignOnService` or `SingleLogoutService`.
|
111
111
|
def service_for(binding:, type:)
|
112
112
|
binding = Saml::Kit::Bindings.binding_for(binding)
|
113
|
-
services(type).find { |
|
113
|
+
services(type).find { |xxx| xxx.binding?(binding) }
|
114
114
|
end
|
115
115
|
|
116
116
|
# Returns each of the SingleLogoutService bindings
|
@@ -132,7 +132,7 @@ module Saml
|
|
132
132
|
# @param relay_state [String] the relay state to have echo'd back.
|
133
133
|
# @return [Array] Returns an array with a url and Hash of parameters to send to the other party.
|
134
134
|
def logout_request_for(user, binding: :http_post, relay_state: nil)
|
135
|
-
builder = Saml::Kit::LogoutRequest.builder(user) { |
|
135
|
+
builder = Saml::Kit::LogoutRequest.builder(user) { |xxx| yield xxx if block_given? }
|
136
136
|
request_binding = single_logout_service_for(binding: binding)
|
137
137
|
request_binding.serialize(builder, relay_state: relay_state)
|
138
138
|
end
|
@@ -143,7 +143,7 @@ module Saml
|
|
143
143
|
# @param use [Symbol] the type of certificates to look at. Can be `:signing` or `:encryption`.
|
144
144
|
# @return [Xml::Kit::Certificate] returns the matching `{Xml::Kit::Certificate}`
|
145
145
|
def matches?(fingerprint, use: :signing)
|
146
|
-
certificates.find { |
|
146
|
+
certificates.find { |xxx| xxx.for?(use) && xxx.fingerprint == fingerprint }
|
147
147
|
end
|
148
148
|
|
149
149
|
# Returns the XML document converted to a Hash.
|
@@ -153,14 +153,14 @@ module Saml
|
|
153
153
|
|
154
154
|
# Returns the XML document as a String.
|
155
155
|
#
|
156
|
-
# @param pretty [
|
157
|
-
def to_xml(pretty:
|
158
|
-
pretty ? to_nokogiri.to_xml(indent: 2) :
|
156
|
+
# @param pretty [Boolean] true to return a human friendly version of the XML.
|
157
|
+
def to_xml(pretty: nil)
|
158
|
+
pretty ? to_nokogiri.to_xml(indent: 2) : to_s
|
159
159
|
end
|
160
160
|
|
161
161
|
# Returns the XML document as a [String].
|
162
162
|
def to_s
|
163
|
-
|
163
|
+
@xml
|
164
164
|
end
|
165
165
|
|
166
166
|
# Verifies the signature and data using the signing certificates.
|
data/lib/saml/kit/requestable.rb
CHANGED
data/lib/saml/kit/respondable.rb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
module Saml
|
4
4
|
module Kit
|
5
|
+
# This module provides the behaviours
|
6
|
+
# associated with SAML Response documents.
|
7
|
+
# .e.g. Response, LogoutResponse
|
5
8
|
module Respondable
|
6
9
|
extend ActiveSupport::Concern
|
7
10
|
attr_reader :request_id
|
@@ -21,6 +24,11 @@ module Saml
|
|
21
24
|
at_xpath('./*/samlp:Status/samlp:StatusCode/@Value').try(:value)
|
22
25
|
end
|
23
26
|
|
27
|
+
# Returns the /Status/StatusMessage
|
28
|
+
def status_message
|
29
|
+
at_xpath('./*/samlp:Status/samlp:StatusMessage').try(:text)
|
30
|
+
end
|
31
|
+
|
24
32
|
# Returns the /InResponseTo attribute.
|
25
33
|
def in_response_to
|
26
34
|
at_xpath('./*/@InResponseTo').try(:value)
|
data/lib/saml/kit/response.rb
CHANGED
data/lib/saml/kit/signature.rb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
module Saml
|
4
4
|
module Kit
|
5
|
+
# This class is responsible for
|
6
|
+
# validating an xml digital signature
|
7
|
+
# in an xml document.
|
5
8
|
class Signature
|
6
9
|
include ActiveModel::Validations
|
7
10
|
include Translatable
|
@@ -34,8 +37,8 @@ module Saml
|
|
34
37
|
end
|
35
38
|
|
36
39
|
def expected_digest_value
|
37
|
-
digests = dsignature.references.map do |
|
38
|
-
Base64.encode64(
|
40
|
+
digests = dsignature.references.map do |xxx|
|
41
|
+
Base64.encode64(xxx.calculate_digest_value).chomp
|
39
42
|
end
|
40
43
|
digests.count > 1 ? digests : digests[0]
|
41
44
|
end
|
@@ -69,8 +72,12 @@ module Saml
|
|
69
72
|
node.present?
|
70
73
|
end
|
71
74
|
|
72
|
-
def to_xml(pretty:
|
73
|
-
pretty ? node.to_xml(indent: 2) :
|
75
|
+
def to_xml(pretty: nil)
|
76
|
+
pretty ? node.to_xml(indent: 2) : to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_s
|
80
|
+
node.to_s
|
74
81
|
end
|
75
82
|
|
76
83
|
private
|
data/lib/saml/kit/trustable.rb
CHANGED
data/lib/saml/kit/version.rb
CHANGED
data/saml-kit.gemspec
CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_development_dependency 'bundler-audit', '~> 0.6'
|
35
35
|
spec.add_development_dependency 'ffaker', '~> 2.7'
|
36
36
|
spec.add_development_dependency 'rake', '~> 10.0'
|
37
|
+
spec.add_development_dependency 'reek', '~> 4.8'
|
37
38
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
38
39
|
spec.add_development_dependency 'rspec-benchmark', '~> 0.3'
|
39
40
|
spec.add_development_dependency 'rubocop', '~> 0.52'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saml-kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mo khan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -100,6 +100,20 @@ dependencies:
|
|
100
100
|
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '10.0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: reek
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '4.8'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '4.8'
|
103
117
|
- !ruby/object:Gem::Dependency
|
104
118
|
name: rspec
|
105
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -233,6 +247,7 @@ files:
|
|
233
247
|
- lib/saml/kit/builders/logout_request.rb
|
234
248
|
- lib/saml/kit/builders/logout_response.rb
|
235
249
|
- lib/saml/kit/builders/metadata.rb
|
250
|
+
- lib/saml/kit/builders/null.rb
|
236
251
|
- lib/saml/kit/builders/response.rb
|
237
252
|
- lib/saml/kit/builders/service_provider_metadata.rb
|
238
253
|
- lib/saml/kit/builders/templates/assertion.builder
|
@@ -242,6 +257,7 @@ files:
|
|
242
257
|
- lib/saml/kit/builders/templates/logout_request.builder
|
243
258
|
- lib/saml/kit/builders/templates/logout_response.builder
|
244
259
|
- lib/saml/kit/builders/templates/metadata.builder
|
260
|
+
- lib/saml/kit/builders/templates/null.builder
|
245
261
|
- lib/saml/kit/builders/templates/response.builder
|
246
262
|
- lib/saml/kit/builders/templates/service_provider_metadata.builder
|
247
263
|
- lib/saml/kit/composite_metadata.rb
|