fix: authentication via env variables repo argument (#809)

---------

Co-authored-by: techknowlogick <techknowlogick@gitea.com>
Reviewed-on: https://gitea.com/gitea/tea/pulls/809
Co-authored-by: Nikolaos Karaolidis <nick@karaolidis.com>
Co-committed-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
Nikolaos Karaolidis
2026-02-19 19:23:44 +00:00
committed by techknowlogick
parent fab70f83c1
commit e3c550ff22
4 changed files with 41 additions and 9 deletions

View File

@@ -92,9 +92,19 @@ func InitCommand(cmd *cli.Command) *TeaContext {
} }
} }
// Create env login before repo context detection so it participates in remote URL matching
var extraLogins []config.Login
envLogin := GetLoginByEnvVar()
if envLogin != nil {
if _, err := utils.ValidateAuthenticationMethod(envLogin.URL, envLogin.Token, "", "", false, "", ""); err != nil {
log.Fatal(err.Error())
}
extraLogins = append(extraLogins, *envLogin)
}
// try to read local git repo & extract context: if repoFlag specifies a valid path, read repo in that dir, // try to read local git repo & extract context: if repoFlag specifies a valid path, read repo in that dir,
// otherwise attempt PWD. if no repo is found, continue with default login // otherwise attempt PWD. if no repo is found, continue with default login
if c.LocalRepo, c.Login, c.RepoSlug, err = contextFromLocalRepo(repoPath, remoteFlag); err != nil { if c.LocalRepo, c.Login, c.RepoSlug, err = contextFromLocalRepo(repoPath, remoteFlag, extraLogins); err != nil {
if err == errNotAGiteaRepo || err == gogit.ErrRepositoryNotExists { if err == errNotAGiteaRepo || err == gogit.ErrRepositoryNotExists {
// we can deal with that, commands needing the optional values use ctx.Ensure() // we can deal with that, commands needing the optional values use ctx.Ensure()
} else { } else {
@@ -107,13 +117,9 @@ func InitCommand(cmd *cli.Command) *TeaContext {
c.RepoSlug = repoFlag c.RepoSlug = repoFlag
} }
// override config user with env variable // If env vars are set, always use the env login (but repo slug was already
envLogin := GetLoginByEnvVar() // resolved by contextFromLocalRepo with the env login in the match list)
if envLogin != nil { if envLogin != nil {
_, err := utils.ValidateAuthenticationMethod(envLogin.URL, envLogin.Token, "", "", false, "", "")
if err != nil {
log.Fatal(err.Error())
}
c.Login = envLogin c.Login = envLogin
} }

View File

@@ -18,6 +18,7 @@ func GetLoginByEnvVar() *config.Login {
giteaToken := os.Getenv("GITEA_TOKEN") giteaToken := os.Getenv("GITEA_TOKEN")
githubToken := os.Getenv("GH_TOKEN") githubToken := os.Getenv("GH_TOKEN")
giteaInstanceURL := os.Getenv("GITEA_INSTANCE_URL") giteaInstanceURL := os.Getenv("GITEA_INSTANCE_URL")
giteaInstanceSSHHost := os.Getenv("GITEA_INSTANCE_SSH_HOST")
instanceInsecure := os.Getenv("GITEA_INSTANCE_INSECURE") instanceInsecure := os.Getenv("GITEA_INSTANCE_INSECURE")
insecure := false insecure := false
if len(instanceInsecure) > 0 { if len(instanceInsecure) > 0 {
@@ -38,6 +39,7 @@ func GetLoginByEnvVar() *config.Login {
Name: "GITEA_LOGIN_VIA_ENV", Name: "GITEA_LOGIN_VIA_ENV",
URL: giteaInstanceURL, URL: giteaInstanceURL,
Token: token, Token: token,
SSHHost: giteaInstanceSSHHost,
Insecure: insecure, Insecure: insecure,
SSHKey: "", SSHKey: "",
SSHCertPrincipal: "", SSHCertPrincipal: "",

View File

@@ -12,7 +12,7 @@ import (
) )
// contextFromLocalRepo discovers login & repo slug from the default branch remote of the given local repo // contextFromLocalRepo discovers login & repo slug from the default branch remote of the given local repo
func contextFromLocalRepo(repoPath, remoteValue string) (*git.TeaRepo, *config.Login, string, error) { func contextFromLocalRepo(repoPath, remoteValue string, extraLogins []config.Login) (*git.TeaRepo, *config.Login, string, error) {
repo, err := git.RepoFromPath(repoPath) repo, err := git.RepoFromPath(repoPath)
if err != nil { if err != nil {
return nil, nil, "", err return nil, nil, "", err
@@ -69,6 +69,10 @@ func contextFromLocalRepo(repoPath, remoteValue string) (*git.TeaRepo, *config.L
if err != nil { if err != nil {
return repo, nil, "", err return repo, nil, "", err
} }
// Prepend extra logins (e.g. from env vars) so they are matched first
if len(extraLogins) > 0 {
logins = append(extraLogins, logins...)
}
for _, u := range remoteConfig.URLs { for _, u := range remoteConfig.URLs {
if l, p, err := MatchLogins(u, logins); err == nil { if l, p, err := MatchLogins(u, logins); err == nil {
return repo, l, p, nil return repo, l, p, nil

View File

@@ -31,17 +31,37 @@ func Test_MatchLogins(t *testing.T) {
expectedRepoPath: "owner/repo", expectedRepoPath: "owner/repo",
hasError: false, hasError: false,
}, },
{
remoteURL: "git@custom-ssh.example.com:owner/repo.git",
logins: []config.Login{{Name: "env", URL: "https://gitea.example.com", SSHHost: "custom-ssh.example.com"}},
matchedLoginName: "env",
expectedRepoPath: "owner/repo",
hasError: false,
},
{
remoteURL: "https://gitea.example.com/owner/repo.git",
logins: []config.Login{
{Name: "env", URL: "https://gitea.example.com"},
{Name: "config", URL: "https://gitea.example.com"},
},
matchedLoginName: "env",
expectedRepoPath: "owner/repo",
hasError: false,
},
} }
for _, kase := range kases { for _, kase := range kases {
t.Run(kase.remoteURL, func(t *testing.T) { t.Run(kase.remoteURL, func(t *testing.T) {
_, repoPath, err := MatchLogins(kase.remoteURL, kase.logins) login, repoPath, err := MatchLogins(kase.remoteURL, kase.logins)
if (err != nil) != kase.hasError { if (err != nil) != kase.hasError {
t.Errorf("Expected error: %v, got: %v", kase.hasError, err) t.Errorf("Expected error: %v, got: %v", kase.hasError, err)
} }
if repoPath != kase.expectedRepoPath { if repoPath != kase.expectedRepoPath {
t.Errorf("Expected repo path: %s, got: %s", kase.expectedRepoPath, repoPath) t.Errorf("Expected repo path: %s, got: %s", kase.expectedRepoPath, repoPath)
} }
if !kase.hasError && login.Name != kase.matchedLoginName {
t.Errorf("Expected login name: %s, got: %s", kase.matchedLoginName, login.Name)
}
}) })
} }
} }