mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Move some repositories' operations to a standalone service package (#8557)
* Move some repositories' operations to a standalone service package * improve code * remove unused codes * add rollback when fork failed * add repo when return
This commit is contained in:
		@@ -742,6 +742,28 @@ func (repo *Repository) CanUserFork(user *User) (bool, error) {
 | 
				
			|||||||
	return false, nil
 | 
						return false, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CanUserDelete returns true if user could delete the repository
 | 
				
			||||||
 | 
					func (repo *Repository) CanUserDelete(user *User) (bool, error) {
 | 
				
			||||||
 | 
						if user.IsAdmin || user.ID == repo.OwnerID {
 | 
				
			||||||
 | 
							return true, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := repo.GetOwner(); err != nil {
 | 
				
			||||||
 | 
							return false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if repo.Owner.IsOrganization() {
 | 
				
			||||||
 | 
							isOwner, err := repo.Owner.IsOwnedBy(user.ID)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return false, err
 | 
				
			||||||
 | 
							} else if isOwner {
 | 
				
			||||||
 | 
								return true, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CanEnablePulls returns true if repository meets the requirements of accepting pulls.
 | 
					// CanEnablePulls returns true if repository meets the requirements of accepting pulls.
 | 
				
			||||||
func (repo *Repository) CanEnablePulls() bool {
 | 
					func (repo *Repository) CanEnablePulls() bool {
 | 
				
			||||||
	return !repo.IsMirror && !repo.IsEmpty
 | 
						return !repo.IsMirror && !repo.IsEmpty
 | 
				
			||||||
@@ -1430,15 +1452,9 @@ func createRepository(e *xorm.Session, doer, u *User, repo *Repository) (err err
 | 
				
			|||||||
		t, err := u.getOwnerTeam(e)
 | 
							t, err := u.getOwnerTeam(e)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return fmt.Errorf("getOwnerTeam: %v", err)
 | 
								return fmt.Errorf("getOwnerTeam: %v", err)
 | 
				
			||||||
		} else if err = t.addRepository(e, repo); err != nil {
 | 
							}
 | 
				
			||||||
 | 
							if err = t.addRepository(e, repo); err != nil {
 | 
				
			||||||
			return fmt.Errorf("addRepository: %v", err)
 | 
								return fmt.Errorf("addRepository: %v", err)
 | 
				
			||||||
		} else if err = prepareWebhooks(e, repo, HookEventRepository, &api.RepositoryPayload{
 | 
					 | 
				
			||||||
			Action:       api.HookRepoCreated,
 | 
					 | 
				
			||||||
			Repository:   repo.innerAPIFormat(e, AccessModeOwner, false),
 | 
					 | 
				
			||||||
			Organization: u.APIFormat(),
 | 
					 | 
				
			||||||
			Sender:       doer.APIFormat(),
 | 
					 | 
				
			||||||
		}); err != nil {
 | 
					 | 
				
			||||||
			return fmt.Errorf("prepareWebhooks: %v", err)
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if err = repo.recalculateAccesses(e); err != nil {
 | 
						} else if err = repo.recalculateAccesses(e); err != nil {
 | 
				
			||||||
		// Organization automatically called this in addRepository method.
 | 
							// Organization automatically called this in addRepository method.
 | 
				
			||||||
@@ -1522,11 +1538,6 @@ func CreateRepository(doer, u *User, opts CreateRepoOptions) (_ *Repository, err
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add to hook queue for created repo after session commit.
 | 
					 | 
				
			||||||
	if u.IsOrganization() {
 | 
					 | 
				
			||||||
		go HookQueue.Add(repo.ID)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return repo, err
 | 
						return repo, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2044,18 +2055,6 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
 | 
				
			|||||||
		return fmt.Errorf("Commit: %v", err)
 | 
							return fmt.Errorf("Commit: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if org.IsOrganization() {
 | 
					 | 
				
			||||||
		if err = PrepareWebhooks(repo, HookEventRepository, &api.RepositoryPayload{
 | 
					 | 
				
			||||||
			Action:       api.HookRepoDeleted,
 | 
					 | 
				
			||||||
			Repository:   repo.APIFormat(AccessModeOwner),
 | 
					 | 
				
			||||||
			Organization: org.APIFormat(),
 | 
					 | 
				
			||||||
			Sender:       doer.APIFormat(),
 | 
					 | 
				
			||||||
		}); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		go HookQueue.Add(repo.ID)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if len(repo.Avatar) > 0 {
 | 
						if len(repo.Avatar) > 0 {
 | 
				
			||||||
		avatarPath := repo.CustomAvatarPath()
 | 
							avatarPath := repo.CustomAvatarPath()
 | 
				
			||||||
		if com.IsExist(avatarPath) {
 | 
							if com.IsExist(avatarPath) {
 | 
				
			||||||
@@ -2065,7 +2064,6 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DeleteRepoFromIndexer(repo)
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2521,22 +2519,22 @@ func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ForkRepository forks a repository
 | 
					// ForkRepository forks a repository
 | 
				
			||||||
func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
 | 
					func ForkRepository(doer, owner *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
 | 
				
			||||||
	forkedRepo, err := oldRepo.GetUserFork(u.ID)
 | 
						forkedRepo, err := oldRepo.GetUserFork(owner.ID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if forkedRepo != nil {
 | 
						if forkedRepo != nil {
 | 
				
			||||||
		return nil, ErrForkAlreadyExist{
 | 
							return nil, ErrForkAlreadyExist{
 | 
				
			||||||
			Uname:    u.Name,
 | 
								Uname:    owner.Name,
 | 
				
			||||||
			RepoName: oldRepo.FullName(),
 | 
								RepoName: oldRepo.FullName(),
 | 
				
			||||||
			ForkName: forkedRepo.FullName(),
 | 
								ForkName: forkedRepo.FullName(),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo := &Repository{
 | 
						repo := &Repository{
 | 
				
			||||||
		OwnerID:       u.ID,
 | 
							OwnerID:       owner.ID,
 | 
				
			||||||
		Owner:         u,
 | 
							Owner:         owner,
 | 
				
			||||||
		Name:          name,
 | 
							Name:          name,
 | 
				
			||||||
		LowerName:     strings.ToLower(name),
 | 
							LowerName:     strings.ToLower(name),
 | 
				
			||||||
		Description:   desc,
 | 
							Description:   desc,
 | 
				
			||||||
@@ -2553,7 +2551,7 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = createRepository(sess, doer, u, repo); err != nil {
 | 
						if err = createRepository(sess, doer, owner, repo); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2561,9 +2559,9 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repoPath := RepoPath(u.Name, repo.Name)
 | 
						repoPath := RepoPath(owner.Name, repo.Name)
 | 
				
			||||||
	_, stderr, err := process.GetManager().ExecTimeout(10*time.Minute,
 | 
						_, stderr, err := process.GetManager().ExecTimeout(10*time.Minute,
 | 
				
			||||||
		fmt.Sprintf("ForkRepository(git clone): %s/%s", u.Name, repo.Name),
 | 
							fmt.Sprintf("ForkRepository(git clone): %s/%s", owner.Name, repo.Name),
 | 
				
			||||||
		git.GitExecutable, "clone", "--bare", oldRepo.repoPath(sess), repoPath)
 | 
							git.GitExecutable, "clone", "--bare", oldRepo.repoPath(sess), repoPath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("git clone: %v", stderr)
 | 
							return nil, fmt.Errorf("git clone: %v", stderr)
 | 
				
			||||||
@@ -2586,24 +2584,6 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	oldMode, _ := AccessLevel(doer, oldRepo)
 | 
					 | 
				
			||||||
	mode, _ := AccessLevel(doer, repo)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err = PrepareWebhooks(oldRepo, HookEventFork, &api.ForkPayload{
 | 
					 | 
				
			||||||
		Forkee: oldRepo.APIFormat(oldMode),
 | 
					 | 
				
			||||||
		Repo:   repo.APIFormat(mode),
 | 
					 | 
				
			||||||
		Sender: doer.APIFormat(),
 | 
					 | 
				
			||||||
	}); err != nil {
 | 
					 | 
				
			||||||
		log.Error("PrepareWebhooks [repo_id: %d]: %v", oldRepo.ID, err)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		go HookQueue.Add(oldRepo.ID)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Add to hook queue for created repo after session commit.
 | 
					 | 
				
			||||||
	if u.IsOrganization() {
 | 
					 | 
				
			||||||
		go HookQueue.Add(repo.ID)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err = repo.UpdateSize(); err != nil {
 | 
						if err = repo.UpdateSize(); err != nil {
 | 
				
			||||||
		log.Error("Failed to update size for repository: %v", err)
 | 
							log.Error("Failed to update size for repository: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -2612,20 +2592,19 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
 | 
				
			|||||||
	sess2 := x.NewSession()
 | 
						sess2 := x.NewSession()
 | 
				
			||||||
	defer sess2.Close()
 | 
						defer sess2.Close()
 | 
				
			||||||
	if err = sess2.Begin(); err != nil {
 | 
						if err = sess2.Begin(); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return repo, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var lfsObjects []*LFSMetaObject
 | 
						var lfsObjects []*LFSMetaObject
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err = sess2.Where("repository_id=?", oldRepo.ID).Find(&lfsObjects); err != nil {
 | 
						if err = sess2.Where("repository_id=?", oldRepo.ID).Find(&lfsObjects); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return repo, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, v := range lfsObjects {
 | 
						for _, v := range lfsObjects {
 | 
				
			||||||
		v.ID = 0
 | 
							v.ID = 0
 | 
				
			||||||
		v.RepositoryID = repo.ID
 | 
							v.RepositoryID = repo.ID
 | 
				
			||||||
		if _, err = sess2.Insert(v); err != nil {
 | 
							if _, err = sess2.Insert(v); err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return repo, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -98,6 +98,7 @@ func (r *indexerNotifier) NotifyDeleteComment(doer *models.User, comment *models
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (r *indexerNotifier) NotifyDeleteRepository(doer *models.User, repo *models.Repository) {
 | 
					func (r *indexerNotifier) NotifyDeleteRepository(doer *models.User, repo *models.Repository) {
 | 
				
			||||||
	issue_indexer.DeleteRepoIssueIndexer(repo)
 | 
						issue_indexer.DeleteRepoIssueIndexer(repo)
 | 
				
			||||||
 | 
						models.DeleteRepoFromIndexer(repo)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *indexerNotifier) NotifyIssueChangeContent(doer *models.User, issue *models.Issue, oldContent string) {
 | 
					func (r *indexerNotifier) NotifyIssueChangeContent(doer *models.User, issue *models.Issue, oldContent string) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,3 +65,67 @@ func (m *webhookNotifier) NotifyIssueClearLabels(doer *models.User, issue *model
 | 
				
			|||||||
		go models.HookQueue.Add(issue.RepoID)
 | 
							go models.HookQueue.Add(issue.RepoID)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *webhookNotifier) NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) {
 | 
				
			||||||
 | 
						oldMode, _ := models.AccessLevel(doer, oldRepo)
 | 
				
			||||||
 | 
						mode, _ := models.AccessLevel(doer, repo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// forked webhook
 | 
				
			||||||
 | 
						if err := models.PrepareWebhooks(oldRepo, models.HookEventFork, &api.ForkPayload{
 | 
				
			||||||
 | 
							Forkee: oldRepo.APIFormat(oldMode),
 | 
				
			||||||
 | 
							Repo:   repo.APIFormat(mode),
 | 
				
			||||||
 | 
							Sender: doer.APIFormat(),
 | 
				
			||||||
 | 
						}); err != nil {
 | 
				
			||||||
 | 
							log.Error("PrepareWebhooks [repo_id: %d]: %v", oldRepo.ID, err)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							go models.HookQueue.Add(oldRepo.ID)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u := repo.MustOwner()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Add to hook queue for created repo after session commit.
 | 
				
			||||||
 | 
						if u.IsOrganization() {
 | 
				
			||||||
 | 
							if err := models.PrepareWebhooks(repo, models.HookEventRepository, &api.RepositoryPayload{
 | 
				
			||||||
 | 
								Action:       api.HookRepoCreated,
 | 
				
			||||||
 | 
								Repository:   repo.APIFormat(models.AccessModeOwner),
 | 
				
			||||||
 | 
								Organization: u.APIFormat(),
 | 
				
			||||||
 | 
								Sender:       doer.APIFormat(),
 | 
				
			||||||
 | 
							}); err != nil {
 | 
				
			||||||
 | 
								log.Error("PrepareWebhooks [repo_id: %d]: %v", repo.ID, err)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								go models.HookQueue.Add(repo.ID)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *webhookNotifier) NotifyCreateRepository(doer *models.User, u *models.User, repo *models.Repository) {
 | 
				
			||||||
 | 
						// Add to hook queue for created repo after session commit.
 | 
				
			||||||
 | 
						if u.IsOrganization() {
 | 
				
			||||||
 | 
							if err := models.PrepareWebhooks(repo, models.HookEventRepository, &api.RepositoryPayload{
 | 
				
			||||||
 | 
								Action:       api.HookRepoCreated,
 | 
				
			||||||
 | 
								Repository:   repo.APIFormat(models.AccessModeOwner),
 | 
				
			||||||
 | 
								Organization: u.APIFormat(),
 | 
				
			||||||
 | 
								Sender:       doer.APIFormat(),
 | 
				
			||||||
 | 
							}); err != nil {
 | 
				
			||||||
 | 
								log.Error("PrepareWebhooks [repo_id: %d]: %v", repo.ID, err)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								go models.HookQueue.Add(repo.ID)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *webhookNotifier) NotifyDeleteRepository(doer *models.User, repo *models.Repository) {
 | 
				
			||||||
 | 
						u := repo.MustOwner()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if u.IsOrganization() {
 | 
				
			||||||
 | 
							if err := models.PrepareWebhooks(repo, models.HookEventRepository, &api.RepositoryPayload{
 | 
				
			||||||
 | 
								Action:       api.HookRepoDeleted,
 | 
				
			||||||
 | 
								Repository:   repo.APIFormat(models.AccessModeOwner),
 | 
				
			||||||
 | 
								Organization: u.APIFormat(),
 | 
				
			||||||
 | 
								Sender:       doer.APIFormat(),
 | 
				
			||||||
 | 
							}); err != nil {
 | 
				
			||||||
 | 
								log.Error("PrepareWebhooks [repo_id: %d]: %v", repo.ID, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							go models.HookQueue.Add(repo.ID)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/routers"
 | 
						"code.gitea.io/gitea/routers"
 | 
				
			||||||
 | 
						repo_service "code.gitea.io/gitea/services/repository"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -38,7 +39,7 @@ func DeleteRepo(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := models.DeleteRepository(ctx.User, repo.MustOwner().ID, repo.ID); err != nil {
 | 
						if err := repo_service.DeleteRepository(ctx.User, repo); err != nil {
 | 
				
			||||||
		ctx.ServerError("DeleteRepository", err)
 | 
							ctx.ServerError("DeleteRepository", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/context"
 | 
						"code.gitea.io/gitea/modules/context"
 | 
				
			||||||
	api "code.gitea.io/gitea/modules/structs"
 | 
						api "code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
 | 
						repo_service "code.gitea.io/gitea/services/repository"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ListForks list a repository's forks
 | 
					// ListForks list a repository's forks
 | 
				
			||||||
@@ -97,10 +98,12 @@ func CreateFork(ctx *context.APIContext, form api.CreateForkOption) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		forker = org
 | 
							forker = org
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fork, err := models.ForkRepository(ctx.User, forker, repo, repo.Name, repo.Description)
 | 
					
 | 
				
			||||||
 | 
						fork, err := repo_service.ForkRepository(ctx.User, forker, repo, repo.Name, repo.Description)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.Error(500, "ForkRepository", err)
 | 
							ctx.Error(500, "ForkRepository", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.JSON(202, fork.APIFormat(models.AccessModeOwner))
 | 
						ctx.JSON(202, fork.APIFormat(models.AccessModeOwner))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/validation"
 | 
						"code.gitea.io/gitea/modules/validation"
 | 
				
			||||||
	"code.gitea.io/gitea/routers/api/v1/convert"
 | 
						"code.gitea.io/gitea/routers/api/v1/convert"
 | 
				
			||||||
	mirror_service "code.gitea.io/gitea/services/mirror"
 | 
						mirror_service "code.gitea.io/gitea/services/mirror"
 | 
				
			||||||
 | 
						repo_service "code.gitea.io/gitea/services/repository"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var searchOrderByMap = map[string]map[string]models.SearchOrderBy{
 | 
					var searchOrderByMap = map[string]map[string]models.SearchOrderBy{
 | 
				
			||||||
@@ -207,7 +208,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR
 | 
				
			|||||||
	if opt.AutoInit && opt.Readme == "" {
 | 
						if opt.AutoInit && opt.Readme == "" {
 | 
				
			||||||
		opt.Readme = "Default"
 | 
							opt.Readme = "Default"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	repo, err := models.CreateRepository(ctx.User, owner, models.CreateRepoOptions{
 | 
						repo, err := repo_service.CreateRepository(ctx.User, owner, models.CreateRepoOptions{
 | 
				
			||||||
		Name:        opt.Name,
 | 
							Name:        opt.Name,
 | 
				
			||||||
		Description: opt.Description,
 | 
							Description: opt.Description,
 | 
				
			||||||
		IssueLabels: opt.IssueLabels,
 | 
							IssueLabels: opt.IssueLabels,
 | 
				
			||||||
@@ -224,18 +225,11 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR
 | 
				
			|||||||
			models.IsErrNamePatternNotAllowed(err) {
 | 
								models.IsErrNamePatternNotAllowed(err) {
 | 
				
			||||||
			ctx.Error(422, "", err)
 | 
								ctx.Error(422, "", err)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if repo != nil {
 | 
					 | 
				
			||||||
				if err = models.DeleteRepository(ctx.User, ctx.User.ID, repo.ID); err != nil {
 | 
					 | 
				
			||||||
					log.Error("DeleteRepository: %v", err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			ctx.Error(500, "CreateRepository", err)
 | 
								ctx.Error(500, "CreateRepository", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	notification.NotifyCreateRepository(ctx.User, owner, repo)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx.JSON(201, repo.APIFormat(models.AccessModeOwner))
 | 
						ctx.JSON(201, repo.APIFormat(models.AccessModeOwner))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -433,7 +427,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	repo, err := migrations.MigrateRepository(ctx.User, ctxUser.Name, opts)
 | 
						repo, err := migrations.MigrateRepository(ctx.User, ctxUser.Name, opts)
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		notification.NotifyCreateRepository(ctx.User, ctxUser, repo)
 | 
							notification.NotifyMigrateRepository(ctx.User, ctxUser, repo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
 | 
							log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
 | 
				
			||||||
		ctx.JSON(201, repo.APIFormat(models.AccessModeAdmin))
 | 
							ctx.JSON(201, repo.APIFormat(models.AccessModeAdmin))
 | 
				
			||||||
@@ -876,18 +870,16 @@ func Delete(ctx *context.APIContext) {
 | 
				
			|||||||
	owner := ctx.Repo.Owner
 | 
						owner := ctx.Repo.Owner
 | 
				
			||||||
	repo := ctx.Repo.Repository
 | 
						repo := ctx.Repo.Repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if owner.IsOrganization() && !ctx.User.IsAdmin {
 | 
						canDelete, err := repo.CanUserDelete(ctx.User)
 | 
				
			||||||
		isOwner, err := owner.IsOwnedBy(ctx.User.ID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
			ctx.Error(500, "IsOwnedBy", err)
 | 
							ctx.Error(500, "CanUserDelete", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
		} else if !isOwner {
 | 
						} else if !canDelete {
 | 
				
			||||||
		ctx.Error(403, "", "Given user is not owner of organization.")
 | 
							ctx.Error(403, "", "Given user is not owner of organization.")
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := models.DeleteRepository(ctx.User, owner.ID, repo.ID); err != nil {
 | 
						if err := repo_service.DeleteRepository(ctx.User, repo); err != nil {
 | 
				
			||||||
		ctx.Error(500, "DeleteRepository", err)
 | 
							ctx.Error(500, "DeleteRepository", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/services/gitdiff"
 | 
						"code.gitea.io/gitea/services/gitdiff"
 | 
				
			||||||
	issue_service "code.gitea.io/gitea/services/issue"
 | 
						issue_service "code.gitea.io/gitea/services/issue"
 | 
				
			||||||
	pull_service "code.gitea.io/gitea/services/pull"
 | 
						pull_service "code.gitea.io/gitea/services/pull"
 | 
				
			||||||
 | 
						repo_service "code.gitea.io/gitea/services/repository"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/unknwon/com"
 | 
						"github.com/unknwon/com"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -209,7 +210,7 @@ func ForkPost(ctx *context.Context, form auth.CreateRepoForm) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo, err := models.ForkRepository(ctx.User, ctxUser, forkRepo, form.RepoName, form.Description)
 | 
						repo, err := repo_service.ForkRepository(ctx.User, ctxUser, forkRepo, form.RepoName, form.Description)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.Data["Err_RepoName"] = true
 | 
							ctx.Data["Err_RepoName"] = true
 | 
				
			||||||
		switch {
 | 
							switch {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,10 +17,10 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/git"
 | 
						"code.gitea.io/gitea/modules/git"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/migrations"
 | 
						"code.gitea.io/gitea/modules/migrations"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/notification"
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/task"
 | 
						"code.gitea.io/gitea/modules/task"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
 | 
						repo_service "code.gitea.io/gitea/services/repository"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/unknwon/com"
 | 
						"github.com/unknwon/com"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -170,7 +170,7 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo, err := models.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{
 | 
						repo, err := repo_service.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{
 | 
				
			||||||
		Name:        form.RepoName,
 | 
							Name:        form.RepoName,
 | 
				
			||||||
		Description: form.Description,
 | 
							Description: form.Description,
 | 
				
			||||||
		Gitignores:  form.Gitignores,
 | 
							Gitignores:  form.Gitignores,
 | 
				
			||||||
@@ -181,19 +181,11 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) {
 | 
				
			|||||||
		AutoInit:    form.AutoInit,
 | 
							AutoInit:    form.AutoInit,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		notification.NotifyCreateRepository(ctx.User, ctxUser, repo)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
 | 
							log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
 | 
				
			||||||
		ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name)
 | 
							ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if repo != nil {
 | 
					 | 
				
			||||||
		if errDelete := models.DeleteRepository(ctx.User, ctxUser.ID, repo.ID); errDelete != nil {
 | 
					 | 
				
			||||||
			log.Error("DeleteRepository: %v", errDelete)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	handleCreateError(ctx, ctxUser, err, "CreatePost", tplCreate, &form)
 | 
						handleCreateError(ctx, ctxUser, err, "CreatePost", tplCreate, &form)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/routers/utils"
 | 
						"code.gitea.io/gitea/routers/utils"
 | 
				
			||||||
	"code.gitea.io/gitea/services/mailer"
 | 
						"code.gitea.io/gitea/services/mailer"
 | 
				
			||||||
	mirror_service "code.gitea.io/gitea/services/mirror"
 | 
						mirror_service "code.gitea.io/gitea/services/mirror"
 | 
				
			||||||
 | 
						repo_service "code.gitea.io/gitea/services/repository"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/unknwon/com"
 | 
						"github.com/unknwon/com"
 | 
				
			||||||
	"mvdan.cc/xurls/v2"
 | 
						"mvdan.cc/xurls/v2"
 | 
				
			||||||
@@ -407,7 +408,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
 | 
				
			|||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := models.DeleteRepository(ctx.User, ctx.Repo.Owner.ID, repo.ID); err != nil {
 | 
							if err := repo_service.DeleteRepository(ctx.User, ctx.Repo.Repository); err != nil {
 | 
				
			||||||
			ctx.ServerError("DeleteRepository", err)
 | 
								ctx.ServerError("DeleteRepository", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										56
									
								
								services/repository/repository.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								services/repository/repository.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					// Copyright 2019 The Gitea Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/notification"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CreateRepository creates a repository for the user/organization.
 | 
				
			||||||
 | 
					func CreateRepository(doer, owner *models.User, opts models.CreateRepoOptions) (*models.Repository, error) {
 | 
				
			||||||
 | 
						repo, err := models.CreateRepository(doer, owner, opts)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if repo != nil {
 | 
				
			||||||
 | 
								if errDelete := models.DeleteRepository(doer, owner.ID, repo.ID); errDelete != nil {
 | 
				
			||||||
 | 
									log.Error("Rollback deleteRepository: %v", errDelete)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						notification.NotifyCreateRepository(doer, owner, repo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return repo, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ForkRepository forks a repository
 | 
				
			||||||
 | 
					func ForkRepository(doer, u *models.User, oldRepo *models.Repository, name, desc string) (*models.Repository, error) {
 | 
				
			||||||
 | 
						repo, err := models.ForkRepository(doer, u, oldRepo, name, desc)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if repo != nil {
 | 
				
			||||||
 | 
								if errDelete := models.DeleteRepository(doer, u.ID, repo.ID); errDelete != nil {
 | 
				
			||||||
 | 
									log.Error("Rollback deleteRepository: %v", errDelete)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						notification.NotifyForkRepository(doer, oldRepo, repo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return repo, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeleteRepository deletes a repository for a user or organization.
 | 
				
			||||||
 | 
					func DeleteRepository(doer *models.User, repo *models.Repository) error {
 | 
				
			||||||
 | 
						if err := models.DeleteRepository(doer, repo.OwnerID, repo.ID); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						notification.NotifyDeleteRepository(doer, repo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user