Repository navigation
fix(auth): pick the push credential from the resolved forge, not the host name #1124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||||||||||
| use std::process::Command; | ||||||||||||||
|
|
||||||||||||||
| use super::repo::Repository; | ||||||||||||||
| use crate::config::ForgeKind; | ||||||||||||||
| use crate::forge::gitlab::GitLabToken; | ||||||||||||||
|
|
||||||||||||||
| #[cfg(test)] | ||||||||||||||
|
|
@@ -32,24 +33,36 @@ fn is_gitlab(url: &str) -> bool { | |||||||||||||
| host_of(url).is_some_and(|host| host.contains("gitlab")) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| pub(super) fn token_for_url(url: &str) -> Option<(String, String)> { | ||||||||||||||
| if let Ok(token) = std::env::var("FERRFLOW_TOKEN") { | ||||||||||||||
| let user = if is_gitlab(url) { | ||||||||||||||
| fn forge_of(url: &str, configured: ForgeKind) -> Option<ForgeKind> { | ||||||||||||||
| match configured { | ||||||||||||||
| ForgeKind::Auto if is_gitlab(url) => Some(ForgeKind::Gitlab), | ||||||||||||||
| ForgeKind::Auto => crate::forge::detect_forge_with_probe(url), | ||||||||||||||
| explicit => Some(explicit), | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| pub(super) fn token_for_url(url: &str, forge: ForgeKind) -> Option<(String, String)> { | ||||||||||||||
| let ferrflow_token = std::env::var("FERRFLOW_TOKEN").ok(); | ||||||||||||||
| let gitlab_token = std::env::var("GITLAB_TOKEN").ok(); | ||||||||||||||
| let github_token = std::env::var("GITHUB_TOKEN").ok(); | ||||||||||||||
|
Comment on lines
+45
to
+47
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: an empty variable counts as present here.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Taken in #1132 (this PR had already merged). |
||||||||||||||
| if ferrflow_token.is_none() && gitlab_token.is_none() && github_token.is_none() { | ||||||||||||||
| return None; | ||||||||||||||
| } | ||||||||||||||
| let is_gitlab = forge_of(url, forge) == Some(ForgeKind::Gitlab); | ||||||||||||||
| if let Some(token) = ferrflow_token { | ||||||||||||||
| let user = if is_gitlab { | ||||||||||||||
| GitLabToken::of(&token).git_username() | ||||||||||||||
| } else { | ||||||||||||||
| "x-access-token" | ||||||||||||||
| }; | ||||||||||||||
| return Some((user.to_string(), token)); | ||||||||||||||
| } | ||||||||||||||
| if is_gitlab(url) { | ||||||||||||||
| if let Ok(token) = std::env::var("GITLAB_TOKEN") { | ||||||||||||||
| let user = GitLabToken::of(&token).git_username(); | ||||||||||||||
| return Some((user.to_string(), token)); | ||||||||||||||
| } | ||||||||||||||
| } else if let Ok(token) = std::env::var("GITHUB_TOKEN") { | ||||||||||||||
| return Some(("x-access-token".to_string(), token)); | ||||||||||||||
| if is_gitlab { | ||||||||||||||
| let token = gitlab_token?; | ||||||||||||||
| let user = GitLabToken::of(&token).git_username(); | ||||||||||||||
| return Some((user.to_string(), token)); | ||||||||||||||
| } | ||||||||||||||
| None | ||||||||||||||
| github_token.map(|token| ("x-access-token".to_string(), token)) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// Where the credential reaches git. `/proc/<pid>/cmdline` is world-readable, | ||||||||||||||
|
|
@@ -68,9 +81,9 @@ pub(super) const GIT_PASSWORD_VAR: &str = "FERRFLOW_GIT_PASSWORD"; | |||||||||||||
| const CREDENTIAL_HELPER: &str = | ||||||||||||||
| r#"!f() { echo "username=$FERRFLOW_GIT_USER"; echo "password=$FERRFLOW_GIT_PASSWORD"; }; f"#; | ||||||||||||||
|
|
||||||||||||||
| pub(super) fn configure_git_command(cmd: &mut Command, url: &str) { | ||||||||||||||
| pub(super) fn configure_git_command(cmd: &mut Command, url: &str, forge: ForgeKind) { | ||||||||||||||
| scrub_trace_env(cmd); | ||||||||||||||
| if let Some((user, token)) = token_for_url(url) { | ||||||||||||||
| if let Some((user, token)) = token_for_url(url, forge) { | ||||||||||||||
| cmd.env(GIT_USER_VAR, user); | ||||||||||||||
| cmd.env(GIT_PASSWORD_VAR, token); | ||||||||||||||
| cmd.arg("-c") | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
detect_forge_with_probefalls through todetect_forge_from_url, which matchesgithub.com/gitlab.com/codeberg.organywhere in the string, path included. This file deliberately went the other way:is_gitlabmatches onhost_of(url)only, anda_repository_name_does_not_pick_the_forgeasserts a repo name must not select the credential. The auto branch now gives that up.Concretely, remote
https://git.acme.com/tools/gitlab.com-exporter.gitwithforge: autoresolves to GitLab off the path: withFERRFLOW_TOKENset the push username flips fromx-access-tokentooauth2, and with onlyGITHUB_TOKENsettoken_for_urlreturnsNone, so the push goes out with no credential at all. The existing test does not catch it because all four of its URLs are ongithub.com.Detecting on the host keeps the probe cache key identical and leaves the SaaS short-circuits working:
(
forge_targetinpreview.rspasses the full URL too, so the API side has the same quirk. Worth fixing there in the same pass, or insidedetect_forge_from_url.)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Taken in #1132 (this PR had already merged).