From 583968f274b85d1c9184c614cbdae763899f7827 Mon Sep 17 00:00:00 2001
From: Bogdan Petrea <bogdan@presslabs.com>
Date: Fri, 15 Mar 2019 14:19:09 +0000
Subject: Return 409 when creating repo if it already exists. (#6330)

---
 integrations/api_repo_test.go | 71 +++++++++++++++++++++++++++++++++++++++++++
 routers/api/v1/repo/repo.go   |  5 +--
 2 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go
index 237c4eea9a..a919a8370b 100644
--- a/integrations/api_repo_test.go
+++ b/integrations/api_repo_test.go
@@ -6,7 +6,10 @@ package integrations
 
 import (
 	"fmt"
+	"io/ioutil"
 	"net/http"
+	"net/url"
+	"os"
 	"testing"
 
 	"code.gitea.io/gitea/models"
@@ -291,6 +294,44 @@ func TestAPIRepoMigrate(t *testing.T) {
 	}
 }
 
+func TestAPIRepoMigrateConflict(t *testing.T) {
+	onGiteaRun(t, testAPIRepoMigrateConflict)
+}
+
+func testAPIRepoMigrateConflict(t *testing.T, u *url.URL) {
+	username := "user2"
+	baseAPITestContext := NewAPITestContext(t, username, "repo1")
+
+	u.Path = baseAPITestContext.GitPath()
+
+	t.Run("Existing", func(t *testing.T) {
+		httpContext := baseAPITestContext
+
+		httpContext.Reponame = "repo-tmp-17"
+		dstPath, err := ioutil.TempDir("", httpContext.Reponame)
+		assert.NoError(t, err)
+		defer os.RemoveAll(dstPath)
+		t.Run("CreateRepo", doAPICreateRepository(httpContext, false))
+
+		user, err := models.GetUserByName(httpContext.Username)
+		assert.NoError(t, err)
+		userID := user.ID
+
+		cloneURL := "https://github.com/go-gitea/git.git"
+
+		req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+httpContext.Token,
+			&api.MigrateRepoOption{
+				CloneAddr: cloneURL,
+				UID:       int(userID),
+				RepoName:  httpContext.Reponame,
+			})
+		resp := httpContext.Session.MakeRequest(t, req, http.StatusConflict)
+		respJSON := map[string]string{}
+		DecodeJSON(t, resp, &respJSON)
+		assert.Equal(t, respJSON["message"], "The repository with the same name already exists.")
+	})
+}
+
 func TestAPIOrgRepoCreate(t *testing.T) {
 	testCases := []struct {
 		ctxUserID         int64
@@ -313,3 +354,33 @@ func TestAPIOrgRepoCreate(t *testing.T) {
 		session.MakeRequest(t, req, testCase.expectedStatus)
 	}
 }
+
+func TestAPIRepoCreateConflict(t *testing.T) {
+	onGiteaRun(t, testAPIRepoCreateConflict)
+}
+
+func testAPIRepoCreateConflict(t *testing.T, u *url.URL) {
+	username := "user2"
+	baseAPITestContext := NewAPITestContext(t, username, "repo1")
+
+	u.Path = baseAPITestContext.GitPath()
+
+	t.Run("Existing", func(t *testing.T) {
+		httpContext := baseAPITestContext
+
+		httpContext.Reponame = "repo-tmp-17"
+		dstPath, err := ioutil.TempDir("", httpContext.Reponame)
+		assert.NoError(t, err)
+		defer os.RemoveAll(dstPath)
+		t.Run("CreateRepo", doAPICreateRepository(httpContext, false))
+
+		req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos?token="+httpContext.Token,
+			&api.CreateRepoOption{
+				Name: httpContext.Reponame,
+			})
+		resp := httpContext.Session.MakeRequest(t, req, http.StatusConflict)
+		respJSON := map[string]string{}
+		DecodeJSON(t, resp, &respJSON)
+		assert.Equal(t, respJSON["message"], "The repository with the same name already exists.")
+	})
+}
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index c6a7803acb..e5922e77dc 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -226,8 +226,9 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR
 		AutoInit:    opt.AutoInit,
 	})
 	if err != nil {
-		if models.IsErrRepoAlreadyExist(err) ||
-			models.IsErrNameReserved(err) ||
+		if models.IsErrRepoAlreadyExist(err) {
+			ctx.Error(409, "", "The repository with the same name already exists.")
+		} else if models.IsErrNameReserved(err) ||
 			models.IsErrNamePatternNotAllowed(err) {
 			ctx.Error(422, "", err)
 		} else {
-- 
cgit v1.2.3