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.

280 lines
7.2 KiB

  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package org
  5. import (
  6. "fmt"
  7. api "code.gitea.io/sdk/gitea"
  8. "code.gitea.io/gitea/models"
  9. "code.gitea.io/gitea/modules/context"
  10. "code.gitea.io/gitea/modules/setting"
  11. "code.gitea.io/gitea/routers/api/v1/user"
  12. )
  13. // listMembers list an organization's members
  14. func listMembers(ctx *context.APIContext, publicOnly bool) {
  15. var members []*models.User
  16. if publicOnly {
  17. orgUsers, err := models.GetOrgUsersByOrgID(ctx.Org.Organization.ID)
  18. if err != nil {
  19. ctx.Error(500, "GetOrgUsersByOrgID", err)
  20. return
  21. }
  22. memberIDs := make([]int64, 0, len(orgUsers))
  23. for _, orgUser := range orgUsers {
  24. if orgUser.IsPublic {
  25. memberIDs = append(memberIDs, orgUser.UID)
  26. }
  27. }
  28. if members, err = models.GetUsersByIDs(memberIDs); err != nil {
  29. ctx.Error(500, "GetUsersByIDs", err)
  30. return
  31. }
  32. } else {
  33. if err := ctx.Org.Organization.GetMembers(); err != nil {
  34. ctx.Error(500, "GetMembers", err)
  35. return
  36. }
  37. members = ctx.Org.Organization.Members
  38. }
  39. apiMembers := make([]*api.User, len(members))
  40. for i, member := range members {
  41. apiMembers[i] = member.APIFormat()
  42. }
  43. ctx.JSON(200, apiMembers)
  44. }
  45. // ListMembers list an organization's members
  46. func ListMembers(ctx *context.APIContext) {
  47. // swagger:operation GET /orgs/{org}/members organization orgListMembers
  48. // ---
  49. // summary: List an organization's members
  50. // produces:
  51. // - application/json
  52. // parameters:
  53. // - name: org
  54. // in: path
  55. // description: name of the organization
  56. // type: string
  57. // required: true
  58. // responses:
  59. // "200":
  60. // "$ref": "#/responses/UserList"
  61. publicOnly := ctx.User == nil || !ctx.Org.Organization.IsOrgMember(ctx.User.ID)
  62. listMembers(ctx, publicOnly)
  63. }
  64. // ListPublicMembers list an organization's public members
  65. func ListPublicMembers(ctx *context.APIContext) {
  66. // swagger:operation GET /orgs/{org}/public_members organization orgListPublicMembers
  67. // ---
  68. // summary: List an organization's public members
  69. // parameters:
  70. // - name: org
  71. // in: path
  72. // description: name of the organization
  73. // type: string
  74. // required: true
  75. // produces:
  76. // - application/json
  77. // responses:
  78. // "200":
  79. // "$ref": "#/responses/UserList"
  80. listMembers(ctx, true)
  81. }
  82. // IsMember check if a user is a member of an organization
  83. func IsMember(ctx *context.APIContext) {
  84. // swagger:operation GET /orgs/{org}/members/{username} organization orgIsMember
  85. // ---
  86. // summary: Check if a user is a member of an organization
  87. // parameters:
  88. // - name: org
  89. // in: path
  90. // description: name of the organization
  91. // type: string
  92. // required: true
  93. // - name: username
  94. // in: path
  95. // description: username of the user
  96. // type: string
  97. // required: true
  98. // responses:
  99. // "204":
  100. // description: user is a member
  101. // schema:
  102. // "$ref": "#/responses/empty"
  103. // "404":
  104. // description: user is not a member
  105. // schema:
  106. // "$ref": "#/responses/empty"
  107. userToCheck := user.GetUserByParams(ctx)
  108. if ctx.Written() {
  109. return
  110. }
  111. if ctx.User != nil && ctx.Org.Organization.IsOrgMember(ctx.User.ID) {
  112. if ctx.Org.Organization.IsOrgMember(userToCheck.ID) {
  113. ctx.Status(204)
  114. } else {
  115. ctx.Status(404)
  116. }
  117. } else if ctx.User != nil && ctx.User.ID == userToCheck.ID {
  118. ctx.Status(404)
  119. } else {
  120. redirectURL := fmt.Sprintf("%sapi/v1/orgs/%s/public_members/%s",
  121. setting.AppURL, ctx.Org.Organization.Name, userToCheck.Name)
  122. ctx.Redirect(redirectURL, 302)
  123. }
  124. }
  125. // IsPublicMember check if a user is a public member of an organization
  126. func IsPublicMember(ctx *context.APIContext) {
  127. // swagger:operation GET /orgs/{org}/public_members/{username} organization orgIsPublicMember
  128. // ---
  129. // summary: Check if a user is a public member of an organization
  130. // parameters:
  131. // - name: org
  132. // in: path
  133. // description: name of the organization
  134. // type: string
  135. // required: true
  136. // - name: username
  137. // in: path
  138. // description: username of the user
  139. // type: string
  140. // required: true
  141. // responses:
  142. // "204":
  143. // description: user is a public member
  144. // schema:
  145. // "$ref": "#/responses/empty"
  146. // "404":
  147. // description: user is not a public member
  148. // schema:
  149. // "$ref": "#/responses/empty"
  150. userToCheck := user.GetUserByParams(ctx)
  151. if ctx.Written() {
  152. return
  153. }
  154. if userToCheck.IsPublicMember(ctx.Org.Organization.ID) {
  155. ctx.Status(204)
  156. } else {
  157. ctx.Status(404)
  158. }
  159. }
  160. // PublicizeMember make a member's membership public
  161. func PublicizeMember(ctx *context.APIContext) {
  162. // swagger:operation PUT /orgs/{org}/public_members/{username} organization orgPublicizeMember
  163. // ---
  164. // summary: Publicize a user's membership
  165. // produces:
  166. // - application/json
  167. // parameters:
  168. // - name: org
  169. // in: path
  170. // description: name of the organization
  171. // type: string
  172. // required: true
  173. // - name: username
  174. // in: path
  175. // description: username of the user
  176. // type: string
  177. // required: true
  178. // responses:
  179. // "204":
  180. // description: membership publicized
  181. // schema:
  182. // "$ref": "#/responses/empty"
  183. userToPublicize := user.GetUserByParams(ctx)
  184. if ctx.Written() {
  185. return
  186. }
  187. if userToPublicize.ID != ctx.User.ID {
  188. ctx.Error(403, "", "Cannot publicize another member")
  189. return
  190. }
  191. err := models.ChangeOrgUserStatus(ctx.Org.Organization.ID, userToPublicize.ID, true)
  192. if err != nil {
  193. ctx.Error(500, "ChangeOrgUserStatus", err)
  194. return
  195. }
  196. ctx.Status(204)
  197. }
  198. // ConcealMember make a member's membership not public
  199. func ConcealMember(ctx *context.APIContext) {
  200. // swagger:operation DELETE /orgs/{org}/public_members/{username} organization orgConcealMember
  201. // ---
  202. // summary: Conceal a user's membership
  203. // produces:
  204. // - application/json
  205. // parameters:
  206. // - name: org
  207. // in: path
  208. // description: name of the organization
  209. // type: string
  210. // required: true
  211. // - name: username
  212. // in: path
  213. // description: username of the user
  214. // type: string
  215. // required: true
  216. // responses:
  217. // "204":
  218. // "$ref": "#/responses/empty"
  219. userToConceal := user.GetUserByParams(ctx)
  220. if ctx.Written() {
  221. return
  222. }
  223. if userToConceal.ID != ctx.User.ID {
  224. ctx.Error(403, "", "Cannot conceal another member")
  225. return
  226. }
  227. err := models.ChangeOrgUserStatus(ctx.Org.Organization.ID, userToConceal.ID, false)
  228. if err != nil {
  229. ctx.Error(500, "ChangeOrgUserStatus", err)
  230. return
  231. }
  232. ctx.Status(204)
  233. }
  234. // DeleteMember remove a member from an organization
  235. func DeleteMember(ctx *context.APIContext) {
  236. // swagger:operation DELETE /orgs/{org}/members/{username} organization orgDeleteMember
  237. // ---
  238. // summary: Remove a member from an organization
  239. // produces:
  240. // - application/json
  241. // parameters:
  242. // - name: org
  243. // in: path
  244. // description: name of the organization
  245. // type: string
  246. // required: true
  247. // - name: username
  248. // in: path
  249. // description: username of the user
  250. // type: string
  251. // required: true
  252. // responses:
  253. // "204":
  254. // description: member removed
  255. // schema:
  256. // "$ref": "#/responses/empty"
  257. member := user.GetUserByParams(ctx)
  258. if ctx.Written() {
  259. return
  260. }
  261. if err := ctx.Org.Organization.RemoveMember(member.ID); err != nil {
  262. ctx.Error(500, "RemoveMember", err)
  263. }
  264. ctx.Status(204)
  265. }