Class: Spaceship::Portal::Certificate
- Inherits:
-
Spaceship::PortalBase
- Object
- Base
- Spaceship::PortalBase
- Spaceship::Portal::Certificate
- Defined in:
- spaceship/lib/spaceship/portal/certificate.rb
Overview
Represents a certificate from the Apple Developer Portal.
This can either be a code signing identity or a push profile
Direct Known Subclasses
AppleDevelopment, AppleDistribution, ApplePay, ApplePayMerchantIdentity, DeveloperIdApplication, DeveloperIdInstaller, Development, InHouse, MacAppDistribution, MacDevelopment, MacInstallerDistribution, Passbook, Production, PushCertificate
Defined Under Namespace
Classes: AppleDevelopment, AppleDistribution, ApplePay, ApplePayMerchantIdentity, DeveloperIdApplication, DeveloperIdInstaller, Development, DevelopmentPush, InHouse, MacAppDistribution, MacDevelopment, MacDevelopmentPush, MacInstallerDistribution, MacProductionPush, Passbook, Production, ProductionPush, PushCertificate, VoipPush, WebsitePush
Constant Summary collapse
- APPLE_CERTIFICATE_TYPE_IDS =
{ "83Q87W3TGH" => AppleDevelopment, "WXV89964HE" => AppleDistribution }
- IOS_CERTIFICATE_TYPE_IDS =
{ "5QPB9NHCEI" => Development, "R58UK2EWSO" => Production, "9RQEK7MSXA" => InHouse, "LA30L5BJEU" => Certificate, "JKG5JZ54H7" => DevelopmentPush, "UPV3DW712I" => ProductionPush, "Y3B2F3TYSI" => Passbook, "3T2ZP62QW8" => WebsitePush, "E5D663CMZW" => VoipPush, "4APLUP237T" => ApplePay, "MD8Q2VRT6A" => ApplePayMerchantIdentity }
- OLDER_IOS_CERTIFICATE_TYPES =
[ "3BQKVH9I2X", # old ProductionPush "BKLRAVXMGM", # old DevelopmentPush # those are also sent by the browser, but not sure what they represent: "T44PTHVNID", "DZQUP8189Y", "FGQUP4785Z", "S5WE21TULA", "FUOY7LWJET" ]
- MAC_CERTIFICATE_TYPE_IDS =
{ "749Y1QAGU7" => MacDevelopment, "HXZEUKP0FP" => MacAppDistribution, "2PQI8IDXNH" => MacInstallerDistribution, "OYVN2GW35E" => DeveloperIdInstaller, "W0EURJRMC5" => DeveloperIdApplication, "CDZ7EMXIZ1" => MacProductionPush, "HQ4KP3I34R" => MacDevelopmentPush, "DIVN2GW3XT" => DeveloperIdApplication }
- CERTIFICATE_TYPE_IDS =
APPLE_CERTIFICATE_TYPE_IDS .merge(IOS_CERTIFICATE_TYPE_IDS) .merge(MAC_CERTIFICATE_TYPE_IDS)
Instance Attribute Summary collapse
-
#can_download ⇒ Bool
Whether or not the certificate can be downloaded.
-
#created ⇒ Date
The date and time when the certificate was created.
-
#expires ⇒ Date
The date and time when the certificate will expire.
-
#id ⇒ String
The ID given from the developer portal.
-
#name ⇒ String
The name of the certificate.
-
#owner_id ⇒ String
The ID of the owner, that can be used to fetch more information.
-
#owner_name ⇒ String
The name of the owner.
-
#owner_type ⇒ String
The owner type that defines if it’s a push profile or a code signing identity.
-
#status ⇒ String
Status of the certificate.
-
#type_display_id ⇒ String
Indicates the type of this certificate which is automatically used to determine the class of the certificate.
Attributes inherited from Base
Class Method Summary collapse
-
.all(mac: false) ⇒ Array
Returns all certificates of this account.
-
.create!(csr: nil, bundle_id: nil) ⇒ Certificate
Generate a new certificate based on a code certificate signing request.
-
.create_certificate_signing_request ⇒ Object
Create a new cert signing request that can be used to generate a new certificate.
-
.factory(attrs) ⇒ Object
Create a new object based on a hash.
-
.find(certificate_id, mac: false) ⇒ Certificate
Find a certificate based on the ID of the certificate.
-
.portal_type ⇒ Class
Default portal class to use when finding by bundle_id.
Instance Method Summary collapse
-
#download ⇒ OpenSSL::X509::Certificate
Downloads and parses the certificate.
-
#download_raw ⇒ String
Download the raw data of the certificate without parsing.
-
#is_push? ⇒ Bool
: Is this certificate a push profile for apps?.
-
#mac? ⇒ Bool
Is this a Mac profile?.
-
#revoke! ⇒ Object
Revoke the certificate.
Methods inherited from Spaceship::PortalBase
Methods inherited from Base
attr_accessor, attr_mapping, attributes, #attributes, #initialize, #inspect, mapping_module, method_missing, set_client, #setup, #to_s
Constructor Details
This class inherits a constructor from Spaceship::Base
Instance Attribute Details
#can_download ⇒ Bool
Returns Whether or not the certificate can be downloaded.
73 74 75 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 73 def can_download @can_download end |
#created ⇒ Date
Returns The date and time when the certificate was created.
32 33 34 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 32 def created @created end |
#expires ⇒ Date
Returns The date and time when the certificate will expire.
37 38 39 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 37 def expires @expires end |
#id ⇒ String
Returns The ID given from the developer portal. You’ll probably not need it.
15 16 17 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 15 def id @id end |
#name ⇒ String
Returns The name of the certificate.
22 23 24 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 22 def name @name end |
#owner_id ⇒ String
Returns The ID of the owner, that can be used to fetch more information.
60 61 62 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 60 def owner_id @owner_id end |
#owner_name ⇒ String
Returns The name of the owner.
54 55 56 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 54 def owner_name @owner_name end |
#owner_type ⇒ String
Returns The owner type that defines if it’s a push profile or a code signing identity.
46 47 48 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 46 def owner_type @owner_type end |
#status ⇒ String
Returns Status of the certificate.
27 28 29 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 27 def status @status end |
#type_display_id ⇒ String
Indicates the type of this certificate which is automatically used to determine the class of the certificate. Available values listed in CERTIFICATE_TYPE_IDS
70 71 72 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 70 def type_display_id @type_display_id end |
Class Method Details
.all(mac: false) ⇒ 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.
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 273 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 |
.create!(csr: nil, bundle_id: nil) ⇒ Certificate
Generate a new certificate based on a code certificate signing request
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 310 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_certificate_signing_request ⇒ Object
Create a new cert signing request that can be used to generate a new certificate
216 217 218 219 220 221 222 223 224 225 226 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 216 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::SHA256.new) return [csr, key] end |
.factory(attrs) ⇒ Object
Create a new object based on a hash. This is used to create a new object based on the server response.
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 230 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 |
.find(certificate_id, mac: false) ⇒ Certificate
Returns Find a certificate based on the ID of the certificate.
291 292 293 294 295 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 291 def find(certificate_id, mac: false) all(mac: mac).find do |c| c.id == certificate_id end end |
Instance Method Details
#download ⇒ OpenSSL::X509::Certificate
Returns Downloads and parses the certificate.
346 347 348 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 346 def download OpenSSL::X509::Certificate.new(download_raw) end |
#download_raw ⇒ String
Returns Download the raw data of the certificate without parsing.
341 342 343 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 341 def download_raw client.download_certificate(id, type_display_id, mac: mac?) end |
#is_push? ⇒ Bool
Returns : Is this certificate a push profile for apps?.
356 357 358 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 356 def is_push? self.kind_of?(PushCertificate) end |
#mac? ⇒ Bool
Returns Is this a Mac profile?.
361 362 363 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 361 def mac? MAC_CERTIFICATE_TYPE_IDS.include?(type_display_id) end |
#revoke! ⇒ Object
Revoke the certificate. You shouldn’t use this method probably.
351 352 353 |
# File 'spaceship/lib/spaceship/portal/certificate.rb', line 351 def revoke! client.revoke_certificate!(id, type_display_id, mac: mac?) end |