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

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