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.

member.go 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  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. "net/http"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/context"
  9. "code.gitea.io/gitea/modules/convert"
  10. "code.gitea.io/gitea/modules/setting"
  11. api "code.gitea.io/gitea/modules/structs"
  12. "code.gitea.io/gitea/routers/api/v1/user"
  13. "code.gitea.io/gitea/routers/api/v1/utils"
  14. )
  15. // listMembers list an organization's members
  16. func listMembers(ctx *context.APIContext, publicOnly bool) {
  17. opts := &models.FindOrgMembersOpts{
  18. OrgID: ctx.Org.Organization.ID,
  19. PublicOnly: publicOnly,
  20. ListOptions: utils.GetListOptions(ctx),
  21. }
  22. count, err := models.CountOrgMembers(opts)
  23. if err != nil {
  24. ctx.InternalServerError(err)
  25. return
  26. }
  27. members, _, err := models.FindOrgMembers(opts)
  28. if err != nil {
  29. ctx.InternalServerError(err)
  30. return
  31. }
  32. apiMembers := make([]*api.User, len(members))
  33. for i, member := range members {
  34. apiMembers[i] = convert.ToUser(member, ctx.User)
  35. }
  36. ctx.SetTotalCountHeader(count)
  37. ctx.JSON(http.StatusOK, apiMembers)
  38. }
  39. // ListMembers list an organization's members
  40. func ListMembers(ctx *context.APIContext) {
  41. // swagger:operation GET /orgs/{org}/members organization orgListMembers
  42. // ---
  43. // summary: List an organization's members
  44. // produces:
  45. // - application/json
  46. // parameters:
  47. // - name: org
  48. // in: path
  49. // description: name of the organization
  50. // type: string
  51. // required: true
  52. // - name: page
  53. // in: query
  54. // description: page number of results to return (1-based)
  55. // type: integer
  56. // - name: limit
  57. // in: query
  58. // description: page size of results
  59. // type: integer
  60. // responses:
  61. // "200":
  62. // "$ref": "#/responses/UserList"
  63. publicOnly := true
  64. if ctx.User != nil {
  65. isMember, err := ctx.Org.Organization.IsOrgMember(ctx.User.ID)
  66. if err != nil {
  67. ctx.Error(http.StatusInternalServerError, "IsOrgMember", err)
  68. return
  69. }
  70. publicOnly = !isMember && !ctx.User.IsAdmin
  71. }
  72. listMembers(ctx, publicOnly)
  73. }
  74. // ListPublicMembers list an organization's public members
  75. func ListPublicMembers(ctx *context.APIContext) {
  76. // swagger:operation GET /orgs/{org}/public_members organization orgListPublicMembers
  77. // ---
  78. // summary: List an organization's public members
  79. // parameters:
  80. // - name: org
  81. // in: path
  82. // description: name of the organization
  83. // type: string
  84. // required: true
  85. // - name: page
  86. // in: query
  87. // description: page number of results to return (1-based)
  88. // type: integer
  89. // - name: limit
  90. // in: query
  91. // description: page size of results
  92. // type: integer
  93. // produces:
  94. // - application/json
  95. // responses:
  96. // "200":
  97. // "$ref": "#/responses/UserList"
  98. listMembers(ctx, true)
  99. }
  100. // IsMember check if a user is a member of an organization
  101. func IsMember(ctx *context.APIContext) {
  102. // swagger:operation GET /orgs/{org}/members/{username} organization orgIsMember
  103. // ---
  104. // summary: Check if a user is a member of an organization
  105. // parameters:
  106. // - name: org
  107. // in: path
  108. // description: name of the organization
  109. // type: string
  110. // required: true
  111. // - name: username
  112. // in: path
  113. // description: username of the user
  114. // type: string
  115. // required: true
  116. // responses:
  117. // "204":
  118. // description: user is a member
  119. // "302":
  120. // description: redirection to /orgs/{org}/public_members/{username}
  121. // "404":
  122. // description: user is not a member
  123. userToCheck := user.GetUserByParams(ctx)
  124. if ctx.Written() {
  125. return
  126. }
  127. if ctx.User != nil {
  128. userIsMember, err := ctx.Org.Organization.IsOrgMember(ctx.User.ID)
  129. if err != nil {
  130. ctx.Error(http.StatusInternalServerError, "IsOrgMember", err)
  131. return
  132. } else if userIsMember || ctx.User.IsAdmin {
  133. userToCheckIsMember, err := ctx.Org.Organization.IsOrgMember(userToCheck.ID)
  134. if err != nil {
  135. ctx.Error(http.StatusInternalServerError, "IsOrgMember", err)
  136. } else if userToCheckIsMember {
  137. ctx.Status(http.StatusNoContent)
  138. } else {
  139. ctx.NotFound()
  140. }
  141. return
  142. } else if ctx.User.ID == userToCheck.ID {
  143. ctx.NotFound()
  144. return
  145. }
  146. }
  147. redirectURL := setting.AppURL + "api/v1/orgs/" + ctx.Org.Organization.Name + "/public_members/" + userToCheck.Name
  148. ctx.Redirect(redirectURL, 302)
  149. }
  150. // IsPublicMember check if a user is a public member of an organization
  151. func IsPublicMember(ctx *context.APIContext) {
  152. // swagger:operation GET /orgs/{org}/public_members/{username} organization orgIsPublicMember
  153. // ---
  154. // summary: Check if a user is a public member of an organization
  155. // parameters:
  156. // - name: org
  157. // in: path
  158. // description: name of the organization
  159. // type: string
  160. // required: true
  161. // - name: username
  162. // in: path
  163. // description: username of the user
  164. // type: string
  165. // required: true
  166. // responses:
  167. // "204":
  168. // description: user is a public member
  169. // "404":
  170. // description: user is not a public member
  171. userToCheck := user.GetUserByParams(ctx)
  172. if ctx.Written() {
  173. return
  174. }
  175. if userToCheck.IsPublicMember(ctx.Org.Organization.ID) {
  176. ctx.Status(http.StatusNoContent)
  177. } else {
  178. ctx.NotFound()
  179. }
  180. }
  181. // PublicizeMember make a member's membership public
  182. func PublicizeMember(ctx *context.APIContext) {
  183. // swagger:operation PUT /orgs/{org}/public_members/{username} organization orgPublicizeMember
  184. // ---
  185. // summary: Publicize a user's membership
  186. // produces:
  187. // - application/json
  188. // parameters:
  189. // - name: org
  190. // in: path
  191. // description: name of the organization
  192. // type: string
  193. // required: true
  194. // - name: username
  195. // in: path
  196. // description: username of the user
  197. // type: string
  198. // required: true
  199. // responses:
  200. // "204":
  201. // description: membership publicized
  202. // "403":
  203. // "$ref": "#/responses/forbidden"
  204. userToPublicize := user.GetUserByParams(ctx)
  205. if ctx.Written() {
  206. return
  207. }
  208. if userToPublicize.ID != ctx.User.ID {
  209. ctx.Error(http.StatusForbidden, "", "Cannot publicize another member")
  210. return
  211. }
  212. err := models.ChangeOrgUserStatus(ctx.Org.Organization.ID, userToPublicize.ID, true)
  213. if err != nil {
  214. ctx.Error(http.StatusInternalServerError, "ChangeOrgUserStatus", err)
  215. return
  216. }
  217. ctx.Status(http.StatusNoContent)
  218. }
  219. // ConcealMember make a member's membership not public
  220. func ConcealMember(ctx *context.APIContext) {
  221. // swagger:operation DELETE /orgs/{org}/public_members/{username} organization orgConcealMember
  222. // ---
  223. // summary: Conceal a user's membership
  224. // produces:
  225. // - application/json
  226. // parameters:
  227. // - name: org
  228. // in: path
  229. // description: name of the organization
  230. // type: string
  231. // required: true
  232. // - name: username
  233. // in: path
  234. // description: username of the user
  235. // type: string
  236. // required: true
  237. // responses:
  238. // "204":
  239. // "$ref": "#/responses/empty"
  240. // "403":
  241. // "$ref": "#/responses/forbidden"
  242. userToConceal := user.GetUserByParams(ctx)
  243. if ctx.Written() {
  244. return
  245. }
  246. if userToConceal.ID != ctx.User.ID {
  247. ctx.Error(http.StatusForbidden, "", "Cannot conceal another member")
  248. return
  249. }
  250. err := models.ChangeOrgUserStatus(ctx.Org.Organization.ID, userToConceal.ID, false)
  251. if err != nil {
  252. ctx.Error(http.StatusInternalServerError, "ChangeOrgUserStatus", err)
  253. return
  254. }
  255. ctx.Status(http.StatusNoContent)
  256. }
  257. // DeleteMember remove a member from an organization
  258. func DeleteMember(ctx *context.APIContext) {
  259. // swagger:operation DELETE /orgs/{org}/members/{username} organization orgDeleteMember
  260. // ---
  261. // summary: Remove a member from an organization
  262. // produces:
  263. // - application/json
  264. // parameters:
  265. // - name: org
  266. // in: path
  267. // description: name of the organization
  268. // type: string
  269. // required: true
  270. // - name: username
  271. // in: path
  272. // description: username of the user
  273. // type: string
  274. // required: true
  275. // responses:
  276. // "204":
  277. // description: member removed
  278. member := user.GetUserByParams(ctx)
  279. if ctx.Written() {
  280. return
  281. }
  282. if err := ctx.Org.Organization.RemoveMember(member.ID); err != nil {
  283. ctx.Error(http.StatusInternalServerError, "RemoveMember", err)
  284. }
  285. ctx.Status(http.StatusNoContent)
  286. }