mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Backport #23874
This commit is contained in:
		@@ -64,3 +64,12 @@
 | 
				
			|||||||
  repo_id: 1700 # dangling intentional
 | 
					  repo_id: 1700 # dangling intentional
 | 
				
			||||||
  is_private: false
 | 
					  is_private: false
 | 
				
			||||||
  created_unix: 1603011541
 | 
					  created_unix: 1603011541
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- id: 9
 | 
				
			||||||
 | 
					  user_id: 34
 | 
				
			||||||
 | 
					  op_type: 12 # close issue
 | 
				
			||||||
 | 
					  act_user_id: 34
 | 
				
			||||||
 | 
					  repo_id: 1 # public
 | 
				
			||||||
 | 
					  is_private: false
 | 
				
			||||||
 | 
					  created_unix: 1680454039
 | 
				
			||||||
 | 
					  content: '4|' # issueId 5
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1220,3 +1220,41 @@
 | 
				
			|||||||
  repo_admin_change_team_access: false
 | 
					  repo_admin_change_team_access: false
 | 
				
			||||||
  theme: ""
 | 
					  theme: ""
 | 
				
			||||||
  keep_activity_private: false
 | 
					  keep_activity_private: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					  id: 34
 | 
				
			||||||
 | 
					  lower_name: the_34-user.with.all.allowedchars
 | 
				
			||||||
 | 
					  name: the_34-user.with.all.allowedChars
 | 
				
			||||||
 | 
					  full_name: the_1-user.with.all.allowedChars
 | 
				
			||||||
 | 
					  description: 'some [commonmark](https://commonmark.org/)!'
 | 
				
			||||||
 | 
					  email: user34@example.com
 | 
				
			||||||
 | 
					  keep_email_private: false
 | 
				
			||||||
 | 
					  email_notifications_preference: enabled
 | 
				
			||||||
 | 
					  passwd: ZogKvWdyEx:password
 | 
				
			||||||
 | 
					  passwd_hash_algo: dummy
 | 
				
			||||||
 | 
					  must_change_password: false
 | 
				
			||||||
 | 
					  login_source: 0
 | 
				
			||||||
 | 
					  login_name: the_34-user.with.all.allowedchars
 | 
				
			||||||
 | 
					  type: 0
 | 
				
			||||||
 | 
					  salt: ZogKvWdyEx
 | 
				
			||||||
 | 
					  max_repo_creation: -1
 | 
				
			||||||
 | 
					  is_active: true
 | 
				
			||||||
 | 
					  is_admin: false
 | 
				
			||||||
 | 
					  is_restricted: false
 | 
				
			||||||
 | 
					  allow_git_hook: false
 | 
				
			||||||
 | 
					  allow_import_local: false
 | 
				
			||||||
 | 
					  allow_create_organization: false
 | 
				
			||||||
 | 
					  prohibit_login: false
 | 
				
			||||||
 | 
					  avatar: avatar34
 | 
				
			||||||
 | 
					  avatar_email: user34@example.com
 | 
				
			||||||
 | 
					  use_custom_avatar: true
 | 
				
			||||||
 | 
					  num_followers: 0
 | 
				
			||||||
 | 
					  num_following: 0
 | 
				
			||||||
 | 
					  num_stars: 0
 | 
				
			||||||
 | 
					  num_repos: 0
 | 
				
			||||||
 | 
					  num_teams: 0
 | 
				
			||||||
 | 
					  num_members: 0
 | 
				
			||||||
 | 
					  visibility: 0
 | 
				
			||||||
 | 
					  repo_admin_change_team_access: false
 | 
				
			||||||
 | 
					  theme: ""
 | 
				
			||||||
 | 
					  keep_activity_private: false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -99,13 +99,13 @@ func TestSearchUsers(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}},
 | 
						testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}},
 | 
				
			||||||
		[]int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32})
 | 
							[]int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolFalse},
 | 
						testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolFalse},
 | 
				
			||||||
		[]int64{9})
 | 
							[]int64{9})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
 | 
						testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
 | 
				
			||||||
		[]int64{1, 2, 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32})
 | 
							[]int64{1, 2, 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
 | 
						testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
 | 
				
			||||||
		[]int64{1, 10, 11, 12, 13, 14, 15, 16, 18})
 | 
							[]int64{1, 10, 11, 12, 13, 14, 15, 16, 18})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/perm"
 | 
						"code.gitea.io/gitea/models/perm"
 | 
				
			||||||
	"code.gitea.io/gitea/models/unit"
 | 
						"code.gitea.io/gitea/models/unit"
 | 
				
			||||||
@@ -651,16 +652,47 @@ func RegisterRoutes(m *web.Route) {
 | 
				
			|||||||
			})
 | 
								})
 | 
				
			||||||
			http.ServeFile(ctx.Resp, ctx.Req, path.Join(setting.StaticRootPath, "public/img/favicon.png"))
 | 
								http.ServeFile(ctx.Resp, ctx.Req, path.Join(setting.StaticRootPath, "public/img/favicon.png"))
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		m.Group("/{username}", func() {
 | 
							m.Get("/{username}", func(ctx *context.Context) {
 | 
				
			||||||
			m.Get(".png", user.AvatarByUserName)
 | 
								// WORKAROUND to support usernames with "." in it
 | 
				
			||||||
			m.Get(".keys", user.ShowSSHKeys)
 | 
								// https://github.com/go-chi/chi/issues/781
 | 
				
			||||||
			m.Get(".gpg", user.ShowGPGKeys)
 | 
								username := ctx.Params("username")
 | 
				
			||||||
			m.Get(".rss", feedEnabled, feed.ShowUserFeedRSS)
 | 
								reloadParam := func(suffix string) (success bool) {
 | 
				
			||||||
			m.Get(".atom", feedEnabled, feed.ShowUserFeedAtom)
 | 
									ctx.SetParams("username", strings.TrimSuffix(username, suffix))
 | 
				
			||||||
			m.Get("", user.Profile)
 | 
									context_service.UserAssignmentWeb()(ctx)
 | 
				
			||||||
		}, func(ctx *context.Context) {
 | 
									return !ctx.Written()
 | 
				
			||||||
			ctx.Data["EnableFeed"] = setting.EnableFeed
 | 
								}
 | 
				
			||||||
		}, context_service.UserAssignmentWeb())
 | 
								switch {
 | 
				
			||||||
 | 
								case strings.HasSuffix(username, ".png"):
 | 
				
			||||||
 | 
									if reloadParam(".png") {
 | 
				
			||||||
 | 
										user.AvatarByUserName(ctx)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								case strings.HasSuffix(username, ".keys"):
 | 
				
			||||||
 | 
									if reloadParam(".keys") {
 | 
				
			||||||
 | 
										user.ShowSSHKeys(ctx)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								case strings.HasSuffix(username, ".gpg"):
 | 
				
			||||||
 | 
									if reloadParam(".gpg") {
 | 
				
			||||||
 | 
										user.ShowGPGKeys(ctx)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								case strings.HasSuffix(username, ".rss"):
 | 
				
			||||||
 | 
									feedEnabled(ctx)
 | 
				
			||||||
 | 
									if !ctx.Written() && reloadParam(".rss") {
 | 
				
			||||||
 | 
										context_service.UserAssignmentWeb()(ctx)
 | 
				
			||||||
 | 
										feed.ShowUserFeedRSS(ctx)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								case strings.HasSuffix(username, ".atom"):
 | 
				
			||||||
 | 
									feedEnabled(ctx)
 | 
				
			||||||
 | 
									if !ctx.Written() && reloadParam(".atom") {
 | 
				
			||||||
 | 
										feed.ShowUserFeedAtom(ctx)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									context_service.UserAssignmentWeb()(ctx)
 | 
				
			||||||
 | 
									if !ctx.Written() {
 | 
				
			||||||
 | 
										ctx.Data["EnableFeed"] = setting.EnableFeed
 | 
				
			||||||
 | 
										user.Profile(ctx)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		m.Get("/attachments/{uuid}", repo.GetAttachment)
 | 
							m.Get("/attachments/{uuid}", repo.GetAttachment)
 | 
				
			||||||
	}, ignSignIn)
 | 
						}, ignSignIn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,7 @@ func TestNodeinfo(t *testing.T) {
 | 
				
			|||||||
		DecodeJSON(t, resp, &nodeinfo)
 | 
							DecodeJSON(t, resp, &nodeinfo)
 | 
				
			||||||
		assert.True(t, nodeinfo.OpenRegistrations)
 | 
							assert.True(t, nodeinfo.OpenRegistrations)
 | 
				
			||||||
		assert.Equal(t, "gitea", nodeinfo.Software.Name)
 | 
							assert.Equal(t, "gitea", nodeinfo.Software.Name)
 | 
				
			||||||
		assert.Equal(t, 24, nodeinfo.Usage.Users.Total)
 | 
							assert.Equal(t, 25, nodeinfo.Usage.Users.Total)
 | 
				
			||||||
		assert.Equal(t, 18, nodeinfo.Usage.LocalPosts)
 | 
							assert.Equal(t, 18, nodeinfo.Usage.LocalPosts)
 | 
				
			||||||
		assert.Equal(t, 2, nodeinfo.Usage.LocalComments)
 | 
							assert.Equal(t, 2, nodeinfo.Usage.LocalComments)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,7 @@ func TestSettingShowUserEmailExplore(t *testing.T) {
 | 
				
			|||||||
	htmlDoc := NewHTMLParser(t, resp.Body)
 | 
						htmlDoc := NewHTMLParser(t, resp.Body)
 | 
				
			||||||
	assert.Contains(t,
 | 
						assert.Contains(t,
 | 
				
			||||||
		htmlDoc.doc.Find(".ui.user.list").Text(),
 | 
							htmlDoc.doc.Find(".ui.user.list").Text(),
 | 
				
			||||||
		"user4@example.com",
 | 
							"user34@example.com",
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setting.UI.ShowUserEmail = false
 | 
						setting.UI.ShowUserEmail = false
 | 
				
			||||||
@@ -35,7 +35,7 @@ func TestSettingShowUserEmailExplore(t *testing.T) {
 | 
				
			|||||||
	htmlDoc = NewHTMLParser(t, resp.Body)
 | 
						htmlDoc = NewHTMLParser(t, resp.Body)
 | 
				
			||||||
	assert.NotContains(t,
 | 
						assert.NotContains(t,
 | 
				
			||||||
		htmlDoc.doc.Find(".ui.user.list").Text(),
 | 
							htmlDoc.doc.Find(".ui.user.list").Text(),
 | 
				
			||||||
		"user4@example.com",
 | 
							"user34@example.com",
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setting.UI.ShowUserEmail = showUserEmail
 | 
						setting.UI.ShowUserEmail = showUserEmail
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -241,6 +241,19 @@ func testExportUserGPGKeys(t *testing.T, user, expected string) {
 | 
				
			|||||||
	assert.Equal(t, expected, resp.Body.String())
 | 
						assert.Equal(t, expected, resp.Body.String())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestGetUserRss(t *testing.T) {
 | 
				
			||||||
 | 
						user34 := "the_34-user.with.all.allowedChars"
 | 
				
			||||||
 | 
						req := NewRequestf(t, "GET", "/%s.rss", user34)
 | 
				
			||||||
 | 
						resp := MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
						if assert.EqualValues(t, "application/rss+xml;charset=utf-8", resp.Header().Get("Content-Type")) {
 | 
				
			||||||
 | 
							rssDoc := NewHTMLParser(t, resp.Body).Find("channel")
 | 
				
			||||||
 | 
							title, _ := rssDoc.ChildrenFiltered("title").Html()
 | 
				
			||||||
 | 
							assert.EqualValues(t, "Feed of "the_1-user.with.all.allowedChars"", title)
 | 
				
			||||||
 | 
							description, _ := rssDoc.ChildrenFiltered("description").Html()
 | 
				
			||||||
 | 
							assert.EqualValues(t, "<p>some <a href="https://commonmark.org/" rel="nofollow">commonmark</a>!</p>\n", description)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestListStopWatches(t *testing.T) {
 | 
					func TestListStopWatches(t *testing.T) {
 | 
				
			||||||
	defer tests.PrepareTestEnv(t)()
 | 
						defer tests.PrepareTestEnv(t)()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user