class Spaceship::Portal::Certificate
Represents a certificate from the Apple Developer Portal
.
This can either be a code signing identity or a push profile
Constants
- APPLE_CERTIFICATE_TYPE_IDS
- CERTIFICATE_TYPE_IDS
- IOS_CERTIFICATE_TYPE_IDS
- MAC_CERTIFICATE_TYPE_IDS
- OLDER_IOS_CERTIFICATE_TYPES
Attributes
@return (Bool) Whether or not the certificate can be downloaded
@return (Date) The date and time when the certificate was created @example
2015-04-01 21:24:00 UTC
@return (Date) The date and time when the certificate will expire @example
2016-04-01 21:24:00 UTC
@return (String
) The ID given from the developer portal. You'll probably not need it. @example
"P577TH3PAA"
@return (String
) The name of the certificate @example Company
"SunApps GmbH"
@example Push Profile
"Apple Push Services"
@return (String
) The ID of the owner, that can be used to
fetch more information
@example
"75B83SPLAA"
@return (String
) The name of the owner
@example Code Signing Identity (usually the company name)
"SunApps Gmbh"
@example Push Certificate
(the bundle identifier)
"tools.fastlane.app"
@return (String
) The owner type that defines if it's a push profile
or a code signing identity
@example Code Signing Identity
"team"
@example Push Certificate
"bundle"
@return (String
) Status of the certificate @example
"Issued"
Indicates the type of this certificate which is automatically used to determine the class of the certificate. Available values listed in CERTIFICATE_TYPE_IDS
@return (String
) The type of the certificate @example Production Certificate
"R58UK2EWSO"
@example Development Certificate
"5QPB9NHCEI"
Private Class Methods
@param mac [Bool] Fetches Mac certificates if true. (Ignored if called from a subclass) @return (Array
) Returns all certificates of this account.
If this is called from a subclass of Certificate, this will only include certificates matching the current type.
# File spaceship/lib/spaceship/portal/certificate.rb, line 272 def all(mac: false) if self == Certificate # are we the base-class? type_ids = mac ? MAC_CERTIFICATE_TYPE_IDS : IOS_CERTIFICATE_TYPE_IDS type_ids = APPLE_CERTIFICATE_TYPE_IDS.merge(type_ids) types = type_ids.keys types += OLDER_IOS_CERTIFICATE_TYPES unless mac else types = [CERTIFICATE_TYPE_IDS.key(self)] mac = MAC_CERTIFICATE_TYPE_IDS.values.include?(self) end client.certificates(types, mac: mac).map do |cert| factory(cert) end end
Generate a new certificate based on a code certificate signing request @param csr (OpenSSL::X509::Request) (required): The certificate signing request to use. Get one using
`create_certificate_signing_request`
@param bundle_id (String
) (optional): The app identifier this certificate is for.
This value is only needed if you create a push profile. For normal code signing certificates, you must only pass a certificate signing request.
@example
# Create a new certificate signing request csr, pkey = Spaceship::Certificate.create_certificate_signing_request # Use the signing request to create a new distribution certificate Spaceship::Certificate::Production.create!(csr: csr)
@return (Certificate
): The newly created certificate
# File spaceship/lib/spaceship/portal/certificate.rb, line 309 def create!(csr: nil, bundle_id: nil) type = CERTIFICATE_TYPE_IDS.key(self) mac = MAC_CERTIFICATE_TYPE_IDS.include?(type) # look up the app_id by the bundle_id if bundle_id app = portal_type.set_client(client).find(bundle_id) raise "Could not find app with bundle id '#{bundle_id}'" unless app app_id = app.app_id end # ensure csr is a OpenSSL::X509::Request csr = OpenSSL::X509::Request.new(csr) if csr.kind_of?(String) # if this succeeds, we need to save the .cer and the private key in keychain access or wherever they go in linux response = client.create_certificate!(type, csr.to_pem, app_id, mac) # munge the response to make it work for the factory response['certificateTypeDisplayId'] = response['certificateType']['certificateTypeDisplayId'] self.new(response) end
Create a new code signing request that can be used to generate a new certificate @example
Create a new certificate signing request csr, pkey = Spaceship.certificate.create_certificate_signing_request # Use the signing request to create a new distribution certificate Spaceship.certificate.production.create!(csr: csr)
# File spaceship/lib/spaceship/portal/certificate.rb, line 215 def create_certificate_signing_request key = OpenSSL::PKey::RSA.new(2048) csr = OpenSSL::X509::Request.new csr.version = 0 csr.subject = OpenSSL::X509::Name.new([ ['CN', 'PEM', OpenSSL::ASN1::UTF8STRING] ]) csr.public_key = key.public_key csr.sign(key, OpenSSL::Digest::SHA1.new) return [csr, key] end
Create a new object based on a hash. This is used to create a new object based on the server response.
# File spaceship/lib/spaceship/portal/certificate.rb, line 229 def factory(attrs) # Example: # => {"name"=>"iOS Distribution: SunApps GmbH", # "certificateId"=>"XC5PH8DAAA", # "serialNumber"=>"797E732CCE8B7AAA", # "status"=>"Issued", # "statusCode"=>0, # "expirationDate"=>#<DateTime: 2015-11-25T22:45:50+00:00 ((2457352j,81950s,0n),+0s,2299161j)>, # "certificatePlatform"=>"ios", # "certificateType"=> # {"certificateTypeDisplayId"=>"R58UK2EAAA", # "name"=>"iOS Distribution", # "platform"=>"ios", # "permissionType"=>"distribution", # "distributionType"=>"store", # "distributionMethod"=>"app", # "ownerType"=>"team", # "daysOverlap"=>364, # "maxActive"=>2}} if attrs['certificateType'] # On some accounts this is nested, so we need to flatten it attrs.merge!(attrs['certificateType']) attrs.delete('certificateType') end # Parse the dates # rubocop:disable Style/RescueModifier attrs['expirationDate'] = (Time.parse(attrs['expirationDate']) rescue attrs['expirationDate']) attrs['dateCreated'] = (Time.parse(attrs['dateCreated']) rescue attrs['dateCreated']) # rubocop:enable Style/RescueModifier # Here we go klass = CERTIFICATE_TYPE_IDS[attrs['certificateTypeDisplayId']] klass ||= Certificate klass.client = @client klass.new(attrs) end
@param mac [Bool] Searches Mac certificates if true @return (Certificate
) Find a certificate based on the ID of the certificate.
# File spaceship/lib/spaceship/portal/certificate.rb, line 290 def find(certificate_id, mac: false) all(mac: mac).find do |c| c.id == certificate_id end end
Default portal class to use when finding by bundle_id @return (Class): The class this type of certificate belongs to
# File spaceship/lib/spaceship/portal/certificate.rb, line 332 def portal_type Spaceship::Portal::App end
Private Instance Methods
@return (OpenSSL::X509::Certificate) Downloads and parses the certificate
# File spaceship/lib/spaceship/portal/certificate.rb, line 345 def download OpenSSL::X509::Certificate.new(download_raw) end
@return (String
) Download the raw data of the certificate without parsing
# File spaceship/lib/spaceship/portal/certificate.rb, line 340 def download_raw client.download_certificate(id, type_display_id, mac: mac?) end
@return (Bool): Is this certificate a push profile for apps?
# File spaceship/lib/spaceship/portal/certificate.rb, line 355 def is_push? self.kind_of?(PushCertificate) end
@return (Bool) Is this a Mac profile?
# File spaceship/lib/spaceship/portal/certificate.rb, line 360 def mac? MAC_CERTIFICATE_TYPE_IDS.include?(type_display_id) end
Revoke the certificate. You shouldn't use this method probably.
# File spaceship/lib/spaceship/portal/certificate.rb, line 350 def revoke! client.revoke_certificate!(id, type_display_id, mac: mac?) end