code.gitea.io/gitea@v1.21.7/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  )
    16  
    17  func removeOrgUser(ctx context.Context, orgID, userID int64) error {
    18  	ou := new(organization.OrgUser)
    19  
    20  	sess := db.GetEngine(ctx)
    21  
    22  	has, err := sess.
    23  		Where("uid=?", userID).
    24  		And("org_id=?", orgID).
    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  	org, err := organization.GetOrgByID(ctx, orgID)
    33  	if err != nil {
    34  		return fmt.Errorf("GetUserByID [%d]: %w", orgID, err)
    35  	}
    36  
    37  	// Check if the user to delete is the last member in owner team.
    38  	if isOwner, err := organization.IsOrganizationOwner(ctx, orgID, userID); err != nil {
    39  		return err
    40  	} else if isOwner {
    41  		t, err := organization.GetOwnerTeam(ctx, org.ID)
    42  		if err != nil {
    43  			return err
    44  		}
    45  		if t.NumMembers == 1 {
    46  			if err := t.LoadMembers(ctx); err != nil {
    47  				return err
    48  			}
    49  			if t.Members[0].ID == userID {
    50  				return organization.ErrLastOrgOwner{UID: userID}
    51  			}
    52  		}
    53  	}
    54  
    55  	if _, err := sess.ID(ou.ID).Delete(ou); err != nil {
    56  		return err
    57  	} else if _, err = db.Exec(ctx, "UPDATE `user` SET num_members=num_members-1 WHERE id=?", orgID); err != nil {
    58  		return err
    59  	}
    60  
    61  	// Delete all repository accesses and unwatch them.
    62  	env, err := organization.AccessibleReposEnv(ctx, org, userID)
    63  	if err != nil {
    64  		return fmt.Errorf("AccessibleReposEnv: %w", err)
    65  	}
    66  	repoIDs, err := env.RepoIDs(1, org.NumRepos)
    67  	if err != nil {
    68  		return fmt.Errorf("GetUserRepositories [%d]: %w", userID, err)
    69  	}
    70  	for _, repoID := range repoIDs {
    71  		if err = repo_model.WatchRepo(ctx, userID, repoID, false); err != nil {
    72  			return err
    73  		}
    74  	}
    75  
    76  	if len(repoIDs) > 0 {
    77  		if _, err = sess.
    78  			Where("user_id = ?", userID).
    79  			In("repo_id", repoIDs).
    80  			Delete(new(access_model.Access)); err != nil {
    81  			return err
    82  		}
    83  	}
    84  
    85  	// Delete member in their teams.
    86  	teams, err := organization.GetUserOrgTeams(ctx, org.ID, userID)
    87  	if err != nil {
    88  		return err
    89  	}
    90  	for _, t := range teams {
    91  		if err = removeTeamMember(ctx, t, userID); err != nil {
    92  			return err
    93  		}
    94  	}
    95  
    96  	return nil
    97  }
    98  
    99  // RemoveOrgUser removes user from given organization.
   100  func RemoveOrgUser(orgID, userID int64) error {
   101  	ctx, committer, err := db.TxContext(db.DefaultContext)
   102  	if err != nil {
   103  		return err
   104  	}
   105  	defer committer.Close()
   106  	if err := removeOrgUser(ctx, orgID, userID); err != nil {
   107  		return err
   108  	}
   109  	return committer.Commit()
   110  }