code.gitea.io/gitea@v1.21.7/routers/web/explore/user.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package explore 5 6 import ( 7 "bytes" 8 "net/http" 9 10 "code.gitea.io/gitea/models/db" 11 user_model "code.gitea.io/gitea/models/user" 12 "code.gitea.io/gitea/modules/base" 13 "code.gitea.io/gitea/modules/context" 14 "code.gitea.io/gitea/modules/log" 15 "code.gitea.io/gitea/modules/setting" 16 "code.gitea.io/gitea/modules/sitemap" 17 "code.gitea.io/gitea/modules/structs" 18 "code.gitea.io/gitea/modules/util" 19 ) 20 21 const ( 22 // tplExploreUsers explore users page template 23 tplExploreUsers base.TplName = "explore/users" 24 ) 25 26 // UserSearchDefaultSortType is the default sort type for user search 27 const ( 28 UserSearchDefaultSortType = "recentupdate" 29 UserSearchDefaultAdminSort = "alphabetically" 30 ) 31 32 var nullByte = []byte{0x00} 33 34 func isKeywordValid(keyword string) bool { 35 return !bytes.Contains([]byte(keyword), nullByte) 36 } 37 38 // RenderUserSearch render user search page 39 func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions, tplName base.TplName) { 40 // Sitemap index for sitemap paths 41 opts.Page = int(ctx.ParamsInt64("idx")) 42 isSitemap := ctx.Params("idx") != "" 43 if opts.Page <= 1 { 44 opts.Page = ctx.FormInt("page") 45 } 46 if opts.Page <= 1 { 47 opts.Page = 1 48 } 49 50 if isSitemap { 51 opts.PageSize = setting.UI.SitemapPagingNum 52 } 53 54 var ( 55 users []*user_model.User 56 count int64 57 err error 58 orderBy db.SearchOrderBy 59 ) 60 61 // we can not set orderBy to `models.SearchOrderByXxx`, because there may be a JOIN in the statement, different tables may have the same name columns 62 63 ctx.Data["SortType"] = ctx.FormString("sort") 64 switch ctx.FormString("sort") { 65 case "newest": 66 orderBy = "`user`.id DESC" 67 case "oldest": 68 orderBy = "`user`.id ASC" 69 case "leastupdate": 70 orderBy = "`user`.updated_unix ASC" 71 case "reversealphabetically": 72 orderBy = "`user`.name DESC" 73 case "lastlogin": 74 orderBy = "`user`.last_login_unix ASC" 75 case "reverselastlogin": 76 orderBy = "`user`.last_login_unix DESC" 77 case "alphabetically": 78 orderBy = "`user`.name ASC" 79 case "recentupdate": 80 fallthrough 81 default: 82 // in case the sortType is not valid, we set it to recentupdate 83 ctx.Data["SortType"] = "recentupdate" 84 orderBy = "`user`.updated_unix DESC" 85 } 86 87 opts.Keyword = ctx.FormTrim("q") 88 opts.OrderBy = orderBy 89 if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) { 90 users, count, err = user_model.SearchUsers(ctx, opts) 91 if err != nil { 92 ctx.ServerError("SearchUsers", err) 93 return 94 } 95 } 96 if isSitemap { 97 m := sitemap.NewSitemap() 98 for _, item := range users { 99 m.Add(sitemap.URL{URL: item.HTMLURL(), LastMod: item.UpdatedUnix.AsTimePtr()}) 100 } 101 ctx.Resp.Header().Set("Content-Type", "text/xml") 102 if _, err := m.WriteTo(ctx.Resp); err != nil { 103 log.Error("Failed writing sitemap: %v", err) 104 } 105 return 106 } 107 108 ctx.Data["Keyword"] = opts.Keyword 109 ctx.Data["Total"] = count 110 ctx.Data["Users"] = users 111 ctx.Data["UsersTwoFaStatus"] = user_model.UserList(users).GetTwoFaStatus(ctx) 112 ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail 113 ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled 114 115 pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5) 116 pager.SetDefaultParams(ctx) 117 for paramKey, paramVal := range opts.ExtraParamStrings { 118 pager.AddParamString(paramKey, paramVal) 119 } 120 ctx.Data["Page"] = pager 121 122 ctx.HTML(http.StatusOK, tplName) 123 } 124 125 // Users render explore users page 126 func Users(ctx *context.Context) { 127 if setting.Service.Explore.DisableUsersPage { 128 ctx.Redirect(setting.AppSubURL + "/explore/repos") 129 return 130 } 131 ctx.Data["Title"] = ctx.Tr("explore") 132 ctx.Data["PageIsExplore"] = true 133 ctx.Data["PageIsExploreUsers"] = true 134 ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled 135 136 if ctx.FormString("sort") == "" { 137 ctx.SetFormString("sort", UserSearchDefaultSortType) 138 } 139 140 RenderUserSearch(ctx, &user_model.SearchUserOptions{ 141 Actor: ctx.Doer, 142 Type: user_model.UserTypeIndividual, 143 ListOptions: db.ListOptions{PageSize: setting.UI.ExplorePagingNum}, 144 IsActive: util.OptionalBoolTrue, 145 Visible: []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate}, 146 }, tplExploreUsers) 147 }