Commit 09c7171

mo <mo@mokhan.ca>
2017-12-19 16:50:50
add documentation.
1 parent 6bbbe6d
lib/saml/kit/builders/assertion.rb
@@ -45,7 +45,7 @@ module Saml
         def conditions_options
           {
             NotBefore: now.utc.iso8601,
-            NotOnOrAfter: configuration.session_timeout.from_now.utc.iso8601,
+            NotOnOrAfter: configuration.session_timeout.since(now).utc.iso8601,
           }
         end
 
@@ -53,7 +53,7 @@ module Saml
           {
             AuthnInstant: now.iso8601,
             SessionIndex: reference_id,
-            SessionNotOnOrAfter: 3.hours.since(now).utc.iso8601,
+            SessionNotOnOrAfter: configuration.session_timeout.since(now).utc.iso8601,
           }
         end
       end
lib/saml/kit/builders/authentication_request.rb
@@ -16,11 +16,13 @@ module Saml
           @version = "2.0"
         end
 
+        # @deprecated Use {#assertion_consumer_service_url} instead of this method.
         def acs_url
           Saml::Kit.deprecate("acs_url is deprecated. Use assertion_consumer_service_url instead")
           self.assertion_consumer_service_url
         end
 
+        # @deprecated Use {#assertion_consumer_service_url=} instead of this method.
         def acs_url=(value)
           Saml::Kit.deprecate("acs_url= is deprecated. Use assertion_consumer_service_url= instead")
           self.assertion_consumer_service_url = value
lib/saml/kit/authentication_request.rb
@@ -1,8 +1,25 @@
 module Saml
   module Kit
+    # This class can be used to parse a SAML AuthnRequest or generate one.
+    #
+    # To generate an AuthnRequest use the builder API.
+    #
+    #    request = AuthenticationRequest.build do |builder|
+    #      builder.name_id_format = [Saml::Kit::Namespaces::EMAIL_ADDRESS]
+    #    end
+    #
+    #    <?xml version="1.0" encoding="UTF-8"?>
+    #    <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_ca3a0e72-9530-41f1-9518-c53716de88b2" Version="2.0" IssueInstant="2017-12-19T16:27:44Z" Destination="http://hartmann.info" AssertionConsumerServiceURL="https://carroll.com/acs">
+    #      <saml:Issuer>Day of the Dangerous Cousins</saml:Issuer>
+    #      <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/>
+    #    </samlp:AuthnRequest>
     class AuthenticationRequest < Document
       include Requestable
 
+      # Create an instance of an AuthnRequest document.
+      #
+      # @param xml [String] the raw xml.
+      # @param configuration [Saml::Kit::Configuration] defaults to the global configuration.
       def initialize(xml, configuration: Saml::Kit.configuration)
         super(xml, name: "AuthnRequest", configuration: configuration)
       end
lib/saml/kit/buildable.rb
@@ -4,15 +4,15 @@ module Saml
       extend ActiveSupport::Concern
 
       class_methods do
-        def build(*args, &block)
+        def build(*args, &block) # :yields builder
           builder(*args, &block).build
         end
 
-        def build_xml(*args, &block)
+        def build_xml(*args, &block) # :yields builder
           builder(*args, &block).to_xml
         end
 
-        def builder(*args)
+        def builder(*args) # :yields builder
           builder_class.new(*args).tap do |builder|
             yield builder if block_given?
           end
lib/saml/kit/composite_metadata.rb
@@ -1,6 +1,6 @@
 module Saml
   module Kit
-    class CompositeMetadata < Metadata
+    class CompositeMetadata < Metadata # :nodoc:
       include Enumerable
       attr_reader :service_provider, :identity_provider
 
lib/saml/kit/configuration.rb
@@ -1,12 +1,39 @@
 module Saml
   module Kit
+    # This class represents the main configuration that is use for generating SAML documents.
+    #
+    #   Saml::Kit::Configuration.new do |config|
+    #     config.issuer = "com:saml:kit"
+    #     config.signature_method = :SHA256
+    #     config.digest_method = :SHA256
+    #     config.registry = Saml::Kit::DefaultRegistry.new
+    #     config.session_timeout = 30.minutes
+    #     config.logger = Rails.logger
+    #   end
+    #
+    #   To specify global configuration it is best to do this in an initialize 
+    #   that runs at the start of the program.
+    #
+    #   Saml::Kit.configure do |configuration|
+    #     configuration.issuer = "https://www.example.com/saml/metadata"
+    #     configuration.generate_key_pair_for(use: :signing)
+    #     configuration.add_key_pair(ENV["X509_CERTIFICATE"], ENV["PRIVATE_KEY"], password: ENV['PRIVATE_KEY_PASSWORD'], use: :encryption)
+    #   end
     class Configuration
+      # The issuer or entity_id to use.
       attr_accessor :issuer
-      attr_accessor :signature_method, :digest_method
-      attr_accessor :registry, :session_timeout
+      # The signature method to use when generating signatures (See {SAML::Kit::Builders::XmlSignature::SIGNATURE_METHODS})
+      attr_accessor :signature_method
+      # The digest method to use when generating signatures (See {SAML::Kit::Builders::XmlSignature::DIGEST_METHODS})
+      attr_accessor :digest_method
+      # The metadata registry to use for searching for metadata associated with an issuer.
+      attr_accessor :registry
+      # The session timeout to use when generating an Assertion.
+      attr_accessor :session_timeout
+      # The logger to write log messages to.
       attr_accessor :logger
 
-      def initialize
+      def initialize # :yields configuration
         @signature_method = :SHA256
         @digest_method = :SHA256
         @registry = DefaultRegistry.new
@@ -16,42 +43,65 @@ module Saml
         yield self if block_given?
       end
 
-      def add_key_pair(certificate, private_key, password:, use: :signing)
+      # Add a key pair that can be used for either signing or encryption.
+      #
+      # @param certificate [String] the x509 certificate with public key.
+      # @param private_key [String] the plain text private key.
+      # @param password [String] the password to decrypt the private key.
+      # @param use [Symbol] the type of key pair, `:signing` or `:encryption`
+      def add_key_pair(certificate, private_key, password: '', use: :signing)
         @key_pairs.push(KeyPair.new(certificate, private_key, password, use.to_sym))
       end
 
+      # Generates a unique key pair that can be used for signing or encryption.
+      #
+      # @param use [Symbol] the type of key pair, `:signing` or `:encryption`
+      # @param password [String] the private key password to use.
       def generate_key_pair_for(use:, password: SecureRandom.uuid)
         certificate, private_key = SelfSignedCertificate.new(password).create
         add_key_pair(certificate, private_key, password: password, use: use)
       end
 
+      # Return each key pair for a specific use.
+      #
+      # @param use [Symbol] the type of key pair to return `nil`, `:signing` or `:encryption`
       def key_pairs(use: nil)
         use.present? ? @key_pairs.find_all { |x| x.for?(use) } : @key_pairs
       end
 
+      # Return each certificate for a specific use.
+      #
+      # @param use [Symbol] the type of key pair to return `nil`, `:signing` or `:encryption`
       def certificates(use: nil)
         key_pairs(use: use).flat_map(&:certificate)
       end
 
+      # Return each private for a specific use.
+      #
+      # @param use [Symbol] the type of key pair to return `nil`, `:signing` or `:encryption`
       def private_keys(use: :signing)
         key_pairs(use: use).flat_map(&:private_key)
       end
 
+      # @deprecated Use {#certificates} instead of this method.
       def encryption_certificate
         Saml::Kit.deprecate("encryption_certificate is deprecated. Use certificates(use: :encryption) instead")
         certificates(use: :encryption).last
       end
 
+      # @deprecated Use {#private_keys} instead of this method.
       def signing_private_key
         Saml::Kit.deprecate("signing_private_key is deprecated. Use private_keys(use: :signing) instead")
         private_keys(use: :signing).last
       end
 
+      # @deprecated Use {#private_keys} instead of this method.
       def encryption_private_key
         Saml::Kit.deprecate("encryption_private_key is deprecated. Use private_keys(use: :encryption) instead")
         private_keys(use: :encryption).last
       end
 
+      # Returns true if there is at least one signing certificate registered.
       def sign?
         certificates(use: :signing).any?
       end
lib/saml/kit/key_pair.rb
@@ -1,6 +1,6 @@
 module Saml
   module Kit
-    class KeyPair
+    class KeyPair # :nodoc:
       attr_reader :certificate, :private_key, :use
 
       def initialize(certificate, private_key, password, use)
lib/saml/kit/signatures.rb
@@ -1,6 +1,6 @@
 module Saml
   module Kit
-    class Signatures
+    class Signatures # :nodoc:
       attr_reader :configuration
 
       def initialize(configuration:)
lib/saml/kit/xml.rb
@@ -1,6 +1,6 @@
 module Saml
   module Kit
-    class Xml
+    class Xml # :nodoc:
       include ActiveModel::Validations
       NAMESPACES = {
         "NameFormat": Namespaces::ATTR_SPLAT,
spec/saml/authentication_request_spec.rb
@@ -40,6 +40,7 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
 
     it 'is valid when left untampered' do
       subject = described_class.new(raw_xml, configuration: configuration)
+      puts subject.to_xml(pretty: true)
       expect(subject).to be_valid
     end