182
pub profile_type: ProfileType,
183
}
184
185
+/// The bundle ID behind a profile, as `GET /v1/profiles/{id}/bundleId`
186
+/// returns it. Only the fields a caller needs to match a profile to an
187
+/// app; the signing crate doesn't depend on the aso crate's full type.
188
+#[derive(Debug, Clone, Serialize, Deserialize)]
189
+#[serde(rename_all = "camelCase")]
190
+pub struct ProfileBundleIdAttributes {
191
+ pub identifier: Option<String>,
192
+ pub platform: Option<String>,
193
+}
194
+
195
+pub type ProfileBundleId = Resource<ProfileBundleIdAttributes>;
196
+
197
/// The relationships a create request must carry.
198
///
199
/// Built explicitly rather than derived from ids alone, because `devices`
293
relationships: ProfileCreateRelationships,
294
) -> Result<Profile>;
295
296
+ /// `GET /v1/profiles/{id}/bundleId` — the bundle ID a profile is for.
297
+ ///
298
+ /// A list response carries only the relationship link, not the
299
+ /// identifier, so finding which app an expired profile belongs to
300
+ /// takes one of these per profile.
301
+ async fn get_profile_bundle_id(&self, id: &str) -> Result<ProfileBundleId>;
302
+
303
/// `DELETE /v1/profiles/{id}`.
304
///
305
/// Narrower than revoking a certificate: it invalidates only this
365
Ok(doc.data)
366
}
367
368
+ async fn get_profile_bundle_id(&self, id: &str) -> Result<ProfileBundleId> {
369
+ let doc: Document<ProfileBundleIdAttributes> = self
370
+ .request(
371
+ Method::GET,
372
+ &format!("/v1/profiles/{id}/bundleId"),
373
+ &[],
374
+ None::<&()>,
375
+ )
376
+ .await?;
377
+ Ok(doc.data)
378
+ }
379
+
380
async fn delete_profile(&self, id: &str) -> Result<()> {
381
self.request_no_content(
382
Method::DELETE,
482
let json = serde_json::to_value(&relationships).expect("serializes");
483
assert!(json.get("devices").is_none());
484
}
485
+
486
+ #[test]
487
+ fn reads_the_bundle_id_behind_a_profile() {
488
+ let doc: Document<ProfileBundleIdAttributes> = serde_json::from_value(serde_json::json!({
489
+ "data": { "id": "C3PP53MLM3", "type": "bundleIds",
490
+ "attributes": { "identifier": "ai.splitfire.SplitfireAI",
491
+ "platform": "UNIVERSAL", "name": "SplitFire AI", "seedId": "2TQF86ZACD" } }
492
+ }))
493
+ .unwrap();
494
+ assert_eq!(doc.data.id, "C3PP53MLM3");
495
+ assert_eq!(
496
+ doc.data.attributes.identifier.as_deref(),
497
+ Some("ai.splitfire.SplitfireAI")
498
+ );
499
+ }
500
}