From 93d4d3cc5534baf955eda4b5096a6e51a3f945b5 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 19 Feb 2026 15:19:45 +0000 Subject: [PATCH] Skip token uniqueness check when using SSH authentication (#898) Co-authored-by: techknowlogick Co-authored-by: silverwind Reviewed-on: https://gitea.com/gitea/tea/pulls/898 Co-authored-by: Lunny Xiao Co-committed-by: Lunny Xiao --- modules/task/login_create.go | 14 ++++++-- modules/task/login_create_test.go | 57 +++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 modules/task/login_create_test.go diff --git a/modules/task/login_create.go b/modules/task/login_create.go index 8a2fbce..00af245 100644 --- a/modules/task/login_create.go +++ b/modules/task/login_create.go @@ -59,8 +59,10 @@ func CreateLogin(name, token, user, passwd, otp, scopes, sshKey, giteaURL, sshCe return fmt.Errorf("login name '%s' has already been used", login.Name) } // ... if we already use this token - if login := config.GetLoginByToken(token); login != nil { - return fmt.Errorf("token already been used, delete login '%s' first", login.Name) + if shouldCheckTokenUniqueness(token, sshAgent, sshKey, sshCertPrincipal, sshKeyFingerprint) { + if login := config.GetLoginByToken(token); login != nil { + return fmt.Errorf("token already been used, delete login '%s' first", login.Name) + } } serverURL, err := utils.ValidateAuthenticationMethod( @@ -141,6 +143,14 @@ func CreateLogin(name, token, user, passwd, otp, scopes, sshKey, giteaURL, sshCe return nil } +func shouldCheckTokenUniqueness(token string, sshAgent bool, sshKey, sshCertPrincipal, sshKeyFingerprint string) bool { + if sshAgent || sshKey != "" || sshCertPrincipal != "" || sshKeyFingerprint != "" { + return false + } + + return true +} + // generateToken creates a new token when given BasicAuth credentials func generateToken(login config.Login, user, pass, otp, scopes string) (string, error) { opts := []gitea.ClientOption{gitea.SetBasicAuth(user, pass)} diff --git a/modules/task/login_create_test.go b/modules/task/login_create_test.go new file mode 100644 index 0000000..593d37c --- /dev/null +++ b/modules/task/login_create_test.go @@ -0,0 +1,57 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package task + +import "testing" + +func TestShouldCheckTokenUniqueness(t *testing.T) { + tests := []struct { + name string + token string + sshAgent bool + sshKey string + sshCertPrincipal string + sshKeyFingerprint string + wantCheckUniqueness bool + }{ + { + name: "token only", + token: "token", + wantCheckUniqueness: true, + }, + { + name: "token with ssh agent", + token: "token", + sshAgent: true, + wantCheckUniqueness: false, + }, + { + name: "token with ssh key path", + token: "token", + sshKey: "~/.ssh/id_ed25519", + wantCheckUniqueness: false, + }, + { + name: "token with ssh cert principal", + token: "token", + sshCertPrincipal: "principal", + wantCheckUniqueness: false, + }, + { + name: "token with ssh key fingerprint", + token: "token", + sshKeyFingerprint: "SHA256:example", + wantCheckUniqueness: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := shouldCheckTokenUniqueness(tt.token, tt.sshAgent, tt.sshKey, tt.sshCertPrincipal, tt.sshKeyFingerprint) + if got != tt.wantCheckUniqueness { + t.Fatalf("expected %v, got %v", tt.wantCheckUniqueness, got) + } + }) + } +}