Skip to content

Commit 960a5b9

Browse files
authored
Merge branch 'main' into lunny/refactor_review_request
2 parents be34352 + 2802f96 commit 960a5b9

File tree

4 files changed

+76
-5
lines changed

4 files changed

+76
-5
lines changed

cmd/serv.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,6 @@ func runServ(ctx context.Context, c *cli.Command) error {
229229
username := repoPathFields[0]
230230
reponame := strings.TrimSuffix(repoPathFields[1], ".git") // “the-repo-name" or "the-repo-name.wiki"
231231

232-
// LowerCase and trim the repoPath as that's how they are stored.
233-
// This should be done after splitting the repoPath into username and reponame
234-
// so that username and reponame are not affected.
235-
repoPath = strings.ToLower(strings.TrimSpace(repoPath))
236-
237232
if !repo.IsValidSSHAccessRepoName(reponame) {
238233
return fail(ctx, "Invalid repo name", "Invalid repo name: %s", reponame)
239234
}
@@ -280,6 +275,11 @@ func runServ(ctx context.Context, c *cli.Command) error {
280275
return fail(ctx, extra.UserMsg, "ServCommand failed: %s", extra.Error)
281276
}
282277

278+
// LowerCase and trim the repoPath as that's how they are stored.
279+
// This should be done after splitting the repoPath into username and reponame
280+
// so that username and reponame are not affected.
281+
repoPath = strings.ToLower(results.OwnerName + "/" + results.RepoName + ".git")
282+
283283
// LFS SSH protocol
284284
if verb == git.CmdVerbLfsTransfer {
285285
token, err := getLFSAuthToken(ctx, lfsVerb, results)

models/fixtures/user_redirect.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22
id: 1
33
lower_name: olduser1
44
redirect_user_id: 1
5+
-
6+
id: 2
7+
lower_name: olduser2
8+
redirect_user_id: 2

routers/private/serv.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ func ServCommand(ctx *context.PrivateContext) {
108108
results.RepoName = repoName[:len(repoName)-5]
109109
}
110110

111+
// Check if there is a user redirect for the requested owner
112+
redirectedUserID, err := user_model.LookupUserRedirect(ctx, results.OwnerName)
113+
if err == nil {
114+
owner, err := user_model.GetUserByID(ctx, redirectedUserID)
115+
if err == nil {
116+
log.Info("User %s has been redirected to %s", results.OwnerName, owner.Name)
117+
results.OwnerName = owner.Name
118+
} else {
119+
log.Warn("User %s has a redirect to user with ID %d, but no user with this ID could be found. Trying without redirect...", results.OwnerName, redirectedUserID)
120+
}
121+
}
122+
111123
owner, err := user_model.GetUserByName(ctx, results.OwnerName)
112124
if err != nil {
113125
if user_model.IsErrUserNotExist(err) {
@@ -131,6 +143,19 @@ func ServCommand(ctx *context.PrivateContext) {
131143
return
132144
}
133145

146+
redirectedRepoID, err := repo_model.LookupRedirect(ctx, owner.ID, results.RepoName)
147+
if err == nil {
148+
redirectedRepo, err := repo_model.GetRepositoryByID(ctx, redirectedRepoID)
149+
if err == nil {
150+
log.Info("Repository %s/%s has been redirected to %s/%s", results.OwnerName, results.RepoName, redirectedRepo.OwnerName, redirectedRepo.Name)
151+
results.RepoName = redirectedRepo.Name
152+
results.OwnerName = redirectedRepo.OwnerName
153+
owner.ID = redirectedRepo.OwnerID
154+
} else {
155+
log.Warn("Repo %s/%s has a redirect to repo with ID %d, but no repo with this ID could be found. Trying without redirect...", results.OwnerName, results.RepoName, redirectedRepoID)
156+
}
157+
}
158+
134159
// Now get the Repository and set the results section
135160
repoExist := true
136161
repo, err := repo_model.GetRepositoryByName(ctx, owner.ID, results.RepoName)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package integration
5+
6+
import (
7+
"fmt"
8+
"net/url"
9+
"testing"
10+
11+
auth_model "code.gitea.io/gitea/models/auth"
12+
)
13+
14+
func TestGitSSHRedirect(t *testing.T) {
15+
onGiteaRun(t, testGitSSHRedirect)
16+
}
17+
18+
func testGitSSHRedirect(t *testing.T, u *url.URL) {
19+
apiTestContext := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
20+
21+
withKeyFile(t, "my-testing-key", func(keyFile string) {
22+
t.Run("CreateUserKey", doAPICreateUserKey(apiTestContext, "test-key", keyFile))
23+
24+
testCases := []struct {
25+
testName string
26+
userName string
27+
repoName string
28+
}{
29+
{"Test untouched", "user2", "repo1"},
30+
{"Test renamed user", "olduser2", "repo1"},
31+
{"Test renamed repo", "user2", "oldrepo1"},
32+
{"Test renamed user and repo", "olduser2", "oldrepo1"},
33+
}
34+
35+
for _, tc := range testCases {
36+
t.Run(tc.testName, func(t *testing.T) {
37+
cloneURL := createSSHUrl(fmt.Sprintf("%s/%s.git", tc.userName, tc.repoName), u)
38+
t.Run("Clone", doGitClone(t.TempDir(), cloneURL))
39+
})
40+
}
41+
})
42+
}

0 commit comments

Comments
 (0)