class Cert::Runner

Public Instance Methods

certificate_type() click to toggle source

The kind of certificate we're interested in

# File lib/cert/runner.rb, line 125
def certificate_type
  cert_type = Spaceship.certificate.production
  cert_type = Spaceship.certificate.in_house if Spaceship.client.in_house?
  cert_type = Spaceship.certificate.development if Cert.config[:development]

  cert_type
end
certificates() click to toggle source

All certificates of this type

# File lib/cert/runner.rb, line 120
def certificates
  certificate_type.all
end
create_certificate() click to toggle source
# File lib/cert/runner.rb, line 133
def create_certificate
  # Create a new certificate signing request
  csr, pkey = Spaceship.certificate.create_certificate_signing_request

  # Use the signing request to create a new distribution certificate
  begin
    certificate = certificate_type.create!(csr: csr)
  rescue => ex
    if ex.to_s.include?("You already have a current")
      type_name = (Cert.config[:development] ? "Development" : "Distribution")
      UI.user_error!("Could not create another #{type_name} certificate, reached the maximum number of available #{type_name} certificates.", show_github_issues: true)
    end

    raise ex
  end

  # Store all that onto the filesystem

  request_path = File.expand_path(File.join(Cert.config[:output_path], "#{certificate.id}.certSigningRequest"))
  File.write(request_path, csr.to_pem)

  private_key_path = File.expand_path(File.join(Cert.config[:output_path], "#{certificate.id}.p12"))
  File.write(private_key_path, pkey)

  cert_path = store_certificate(certificate)

  # Import all the things into the Keychain
  keychain = File.expand_path(Cert.config[:keychain_path])
  password = Cert.config[:keychain_password]
  FastlaneCore::KeychainImporter.import_file(private_key_path, keychain, keychain_password: password)
  FastlaneCore::KeychainImporter.import_file(cert_path, keychain, keychain_password: password)

  # Environment variables for the fastlane action
  ENV["CER_CERTIFICATE_ID"] = certificate.id
  ENV["CER_FILE_PATH"] = cert_path

  UI.success "Successfully generated #{certificate.id} which was imported to the local machine."

  return cert_path
end
expired_certs() click to toggle source
# File lib/cert/runner.rb, line 73
def expired_certs
  certificates.select do |certificate|
    certificate.expires < Time.now.utc
  end
end
find_existing_cert() click to toggle source
# File lib/cert/runner.rb, line 79
def find_existing_cert
  certificates.each do |certificate|
    unless certificate.can_download
      next
    end

    path = store_certificate(certificate)
    private_key_path = File.expand_path(File.join(Cert.config[:output_path], "#{certificate.id}.p12"))

    if FastlaneCore::CertChecker.installed?(path)
      # This certificate is installed on the local machine
      ENV["CER_CERTIFICATE_ID"] = certificate.id
      ENV["CER_FILE_PATH"] = path

      UI.success "Found the certificate #{certificate.id} (#{certificate.name}) which is installed on the local machine. Using this one."

      return path
    elsif File.exist?(private_key_path)
      keychain = File.expand_path(Cert.config[:keychain_path])
      password = Cert.config[:keychain_password]
      FastlaneCore::KeychainImporter.import_file(private_key_path, keychain, keychain_password: password)
      FastlaneCore::KeychainImporter.import_file(path, keychain, keychain_password: password)

      ENV["CER_CERTIFICATE_ID"] = certificate.id
      ENV["CER_FILE_PATH"] = path

      UI.success "Found the cached certificate #{certificate.id} (#{certificate.name}). Using this one."

      return path
    else
      UI.error "Certificate #{certificate.id} (#{certificate.name}) can't be found on your local computer"
    end

    File.delete(path) # as apparantly this certificate is pretty useless without a private key
  end

  UI.important "Couldn't find an existing certificate... creating a new one"
  return nil
end
launch() click to toggle source
# File lib/cert/runner.rb, line 5
def launch
  run

  installed = FastlaneCore::CertChecker.installed?(ENV["CER_FILE_PATH"])
  UI.message "Verifying the certificate is properly installed locally..."
  UI.user_error!("Could not find the newly generated certificate installed", show_github_issues: true) unless installed
  UI.success "Successfully installed certificate #{ENV['CER_CERTIFICATE_ID']}"
  return ENV["CER_FILE_PATH"]
end
login() click to toggle source
# File lib/cert/runner.rb, line 15
def login
  UI.message "Starting login with user '#{Cert.config[:username]}'"
  Spaceship.login(Cert.config[:username], nil)
  Spaceship.select_team
  UI.message "Successfully logged in"
end
revoke_expired_certs!() click to toggle source

Command method for the :revoke_expired sub-command

# File lib/cert/runner.rb, line 45
def revoke_expired_certs!
  FastlaneCore::PrintTable.print_values(config: Cert.config, hide_keys: [:output_path], title: "Summary for cert #{Cert::VERSION}")

  login

  to_revoke = expired_certs

  if to_revoke.empty?
    UI.success "No expired certificates were found to revoke! 👍"
    return
  end

  revoke_count = 0

  to_revoke.each do |certificate|
    begin
      UI.message "#{certificate.id} #{certificate.name} has expired, revoking..."
      certificate.revoke!
      revoke_count += 1
    rescue => e
      UI.error "An error occurred while revoking #{certificate.id} #{certificate.name}"
      UI.error "#{e.message}\n#{e.backtrace.join("\n")}" if $verbose
    end
  end

  UI.success "#{revoke_count} expired certificate#{'s' if revoke_count != 1} #{revoke_count == 1 ? 'has' : 'have'} been revoked! 👍"
end
run() click to toggle source
# File lib/cert/runner.rb, line 22
def run
  FileUtils.mkdir_p(Cert.config[:output_path])

  FastlaneCore::PrintTable.print_values(config: Cert.config, hide_keys: [:output_path], title: "Summary for cert #{Cert::VERSION}")

  login

  should_create = Cert.config[:force]
  unless should_create
    cert_path = find_existing_cert
    should_create = cert_path.nil?
  end

  return unless should_create

  if create_certificate # no certificate here, creating a new one
    return # success
  else
    UI.user_error!("Something went wrong when trying to create a new certificate...")
  end
end
store_certificate(certificate) click to toggle source
# File lib/cert/runner.rb, line 174
def store_certificate(certificate)
  path = File.expand_path(File.join(Cert.config[:output_path], "#{certificate.id}.cer"))
  raw_data = certificate.download_raw
  File.write(path, raw_data)
  return path
end