summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEthan Koenig <etk39@cornell.edu>2017-01-19 19:31:46 -0700
committerLunny Xiao <xiaolunwen@gmail.com>2017-01-20 10:31:46 +0800
commitfcf02e4961beb98cf1bc0f60537589e41a871369 (patch)
tree08d983c149b094dcb537828dda5e44578159eea2
parent3c4d5e1ed576cbb203428f61f4b181c77b5fd61a (diff)
downloadgitea-fcf02e4961beb98cf1bc0f60537589e41a871369.tar.gz
gitea-fcf02e4961beb98cf1bc0f60537589e41a871369.zip
API Endpoints for organization members (#645)
-rw-r--r--models/user.go6
-rw-r--r--routers/api/v1/api.go10
-rw-r--r--routers/api/v1/org/member.go141
3 files changed, 155 insertions, 2 deletions
diff --git a/models/user.go b/models/user.go
index e6ba2fa6f3..8b20d7e0ba 100644
--- a/models/user.go
+++ b/models/user.go
@@ -1052,8 +1052,10 @@ func GetUserEmailsByNames(names []string) []string {
// GetUsersByIDs returns all resolved users from a list of Ids.
func GetUsersByIDs(ids []int64) ([]*User, error) {
ous := make([]*User, 0, len(ids))
- err := x.
- In("id", ids).
+ if len(ids) == 0 {
+ return ous, nil
+ }
+ err := x.In("id", ids).
Asc("name").
Find(&ous)
return ous, err
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index c30db1a33a..29f268d6bc 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -395,6 +395,16 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/users/:username/orgs", org.ListUserOrgs)
m.Group("/orgs/:orgname", func() {
m.Combo("").Get(org.Get).Patch(bind(api.EditOrgOption{}), org.Edit)
+ m.Group("/members", func() {
+ m.Get("", org.ListMembers)
+ m.Combo("/:username").Get(org.IsMember).Delete(org.DeleteMember)
+ })
+ m.Group("/public_members", func() {
+ m.Get("", org.ListPublicMembers)
+ m.Combo("/:username").Get(org.IsPublicMember).
+ Put(org.PublicizeMember).
+ Delete(org.ConcealMember)
+ })
m.Combo("/teams").Get(org.ListTeams)
m.Group("/hooks", func() {
m.Combo("").Get(org.ListHooks).
diff --git a/routers/api/v1/org/member.go b/routers/api/v1/org/member.go
new file mode 100644
index 0000000000..2420b9b541
--- /dev/null
+++ b/routers/api/v1/org/member.go
@@ -0,0 +1,141 @@
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package org
+
+import (
+ "fmt"
+
+ api "code.gitea.io/sdk/gitea"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/routers/api/v1/user"
+)
+
+// listMembers list an organization's members
+func listMembers(ctx *context.APIContext, publicOnly bool) {
+ var members []*models.User
+ if publicOnly {
+ orgUsers, err := models.GetOrgUsersByOrgID(ctx.Org.Organization.ID)
+ if err != nil {
+ ctx.Error(500, "GetOrgUsersByOrgID", err)
+ return
+ }
+
+ memberIDs := make([]int64, 0, len(orgUsers))
+ for _, orgUser := range orgUsers {
+ if orgUser.IsPublic {
+ memberIDs = append(memberIDs, orgUser.UID)
+ }
+ }
+
+ if members, err = models.GetUsersByIDs(memberIDs); err != nil {
+ ctx.Error(500, "GetUsersByIDs", err)
+ return
+ }
+ } else {
+ if err := ctx.Org.Organization.GetMembers(); err != nil {
+ ctx.Error(500, "GetMembers", err)
+ return
+ }
+ members = ctx.Org.Organization.Members
+ }
+
+ apiMembers := make([]*api.User, len(members))
+ for i, member := range members {
+ apiMembers[i] = member.APIFormat()
+ }
+ ctx.JSON(200, apiMembers)
+}
+
+// ListMembers list an organization's members
+func ListMembers(ctx *context.APIContext) {
+ listMembers(ctx, !ctx.Org.Organization.IsOrgMember(ctx.User.ID))
+}
+
+// ListPublicMembers list an organization's public members
+func ListPublicMembers(ctx *context.APIContext) {
+ listMembers(ctx, true)
+}
+
+// IsMember check if a user is a member of an organization
+func IsMember(ctx *context.APIContext) {
+ org := ctx.Org.Organization
+ requester := ctx.User
+ userToCheck := user.GetUserByParams(ctx)
+ if org.IsOrgMember(requester.ID) {
+ if org.IsOrgMember(userToCheck.ID) {
+ ctx.Status(204)
+ } else {
+ ctx.Status(404)
+ }
+ } else if requester.ID == userToCheck.ID {
+ ctx.Status(404)
+ } else {
+ redirectURL := fmt.Sprintf("%sapi/v1/orgs/%s/public_members/%s",
+ setting.AppURL, org.Name, userToCheck.Name)
+ ctx.Redirect(redirectURL, 302)
+ }
+}
+
+// IsPublicMember check if a user is a public member of an organization
+func IsPublicMember(ctx *context.APIContext) {
+ userToCheck := user.GetUserByParams(ctx)
+ if userToCheck.IsPublicMember(ctx.Org.Organization.ID) {
+ ctx.Status(204)
+ } else {
+ ctx.Status(404)
+ }
+}
+
+// PublicizeMember make a member's membership public
+func PublicizeMember(ctx *context.APIContext) {
+ userToPublicize := user.GetUserByParams(ctx)
+ if userToPublicize.ID != ctx.User.ID {
+ ctx.Error(403, "", "Cannot publicize another member")
+ return
+ } else if !ctx.Org.Organization.IsOrgMember(userToPublicize.ID) {
+ ctx.Error(403, "", "Must be a member of the organization")
+ return
+ }
+ err := models.ChangeOrgUserStatus(ctx.Org.Organization.ID, userToPublicize.ID, true)
+ if err != nil {
+ ctx.Error(500, "ChangeOrgUserStatus", err)
+ return
+ }
+ ctx.Status(204)
+}
+
+// ConcealMember make a member's membership not public
+func ConcealMember(ctx *context.APIContext) {
+ userToConceal := user.GetUserByParams(ctx)
+ if userToConceal.ID != ctx.User.ID {
+ ctx.Error(403, "", "Cannot conceal another member")
+ return
+ } else if !ctx.Org.Organization.IsOrgMember(userToConceal.ID) {
+ ctx.Error(403, "", "Must be a member of the organization")
+ return
+ }
+ err := models.ChangeOrgUserStatus(ctx.Org.Organization.ID, userToConceal.ID, false)
+ if err != nil {
+ ctx.Error(500, "ChangeOrgUserStatus", err)
+ return
+ }
+ ctx.Status(204)
+}
+
+// DeleteMember remove a member from an organization
+func DeleteMember(ctx *context.APIContext) {
+ org := ctx.Org.Organization
+ if !org.IsOwnedBy(ctx.User.ID) {
+ ctx.Error(403, "", "You must be an owner of the organization.")
+ return
+ }
+ if err := org.RemoveMember(user.GetUserByParams(ctx).ID); err != nil {
+ ctx.Error(500, "RemoveMember", err)
+ }
+ ctx.Status(204)
+}