spaceship 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/README.md +390 -17
- data/lib/spaceship.rb +69 -3
- data/lib/spaceship/app.rb +96 -0
- data/lib/spaceship/base.rb +86 -0
- data/lib/spaceship/certificate.rb +270 -0
- data/lib/spaceship/client.rb +399 -0
- data/lib/spaceship/device.rb +100 -0
- data/lib/spaceship/helper/net_http_generic_request.rb +12 -0
- data/lib/spaceship/helper/plist_middleware.rb +15 -0
- data/lib/spaceship/launcher.rb +89 -0
- data/lib/spaceship/profile_types.rb +39 -0
- data/lib/spaceship/provisioning_profile.rb +352 -0
- data/lib/spaceship/ui.rb +28 -0
- data/lib/spaceship/ui/select_team.rb +55 -0
- data/lib/spaceship/version.rb +2 -2
- metadata +179 -33
- data/.gitignore +0 -14
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -22
- data/Rakefile +0 -3
- data/lib/spaceship/ship.rb +0 -7
- data/spaceship.gemspec +0 -24
- data/spec/ship_spec.rb +0 -16
- data/spec/spec_helper.rb +0 -1
- data/tasks/rspec.rake +0 -3
data/lib/spaceship.rb
CHANGED
@@ -1,6 +1,72 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'spaceship/version'
|
2
|
+
require 'spaceship/base'
|
3
|
+
require 'spaceship/client'
|
4
|
+
require 'spaceship/profile_types'
|
5
|
+
require 'spaceship/app'
|
6
|
+
require 'spaceship/certificate'
|
7
|
+
require 'spaceship/device'
|
8
|
+
require 'spaceship/provisioning_profile'
|
9
|
+
require 'spaceship/launcher'
|
3
10
|
|
4
11
|
module Spaceship
|
5
|
-
#
|
12
|
+
# Use this to just setup the configuration attribute and set it later somewhere else
|
13
|
+
class << self
|
14
|
+
# This client stores the default client when using the lazy syntax
|
15
|
+
# Spaceship.app instead of using the spaceship launcher
|
16
|
+
attr_accessor :client
|
17
|
+
|
18
|
+
# Authenticates with Apple's web services. This method has to be called once
|
19
|
+
# to generate a valid session. The session will automatically be used from then
|
20
|
+
# on.
|
21
|
+
#
|
22
|
+
# This method will automatically use the username from the Appfile (if available)
|
23
|
+
# and fetch the password from the Keychain (if available)
|
24
|
+
#
|
25
|
+
# @param user (String) (optional): The username (usually the email address)
|
26
|
+
# @param password (String) (optional): The password
|
27
|
+
#
|
28
|
+
# @raise InvalidUserCredentialsError: raised if authentication failed
|
29
|
+
#
|
30
|
+
# @return (Spaceship::Client) The client the login method was called for
|
31
|
+
def login(user = nil, password = nil)
|
32
|
+
@client = Client.login(user, password)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Open up the team selection for the user (if necessary).
|
36
|
+
#
|
37
|
+
# If the user is in multiple teams, a team selection is shown.
|
38
|
+
# The user can then select a team by entering the number
|
39
|
+
#
|
40
|
+
# Additionally, the team ID is shown next to each team name
|
41
|
+
# so that the user can use the environment variable `FASTLANE_TEAM_ID`
|
42
|
+
# for future user.
|
43
|
+
#
|
44
|
+
# @return (String) The ID of the select team. You also get the value if
|
45
|
+
# the user is only in one team.
|
46
|
+
def select_team
|
47
|
+
@client.select_team
|
48
|
+
end
|
49
|
+
|
50
|
+
# Helper methods for managing multiple instances of spaceship
|
51
|
+
|
52
|
+
# @return (Class) Access the apps for the spaceship
|
53
|
+
def app
|
54
|
+
Spaceship::App.set_client(@client)
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return (Class) Access the devices for the spaceship
|
58
|
+
def device
|
59
|
+
Spaceship::Device.set_client(@client)
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return (Class) Access the certificates for the spaceship
|
63
|
+
def certificate
|
64
|
+
Spaceship::Certificate.set_client(@client)
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return (Class) Access the provisioning profiles for the spaceship
|
68
|
+
def provisioning_profile
|
69
|
+
Spaceship::ProvisioningProfile.set_client(@client)
|
70
|
+
end
|
71
|
+
end
|
6
72
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Spaceship
|
2
|
+
# Represents an App ID from the Developer Portal
|
3
|
+
class App < Base
|
4
|
+
|
5
|
+
# @return (String) The identifier of this app, provided by the Dev Portal
|
6
|
+
# @example
|
7
|
+
# "RGAWZGXSAA"
|
8
|
+
attr_accessor :app_id
|
9
|
+
|
10
|
+
# @return (String) The name you provided for this app
|
11
|
+
# @example
|
12
|
+
# "Spaceship"
|
13
|
+
attr_accessor :name
|
14
|
+
|
15
|
+
# @return (String) the supported platform of this app
|
16
|
+
# @example
|
17
|
+
# "ios"
|
18
|
+
attr_accessor :platform
|
19
|
+
|
20
|
+
# Prefix provided by the Dev Portal
|
21
|
+
# @example
|
22
|
+
# "5A997XSHK2"
|
23
|
+
attr_accessor :prefix
|
24
|
+
|
25
|
+
# @return (String) The bundle_id (app identifier) of your app
|
26
|
+
# @example
|
27
|
+
# "com.krausefx.app"
|
28
|
+
attr_accessor :bundle_id
|
29
|
+
|
30
|
+
# @return (Bool) Is this app a wildcard app (e.g. com.krausefx.*)
|
31
|
+
attr_accessor :is_wildcard
|
32
|
+
|
33
|
+
# @return (Bool) Development Push Enabled?
|
34
|
+
attr_accessor :dev_push_enabled
|
35
|
+
|
36
|
+
# @return (Bool) Production Push Enabled?
|
37
|
+
attr_accessor :prod_push_enabled
|
38
|
+
|
39
|
+
attr_mapping(
|
40
|
+
'appIdId' => :app_id,
|
41
|
+
'name' => :name,
|
42
|
+
'appIdPlatform' => :platform,
|
43
|
+
'prefix' => :prefix,
|
44
|
+
'identifier' => :bundle_id,
|
45
|
+
'isWildCard' => :is_wildcard,
|
46
|
+
'isDevPushEnabled' => :dev_push_enabled,
|
47
|
+
'isProdPushEnabled' => :prod_push_enabled
|
48
|
+
)
|
49
|
+
|
50
|
+
class << self
|
51
|
+
# Create a new object based on a hash.
|
52
|
+
# This is used to create a new object based on the server response.
|
53
|
+
def factory(attrs)
|
54
|
+
self.new(attrs)
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return (Array) Returns all apps available for this account
|
58
|
+
def all
|
59
|
+
client.apps.map { |app| self.factory(app) }
|
60
|
+
end
|
61
|
+
|
62
|
+
# Creates a new App ID on the Apple Dev Portal
|
63
|
+
#
|
64
|
+
# if bundle_id ends with '*' then it is a wildcard id otherwise, it is an explicit id
|
65
|
+
# @param bundle_id [String] the bundle id (app_identifier) of the app associated with this provisioning profile
|
66
|
+
# @param name [String] the name of the App
|
67
|
+
# @return (App) The app you just created
|
68
|
+
def create!(bundle_id: bundle_id, name: name)
|
69
|
+
if bundle_id.end_with?('*')
|
70
|
+
type = :wildcard
|
71
|
+
else
|
72
|
+
type = :explicit
|
73
|
+
end
|
74
|
+
|
75
|
+
new_app = client.create_app!(type, name, bundle_id)
|
76
|
+
self.new(new_app)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Find a specific App ID based on the bundle_id
|
80
|
+
# @return (App) The app you're looking for. This is nil if the app can't be found.
|
81
|
+
def find(bundle_id)
|
82
|
+
all.find do |app|
|
83
|
+
app.bundle_id == bundle_id
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Delete this App ID. This action will most likely fail if the App ID is already in the store
|
89
|
+
# or there are active profiles
|
90
|
+
# @return (App) The app you just deletd
|
91
|
+
def delete!
|
92
|
+
client.delete_app!(app_id)
|
93
|
+
self
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Spaceship
|
2
|
+
class Base
|
3
|
+
class << self
|
4
|
+
attr_accessor :client
|
5
|
+
|
6
|
+
def client
|
7
|
+
@client || Spaceship.client
|
8
|
+
end
|
9
|
+
|
10
|
+
#set client and return self for chaining
|
11
|
+
def set_client(client)
|
12
|
+
self.client = client
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# bang method since it changes the parameter in-place
|
18
|
+
def remap_keys!(attrs)
|
19
|
+
return if attr_mapping.nil?
|
20
|
+
|
21
|
+
attr_mapping.each do |from, to|
|
22
|
+
attrs[to] = attrs.delete(from)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def attr_mapping(attr_map = nil)
|
27
|
+
if attr_map
|
28
|
+
@attr_mapping = attr_map
|
29
|
+
else
|
30
|
+
@attr_mapping ||= ancestors[1].attr_mapping rescue nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Call a method to return a subclass constant.
|
36
|
+
#
|
37
|
+
# If `method_sym` is an underscored name of a class,
|
38
|
+
# return the class with the current client passed into it.
|
39
|
+
# If the method does not match, NoMethodError is raised.
|
40
|
+
#
|
41
|
+
# Example:
|
42
|
+
#
|
43
|
+
# Certificate.production_push
|
44
|
+
# #=> Certificate::ProductionPush
|
45
|
+
#
|
46
|
+
# ProvisioningProfile.ad_hoc
|
47
|
+
# #=> ProvisioningProfile::AdHoc
|
48
|
+
#
|
49
|
+
# ProvisioningProfile.some_other_method
|
50
|
+
# #=> NoMethodError: undefined method `some_other_method' for ProvisioningProfile
|
51
|
+
def method_missing(method_sym, *args, &block)
|
52
|
+
module_name = method_sym.to_s
|
53
|
+
module_name.sub!(/^[a-z\d]/) { $&.upcase }
|
54
|
+
module_name.gsub!(/(?:_|(\/))([a-z\d])/) { $2.upcase }
|
55
|
+
const_name = "#{self.name}::#{module_name}"
|
56
|
+
# if const_defined?(const_name)
|
57
|
+
klass = const_get(const_name)
|
58
|
+
klass.set_client(@client)
|
59
|
+
# else
|
60
|
+
# super
|
61
|
+
# end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def initialize(attrs = {})
|
66
|
+
self.class.remap_keys!(attrs)
|
67
|
+
attrs.each do |key, val|
|
68
|
+
self.send("#{key}=", val) if respond_to?("#{key}=")
|
69
|
+
end
|
70
|
+
@client = self.class.client
|
71
|
+
end
|
72
|
+
|
73
|
+
def client
|
74
|
+
@client
|
75
|
+
end
|
76
|
+
|
77
|
+
def inspect
|
78
|
+
inspectables = instance_variables - [:@client]
|
79
|
+
inspect_vars = inspectables.map do |ivar|
|
80
|
+
val = instance_variable_get(ivar)
|
81
|
+
"#{ivar}=#{val.inspect}"
|
82
|
+
end
|
83
|
+
"\n#<#{self.class.name}\n\t#{inspect_vars.join("\n\t")}>"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
module Spaceship
|
4
|
+
# Represents a certificate from the Apple Developer Portal.
|
5
|
+
#
|
6
|
+
# This can either be a code signing identity or a push profile
|
7
|
+
class Certificate < Base
|
8
|
+
# @return (String) The ID given from the developer portal. You'll probably not need it.
|
9
|
+
# @example
|
10
|
+
# "P577TH3PAA"
|
11
|
+
attr_accessor :id
|
12
|
+
|
13
|
+
# @return (String) The name of the certificate
|
14
|
+
# @example Company
|
15
|
+
# "SunApps GmbH"
|
16
|
+
# @example Push Profile
|
17
|
+
# "com.krausefx.app"
|
18
|
+
attr_accessor :name
|
19
|
+
|
20
|
+
# @return (String) Status of the certificate
|
21
|
+
# @example
|
22
|
+
# "Issued"
|
23
|
+
attr_accessor :status
|
24
|
+
|
25
|
+
# @return (Date) The date and time when the certificate was created
|
26
|
+
# @example
|
27
|
+
# 2015-04-01 21:24:00 UTC
|
28
|
+
attr_accessor :created
|
29
|
+
|
30
|
+
# @return (Date) The date and time when the certificate will expire
|
31
|
+
# @example
|
32
|
+
# 2016-04-01 21:24:00 UTC
|
33
|
+
attr_accessor :expires
|
34
|
+
|
35
|
+
# @return (String) The owner type that defines if it's a push profile
|
36
|
+
# or a code signing identity
|
37
|
+
#
|
38
|
+
# @example Code Signing Identity
|
39
|
+
# "team"
|
40
|
+
# @example Push Certificate
|
41
|
+
# "bundle"
|
42
|
+
attr_accessor :owner_type
|
43
|
+
|
44
|
+
# @return (String) The name of the owner
|
45
|
+
#
|
46
|
+
# @example Code Signing Identity (usually the company name)
|
47
|
+
# "SunApps Gmbh"
|
48
|
+
# @example Push Certificate (the name of your App ID)
|
49
|
+
# "Awesome App"
|
50
|
+
attr_accessor :owner_name
|
51
|
+
|
52
|
+
# @return (String) The ID of the owner, that can be used to
|
53
|
+
# fetch more information
|
54
|
+
# @example
|
55
|
+
# "75B83SPLAA"
|
56
|
+
attr_accessor :owner_id
|
57
|
+
|
58
|
+
# Indicates the type of this certificate
|
59
|
+
# which is automatically used to determine the class of
|
60
|
+
# the certificate. Available values listed in CERTIFICATE_TYPE_IDS
|
61
|
+
# @return (String) The type of the certificate
|
62
|
+
# @example Production Certificate
|
63
|
+
# "R58UK2EWSO"
|
64
|
+
# @example Development Certificate
|
65
|
+
# "5QPB9NHCEI"
|
66
|
+
attr_accessor :type_display_id
|
67
|
+
|
68
|
+
attr_mapping({
|
69
|
+
'certificateId' => :id,
|
70
|
+
'name' => :name,
|
71
|
+
'statusString' => :status,
|
72
|
+
'dateCreated' => :created,
|
73
|
+
'expirationDate' => :expires,
|
74
|
+
'ownerType' => :owner_type,
|
75
|
+
'ownerName' => :owner_name,
|
76
|
+
'ownerId' => :owner_id,
|
77
|
+
'certificateTypeDisplayId' => :type_display_id
|
78
|
+
})
|
79
|
+
|
80
|
+
#####################################################
|
81
|
+
# Certs are not associated with apps
|
82
|
+
#####################################################
|
83
|
+
|
84
|
+
# A development code signing certificate used for development environment
|
85
|
+
class Development < Certificate; end
|
86
|
+
|
87
|
+
# A production code signing certificate used for distribution environment
|
88
|
+
class Production < Certificate; end
|
89
|
+
|
90
|
+
# An In House code signing certificate used for enterprise distributions
|
91
|
+
class InHouse < Certificate; end
|
92
|
+
|
93
|
+
#####################################################
|
94
|
+
# Certs that are specific for one app
|
95
|
+
#####################################################
|
96
|
+
|
97
|
+
# Abstract class for push certificates. Check out the subclasses
|
98
|
+
# DevelopmentPush, ProductionPush, WebsitePush and VoipPush
|
99
|
+
class PushCertificate < Certificate; end
|
100
|
+
|
101
|
+
# A push notification certificate for development environment
|
102
|
+
class DevelopmentPush < PushCertificate; end
|
103
|
+
|
104
|
+
# A push notification certificate for production environment
|
105
|
+
class ProductionPush < PushCertificate; end
|
106
|
+
|
107
|
+
# A push notification certificate for websites
|
108
|
+
class WebsitePush < PushCertificate; end
|
109
|
+
|
110
|
+
# A push notification certificate for the VOIP environment
|
111
|
+
class VoipPush < PushCertificate; end
|
112
|
+
|
113
|
+
# Passbook certificate
|
114
|
+
class Passbook < Certificate; end
|
115
|
+
|
116
|
+
# ApplePay certificate
|
117
|
+
class ApplePay < Certificate; end
|
118
|
+
|
119
|
+
CERTIFICATE_TYPE_IDS = {
|
120
|
+
"5QPB9NHCEI" => Development,
|
121
|
+
"R58UK2EWSO" => Production,
|
122
|
+
"9RQEK7MSXA" => InHouse,
|
123
|
+
"LA30L5BJEU" => Certificate,
|
124
|
+
"BKLRAVXMGM" => DevelopmentPush,
|
125
|
+
"3BQKVH9I2X" => ProductionPush,
|
126
|
+
"Y3B2F3TYSI" => Passbook,
|
127
|
+
"3T2ZP62QW8" => WebsitePush,
|
128
|
+
"E5D663CMZW" => WebsitePush,
|
129
|
+
"4APLUP237T" => ApplePay
|
130
|
+
}
|
131
|
+
|
132
|
+
#class methods
|
133
|
+
class << self
|
134
|
+
# Create a new code signing request that can be used to
|
135
|
+
# generate a new certificate
|
136
|
+
# @example
|
137
|
+
# Create a new certificate signing request
|
138
|
+
# csr, pkey = Spaceship.certificate.create_certificate_signing_request
|
139
|
+
#
|
140
|
+
# # Use the signing request to create a new distribution certificate
|
141
|
+
# Spaceship.certificate.production.create!(csr: csr)
|
142
|
+
def create_certificate_signing_request
|
143
|
+
key = OpenSSL::PKey::RSA.new 2048
|
144
|
+
csr = OpenSSL::X509::Request.new
|
145
|
+
csr.version = 0
|
146
|
+
csr.subject = OpenSSL::X509::Name.new([
|
147
|
+
['CN', 'PEM', OpenSSL::ASN1::UTF8STRING]
|
148
|
+
])
|
149
|
+
csr.public_key = key.public_key
|
150
|
+
csr.sign(key, OpenSSL::Digest::SHA1.new)
|
151
|
+
return [csr, key]
|
152
|
+
end
|
153
|
+
|
154
|
+
# Create a new object based on a hash.
|
155
|
+
# This is used to create a new object based on the server response.
|
156
|
+
def factory(attrs)
|
157
|
+
# Example:
|
158
|
+
# => {"name"=>"iOS Distribution: SunApps GmbH",
|
159
|
+
# "certificateId"=>"XC5PH8DAAA",
|
160
|
+
# "serialNumber"=>"797E732CCE8B7AAA",
|
161
|
+
# "status"=>"Issued",
|
162
|
+
# "statusCode"=>0,
|
163
|
+
# "expirationDate"=>#<DateTime: 2015-11-25T22:45:50+00:00 ((2457352j,81950s,0n),+0s,2299161j)>,
|
164
|
+
# "certificatePlatform"=>"ios",
|
165
|
+
# "certificateType"=>
|
166
|
+
# {"certificateTypeDisplayId"=>"R58UK2EAAA",
|
167
|
+
# "name"=>"iOS Distribution",
|
168
|
+
# "platform"=>"ios",
|
169
|
+
# "permissionType"=>"distribution",
|
170
|
+
# "distributionType"=>"store",
|
171
|
+
# "distributionMethod"=>"app",
|
172
|
+
# "ownerType"=>"team",
|
173
|
+
# "daysOverlap"=>364,
|
174
|
+
# "maxActive"=>2}}
|
175
|
+
|
176
|
+
if attrs['certificateType']
|
177
|
+
# On some accounts this is nested, so we need to flatten it
|
178
|
+
attrs.merge!(attrs['certificateType'])
|
179
|
+
attrs.delete('certificateType')
|
180
|
+
end
|
181
|
+
|
182
|
+
# Parse the dates
|
183
|
+
attrs['expirationDate'] = (Time.parse(attrs['expirationDate']) rescue attrs['expirationDate'])
|
184
|
+
attrs['dateCreated'] = (Time.parse(attrs['dateCreated']) rescue attrs['dateCreated'])
|
185
|
+
|
186
|
+
# Here we go
|
187
|
+
klass = CERTIFICATE_TYPE_IDS[attrs['certificateTypeDisplayId']]
|
188
|
+
klass ||= Certificate
|
189
|
+
klass.client = @client
|
190
|
+
klass.new(attrs)
|
191
|
+
end
|
192
|
+
|
193
|
+
# @return (Array) Returns all certificates of this account.
|
194
|
+
# If this is called from a subclass of Certificate, this will
|
195
|
+
# only include certificates matching the current type.
|
196
|
+
def all
|
197
|
+
if (self == Certificate) # are we the base-class?
|
198
|
+
types = CERTIFICATE_TYPE_IDS.keys
|
199
|
+
else
|
200
|
+
types = [CERTIFICATE_TYPE_IDS.key(self)]
|
201
|
+
end
|
202
|
+
|
203
|
+
client.certificates(types).map do |cert|
|
204
|
+
factory(cert)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# @return (Certificate) Find a certificate based on the ID of the certificate.
|
209
|
+
def find(certificate_id)
|
210
|
+
all.find do |c|
|
211
|
+
c.id == certificate_id
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
# Generate a new certificate based on a code certificate signing request
|
216
|
+
# @param csr (required): The certificate signing request to use. Get one using
|
217
|
+
# `create_certificate_signing_request`
|
218
|
+
# @param bundle_id (String) (optional): The app identifier this certificate is for.
|
219
|
+
# This value is only needed if you create a push profile. For normal code signing
|
220
|
+
# certificates, you must only pass a certificate signing request.
|
221
|
+
# @example
|
222
|
+
# # Create a new certificate signing request
|
223
|
+
# csr, pkey = Spaceship::Certificate.create_certificate_signing_request
|
224
|
+
#
|
225
|
+
# # Use the signing request to create a new distribution certificate
|
226
|
+
# Spaceship::Certificate::Production.create!(csr: csr)
|
227
|
+
# @return (Device): The newly created device
|
228
|
+
def create!(csr: csr, bundle_id: nil)
|
229
|
+
type = CERTIFICATE_TYPE_IDS.key(self)
|
230
|
+
|
231
|
+
# look up the app_id by the bundle_id
|
232
|
+
if bundle_id
|
233
|
+
app = Spaceship::App.find(bundle_id)
|
234
|
+
raise "Could not find app with bundle id '#{bundle_id}'" unless app
|
235
|
+
app_id = app.app_id
|
236
|
+
end
|
237
|
+
|
238
|
+
# if this succeeds, we need to save the .cer and the private key in keychain access or wherever they go in linux
|
239
|
+
response = client.create_certificate!(type, csr.to_pem, app_id)
|
240
|
+
# munge the response to make it work for the factory
|
241
|
+
response['certificateTypeDisplayId'] = response['certificateType']['certificateTypeDisplayId']
|
242
|
+
self.new(response)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# instance methods
|
247
|
+
|
248
|
+
# @return (String) Download the raw data of the certificate without parsing
|
249
|
+
def download_raw
|
250
|
+
client.download_certificate(id, type_display_id)
|
251
|
+
end
|
252
|
+
|
253
|
+
# @return (OpenSSL::X509::Certificate) Downloads and parses the certificate
|
254
|
+
def download
|
255
|
+
OpenSSL::X509::Certificate.new(download_raw)
|
256
|
+
end
|
257
|
+
|
258
|
+
# Revoke the certificate. You shouldn't use this method probably.
|
259
|
+
def revoke!
|
260
|
+
client.revoke_certificate!(id, type_display_id)
|
261
|
+
end
|
262
|
+
|
263
|
+
# @return (Bool): Is this certificate a push profile for apps?
|
264
|
+
def is_push?
|
265
|
+
# does display_type_id match push?
|
266
|
+
[Client::ProfileTypes::Push.development, Client::ProfileTypes::Push.production].include?(type_display_id)
|
267
|
+
end
|
268
|
+
|
269
|
+
end
|
270
|
+
end
|