summaryrefslogtreecommitdiff
path: root/cli/tools
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tools')
-rw-r--r--cli/tools/registry/mod.rs127
-rw-r--r--cli/tools/registry/tar.rs26
2 files changed, 89 insertions, 64 deletions
diff --git a/cli/tools/registry/mod.rs b/cli/tools/registry/mod.rs
index 733ea301f..42bb06087 100644
--- a/cli/tools/registry/mod.rs
+++ b/cli/tools/registry/mod.rs
@@ -4,6 +4,7 @@ use std::fmt::Write;
use std::io::IsTerminal;
use std::path::Path;
use std::path::PathBuf;
+use std::rc::Rc;
use std::sync::Arc;
use base64::prelude::BASE64_STANDARD;
@@ -227,21 +228,21 @@ async fn perform_publish(
let client = http_client.client()?;
let registry_url = crate::cache::DENO_REGISTRY_URL.to_string();
- let authorization = match auth_method {
+ let permissions = packages
+ .iter()
+ .map(|package| Permission::VersionPublish {
+ scope: &package.scope,
+ package: &package.package,
+ version: &package.version,
+ tarball_hash: &package.tarball_hash,
+ })
+ .collect::<Vec<_>>();
+
+ let authorizations = match auth_method {
AuthMethod::Interactive => {
let verifier = uuid::Uuid::new_v4().to_string();
let challenge = BASE64_STANDARD.encode(sha2::Sha256::digest(&verifier));
- let permissions = packages
- .iter()
- .map(|package| Permission::VersionPublish {
- scope: &package.scope,
- package: &package.package,
- version: &package.version,
- tarball_hash: &package.tarball_hash,
- })
- .collect::<Vec<_>>();
-
let response = client
.post(format!("{}authorizations", registry_url))
.json(&serde_json::json!({
@@ -290,7 +291,12 @@ async fn perform_publish(
colors::gray("Authenticated as"),
colors::cyan(res.user.name)
);
- break format!("Bearer {}", res.token);
+ let authorization: Rc<str> = format!("Bearer {}", res.token).into();
+ let mut authorizations = Vec::new();
+ for _ in &packages {
+ authorizations.push(authorization.clone());
+ }
+ break authorizations;
}
Err(err) => {
if err.code == "authorizationPending" {
@@ -302,54 +308,65 @@ async fn perform_publish(
}
}
}
- AuthMethod::Token(token) => format!("Bearer {}", token),
+ AuthMethod::Token(token) => {
+ let authorization: Rc<str> = format!("Bearer {}", token).into();
+ let mut authorizations = Vec::new();
+ for _ in &packages {
+ authorizations.push(authorization.clone());
+ }
+ authorizations
+ }
AuthMethod::Oidc(oidc_config) => {
- let permissions = packages
- .iter()
- .map(|package| Permission::VersionPublish {
- scope: &package.scope,
- package: &package.package,
- version: &package.version,
- tarball_hash: &package.tarball_hash,
- })
- .collect::<Vec<_>>();
- let audience = json!({ "permissions": permissions }).to_string();
-
- let url = format!(
- "{}&audience={}",
- oidc_config.url,
- percent_encoding::percent_encode(
- audience.as_bytes(),
- percent_encoding::NON_ALPHANUMERIC
- )
- );
-
- let response = client
- .get(url)
- .bearer_auth(oidc_config.token)
- .send()
- .await
- .context("Failed to get OIDC token")?;
- let status = response.status();
- let text = response.text().await.with_context(|| {
- format!("Failed to get OIDC token: status {}", status)
- })?;
- if !status.is_success() {
- bail!(
- "Failed to get OIDC token: status {}, response: '{}'",
- status,
- text
+ let mut authorizations = Vec::new();
+ for permissions in permissions.chunks(16) {
+ let audience = json!({ "permissions": permissions }).to_string();
+ let url = format!(
+ "{}&audience={}",
+ oidc_config.url,
+ percent_encoding::percent_encode(
+ audience.as_bytes(),
+ percent_encoding::NON_ALPHANUMERIC
+ )
);
- }
- let OidcTokenResponse { value } = serde_json::from_str(&text)
- .with_context(|| {
- format!("Failed to parse OIDC token: '{}' (status {})", text, status)
+
+ let response = client
+ .get(url)
+ .bearer_auth(&oidc_config.token)
+ .send()
+ .await
+ .context("Failed to get OIDC token")?;
+ let status = response.status();
+ let text = response.text().await.with_context(|| {
+ format!("Failed to get OIDC token: status {}", status)
})?;
- format!("githuboidc {}", value)
+ if !status.is_success() {
+ bail!(
+ "Failed to get OIDC token: status {}, response: '{}'",
+ status,
+ text
+ );
+ }
+ let OidcTokenResponse { value } = serde_json::from_str(&text)
+ .with_context(|| {
+ format!(
+ "Failed to parse OIDC token: '{}' (status {})",
+ text, status
+ )
+ })?;
+
+ let authorization: Rc<str> = format!("githuboidc {}", value).into();
+ for _ in &packages {
+ authorizations.push(authorization.clone());
+ }
+ }
+ authorizations
}
};
- for package in packages {
+ assert_eq!(packages.len(), authorizations.len());
+ for (package, authorization) in
+ packages.into_iter().zip(authorizations.into_iter())
+ {
println!(
"{} @{}/{}@{} ...",
colors::intense_blue("Publishing"),
@@ -365,7 +382,7 @@ async fn perform_publish(
let response = client
.post(url)
- .header(AUTHORIZATION, &authorization)
+ .header(AUTHORIZATION, &*authorization)
.header(CONTENT_ENCODING, "gzip")
.body(package.tarball)
.send()
diff --git a/cli/tools/registry/tar.rs b/cli/tools/registry/tar.rs
index e8097357d..61532917a 100644
--- a/cli/tools/registry/tar.rs
+++ b/cli/tools/registry/tar.rs
@@ -18,25 +18,33 @@ pub fn create_gzipped_tarball(
unfurler: ImportMapUnfurler,
) -> Result<Bytes, AnyError> {
let mut tar = TarGzArchive::new();
- let dir_url = Url::from_directory_path(&dir).unwrap();
+ let dir = dir
+ .canonicalize()
+ .map_err(|_| anyhow::anyhow!("Unable to canonicalize path {:?}", dir))?;
- for entry in walkdir::WalkDir::new(dir).follow_links(false) {
+ for entry in walkdir::WalkDir::new(&dir).follow_links(false) {
let entry = entry?;
if entry.file_type().is_file() {
let url = Url::from_file_path(entry.path())
- .map_err(|_| anyhow::anyhow!("Invalid file path {:?}", entry.path()))?;
- let relative_path = dir_url
- .make_relative(&url)
- .expect("children can be relative to parent");
+ .map_err(|_| anyhow::anyhow!("Unable to convert path to url"))?;
+ let relative_path = entry
+ .path()
+ .strip_prefix(&dir)
+ .map_err(|err| anyhow::anyhow!("Unable to strip prefix: {err}"))?;
+ let relative_path = relative_path.to_str().ok_or_else(|| {
+ anyhow::anyhow!("Unable to convert path to string {:?}", relative_path)
+ })?;
let data = std::fs::read(entry.path())
.with_context(|| format!("Unable to read file {:?}", entry.path()))?;
let content = unfurler
.unfurl(&url, data)
.with_context(|| format!("Unable to unfurl file {:?}", entry.path()))?;
- tar.add_file(relative_path, &content).with_context(|| {
- format!("Unable to add file to tarball {:?}", entry.path())
- })?;
+ tar
+ .add_file(relative_path.to_string(), &content)
+ .with_context(|| {
+ format!("Unable to add file to tarball {:?}", entry.path())
+ })?;
} else if entry.file_type().is_dir() {
// skip
} else {