apt: query the Launchpad PPA API through the shared HTTP client
This commit is contained in:
+28
-20
@@ -198,7 +198,12 @@ fn validate_keyring_dir(dir_uid: u32, mode: u32, euid: u32) -> Result<(), String
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Download and import a PPA key using Launchpad API
|
||||
/// Download and import a PPA key using the Launchpad API
|
||||
///
|
||||
/// The signing key fingerprint is looked up through the shared HTTP client;
|
||||
/// the key itself is fetched from the keyserver with curl through the
|
||||
/// context, because the key file must land in the context's filesystem
|
||||
/// (which may be remote).
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `ctx` - Optional context to use
|
||||
@@ -229,33 +234,36 @@ pub async fn download_trust_ppa_key(
|
||||
ppa_name
|
||||
);
|
||||
|
||||
// Get PPA information from Launchpad API to get signing key fingerprint
|
||||
// Use the correct devel API endpoint
|
||||
let api_url = format!(
|
||||
"https://api.launchpad.net/1.0/~{}/+archive/ubuntu/{}",
|
||||
ppa_owner, ppa_name
|
||||
);
|
||||
// Get PPA information from the Launchpad API to get the signing key
|
||||
// fingerprint. The query is context-independent metadata, so it goes
|
||||
// through the shared HTTP client (timeouts, retries) rather than
|
||||
// shelling out to curl.
|
||||
let api_url = crate::launchpad::archive_url(ppa_owner, ppa_name);
|
||||
log::debug!("Querying Launchpad API: {}", api_url);
|
||||
|
||||
let api_response = ctx
|
||||
.command("curl")
|
||||
.arg("-s")
|
||||
.arg("-f")
|
||||
.arg("-H")
|
||||
.arg("Accept: application/json")
|
||||
.arg(&api_url)
|
||||
.output()?;
|
||||
|
||||
if !api_response.status.success() {
|
||||
let response = distro_info::http_get_retried(&api_url).await.map_err(|e| {
|
||||
format!(
|
||||
"Failed to query Launchpad API for PPA {}/{}: {}",
|
||||
ppa_owner, ppa_name, e
|
||||
)
|
||||
})?;
|
||||
if !response.status().is_success() {
|
||||
return Err(format!(
|
||||
"Failed to query Launchpad API for PPA {}/{}",
|
||||
ppa_owner, ppa_name
|
||||
"Failed to query Launchpad API for PPA {}/{}: HTTP {}",
|
||||
ppa_owner,
|
||||
ppa_name,
|
||||
response.status()
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
// Parse the JSON response to extract the signing key fingerprint
|
||||
let api_response_str = String::from_utf8_lossy(&api_response.stdout);
|
||||
let api_response_str = response.text().await.map_err(|e| {
|
||||
format!(
|
||||
"Failed to read the Launchpad API response for PPA {}/{}: {}",
|
||||
ppa_owner, ppa_name, e
|
||||
)
|
||||
})?;
|
||||
let ppa_response: LaunchpadPpaResponse =
|
||||
serde_json::from_str(&api_response_str).map_err(|e| {
|
||||
format!(
|
||||
|
||||
+3
-2
@@ -92,8 +92,9 @@ fn person_url(user: &str) -> String {
|
||||
}
|
||||
|
||||
/// URL of the Launchpad API resource of a PPA (`~user/+archive/ubuntu/name`
|
||||
/// covers the default `ppa` archive and named archives alike)
|
||||
fn archive_url(user: &str, ppa: &str) -> String {
|
||||
/// covers the default `ppa` archive and named archives alike); shared by the
|
||||
/// put-side pre-flight checks and the apt keyring's fingerprint lookup
|
||||
pub(crate) fn archive_url(user: &str, ppa: &str) -> String {
|
||||
format!("{API_BASE}/~{user}/+archive/ubuntu/{ppa}")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user