Commit 6b5e200

mo <mo@mokhan.ca>
2017-12-21 19:19:27
add documentation.
1 parent ca36f2d
lib/saml/kit/serializable.rb
@@ -1,28 +1,47 @@
 module Saml
   module Kit
     module Serializable
+      # Base 64 decodes the value.
+      #
+      # @param value [String] the string to base 64 decode.
       def decode(value)
         Base64.decode64(value)
       end
 
+      # Base 64 encodes the value.
+      #
+      # @param value [String] the string to base 64 encode.
       def encode(value)
         Base64.strict_encode64(value)
       end
 
+      # Inflates the value using zlib decompression.
+      #
+      # @param value [String] the value to inflate.
       def inflate(value)
         inflater = Zlib::Inflate.new(-Zlib::MAX_WBITS)
         inflater.inflate(value)
       end
 
-      # drop header and checksum as per spec.
+      # Deflate the value and drop the header and checksum as per the SAML spec.
+      # https://en.wikipedia.org/wiki/SAML_2.0#HTTP_Redirect_Binding
+      #
+      # @param value [String] the value to deflate.
+      # @param level [Integer] the level of compression.
       def deflate(value, level: Zlib::BEST_COMPRESSION)
         Zlib::Deflate.deflate(value, level)[2..-5]
       end
 
+      # URL unescape a value
+      #
+      # @param value [String] the value to unescape.
       def unescape(value)
         CGI.unescape(value)
       end
 
+      # URL escape a value
+      #
+      # @param value [String] the value to escape.
       def escape(value)
         CGI.escape(value)
       end
lib/saml/kit/service_provider_metadata.rb
@@ -5,24 +5,31 @@ module Saml
         super("SPSSODescriptor", xml)
       end
 
+      # Returns each of the AssertionConsumerService bindings.
       def assertion_consumer_services
         services('AssertionConsumerService')
       end
 
+      # Returns the AssertionConsumerService for the specified binding.
+      #
+      # @params binding [Symbol] can be either `:http_post` or `:http_redirect`
       def assertion_consumer_service_for(binding:)
         service_for(binding: binding, type: 'AssertionConsumerService')
       end
 
+      # Returns true when the metadata demands that Assertions must be signed.
       def want_assertions_signed
         attribute = document.find_by("/md:EntityDescriptor/md:#{name}").attribute("WantAssertionsSigned")
         return true if attribute.nil?
         attribute.text.downcase == "true"
       end
 
+      # @!visibility private
       def self.builder_class
         Saml::Kit::Builders::ServiceProviderMetadata
       end
 
+      # @deprecated Use 'Saml::Kit::Builders::ServiceProviderMetadata'.
       Builder = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Saml::Kit::ServiceProviderMetadata::Builder', 'Saml::Kit::Builders::ServiceProviderMetadata')
     end
   end
lib/saml/kit/signature.rb
@@ -5,17 +5,20 @@ module Saml
         @xml_hash = xml_hash
       end
 
+      # Returns the embedded X509 Certificate
       def certificate
         value = to_h.fetch('KeyInfo', {}).fetch('X509Data', {}).fetch('X509Certificate', nil)
         return if value.nil?
         Saml::Kit::Certificate.new(value, use: :signing)
       end
 
+      # Returns true when the fingerprint of the certificate matches one of the certificates registered in the metadata.
       def trusted?(metadata)
         return false if metadata.nil?
         metadata.matches?(certificate.fingerprint, use: :signing)
       end
 
+      # Returns the XML Hash.
       def to_h
         @xml_hash
       end
lib/saml/kit/signatures.rb
@@ -1,5 +1,6 @@
 module Saml
   module Kit
+    # @!visibility private
     class Signatures # :nodoc:
       # @!visibility private
       attr_reader :configuration
@@ -10,6 +11,7 @@ module Saml
         @key_pair = configuration.key_pairs(use: :signing).last
       end
 
+      # @!visibility private
       def sign_with(key_pair)
         @key_pair = key_pair
       end
lib/saml/kit/templatable.rb
@@ -1,6 +1,9 @@
 module Saml
   module Kit
     module Templatable
+      # Can be used to disable embeding a signature.
+      # By default a signature will be embedded if a signing
+      # certificate is available via the configuration.
       attr_accessor :embed_signature
 
       # @deprecated Use {#embed_signature=} instead of this method.
@@ -9,11 +12,12 @@ module Saml
         self.embed_signature = value
       end
 
+      # Returns the generated XML document with an XML Digital Signature and XML Encryption.
       def to_xml(xml: ::Builder::XmlMarkup.new)
         signatures.complete(render(self, xml: xml))
       end
 
-      # @api private
+      # @!visibility private
       def signature_for(reference_id:, xml:)
         return unless sign?
         render(signatures.build(reference_id), xml: xml)
@@ -26,17 +30,17 @@ module Saml
         signatures.sign_with(key_pair)
       end
 
-      # Returns true if an embedded signature is requested and ad least one signing certificate is available via the configuration.
+      # Returns true if an embedded signature is requested and at least one signing certificate is available via the configuration.
       def sign?
         embed_signature.nil? ? configuration.sign? : embed_signature && configuration.sign?
       end
 
-      # @api private
+      # @!visibility private
       def signatures
         @signatures ||= Saml::Kit::Signatures.new(configuration: configuration)
       end
 
-      # @api private
+      # @!visibility private
       def encryption_for(xml:)
         if encrypt?
           temp = ::Builder::XmlMarkup.new
@@ -49,12 +53,12 @@ module Saml
         end
       end
 
-      # @api private
+      # @!visibility private
       def encrypt?
         encrypt && encryption_certificate
       end
 
-      # @api private
+      # @!visibility private
       def render(model, options)
         Saml::Kit::Template.new(model).to_xml(options)
       end
lib/saml/kit/template.rb
@@ -7,6 +7,9 @@ module Saml
         @target = target
       end
 
+      # Returns the compiled template as a [String].
+      #
+      # @param options [Hash] The options hash to pass to the template engine.
       def to_xml(options)
         template.render(target, options)
       end
lib/saml/kit/trustable.rb
@@ -9,6 +9,7 @@ module Saml
         validate :must_be_trusted
       end
 
+      # Returns true when the document has an embedded XML Signature or has been verified externally.
       def signed?
         signature_manually_verified || signature.present?
       end
@@ -19,6 +20,7 @@ module Saml
         xml_hash ? Signature.new(xml_hash) : nil
       end
 
+      # Returns true when documents is signed and the signing certificate belongs to a known service entity.
       def trusted?
         return true if signature_manually_verified
         return false unless signed?
lib/saml/kit/xml.rb
@@ -10,8 +10,6 @@ module Saml
         "samlp": Namespaces::PROTOCOL,
       }.freeze
 
-      attr_reader :raw_xml, :document
-
       validate :validate_signatures
       validate :validate_certificates
 
@@ -20,27 +18,31 @@ module Saml
         @document = Nokogiri::XML(raw_xml)
       end
 
-      def x509_certificates
-        xpath = "//ds:KeyInfo/ds:X509Data/ds:X509Certificate"
-        document.search(xpath, Xmldsig::NAMESPACES).map do |item|
-          Certificate.to_x509(item.text)
-        end
-      end
-
+      # Returns the first XML node found by searching the document with the provided XPath.
+      #
+      # @param xpath [String] the XPath to use to search the document
       def find_by(xpath)
         document.at_xpath(xpath, NAMESPACES)
       end
 
+      # Returns all XML nodes found by searching the document with the provided XPath.
+      #
+      # @param xpath [String] the XPath to use to search the document
       def find_all(xpath)
         document.search(xpath, NAMESPACES)
       end
 
+      # Return the XML document as a [String].
+      #
+      # @param pretty [Boolean] return the XML string in a human readable format if true.
       def to_xml(pretty: true)
         pretty ? document.to_xml(indent: 2) : raw_xml
       end
 
       private
 
+      attr_reader :raw_xml, :document
+
       def validate_signatures
         invalid_signatures.flat_map(&:errors).uniq.each do |error|
           errors.add(error, "is invalid")
@@ -69,6 +71,13 @@ module Saml
           end
         end
       end
+
+      def x509_certificates
+        xpath = "//ds:KeyInfo/ds:X509Data/ds:X509Certificate"
+        document.search(xpath, Xmldsig::NAMESPACES).map do |item|
+          Certificate.to_x509(item.text)
+        end
+      end
     end
   end
 end
lib/saml/kit/xml_decryption.rb
@@ -1,12 +1,16 @@
 module Saml
   module Kit
     class XmlDecryption
+      # The list of private keys to use to attempt to decrypt the document.
       attr_reader :private_keys
 
       def initialize(configuration: Saml::Kit.configuration)
         @private_keys = configuration.private_keys(use: :encryption)
       end
 
+      # Decrypts an EncryptedData section of an XML document.
+      #
+      # @param data [Hash] the XML document converted to a [Hash] using Hash.from_xml.
       def decrypt(data)
         encrypted_data = data['EncryptedData']
         symmetric_key = symmetric_key_from(encrypted_data)