Class: Spaceship::Portal::ProvisioningProfile
- Inherits:
-
Spaceship::PortalBase
- Object
- Base
- Spaceship::PortalBase
- Spaceship::Portal::ProvisioningProfile
- Defined in:
- spaceship/lib/spaceship/portal/provisioning_profile.rb
Overview
Represents a provisioning profile of the Apple Dev Portal
NOTE: If the environment variable ‘SPACESHIP_AVOID_XCODE_API` is present when using this class, all requests will be made via Apple developer portal API. In the default case, this class will use the Xcode API for fetching provisioning profiles. This is an optimization that results in 1 query for all Profiles vs 1+N queries.
Direct Known Subclasses
Defined Under Namespace
Classes: AdHoc, AppStore, Development, Direct, InHouse
Instance Attribute Summary collapse
-
#app ⇒ App
A reference to the app this profile is for.
-
#certificates ⇒ Array
A list of certificates used for this profile.
-
#devices ⇒ Array
A list of devices this profile is enabled for.
-
#distribution_method ⇒ String
The profile distribution type.
-
#expires ⇒ DateTime
The date and time of when the profile expires.
-
#id ⇒ String
The ID generated by the Dev Portal You’ll probably not really need this value.
-
#is_template_profile ⇒ Bool
Does the profile use a template (has extended entitlements)?.
-
#managing_app ⇒ Object
No information about this attribute.
-
#name ⇒ String
The name of this profile.
-
#platform ⇒ String
The supported platform for this profile.
-
#profile_details ⇒ Object
This is an expensive operation as it triggers a new request.
-
#status ⇒ String
The status of this profile.
-
#sub_platform ⇒ String
The supported sub_platform for this profile.
-
#template ⇒ Bool
Lazily instantiates the provisioning profile template model.
-
#type ⇒ String
The type of the profile (development or distribution).
-
#uuid ⇒ String
The UDID of this provisioning profile This value is used for example for code signing It is also contained in the actual profile.
-
#version ⇒ String
This will always be “2”.
Attributes inherited from Base
Class Method Summary collapse
-
.all(mac: false, xcode: false) ⇒ Array
Returns all profiles registered for this account If you’re calling this from a subclass (like AdHoc), this will only return the profiles that are of this type.
-
.all_tvos ⇒ Array
Returns all profiles registered for this account If you’re calling this from a subclass (like AdHoc), this will only return the profiles that are of this type.
-
.create!(name: nil, bundle_id: nil, certificate: nil, devices: [], mac: false, sub_platform: nil, template_name: nil) ⇒ ProvisioningProfile
Create a new provisioning profile.
-
.factory(attrs) ⇒ Object
Create a new object based on a hash.
-
.find_by_bundle_id(bundle_id: nil, mac: false, sub_platform: nil) ⇒ Array
Returns an array of provisioning profiles matching the bundle identifier Returns [] if no profiles were found This may also contain invalid or expired profiles.
-
.pretty_type ⇒ String
The human readable name of this profile type.
-
.type ⇒ String
The profile type used for web requests to the Dev Portal.
Instance Method Summary collapse
-
#certificate_valid? ⇒ Bool
Is the certificate of this profile available?.
-
#delete! ⇒ Object
Delete the provisioning profile.
-
#download ⇒ String
Download the current provisioning profile.
-
#mac? ⇒ Bool
Is this a Mac provisioning profile?.
-
#managed_by_xcode? ⇒ Bool
Is this profile managed by Xcode?.
-
#repair! ⇒ ProvisioningProfile
Repair an existing provisioning profile alias to update!.
-
#template_name ⇒ String
The name of the template (as displayed in Dev Portal) or nil if provisioning profile doesn’t have a template.
-
#tvos? ⇒ Bool
Is this a tvos provisioning profile?.
-
#update! ⇒ ProvisioningProfile
Updates the provisioning profile from the local data e.g.
-
#valid? ⇒ Bool
Is the current provisioning profile valid? To also verify the certificate call certificate_valid?.
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
#app ⇒ App
A reference to the app this profile is for. You can then easily access the value directly
101 102 103 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 101 def app @app end |
#certificates ⇒ Array
Returns A list of certificates used for this profile.
120 121 122 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 120 def certificates @certificates end |
#devices ⇒ Array
Returns A list of devices this profile is enabled for. This will always be [] for AppStore profiles.
135 136 137 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 135 def devices @devices end |
#distribution_method ⇒ String
Returns The profile distribution type. You probably want to use the class type to detect the profile type instead of this string.
42 43 44 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 42 def distribution_method @distribution_method end |
#expires ⇒ DateTime
Returns The date and time of when the profile expires.
30 31 32 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 30 def expires @expires end |
#id ⇒ String
Returns The ID generated by the Dev Portal You’ll probably not really need this value.
17 18 19 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 17 def id @id end |
#is_template_profile ⇒ Bool
Returns Does the profile use a template (has extended entitlements)?.
146 147 148 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 146 def is_template_profile @is_template_profile end |
#managing_app ⇒ Object
No information about this attribute
82 83 84 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 82 def managing_app @managing_app end |
#name ⇒ String
Returns The name of this profile.
47 48 49 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 47 def name @name end |
#platform ⇒ String
Returns The supported platform for this profile.
74 75 76 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 74 def platform @platform end |
#profile_details ⇒ Object
This is an expensive operation as it triggers a new request
140 141 142 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 140 def profile_details @profile_details end |
#status ⇒ String
Returns The status of this profile.
56 57 58 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 56 def status @status end |
#sub_platform ⇒ String
Returns The supported sub_platform for this profile.
79 80 81 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 79 def sub_platform @sub_platform end |
#template ⇒ Bool
Lazily instantiates the provisioning profile template model
163 164 165 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 163 def template @template end |
#type ⇒ String
Returns The type of the profile (development or distribution). You’ll probably not need this value.
64 65 66 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 64 def type @type end |
#uuid ⇒ String
Returns The UDID of this provisioning profile This value is used for example for code signing It is also contained in the actual profile.
24 25 26 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 24 def uuid @uuid end |
#version ⇒ String
Returns This will always be “2”.
69 70 71 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 69 def version @version end |
Class Method Details
.all(mac: false, xcode: false) ⇒ Array
Returns all profiles registered for this account If you’re calling this from a subclass (like AdHoc), this will only return the profiles that are of this type
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 315 def all(mac: false, xcode: false) if ENV['SPACESHIP_AVOID_XCODE_API'] profiles = client.provisioning_profiles(mac: mac) else profiles = client.provisioning_profiles_via_xcode_api(mac: mac) end # transform raw data to class instances profiles.map! { |profile| self.factory(profile) } # filter out the profiles managed by xcode unless xcode profiles.delete_if(&:managed_by_xcode?) end return profiles if self == ProvisioningProfile return profiles.select { |profile| profile.class == self } end |
.all_tvos ⇒ Array
Returns all profiles registered for this account If you’re calling this from a subclass (like AdHoc), this will only return the profiles that are of this type
337 338 339 340 341 342 343 344 345 346 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 337 def all_tvos profiles = all(mac: false) tv_os_profiles = [] profiles.each do |tv_os_profile| if tv_os_profile.tvos? tv_os_profiles << tv_os_profile end end return tv_os_profiles end |
.create!(name: nil, bundle_id: nil, certificate: nil, devices: [], mac: false, sub_platform: nil, template_name: nil) ⇒ ProvisioningProfile
Create a new provisioning profile
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 260 def create!(name: nil, bundle_id: nil, certificate: nil, devices: [], mac: false, sub_platform: nil, template_name: nil) raise "Missing required parameter 'bundle_id'" if bundle_id.to_s.empty? raise "Missing required parameter 'certificate'. e.g. use `Spaceship::Portal::Certificate::Production.all.first`" if certificate.to_s.empty? app = Spaceship::Portal::App.find(bundle_id, mac: mac) raise "Could not find app with bundle id '#{bundle_id}'" unless app raise "Invalid sub_platform #{sub_platform}, valid values are tvOS" if !sub_platform.nil? && sub_platform != 'tvOS' # Fill in sensible default values name ||= [bundle_id, self.pretty_type].join(' ') if self == AppStore || self == InHouse || self == Direct # Distribution Profiles MUST NOT have devices devices = [] end certificate_parameter = certificate.collect(&:id) if certificate.kind_of?(Array) certificate_parameter ||= [certificate.id] # Fix https://github.com/KrauseFx/fastlane/issues/349 certificate_parameter = certificate_parameter.first if certificate_parameter.count == 1 if devices.nil? || devices.count == 0 if self == Development || self == AdHoc # For Development and AdHoc we usually want all compatible devices by default if mac devices = Spaceship::Portal::Device.all_macs elsif sub_platform == 'tvOS' devices = Spaceship::Portal::Device.all_apple_tvs else devices = Spaceship::Portal::Device.all_ios_profile_devices end end end profile = client.with_retry do client.create_provisioning_profile!(name, self.type, app.app_id, certificate_parameter, devices.map(&:id), mac: mac, sub_platform: sub_platform, template_name: template_name) end self.new(profile) 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.
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 195 def factory(attrs) # available values of `distributionMethod` at this point: ['adhoc', 'store', 'limited', 'direct', 'inhouse'] klass = case attrs['distributionMethod'] when 'limited' Development when 'store' AppStore when 'adhoc' AdHoc when 'inhouse' InHouse when 'direct' Direct # Mac-only else raise "Can't find class '#{attrs['distributionMethod']}'" end # Parse the dates # rubocop:disable Style/RescueModifier attrs['dateExpire'] = (Time.parse(attrs['dateExpire']) rescue attrs['dateExpire']) # rubocop:enable Style/RescueModifier # When a profile is created with a template name, the response # (provisioning profiles info) already contains the data about # template, which is used to instantiate the # ProvisioningProfileTemplate model. # Doing so saves an API call needed to fetch profile details. # # Verify if `attrs` contains the info needed to instantiate a template. # If not, the template will be lazily loaded. if attrs['profile'] && attrs['profile']['description'] attrs['template'] = ProvisioningProfileTemplate.factory(attrs['template']) end klass.client = @client obj = klass.new(attrs) return obj end |
.find_by_bundle_id(bundle_id: nil, mac: false, sub_platform: nil) ⇒ Array
Returns an array of provisioning profiles matching the bundle identifier Returns [] if no profiles were found This may also contain invalid or expired profiles
352 353 354 355 356 357 358 359 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 352 def find_by_bundle_id(bundle_id: nil, mac: false, sub_platform: nil) raise "Missing required parameter 'bundle_id'" if bundle_id.to_s.empty? raise "Invalid sub_platform #{sub_platform}, valid values are tvOS" if !sub_platform.nil? && sub_platform != 'tvOS' find_tvos_profiles = sub_platform == 'tvOS' all(mac: mac).find_all do |profile| profile.app.bundle_id == bundle_id && profile.tvos? == find_tvos_profiles end end |
.pretty_type ⇒ String
Returns The human readable name of this profile type.
241 242 243 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 241 def pretty_type name.split('::').last end |
.type ⇒ String
Returns The profile type used for web requests to the Dev Portal.
189 190 191 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 189 def type raise "You cannot create a ProvisioningProfile without a type. Use a subclass." end |
Instance Method Details
#certificate_valid? ⇒ Bool
Is the certificate of this profile available?
474 475 476 477 478 479 480 481 482 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 474 def certificate_valid? return false if (certificates || []).count == 0 certificates.each do |c| if Spaceship::Portal::Certificate.all(mac: mac?).collect(&:id).include?(c.id) return true end end return false end |
#delete! ⇒ Object
Delete the provisioning profile
409 410 411 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 409 def delete! client.delete_provisioning_profile!(self.id, mac: mac?) end |
#download ⇒ String
Download the current provisioning profile. This will not store the provisioning profile on the file system. Instead this method will return the content of the profile.
404 405 406 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 404 def download client.download_provisioning_profile(self.id, mac: mac?) end |
#mac? ⇒ Bool
Returns Is this a Mac provisioning profile?.
503 504 505 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 503 def mac? platform == 'mac' end |
#managed_by_xcode? ⇒ Bool
Returns Is this profile managed by Xcode?.
498 499 500 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 498 def managed_by_xcode? managing_app == 'Xcode' end |
#repair! ⇒ ProvisioningProfile
Repair an existing provisioning profile alias to update!
417 418 419 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 417 def repair! update! end |
#template_name ⇒ String
Returns The name of the template (as displayed in Dev Portal) or nil if provisioning profile doesn’t have a template.
561 562 563 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 561 def template_name is_template_profile ? template.purpose_display_name : nil end |
#tvos? ⇒ Bool
Returns Is this a tvos provisioning profile?.
508 509 510 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 508 def tvos? sub_platform == 'tvOS' end |
#update! ⇒ ProvisioningProfile
Updates the provisioning profile from the local data e.g. after you added new devices to the profile This will also update the code signing identity if necessary
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 426 def update! # sigh handles more specific filtering and validation steps that make this logic OK # # This is the minimum protection needed for people using spaceship directly unless certificate_valid? if mac? if self.kind_of?(Development) self.certificates = [Spaceship::Portal::Certificate::MacDevelopment.all.first] elsif self.kind_of?(Direct) self.certificates = [Spaceship::Portal::Certificate::DeveloperIdApplication.all.first] else self.certificates = [Spaceship::Portal::Certificate::MacAppDistribution.all.first] end else if self.kind_of?(Development) self.certificates = [Spaceship::Portal::Certificate::Development.all.first] elsif self.kind_of?(InHouse) self.certificates = [Spaceship::Portal::Certificate::InHouse.all.first] else self.certificates = [Spaceship::Portal::Certificate::Production.all.first] end end end client.with_retry do client.repair_provisioning_profile!( id, name, distribution_method, app.app_id, certificates.map(&:id), devices.map(&:id), mac: mac?, sub_platform: tvos? ? 'tvOS' : nil, template_name: is_template_profile ? template.purpose_name : nil ) end # We need to fetch the provisioning profile again, as the ID changes profile = Spaceship::Portal::ProvisioningProfile.all(mac: mac?).find do |p| p.name == self.name # we can use the name as it's valid end return profile end |
#valid? ⇒ Bool
Returns Is the current provisioning profile valid? To also verify the certificate call certificate_valid?.
486 487 488 489 490 491 492 493 494 495 |
# File 'spaceship/lib/spaceship/portal/provisioning_profile.rb', line 486 def valid? # Provisioning profiles are not invalidated automatically on the dev portal when the certificate expires. # They become Invalid only when opened directly in the portal 🤷. # We need to do an extra check on the expiration date to ensure the profile is valid. expired = Time.now.utc > self.expires is_valid = status == 'Active' && !expired return is_valid end |