class RubyAem::Resources::Certificate

AEM class contains API calls related to managing a certificate within AEM Truststore. Since there is only 0 or 1 AEM Truststore with a global scope, a certificate is by default associated to that global AEM Truststore.

Public Class Methods

new( client, serial_number ) click to toggle source

Initialise certificate. Certificate resource uses serial number as identifier because AEM API endpoint for importing a certificate does not allow the ability to specify an alias, hence alias is assigned randomly by AEM, and this force us to use serial number as the identifier because serial number is immutable on the certificate. This is obviously not ideal, but we have to do it due to AEM API limitations.

@param client RubyAem::Client @param serial_number the certificate's serial number @return new RubyAem::Resources::Certificate instance

# File lib/ruby_aem/resources/certificate.rb, line 37
def initialize(
  client,
  serial_number
)
  @client = client
  @truststore = RubyAem::Resources::Truststore.new(client)
  @serial_number = serial_number
  @call_params = {
    serial_number: serial_number
  }
  @cert_alias = _get_alias
end

Public Instance Methods

_get_alias() click to toggle source
# File lib/ruby_aem/resources/certificate.rb, line 108
def _get_alias
  truststore_info = @truststore.info.data
  cert_alias = nil
  truststore_info.aliases.each { |certificate_alias|
    cert_alias = certificate_alias._alias.to_s if certificate_alias.serial_number.to_s == @serial_number.to_s
  }
  cert_alias
end
create(file_path) click to toggle source

Create is an alias to import. Create is needed to satisfy Puppet resource `ensure`.

@param file_path local file path to certificate file @return RubyAem::Result

# File lib/ruby_aem/resources/certificate.rb, line 55
def create(file_path)
  import(file_path)
end
delete() click to toggle source

Delete a specific certificate from AEM Truststore by alias name or serial number.

@return RubyAem::Result

# File lib/ruby_aem/resources/certificate.rb, line 93
def delete
  result = exists
  raise RubyAem::Error.new('Certificate not found', result) if result.data == false

  @call_params[:cert_alias] = @cert_alias
  @client.call(self.class, __callee__.to_s, @call_params)
end
exists() click to toggle source

Check if the certificate exists in AEM truststore.

@return RubyAem::Result

# File lib/ruby_aem/resources/certificate.rb, line 104
def exists
  @client.call(self.class, __callee__.to_s, @call_params)
end
export(truststore_password) click to toggle source

Export a certificate file from AEM Truststore.

@param truststore_password Password for AEM Truststore @return RubyAem::Result

# File lib/ruby_aem/resources/certificate.rb, line 74
def export(truststore_password)
  temp_file = Tempfile.new.path
  @truststore.download(temp_file)

  truststore_raw = File.read temp_file
  truststore = OpenSSL::PKCS12.new(truststore_raw, truststore_password)

  certificate = nil
  truststore.ca_certs.each { |ca_cert|
    certificate = ca_cert if ca_cert.serial.to_s == @serial_number.to_s
  }
  result = RubyAem::Result.new('Certificate exported', nil)
  result.data = certificate
  result
end
import(file_path) click to toggle source

Import a certificate file into AEM Truststore.

@param file_path local file path to certificate file @return RubyAem::Result

# File lib/ruby_aem/resources/certificate.rb, line 63
def import(file_path)
  @call_params[:file_path] = file_path
  result = @client.call(self.class, __callee__.to_s, @call_params)
  @cert_alias = _get_alias
  result
end
import_wait_until_ready( file_path, opts = { _retries: { max_tries: 30, base_sleep_seconds: 2, max_sleep_seconds: 2 } } ) click to toggle source

Import a certificate file into AEM Truststore and wait until the certificate is imported.

@param file_path local file path to certificate file @param opts optional parameters:

@return RubyAem::Result

# File lib/ruby_aem/resources/certificate.rb, line 123
def import_wait_until_ready(
  file_path,
  opts = {
    _retries: {
      max_tries: 30,
      base_sleep_seconds: 2,
      max_sleep_seconds: 2
    }
  }
)
  opts[:_retries] ||= {}
  opts[:_retries][:max_tries] ||= 30
  opts[:_retries][:base_sleep_seconds] ||= 2
  opts[:_retries][:max_sleep_seconds] ||= 2

  # ensure integer retries setting (Puppet 3 passes numeric string)
  opts[:_retries][:max_tries] = opts[:_retries][:max_tries].to_i
  opts[:_retries][:base_sleep_seconds] = opts[:_retries][:base_sleep_seconds].to_i
  opts[:_retries][:max_sleep_seconds] = opts[:_retries][:max_sleep_seconds].to_i

  result = import(file_path)

  with_retries(max_tries: opts[:_retries][:max_tries], base_sleep_seconds: opts[:_retries][:base_sleep_seconds], max_sleep_seconds: opts[:_retries][:max_sleep_seconds]) { |retries_count|
    check_result = exists
    puts format('Import check #%<retries_count>d: %<check_result_data>s - %<check_result_message>s', retries_count: retries_count, check_result_data: check_result.data, check_result_message: check_result.message)
    raise StandardError.new(check_result.message) if check_result.data == false
  }
  result
end