Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions bin/core/src/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,14 @@ pub fn empty_or_only_spaces(word: &str) -> bool {

/// First checks db for token, then checks core config.
/// Only errors if db call errors.
/// Returns (token, use_https)
/// Returns the configured account credential prepared for HTTPS basic auth.
///
/// The returned value is formatted as `"<username>:<token>"` so that
/// [`RepoExecutionArgs::remote_url`] produces
/// `https://<username>:<token>@host/...`. If the stored token already
/// contains a `:`, the user has manually combined the credentials
/// (the v1.19.2 workaround for issue #387) and we pass it through
/// unchanged for backwards compatibility.
pub async fn git_token(
provider_domain: &str,
account_username: &str,
Expand All @@ -71,7 +78,10 @@ pub async fn git_token(
.context("failed to query db for git provider accounts")?;
if let Some(provider) = db_provider {
on_https_found(provider.https);
return Ok(Some(provider.token));
return Ok(Some(combine_account_credential(
account_username,
&provider.token,
)));
}
Ok(
core_config()
Expand All @@ -84,11 +94,32 @@ pub async fn git_token(
.accounts
.iter()
.find(|account| account.username == account_username)
.map(|account| account.token.clone())
.map(|account| {
combine_account_credential(account_username, &account.token)
})
}),
)
}

/// Combine a configured git account `username` with its `token` into the
/// `"<username>:<token>"` form that [`RepoExecutionArgs::remote_url`]
/// splits back out for HTTPS basic auth.
///
/// Without this, [`RepoExecutionArgs::remote_url`] would fall back to its
/// hardcoded `token:<token>@` default and clones against providers that
/// validate the basic-auth username (GitLab deploy tokens, Bitbucket,
/// fine-grained GitHub PATs) would fail with `HTTP Basic: Access denied`.
///
/// If the stored token already contains a `:` the user has manually
/// combined the credentials (the v1.19.2 workaround for issue #387);
/// return it unchanged so existing setups keep working.
fn combine_account_credential(username: &str, token: &str) -> String {
if token.contains(':') {
return token.to_string();
}
format!("{username}:{token}")
}

pub async fn stack_git_token(
stack: &mut Stack,
repo: Option<&mut Repo>,
Expand Down
25 changes: 24 additions & 1 deletion bin/periphery/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,13 @@ pub async fn handle_post_repo_execution(
// Token
// =======

/// Look up a raw access token in the Periphery git provider config.
///
/// Use this when you only need the secret (for example to redact it from
/// log output). For building a clone URL prefer [`git_token`], which also
/// combines the configured username with the token so the resulting URL
/// authenticates correctly against providers that validate the basic-auth
/// username (GitLab deploy tokens, Bitbucket, fine-grained GitHub PATs).
pub fn git_token_simple(
domain: &str,
account_username: &str,
Expand All @@ -252,6 +259,19 @@ pub fn git_token_simple(
.with_context(|| format!("Did not find token in config for git account {account_username} | domain {domain}"))
}

/// Resolve the credential to use when running `git clone` / `git fetch`
/// on the Periphery host.
///
/// If Core sent a token for this execution, use it as-is — Core is
/// responsible for formatting it as `"<username>:<token>"` (see
/// `git_token` in the Core helpers). Otherwise fall back to the
/// Periphery config and combine the configured account username with
/// its token in the same form so [`RepoExecutionArgs::remote_url`]
/// produces `https://<username>:<token>@host/...`.
///
/// Backwards-compatible: if the stored token already contains a `:`
/// the caller used the v1.19.2 workaround for issue #387, so we pass
/// it through unchanged.
pub fn git_token(
core_token: Option<String>,
args: &RepoExecutionArgs,
Expand All @@ -263,7 +283,10 @@ pub fn git_token(
return Ok(None);
};
let token = git_token_simple(&args.provider, account)?;
Ok(Some(token.to_string()))
if token.contains(':') {
return Ok(Some(token.to_string()));
}
Ok(Some(format!("{account}:{token}")))
}

pub fn registry_token(
Expand Down