You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

users.go 8.2 kB

API add/generalize pagination (#9452) * paginate results * fixed deadlock * prevented breaking change * updated swagger * go fmt * fixed find topic * go mod tidy * go mod vendor with go1.13.5 * fixed repo find topics * fixed unit test * added Limit method to Engine struct; use engine variable when provided; fixed gitignore * use ItemsPerPage for default pagesize; fix GetWatchers, getOrgUsersByOrgID and GetStargazers; fix GetAllCommits headers; reverted some changed behaviors * set Page value on Home route * improved memory allocations * fixed response headers * removed logfiles * fixed import order * import order * improved swagger * added function to get models.ListOptions from context * removed pagesize diff on unit test * fixed imports * removed unnecessary struct field * fixed go fmt * scoped PR * code improvements * code improvements * go mod tidy * fixed import order * fixed commit statuses session * fixed files headers * fixed headers; added pagination for notifications * go mod tidy * go fmt * removed Private from user search options; added setting.UI.IssuePagingNum as default valeu on repo's issues list * Apply suggestions from code review Co-Authored-By: 6543 <6543@obermui.de> Co-Authored-By: zeripath <art27@cantab.net> * fixed build error * CI.restart() * fixed merge conflicts resolve * fixed conflicts resolve * improved FindTrackedTimesOptions.ToOptions() method * added backwards compatibility on ListReleases request; fixed issue tracked time ToSession * fixed build error; fixed swagger template * fixed swagger template * fixed ListReleases backwards compatibility * added page to user search route Co-authored-by: techknowlogick <matti@mdranta.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: zeripath <art27@cantab.net>
6 years ago
API add/generalize pagination (#9452) * paginate results * fixed deadlock * prevented breaking change * updated swagger * go fmt * fixed find topic * go mod tidy * go mod vendor with go1.13.5 * fixed repo find topics * fixed unit test * added Limit method to Engine struct; use engine variable when provided; fixed gitignore * use ItemsPerPage for default pagesize; fix GetWatchers, getOrgUsersByOrgID and GetStargazers; fix GetAllCommits headers; reverted some changed behaviors * set Page value on Home route * improved memory allocations * fixed response headers * removed logfiles * fixed import order * import order * improved swagger * added function to get models.ListOptions from context * removed pagesize diff on unit test * fixed imports * removed unnecessary struct field * fixed go fmt * scoped PR * code improvements * code improvements * go mod tidy * fixed import order * fixed commit statuses session * fixed files headers * fixed headers; added pagination for notifications * go mod tidy * go fmt * removed Private from user search options; added setting.UI.IssuePagingNum as default valeu on repo's issues list * Apply suggestions from code review Co-Authored-By: 6543 <6543@obermui.de> Co-Authored-By: zeripath <art27@cantab.net> * fixed build error * CI.restart() * fixed merge conflicts resolve * fixed conflicts resolve * improved FindTrackedTimesOptions.ToOptions() method * added backwards compatibility on ListReleases request; fixed issue tracked time ToSession * fixed build error; fixed swagger template * fixed swagger template * fixed ListReleases backwards compatibility * added page to user search route Co-authored-by: techknowlogick <matti@mdranta.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: zeripath <art27@cantab.net>
6 years ago
10 years ago
Restricted users (#6274) * Restricted users (#4334): initial implementation * Add User.IsRestricted & UI to edit it * Pass user object instead of user id to places where IsRestricted flag matters * Restricted users: maintain access rows for all referenced repos (incl public) * Take logged in user & IsRestricted flag into account in org/repo listings, searches and accesses * Add basic repo access tests for restricted users Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Mention restricted users in the faq Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert unnecessary change `.isUserPartOfOrg` -> `.IsUserPartOfOrg` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Remove unnecessary `org.IsOrganization()` call Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert to an `int64` keyed `accessMap` * Add type `userAccess` * Add convenience func updateUserAccess() * Turn accessMap into a `map[int64]userAccess` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * or even better: `map[int64]*userAccess` * updateUserAccess(): use tighter syntax as suggested by lafriks * even tighter * Avoid extra loop * Don't disclose limited orgs to unauthenticated users * Don't assume block only applies to orgs * Use an array of `VisibleType` for filtering * fix yet another thinko * Ok - no need for u * Revert "Ok - no need for u" This reverts commit 5c3e886aabd5acd997a3b35687d322439732c200. Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv>
6 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2020 The Gitea Authors.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package admin
  6. import (
  7. "strings"
  8. "code.gitea.io/gitea/models"
  9. "code.gitea.io/gitea/modules/auth"
  10. "code.gitea.io/gitea/modules/base"
  11. "code.gitea.io/gitea/modules/context"
  12. "code.gitea.io/gitea/modules/log"
  13. "code.gitea.io/gitea/modules/password"
  14. "code.gitea.io/gitea/modules/setting"
  15. "code.gitea.io/gitea/routers"
  16. "code.gitea.io/gitea/services/mailer"
  17. "github.com/unknwon/com"
  18. )
  19. const (
  20. tplUsers base.TplName = "admin/user/list"
  21. tplUserNew base.TplName = "admin/user/new"
  22. tplUserEdit base.TplName = "admin/user/edit"
  23. )
  24. // Users show all the users
  25. func Users(ctx *context.Context) {
  26. ctx.Data["Title"] = ctx.Tr("admin.users")
  27. ctx.Data["PageIsAdmin"] = true
  28. ctx.Data["PageIsAdminUsers"] = true
  29. routers.RenderUserSearch(ctx, &models.SearchUserOptions{
  30. Type: models.UserTypeIndividual,
  31. ListOptions: models.ListOptions{
  32. PageSize: setting.UI.Admin.UserPagingNum,
  33. },
  34. SearchByEmail: true,
  35. }, tplUsers)
  36. }
  37. // NewUser render adding a new user page
  38. func NewUser(ctx *context.Context) {
  39. ctx.Data["Title"] = ctx.Tr("admin.users.new_account")
  40. ctx.Data["PageIsAdmin"] = true
  41. ctx.Data["PageIsAdminUsers"] = true
  42. ctx.Data["login_type"] = "0-0"
  43. sources, err := models.LoginSources()
  44. if err != nil {
  45. ctx.ServerError("LoginSources", err)
  46. return
  47. }
  48. ctx.Data["Sources"] = sources
  49. ctx.Data["CanSendEmail"] = setting.MailService != nil
  50. ctx.HTML(200, tplUserNew)
  51. }
  52. // NewUserPost response for adding a new user
  53. func NewUserPost(ctx *context.Context, form auth.AdminCreateUserForm) {
  54. ctx.Data["Title"] = ctx.Tr("admin.users.new_account")
  55. ctx.Data["PageIsAdmin"] = true
  56. ctx.Data["PageIsAdminUsers"] = true
  57. sources, err := models.LoginSources()
  58. if err != nil {
  59. ctx.ServerError("LoginSources", err)
  60. return
  61. }
  62. ctx.Data["Sources"] = sources
  63. ctx.Data["CanSendEmail"] = setting.MailService != nil
  64. if ctx.HasError() {
  65. ctx.HTML(200, tplUserNew)
  66. return
  67. }
  68. u := &models.User{
  69. Name: form.UserName,
  70. Email: form.Email,
  71. Passwd: form.Password,
  72. IsActive: true,
  73. LoginType: models.LoginPlain,
  74. }
  75. if len(form.LoginType) > 0 {
  76. fields := strings.Split(form.LoginType, "-")
  77. if len(fields) == 2 {
  78. u.LoginType = models.LoginType(com.StrTo(fields[0]).MustInt())
  79. u.LoginSource = com.StrTo(fields[1]).MustInt64()
  80. u.LoginName = form.LoginName
  81. }
  82. }
  83. if u.LoginType == models.LoginNoType || u.LoginType == models.LoginPlain {
  84. if len(form.Password) < setting.MinPasswordLength {
  85. ctx.Data["Err_Password"] = true
  86. ctx.RenderWithErr(ctx.Tr("auth.password_too_short", setting.MinPasswordLength), tplUserNew, &form)
  87. return
  88. }
  89. if !password.IsComplexEnough(form.Password) {
  90. ctx.Data["Err_Password"] = true
  91. ctx.RenderWithErr(password.BuildComplexityError(ctx), tplUserNew, &form)
  92. return
  93. }
  94. u.MustChangePassword = form.MustChangePassword
  95. }
  96. if err := models.CreateUser(u); err != nil {
  97. switch {
  98. case models.IsErrUserAlreadyExist(err):
  99. ctx.Data["Err_UserName"] = true
  100. ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), tplUserNew, &form)
  101. case models.IsErrEmailAlreadyUsed(err):
  102. ctx.Data["Err_Email"] = true
  103. ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplUserNew, &form)
  104. case models.IsErrNameReserved(err):
  105. ctx.Data["Err_UserName"] = true
  106. ctx.RenderWithErr(ctx.Tr("user.form.name_reserved", err.(models.ErrNameReserved).Name), tplUserNew, &form)
  107. case models.IsErrNamePatternNotAllowed(err):
  108. ctx.Data["Err_UserName"] = true
  109. ctx.RenderWithErr(ctx.Tr("user.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tplUserNew, &form)
  110. default:
  111. ctx.ServerError("CreateUser", err)
  112. }
  113. return
  114. }
  115. log.Trace("Account created by admin (%s): %s", ctx.User.Name, u.Name)
  116. // Send email notification.
  117. if form.SendNotify {
  118. mailer.SendRegisterNotifyMail(ctx.Locale, u)
  119. }
  120. ctx.Flash.Success(ctx.Tr("admin.users.new_success", u.Name))
  121. ctx.Redirect(setting.AppSubURL + "/admin/users/" + com.ToStr(u.ID))
  122. }
  123. func prepareUserInfo(ctx *context.Context) *models.User {
  124. u, err := models.GetUserByID(ctx.ParamsInt64(":userid"))
  125. if err != nil {
  126. ctx.ServerError("GetUserByID", err)
  127. return nil
  128. }
  129. ctx.Data["User"] = u
  130. if u.LoginSource > 0 {
  131. ctx.Data["LoginSource"], err = models.GetLoginSourceByID(u.LoginSource)
  132. if err != nil {
  133. ctx.ServerError("GetLoginSourceByID", err)
  134. return nil
  135. }
  136. } else {
  137. ctx.Data["LoginSource"] = &models.LoginSource{}
  138. }
  139. sources, err := models.LoginSources()
  140. if err != nil {
  141. ctx.ServerError("LoginSources", err)
  142. return nil
  143. }
  144. ctx.Data["Sources"] = sources
  145. return u
  146. }
  147. // EditUser show editting user page
  148. func EditUser(ctx *context.Context) {
  149. ctx.Data["Title"] = ctx.Tr("admin.users.edit_account")
  150. ctx.Data["PageIsAdmin"] = true
  151. ctx.Data["PageIsAdminUsers"] = true
  152. ctx.Data["DisableRegularOrgCreation"] = setting.Admin.DisableRegularOrgCreation
  153. prepareUserInfo(ctx)
  154. if ctx.Written() {
  155. return
  156. }
  157. ctx.HTML(200, tplUserEdit)
  158. }
  159. // EditUserPost response for editting user
  160. func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) {
  161. ctx.Data["Title"] = ctx.Tr("admin.users.edit_account")
  162. ctx.Data["PageIsAdmin"] = true
  163. ctx.Data["PageIsAdminUsers"] = true
  164. u := prepareUserInfo(ctx)
  165. if ctx.Written() {
  166. return
  167. }
  168. if ctx.HasError() {
  169. ctx.HTML(200, tplUserEdit)
  170. return
  171. }
  172. fields := strings.Split(form.LoginType, "-")
  173. if len(fields) == 2 {
  174. loginType := models.LoginType(com.StrTo(fields[0]).MustInt())
  175. loginSource := com.StrTo(fields[1]).MustInt64()
  176. if u.LoginSource != loginSource {
  177. u.LoginSource = loginSource
  178. u.LoginType = loginType
  179. }
  180. }
  181. if len(form.Password) > 0 {
  182. var err error
  183. if len(form.Password) < setting.MinPasswordLength {
  184. ctx.Data["Err_Password"] = true
  185. ctx.RenderWithErr(ctx.Tr("auth.password_too_short", setting.MinPasswordLength), tplUserEdit, &form)
  186. return
  187. }
  188. if !password.IsComplexEnough(form.Password) {
  189. ctx.RenderWithErr(password.BuildComplexityError(ctx), tplUserEdit, &form)
  190. return
  191. }
  192. if u.Salt, err = models.GetUserSalt(); err != nil {
  193. ctx.ServerError("UpdateUser", err)
  194. return
  195. }
  196. u.HashPassword(form.Password)
  197. }
  198. u.LoginName = form.LoginName
  199. u.FullName = form.FullName
  200. u.Email = form.Email
  201. u.Website = form.Website
  202. u.Location = form.Location
  203. u.MaxRepoCreation = form.MaxRepoCreation
  204. u.IsActive = form.Active
  205. u.IsAdmin = form.Admin
  206. u.IsRestricted = form.Restricted
  207. u.AllowGitHook = form.AllowGitHook
  208. u.AllowImportLocal = form.AllowImportLocal
  209. u.AllowCreateOrganization = form.AllowCreateOrganization
  210. u.ProhibitLogin = form.ProhibitLogin
  211. if err := models.UpdateUser(u); err != nil {
  212. if models.IsErrEmailAlreadyUsed(err) {
  213. ctx.Data["Err_Email"] = true
  214. ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplUserEdit, &form)
  215. } else {
  216. ctx.ServerError("UpdateUser", err)
  217. }
  218. return
  219. }
  220. log.Trace("Account profile updated by admin (%s): %s", ctx.User.Name, u.Name)
  221. ctx.Flash.Success(ctx.Tr("admin.users.update_profile_success"))
  222. ctx.Redirect(setting.AppSubURL + "/admin/users/" + ctx.Params(":userid"))
  223. }
  224. // DeleteUser response for deleting a user
  225. func DeleteUser(ctx *context.Context) {
  226. u, err := models.GetUserByID(ctx.ParamsInt64(":userid"))
  227. if err != nil {
  228. ctx.ServerError("GetUserByID", err)
  229. return
  230. }
  231. if err = models.DeleteUser(u); err != nil {
  232. switch {
  233. case models.IsErrUserOwnRepos(err):
  234. ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo"))
  235. ctx.JSON(200, map[string]interface{}{
  236. "redirect": setting.AppSubURL + "/admin/users/" + ctx.Params(":userid"),
  237. })
  238. case models.IsErrUserHasOrgs(err):
  239. ctx.Flash.Error(ctx.Tr("admin.users.still_has_org"))
  240. ctx.JSON(200, map[string]interface{}{
  241. "redirect": setting.AppSubURL + "/admin/users/" + ctx.Params(":userid"),
  242. })
  243. default:
  244. ctx.ServerError("DeleteUser", err)
  245. }
  246. return
  247. }
  248. log.Trace("Account deleted by admin (%s): %s", ctx.User.Name, u.Name)
  249. ctx.Flash.Success(ctx.Tr("admin.users.deletion_success"))
  250. ctx.JSON(200, map[string]interface{}{
  251. "redirect": setting.AppSubURL + "/admin/users",
  252. })
  253. }