code.gitea.io/gitea@v1.22.3/routers/web/org/members.go (about) 1 // Copyright 2014 The Gogs Authors. All rights reserved. 2 // Copyright 2020 The Gitea Authors. 3 // SPDX-License-Identifier: MIT 4 5 package org 6 7 import ( 8 "net/http" 9 10 "code.gitea.io/gitea/models" 11 "code.gitea.io/gitea/models/organization" 12 user_model "code.gitea.io/gitea/models/user" 13 "code.gitea.io/gitea/modules/base" 14 "code.gitea.io/gitea/modules/log" 15 "code.gitea.io/gitea/modules/setting" 16 shared_user "code.gitea.io/gitea/routers/web/shared/user" 17 "code.gitea.io/gitea/services/context" 18 ) 19 20 const ( 21 // tplMembers template for organization members page 22 tplMembers base.TplName = "org/member/members" 23 ) 24 25 // Members render organization users page 26 func Members(ctx *context.Context) { 27 org := ctx.Org.Organization 28 ctx.Data["Title"] = org.FullName 29 ctx.Data["PageIsOrgMembers"] = true 30 31 page := ctx.FormInt("page") 32 if page <= 1 { 33 page = 1 34 } 35 36 opts := &organization.FindOrgMembersOpts{ 37 OrgID: org.ID, 38 PublicOnly: true, 39 } 40 41 if ctx.Doer != nil { 42 isMember, err := ctx.Org.Organization.IsOrgMember(ctx, ctx.Doer.ID) 43 if err != nil { 44 ctx.Error(http.StatusInternalServerError, "IsOrgMember") 45 return 46 } 47 opts.PublicOnly = !isMember && !ctx.Doer.IsAdmin 48 } 49 ctx.Data["PublicOnly"] = opts.PublicOnly 50 51 total, err := organization.CountOrgMembers(ctx, opts) 52 if err != nil { 53 ctx.Error(http.StatusInternalServerError, "CountOrgMembers") 54 return 55 } 56 57 err = shared_user.LoadHeaderCount(ctx) 58 if err != nil { 59 ctx.ServerError("LoadHeaderCount", err) 60 return 61 } 62 63 pager := context.NewPagination(int(total), setting.UI.MembersPagingNum, page, 5) 64 opts.ListOptions.Page = page 65 opts.ListOptions.PageSize = setting.UI.MembersPagingNum 66 members, membersIsPublic, err := organization.FindOrgMembers(ctx, opts) 67 if err != nil { 68 ctx.ServerError("GetMembers", err) 69 return 70 } 71 ctx.Data["Page"] = pager 72 ctx.Data["Members"] = members 73 ctx.Data["MembersIsPublicMember"] = membersIsPublic 74 ctx.Data["MembersIsUserOrgOwner"] = organization.IsUserOrgOwner(ctx, members, org.ID) 75 ctx.Data["MembersTwoFaStatus"] = members.GetTwoFaStatus(ctx) 76 77 ctx.HTML(http.StatusOK, tplMembers) 78 } 79 80 // MembersAction response for operation to a member of organization 81 func MembersAction(ctx *context.Context) { 82 member, err := user_model.GetUserByID(ctx, ctx.FormInt64("uid")) 83 if err != nil { 84 log.Error("GetUserByID: %v", err) 85 } 86 if member == nil { 87 ctx.Redirect(ctx.Org.OrgLink + "/members") 88 return 89 } 90 91 org := ctx.Org.Organization 92 93 switch ctx.Params(":action") { 94 case "private": 95 if ctx.Doer.ID != member.ID && !ctx.Org.IsOwner { 96 ctx.Error(http.StatusNotFound) 97 return 98 } 99 err = organization.ChangeOrgUserStatus(ctx, org.ID, member.ID, false) 100 case "public": 101 if ctx.Doer.ID != member.ID && !ctx.Org.IsOwner { 102 ctx.Error(http.StatusNotFound) 103 return 104 } 105 err = organization.ChangeOrgUserStatus(ctx, org.ID, member.ID, true) 106 case "remove": 107 if !ctx.Org.IsOwner { 108 ctx.Error(http.StatusNotFound) 109 return 110 } 111 err = models.RemoveOrgUser(ctx, org, member) 112 if organization.IsErrLastOrgOwner(err) { 113 ctx.Flash.Error(ctx.Tr("form.last_org_owner")) 114 ctx.JSONRedirect(ctx.Org.OrgLink + "/members") 115 return 116 } 117 case "leave": 118 err = models.RemoveOrgUser(ctx, org, ctx.Doer) 119 if err == nil { 120 ctx.Flash.Success(ctx.Tr("form.organization_leave_success", org.DisplayName())) 121 ctx.JSON(http.StatusOK, map[string]any{ 122 "redirect": "", // keep the user stay on current page, in case they want to do other operations. 123 }) 124 } else if organization.IsErrLastOrgOwner(err) { 125 ctx.Flash.Error(ctx.Tr("form.last_org_owner")) 126 ctx.JSONRedirect(ctx.Org.OrgLink + "/members") 127 } else { 128 log.Error("RemoveOrgUser(%d,%d): %v", org.ID, ctx.Doer.ID, err) 129 } 130 return 131 } 132 133 if err != nil { 134 log.Error("Action(%s): %v", ctx.Params(":action"), err) 135 ctx.JSON(http.StatusOK, map[string]any{ 136 "ok": false, 137 "err": err.Error(), 138 }) 139 return 140 } 141 142 redirect := ctx.Org.OrgLink + "/members" 143 if ctx.Params(":action") == "leave" { 144 redirect = setting.AppSubURL + "/" 145 } 146 147 ctx.JSONRedirect(redirect) 148 }