main
1# frozen_string_literal: true
2
3module Saml
4 module Kit
5 # The default metadata registry is used to fetch the metadata associated
6 # with an issuer or entity id.
7 # The metadata associated with an issuer is used to verify trust for any
8 # SAML documents that are received.
9 #
10 # You can replace the default registry with your own at startup.
11 #
12 # Example:
13 #
14 # class OnDemandRegistry
15 # def initialize(original)
16 # @original = original
17 # end
18 #
19 # def metadata_for(entity_id)
20 # found = @original.metadata_for(entity_id)
21 # return found if found
22 #
23 # @original.register_url(entity_id, verify_ssl: Rails.env.production?)
24 # @original.metadata_for(entity_id)
25 # end
26 # end
27 #
28 # Saml::Kit.configure do |configuration|
29 # configuration.entity_id = ENV['ENTITY_ID']
30 # configuration.registry = OnDemandRegistry.new(configuration.registry)
31 # configuration.logger = Rails.logger
32 # end
33 #
34 # {include:file:spec/saml/kit/default_registry_spec.rb}
35 class DefaultRegistry
36 include Enumerable
37
38 def initialize(items = {})
39 @items = items
40 end
41
42 # Register a metadata document
43 #
44 # @param metadata [Saml::Kit::Metadata] the metadata to register.
45 def register(metadata)
46 ensure_valid_metadata(metadata)
47 Saml::Kit.logger.debug(metadata.to_xml(pretty: true))
48 @items[metadata.entity_id] = metadata
49 end
50
51 # Register metadata via a remote URL.
52 # This will attempt to connect to the remove URL to download the
53 # metadata and register it in the registry.
54 #
55 # @param url [String] the url to download the metadata from.
56 # @param verify_ssl [Boolean] enable/disable SSL peer verification.
57 def register_url(url, verify_ssl: true)
58 headers = { 'User-Agent' => "saml/kit #{Saml::Kit::VERSION}" }
59 verify_mode = verify_ssl ? nil : OpenSSL::SSL::VERIFY_NONE
60 client = Net::Hippie::Client.new(headers: headers, verify_mode: verify_mode)
61 register(Saml::Kit::Metadata.from(client.get(url).body))
62 end
63
64 # Returns the metadata document associated with an issuer or entityID.
65 #
66 # @param entity_id [String] unique entityID/Issuer associated with
67 # metadata.
68 def metadata_for(entity_id)
69 @items[entity_id]
70 end
71
72 # Yields each registered [Saml::Kit::Metadata] to the block.
73 def each
74 @items.each_value do |value|
75 yield value
76 end
77 end
78
79 protected
80
81 def ensure_valid_metadata(metadata)
82 error = ArgumentError.new('Cannot register invalid metadata')
83 raise error if
84 metadata.nil? ||
85 !metadata.respond_to?(:entity_id) ||
86 metadata.invalid?
87 end
88 end
89 end
90end