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.

org.go 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2018 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 org
  6. import (
  7. "net/http"
  8. "code.gitea.io/gitea/models"
  9. "code.gitea.io/gitea/modules/context"
  10. "code.gitea.io/gitea/modules/convert"
  11. api "code.gitea.io/gitea/modules/structs"
  12. "code.gitea.io/gitea/modules/util"
  13. "code.gitea.io/gitea/modules/web"
  14. "code.gitea.io/gitea/routers/api/v1/user"
  15. "code.gitea.io/gitea/routers/api/v1/utils"
  16. )
  17. func listUserOrgs(ctx *context.APIContext, u *models.User) {
  18. listOptions := utils.GetListOptions(ctx)
  19. showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == u.ID)
  20. orgs, err := models.GetOrgsByUserID(u.ID, showPrivate)
  21. if err != nil {
  22. ctx.Error(http.StatusInternalServerError, "GetOrgsByUserID", err)
  23. return
  24. }
  25. maxResults := len(orgs)
  26. orgs, _ = util.PaginateSlice(orgs, listOptions.Page, listOptions.PageSize).([]*models.User)
  27. apiOrgs := make([]*api.Organization, len(orgs))
  28. for i := range orgs {
  29. apiOrgs[i] = convert.ToOrganization(orgs[i])
  30. }
  31. ctx.SetLinkHeader(maxResults, listOptions.PageSize)
  32. ctx.SetTotalCountHeader(int64(maxResults))
  33. ctx.JSON(http.StatusOK, &apiOrgs)
  34. }
  35. // ListMyOrgs list all my orgs
  36. func ListMyOrgs(ctx *context.APIContext) {
  37. // swagger:operation GET /user/orgs organization orgListCurrentUserOrgs
  38. // ---
  39. // summary: List the current user's organizations
  40. // produces:
  41. // - application/json
  42. // parameters:
  43. // - name: page
  44. // in: query
  45. // description: page number of results to return (1-based)
  46. // type: integer
  47. // - name: limit
  48. // in: query
  49. // description: page size of results
  50. // type: integer
  51. // responses:
  52. // "200":
  53. // "$ref": "#/responses/OrganizationList"
  54. listUserOrgs(ctx, ctx.User)
  55. }
  56. // ListUserOrgs list user's orgs
  57. func ListUserOrgs(ctx *context.APIContext) {
  58. // swagger:operation GET /users/{username}/orgs organization orgListUserOrgs
  59. // ---
  60. // summary: List a user's organizations
  61. // produces:
  62. // - application/json
  63. // parameters:
  64. // - name: username
  65. // in: path
  66. // description: username of user
  67. // type: string
  68. // required: true
  69. // - name: page
  70. // in: query
  71. // description: page number of results to return (1-based)
  72. // type: integer
  73. // - name: limit
  74. // in: query
  75. // description: page size of results
  76. // type: integer
  77. // responses:
  78. // "200":
  79. // "$ref": "#/responses/OrganizationList"
  80. u := user.GetUserByParams(ctx)
  81. if ctx.Written() {
  82. return
  83. }
  84. listUserOrgs(ctx, u)
  85. }
  86. // GetAll return list of all public organizations
  87. func GetAll(ctx *context.APIContext) {
  88. // swagger:operation Get /orgs organization orgGetAll
  89. // ---
  90. // summary: Get list of organizations
  91. // produces:
  92. // - application/json
  93. // parameters:
  94. // - name: page
  95. // in: query
  96. // description: page number of results to return (1-based)
  97. // type: integer
  98. // - name: limit
  99. // in: query
  100. // description: page size of results
  101. // type: integer
  102. // responses:
  103. // "200":
  104. // "$ref": "#/responses/OrganizationList"
  105. vMode := []api.VisibleType{api.VisibleTypePublic}
  106. if ctx.IsSigned {
  107. vMode = append(vMode, api.VisibleTypeLimited)
  108. if ctx.User.IsAdmin {
  109. vMode = append(vMode, api.VisibleTypePrivate)
  110. }
  111. }
  112. listOptions := utils.GetListOptions(ctx)
  113. publicOrgs, maxResults, err := models.SearchUsers(&models.SearchUserOptions{
  114. ListOptions: listOptions,
  115. Type: models.UserTypeOrganization,
  116. OrderBy: models.SearchOrderByAlphabetically,
  117. Visible: vMode,
  118. })
  119. if err != nil {
  120. ctx.Error(http.StatusInternalServerError, "SearchOrganizations", err)
  121. return
  122. }
  123. orgs := make([]*api.Organization, len(publicOrgs))
  124. for i := range publicOrgs {
  125. orgs[i] = convert.ToOrganization(publicOrgs[i])
  126. }
  127. ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
  128. ctx.SetTotalCountHeader(maxResults)
  129. ctx.JSON(http.StatusOK, &orgs)
  130. }
  131. // Create api for create organization
  132. func Create(ctx *context.APIContext) {
  133. // swagger:operation POST /orgs organization orgCreate
  134. // ---
  135. // summary: Create an organization
  136. // consumes:
  137. // - application/json
  138. // produces:
  139. // - application/json
  140. // parameters:
  141. // - name: organization
  142. // in: body
  143. // required: true
  144. // schema: { "$ref": "#/definitions/CreateOrgOption" }
  145. // responses:
  146. // "201":
  147. // "$ref": "#/responses/Organization"
  148. // "403":
  149. // "$ref": "#/responses/forbidden"
  150. // "422":
  151. // "$ref": "#/responses/validationError"
  152. form := web.GetForm(ctx).(*api.CreateOrgOption)
  153. if !ctx.User.CanCreateOrganization() {
  154. ctx.Error(http.StatusForbidden, "Create organization not allowed", nil)
  155. return
  156. }
  157. visibility := api.VisibleTypePublic
  158. if form.Visibility != "" {
  159. visibility = api.VisibilityModes[form.Visibility]
  160. }
  161. org := &models.User{
  162. Name: form.UserName,
  163. FullName: form.FullName,
  164. Description: form.Description,
  165. Website: form.Website,
  166. Location: form.Location,
  167. IsActive: true,
  168. Type: models.UserTypeOrganization,
  169. Visibility: visibility,
  170. RepoAdminChangeTeamAccess: form.RepoAdminChangeTeamAccess,
  171. }
  172. if err := models.CreateOrganization(org, ctx.User); err != nil {
  173. if models.IsErrUserAlreadyExist(err) ||
  174. models.IsErrNameReserved(err) ||
  175. models.IsErrNameCharsNotAllowed(err) ||
  176. models.IsErrNamePatternNotAllowed(err) {
  177. ctx.Error(http.StatusUnprocessableEntity, "", err)
  178. } else {
  179. ctx.Error(http.StatusInternalServerError, "CreateOrganization", err)
  180. }
  181. return
  182. }
  183. ctx.JSON(http.StatusCreated, convert.ToOrganization(org))
  184. }
  185. // Get get an organization
  186. func Get(ctx *context.APIContext) {
  187. // swagger:operation GET /orgs/{org} organization orgGet
  188. // ---
  189. // summary: Get an organization
  190. // produces:
  191. // - application/json
  192. // parameters:
  193. // - name: org
  194. // in: path
  195. // description: name of the organization to get
  196. // type: string
  197. // required: true
  198. // responses:
  199. // "200":
  200. // "$ref": "#/responses/Organization"
  201. if !models.HasOrgOrUserVisible(ctx.Org.Organization, ctx.User) {
  202. ctx.NotFound("HasOrgOrUserVisible", nil)
  203. return
  204. }
  205. ctx.JSON(http.StatusOK, convert.ToOrganization(ctx.Org.Organization))
  206. }
  207. // Edit change an organization's information
  208. func Edit(ctx *context.APIContext) {
  209. // swagger:operation PATCH /orgs/{org} organization orgEdit
  210. // ---
  211. // summary: Edit an organization
  212. // consumes:
  213. // - application/json
  214. // produces:
  215. // - application/json
  216. // parameters:
  217. // - name: org
  218. // in: path
  219. // description: name of the organization to edit
  220. // type: string
  221. // required: true
  222. // - name: body
  223. // in: body
  224. // required: true
  225. // schema:
  226. // "$ref": "#/definitions/EditOrgOption"
  227. // responses:
  228. // "200":
  229. // "$ref": "#/responses/Organization"
  230. form := web.GetForm(ctx).(*api.EditOrgOption)
  231. org := ctx.Org.Organization
  232. org.FullName = form.FullName
  233. org.Description = form.Description
  234. org.Website = form.Website
  235. org.Location = form.Location
  236. if form.Visibility != "" {
  237. org.Visibility = api.VisibilityModes[form.Visibility]
  238. }
  239. if form.RepoAdminChangeTeamAccess != nil {
  240. org.RepoAdminChangeTeamAccess = *form.RepoAdminChangeTeamAccess
  241. }
  242. if err := models.UpdateUserCols(org,
  243. "full_name", "description", "website", "location",
  244. "visibility", "repo_admin_change_team_access",
  245. ); err != nil {
  246. ctx.Error(http.StatusInternalServerError, "EditOrganization", err)
  247. return
  248. }
  249. ctx.JSON(http.StatusOK, convert.ToOrganization(org))
  250. }
  251. //Delete an organization
  252. func Delete(ctx *context.APIContext) {
  253. // swagger:operation DELETE /orgs/{org} organization orgDelete
  254. // ---
  255. // summary: Delete an organization
  256. // produces:
  257. // - application/json
  258. // parameters:
  259. // - name: org
  260. // in: path
  261. // description: organization that is to be deleted
  262. // type: string
  263. // required: true
  264. // responses:
  265. // "204":
  266. // "$ref": "#/responses/empty"
  267. if err := models.DeleteOrganization(ctx.Org.Organization); err != nil {
  268. ctx.Error(http.StatusInternalServerError, "DeleteOrganization", err)
  269. return
  270. }
  271. ctx.Status(http.StatusNoContent)
  272. }