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.

user.go 9.5 kB

10 years ago
10 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>
5 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 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>
5 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>
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  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. "errors"
  8. "net/http"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/context"
  11. "code.gitea.io/gitea/modules/convert"
  12. "code.gitea.io/gitea/modules/log"
  13. "code.gitea.io/gitea/modules/password"
  14. api "code.gitea.io/gitea/modules/structs"
  15. "code.gitea.io/gitea/routers/api/v1/user"
  16. "code.gitea.io/gitea/routers/api/v1/utils"
  17. "code.gitea.io/gitea/services/mailer"
  18. )
  19. func parseLoginSource(ctx *context.APIContext, u *models.User, sourceID int64, loginName string) {
  20. if sourceID == 0 {
  21. return
  22. }
  23. source, err := models.GetLoginSourceByID(sourceID)
  24. if err != nil {
  25. if models.IsErrLoginSourceNotExist(err) {
  26. ctx.Error(http.StatusUnprocessableEntity, "", err)
  27. } else {
  28. ctx.Error(http.StatusInternalServerError, "GetLoginSourceByID", err)
  29. }
  30. return
  31. }
  32. u.LoginType = source.Type
  33. u.LoginSource = source.ID
  34. u.LoginName = loginName
  35. }
  36. // CreateUser create a user
  37. func CreateUser(ctx *context.APIContext, form api.CreateUserOption) {
  38. // swagger:operation POST /admin/users admin adminCreateUser
  39. // ---
  40. // summary: Create a user
  41. // consumes:
  42. // - application/json
  43. // produces:
  44. // - application/json
  45. // parameters:
  46. // - name: body
  47. // in: body
  48. // schema:
  49. // "$ref": "#/definitions/CreateUserOption"
  50. // responses:
  51. // "201":
  52. // "$ref": "#/responses/User"
  53. // "400":
  54. // "$ref": "#/responses/error"
  55. // "403":
  56. // "$ref": "#/responses/forbidden"
  57. // "422":
  58. // "$ref": "#/responses/validationError"
  59. u := &models.User{
  60. Name: form.Username,
  61. FullName: form.FullName,
  62. Email: form.Email,
  63. Passwd: form.Password,
  64. MustChangePassword: true,
  65. IsActive: true,
  66. LoginType: models.LoginPlain,
  67. }
  68. if form.MustChangePassword != nil {
  69. u.MustChangePassword = *form.MustChangePassword
  70. }
  71. parseLoginSource(ctx, u, form.SourceID, form.LoginName)
  72. if ctx.Written() {
  73. return
  74. }
  75. if !password.IsComplexEnough(form.Password) {
  76. err := errors.New("PasswordComplexity")
  77. ctx.Error(http.StatusBadRequest, "PasswordComplexity", err)
  78. return
  79. }
  80. if err := models.CreateUser(u); err != nil {
  81. if models.IsErrUserAlreadyExist(err) ||
  82. models.IsErrEmailAlreadyUsed(err) ||
  83. models.IsErrNameReserved(err) ||
  84. models.IsErrNamePatternNotAllowed(err) {
  85. ctx.Error(http.StatusUnprocessableEntity, "", err)
  86. } else {
  87. ctx.Error(http.StatusInternalServerError, "CreateUser", err)
  88. }
  89. return
  90. }
  91. log.Trace("Account created by admin (%s): %s", ctx.User.Name, u.Name)
  92. // Send email notification.
  93. if form.SendNotify {
  94. mailer.SendRegisterNotifyMail(ctx.Locale, u)
  95. }
  96. ctx.JSON(http.StatusCreated, convert.ToUser(u, ctx.IsSigned, ctx.User.IsAdmin))
  97. }
  98. // EditUser api for modifying a user's information
  99. func EditUser(ctx *context.APIContext, form api.EditUserOption) {
  100. // swagger:operation PATCH /admin/users/{username} admin adminEditUser
  101. // ---
  102. // summary: Edit an existing user
  103. // consumes:
  104. // - application/json
  105. // produces:
  106. // - application/json
  107. // parameters:
  108. // - name: username
  109. // in: path
  110. // description: username of user to edit
  111. // type: string
  112. // required: true
  113. // - name: body
  114. // in: body
  115. // schema:
  116. // "$ref": "#/definitions/EditUserOption"
  117. // responses:
  118. // "200":
  119. // "$ref": "#/responses/User"
  120. // "403":
  121. // "$ref": "#/responses/forbidden"
  122. // "422":
  123. // "$ref": "#/responses/validationError"
  124. u := user.GetUserByParams(ctx)
  125. if ctx.Written() {
  126. return
  127. }
  128. parseLoginSource(ctx, u, form.SourceID, form.LoginName)
  129. if ctx.Written() {
  130. return
  131. }
  132. if len(form.Password) > 0 {
  133. if !password.IsComplexEnough(form.Password) {
  134. err := errors.New("PasswordComplexity")
  135. ctx.Error(http.StatusBadRequest, "PasswordComplexity", err)
  136. return
  137. }
  138. var err error
  139. if u.Salt, err = models.GetUserSalt(); err != nil {
  140. ctx.Error(http.StatusInternalServerError, "UpdateUser", err)
  141. return
  142. }
  143. u.HashPassword(form.Password)
  144. }
  145. if form.MustChangePassword != nil {
  146. u.MustChangePassword = *form.MustChangePassword
  147. }
  148. u.LoginName = form.LoginName
  149. u.FullName = form.FullName
  150. u.Email = form.Email
  151. u.Website = form.Website
  152. u.Location = form.Location
  153. if form.Active != nil {
  154. u.IsActive = *form.Active
  155. }
  156. if form.Admin != nil {
  157. u.IsAdmin = *form.Admin
  158. }
  159. if form.AllowGitHook != nil {
  160. u.AllowGitHook = *form.AllowGitHook
  161. }
  162. if form.AllowImportLocal != nil {
  163. u.AllowImportLocal = *form.AllowImportLocal
  164. }
  165. if form.MaxRepoCreation != nil {
  166. u.MaxRepoCreation = *form.MaxRepoCreation
  167. }
  168. if form.AllowCreateOrganization != nil {
  169. u.AllowCreateOrganization = *form.AllowCreateOrganization
  170. }
  171. if form.ProhibitLogin != nil {
  172. u.ProhibitLogin = *form.ProhibitLogin
  173. }
  174. if err := models.UpdateUser(u); err != nil {
  175. if models.IsErrEmailAlreadyUsed(err) {
  176. ctx.Error(http.StatusUnprocessableEntity, "", err)
  177. } else {
  178. ctx.Error(http.StatusInternalServerError, "UpdateUser", err)
  179. }
  180. return
  181. }
  182. log.Trace("Account profile updated by admin (%s): %s", ctx.User.Name, u.Name)
  183. ctx.JSON(http.StatusOK, convert.ToUser(u, ctx.IsSigned, ctx.User.IsAdmin))
  184. }
  185. // DeleteUser api for deleting a user
  186. func DeleteUser(ctx *context.APIContext) {
  187. // swagger:operation DELETE /admin/users/{username} admin adminDeleteUser
  188. // ---
  189. // summary: Delete a user
  190. // produces:
  191. // - application/json
  192. // parameters:
  193. // - name: username
  194. // in: path
  195. // description: username of user to delete
  196. // type: string
  197. // required: true
  198. // responses:
  199. // "204":
  200. // "$ref": "#/responses/empty"
  201. // "403":
  202. // "$ref": "#/responses/forbidden"
  203. // "422":
  204. // "$ref": "#/responses/validationError"
  205. u := user.GetUserByParams(ctx)
  206. if ctx.Written() {
  207. return
  208. }
  209. if err := models.DeleteUser(u); err != nil {
  210. if models.IsErrUserOwnRepos(err) ||
  211. models.IsErrUserHasOrgs(err) {
  212. ctx.Error(http.StatusUnprocessableEntity, "", err)
  213. } else {
  214. ctx.Error(http.StatusInternalServerError, "DeleteUser", err)
  215. }
  216. return
  217. }
  218. log.Trace("Account deleted by admin(%s): %s", ctx.User.Name, u.Name)
  219. ctx.Status(http.StatusNoContent)
  220. }
  221. // CreatePublicKey api for creating a public key to a user
  222. func CreatePublicKey(ctx *context.APIContext, form api.CreateKeyOption) {
  223. // swagger:operation POST /admin/users/{username}/keys admin adminCreatePublicKey
  224. // ---
  225. // summary: Add a public key on behalf of a user
  226. // consumes:
  227. // - application/json
  228. // produces:
  229. // - application/json
  230. // parameters:
  231. // - name: username
  232. // in: path
  233. // description: username of the user
  234. // type: string
  235. // required: true
  236. // - name: key
  237. // in: body
  238. // schema:
  239. // "$ref": "#/definitions/CreateKeyOption"
  240. // responses:
  241. // "201":
  242. // "$ref": "#/responses/PublicKey"
  243. // "403":
  244. // "$ref": "#/responses/forbidden"
  245. // "422":
  246. // "$ref": "#/responses/validationError"
  247. u := user.GetUserByParams(ctx)
  248. if ctx.Written() {
  249. return
  250. }
  251. user.CreateUserPublicKey(ctx, form, u.ID)
  252. }
  253. // DeleteUserPublicKey api for deleting a user's public key
  254. func DeleteUserPublicKey(ctx *context.APIContext) {
  255. // swagger:operation DELETE /admin/users/{username}/keys/{id} admin adminDeleteUserPublicKey
  256. // ---
  257. // summary: Delete a user's public key
  258. // produces:
  259. // - application/json
  260. // parameters:
  261. // - name: username
  262. // in: path
  263. // description: username of user
  264. // type: string
  265. // required: true
  266. // - name: id
  267. // in: path
  268. // description: id of the key to delete
  269. // type: integer
  270. // format: int64
  271. // required: true
  272. // responses:
  273. // "204":
  274. // "$ref": "#/responses/empty"
  275. // "403":
  276. // "$ref": "#/responses/forbidden"
  277. // "404":
  278. // "$ref": "#/responses/notFound"
  279. u := user.GetUserByParams(ctx)
  280. if ctx.Written() {
  281. return
  282. }
  283. if err := models.DeletePublicKey(u, ctx.ParamsInt64(":id")); err != nil {
  284. if models.IsErrKeyNotExist(err) {
  285. ctx.NotFound()
  286. } else if models.IsErrKeyAccessDenied(err) {
  287. ctx.Error(http.StatusForbidden, "", "You do not have access to this key")
  288. } else {
  289. ctx.Error(http.StatusInternalServerError, "DeleteUserPublicKey", err)
  290. }
  291. return
  292. }
  293. log.Trace("Key deleted by admin(%s): %s", ctx.User.Name, u.Name)
  294. ctx.Status(http.StatusNoContent)
  295. }
  296. //GetAllUsers API for getting information of all the users
  297. func GetAllUsers(ctx *context.APIContext) {
  298. // swagger:operation GET /admin/users admin adminGetAllUsers
  299. // ---
  300. // summary: List all users
  301. // produces:
  302. // - application/json
  303. // parameters:
  304. // - name: page
  305. // in: query
  306. // description: page number of results to return (1-based)
  307. // type: integer
  308. // - name: limit
  309. // in: query
  310. // description: page size of results, maximum page size is 50
  311. // type: integer
  312. // responses:
  313. // "200":
  314. // "$ref": "#/responses/UserList"
  315. // "403":
  316. // "$ref": "#/responses/forbidden"
  317. users, _, err := models.SearchUsers(&models.SearchUserOptions{
  318. Type: models.UserTypeIndividual,
  319. OrderBy: models.SearchOrderByAlphabetically,
  320. ListOptions: utils.GetListOptions(ctx),
  321. })
  322. if err != nil {
  323. ctx.Error(http.StatusInternalServerError, "GetAllUsers", err)
  324. return
  325. }
  326. results := make([]*api.User, len(users))
  327. for i := range users {
  328. results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User.IsAdmin)
  329. }
  330. ctx.JSON(http.StatusOK, &results)
  331. }