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