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