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) + } + }) + } +}