main
1# frozen_string_literal: true
2
3module Saml
4 module Kit
5 # This module is responsible for
6 # validating the trustworthiness
7 # of a saml document.
8 module Trustable
9 extend ActiveSupport::Concern
10
11 included do
12 validate :must_have_valid_signature, unless: :signature_verified
13 validate :must_be_registered
14 validate :must_be_trusted
15 end
16
17 # Returns true when the document has an embedded XML Signature or has
18 # been verified externally.
19 def signed?
20 signature_verified || signature.present?
21 end
22
23 # @!visibility private
24 def signature
25 @signature ||= Signature.new(at_xpath("/samlp:#{name}/ds:Signature"))
26 end
27
28 # Returns true when documents is signed and the signing certificate
29 # belongs to a known service entity.
30 def trusted?
31 return true if signature_verified
32 return false unless signed?
33
34 signature.trusted?(provider)
35 end
36
37 # @!visibility private
38 def provider
39 registry.metadata_for(issuer)
40 end
41
42 # @!visibility private
43 def signature_verified!
44 @signature_verified = true
45 end
46
47 private
48
49 attr_reader :signature_verified
50
51 def must_have_valid_signature
52 return if to_xml.blank?
53 return unless signature.present?
54
55 signature.valid?
56 signature.each_error do |attribute, error|
57 errors.add(attribute, error)
58 end
59 end
60
61 def must_be_registered
62 return unless expected_type?
63 return if provider.present?
64
65 errors.add(:provider, error_message(:unregistered))
66 end
67
68 def must_be_trusted
69 return if trusted?
70 return if provider.present? && !signed?
71
72 errors.add(:fingerprint, error_message(:invalid_fingerprint))
73 end
74 end
75 end
76end