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