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