code.gitea.io/gitea@v1.22.3/models/org.go (about)

     1  // Copyright 2014 The Gogs Authors. All rights reserved.
     2  // Copyright 2019 The Gitea Authors. All rights reserved.
     3  // SPDX-License-Identifier: MIT
     4  
     5  package models
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  
    11  	"code.gitea.io/gitea/models/db"
    12  	"code.gitea.io/gitea/models/organization"
    13  	access_model "code.gitea.io/gitea/models/perm/access"
    14  	repo_model "code.gitea.io/gitea/models/repo"
    15  	user_model "code.gitea.io/gitea/models/user"
    16  )
    17  
    18  // RemoveOrgUser removes user from given organization.
    19  func RemoveOrgUser(ctx context.Context, org *organization.Organization, user *user_model.User) error {
    20  	ou := new(organization.OrgUser)
    21  
    22  	has, err := db.GetEngine(ctx).
    23  		Where("uid=?", user.ID).
    24  		And("org_id=?", org.ID).
    25  		Get(ou)
    26  	if err != nil {
    27  		return fmt.Errorf("get org-user: %w", err)
    28  	} else if !has {
    29  		return nil
    30  	}
    31  
    32  	// Check if the user to delete is the last member in owner team.
    33  	if isOwner, err := organization.IsOrganizationOwner(ctx, org.ID, user.ID); err != nil {
    34  		return err
    35  	} else if isOwner {
    36  		t, err := organization.GetOwnerTeam(ctx, org.ID)
    37  		if err != nil {
    38  			return err
    39  		}
    40  		if t.NumMembers == 1 {
    41  			if err := t.LoadMembers(ctx); err != nil {
    42  				return err
    43  			}
    44  			if t.Members[0].ID == user.ID {
    45  				return organization.ErrLastOrgOwner{UID: user.ID}
    46  			}
    47  		}
    48  	}
    49  
    50  	ctx, committer, err := db.TxContext(ctx)
    51  	if err != nil {
    52  		return err
    53  	}
    54  	defer committer.Close()
    55  
    56  	if _, err := db.DeleteByID[organization.OrgUser](ctx, ou.ID); err != nil {
    57  		return err
    58  	} else if _, err = db.Exec(ctx, "UPDATE `user` SET num_members=num_members-1 WHERE id=?", org.ID); err != nil {
    59  		return err
    60  	}
    61  
    62  	// Delete all repository accesses and unwatch them.
    63  	env, err := organization.AccessibleReposEnv(ctx, org, user.ID)
    64  	if err != nil {
    65  		return fmt.Errorf("AccessibleReposEnv: %w", err)
    66  	}
    67  	repoIDs, err := env.RepoIDs(1, org.NumRepos)
    68  	if err != nil {
    69  		return fmt.Errorf("GetUserRepositories [%d]: %w", user.ID, err)
    70  	}
    71  	for _, repoID := range repoIDs {
    72  		repo, err := repo_model.GetRepositoryByID(ctx, repoID)
    73  		if err != nil {
    74  			return err
    75  		}
    76  		if err = repo_model.WatchRepo(ctx, user, repo, false); err != nil {
    77  			return err
    78  		}
    79  	}
    80  
    81  	if len(repoIDs) > 0 {
    82  		if _, err = db.GetEngine(ctx).
    83  			Where("user_id = ?", user.ID).
    84  			In("repo_id", repoIDs).
    85  			Delete(new(access_model.Access)); err != nil {
    86  			return err
    87  		}
    88  	}
    89  
    90  	// Delete member in their teams.
    91  	teams, err := organization.GetUserOrgTeams(ctx, org.ID, user.ID)
    92  	if err != nil {
    93  		return err
    94  	}
    95  	for _, t := range teams {
    96  		if err = removeTeamMember(ctx, t, user); err != nil {
    97  			return err
    98  		}
    99  	}
   100  
   101  	return committer.Commit()
   102  }