gitea/models/organization/org_user.go

139 lines
3.9 KiB
Go

// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package organization
import (
"context"
"fmt"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
"xorm.io/builder"
)
// ________ ____ ___
// \_____ \_______ ____ | | \______ ___________
// / | \_ __ \/ ___\| | / ___// __ \_ __ \
// / | \ | \/ /_/ > | /\___ \\ ___/| | \/
// \_______ /__| \___ /|______//____ >\___ >__|
// \/ /_____/ \/ \/
// OrgUser represents an organization-user relation.
type OrgUser struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"INDEX UNIQUE(s)"`
OrgID int64 `xorm:"INDEX UNIQUE(s)"`
IsPublic bool `xorm:"INDEX"`
}
func init() {
db.RegisterModel(new(OrgUser))
}
// GetOrganizationCount returns count of membership of organization of the user.
func GetOrganizationCount(ctx context.Context, u *user_model.User) (int64, error) {
return db.GetEngine(ctx).
Where("uid=?", u.ID).
Count(new(OrgUser))
}
// IsOrganizationOwner returns true if given user is in the owner team.
func IsOrganizationOwner(ctx context.Context, orgID, uid int64) (bool, error) {
ownerTeam, err := GetOwnerTeam(ctx, orgID)
if err != nil {
if IsErrTeamNotExist(err) {
log.Error("Organization does not have owner team: %d", orgID)
return false, nil
}
return false, err
}
return IsTeamMember(ctx, orgID, ownerTeam.ID, uid)
}
// IsOrganizationAdmin returns true if given user is in the owner team or an admin team.
func IsOrganizationAdmin(ctx context.Context, orgID, uid int64) (bool, error) {
teams, err := GetUserOrgTeams(ctx, orgID, uid)
if err != nil {
return false, err
}
for _, t := range teams {
if t.AccessMode >= perm.AccessModeAdmin {
return true, nil
}
}
return false, nil
}
// IsOrganizationMember returns true if given user is member of organization.
func IsOrganizationMember(ctx context.Context, orgID, uid int64) (bool, error) {
return db.GetEngine(ctx).
Where("uid=?", uid).
And("org_id=?", orgID).
Table("org_user").
Exist()
}
// IsPublicMembership returns true if the given user's membership of given org is public.
func IsPublicMembership(ctx context.Context, orgID, uid int64) (bool, error) {
return db.GetEngine(ctx).
Where("uid=?", uid).
And("org_id=?", orgID).
And("is_public=?", true).
Table("org_user").
Exist()
}
// CanCreateOrgRepo returns true if user can create repo in organization
func CanCreateOrgRepo(ctx context.Context, orgID, uid int64) (bool, error) {
return db.GetEngine(ctx).
Where(builder.Eq{"team.can_create_org_repo": true}).
Join("INNER", "team_user", "team_user.team_id = team.id").
And("team_user.uid = ?", uid).
And("team_user.org_id = ?", orgID).
Exist(new(Team))
}
// IsUserOrgOwner returns true if user is in the owner team of given organization.
func IsUserOrgOwner(ctx context.Context, users user_model.UserList, orgID int64) map[int64]bool {
results := make(map[int64]bool, len(users))
for _, user := range users {
results[user.ID] = false // Set default to false
}
ownerMaps, err := loadOrganizationOwners(ctx, users, orgID)
if err == nil {
for _, owner := range ownerMaps {
results[owner.UID] = true
}
}
return results
}
func loadOrganizationOwners(ctx context.Context, users user_model.UserList, orgID int64) (map[int64]*TeamUser, error) {
if len(users) == 0 {
return nil, nil
}
ownerTeam, err := GetOwnerTeam(ctx, orgID)
if err != nil {
if IsErrTeamNotExist(err) {
log.Error("Organization does not have owner team: %d", orgID)
return nil, nil
}
return nil, err
}
userIDs := users.GetUserIDs()
ownerMaps := make(map[int64]*TeamUser)
err = db.GetEngine(ctx).In("uid", userIDs).
And("org_id=?", orgID).
And("team_id=?", ownerTeam.ID).
Find(&ownerMaps)
if err != nil {
return nil, fmt.Errorf("find team users: %w", err)
}
return ownerMaps, nil
}