diff options
Diffstat (limited to 'integrations')
-rw-r--r-- | integrations/api_helper_for_declarative_test.go | 152 | ||||
-rw-r--r-- | integrations/deploy_key_push_test.go | 160 | ||||
-rw-r--r-- | integrations/git_helper_for_declarative_test.go | 127 | ||||
-rw-r--r-- | integrations/git_test.go | 206 | ||||
-rw-r--r-- | integrations/ssh_key_test.go | 217 |
5 files changed, 563 insertions, 299 deletions
diff --git a/integrations/api_helper_for_declarative_test.go b/integrations/api_helper_for_declarative_test.go new file mode 100644 index 0000000000..32a4ce8047 --- /dev/null +++ b/integrations/api_helper_for_declarative_test.go @@ -0,0 +1,152 @@ +// 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 integrations + +import ( + "fmt" + "io/ioutil" + "net/http" + "testing" + + api "code.gitea.io/sdk/gitea" + "github.com/stretchr/testify/assert" +) + +type APITestContext struct { + Reponame string + Session *TestSession + Token string + Username string + ExpectedCode int +} + +func NewAPITestContext(t *testing.T, username, reponame string) APITestContext { + session := loginUser(t, username) + token := getTokenForLoggedInUser(t, session) + return APITestContext{ + Session: session, + Token: token, + Username: username, + Reponame: reponame, + } +} + +func (ctx APITestContext) GitPath() string { + return fmt.Sprintf("%s/%s.git", ctx.Username, ctx.Reponame) +} + +func doAPICreateRepository(ctx APITestContext, empty bool, callback ...func(*testing.T, api.Repository)) func(*testing.T) { + return func(t *testing.T) { + createRepoOption := &api.CreateRepoOption{ + AutoInit: !empty, + Description: "Temporary repo", + Name: ctx.Reponame, + Private: true, + Gitignores: "", + License: "WTFPL", + Readme: "Default", + } + req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos?token="+ctx.Token, createRepoOption) + if ctx.ExpectedCode != 0 { + ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) + return + } + resp := ctx.Session.MakeRequest(t, req, http.StatusCreated) + + var repository api.Repository + DecodeJSON(t, resp, &repository) + if len(callback) > 0 { + callback[0](t, repository) + } + } +} + +func doAPIGetRepository(ctx APITestContext, callback ...func(*testing.T, api.Repository)) func(*testing.T) { + return func(t *testing.T) { + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", ctx.Username, ctx.Reponame, ctx.Token) + + req := NewRequest(t, "GET", urlStr) + if ctx.ExpectedCode != 0 { + ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) + return + } + resp := ctx.Session.MakeRequest(t, req, http.StatusOK) + + var repository api.Repository + DecodeJSON(t, resp, &repository) + if len(callback) > 0 { + callback[0](t, repository) + } + } +} + +func doAPIDeleteRepository(ctx APITestContext) func(*testing.T) { + return func(t *testing.T) { + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", ctx.Username, ctx.Reponame, ctx.Token) + + req := NewRequest(t, "DELETE", urlStr) + if ctx.ExpectedCode != 0 { + ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) + return + } + ctx.Session.MakeRequest(t, req, http.StatusNoContent) + } +} + +func doAPICreateUserKey(ctx APITestContext, keyname, keyFile string, callback ...func(*testing.T, api.PublicKey)) func(*testing.T) { + return func(t *testing.T) { + urlStr := fmt.Sprintf("/api/v1/user/keys?token=%s", ctx.Token) + + dataPubKey, err := ioutil.ReadFile(keyFile + ".pub") + assert.NoError(t, err) + req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateKeyOption{ + Title: keyname, + Key: string(dataPubKey), + }) + if ctx.ExpectedCode != 0 { + ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) + return + } + resp := ctx.Session.MakeRequest(t, req, http.StatusCreated) + var publicKey api.PublicKey + DecodeJSON(t, resp, &publicKey) + if len(callback) > 0 { + callback[0](t, publicKey) + } + } +} + +func doAPIDeleteUserKey(ctx APITestContext, keyID int64) func(*testing.T) { + return func(t *testing.T) { + urlStr := fmt.Sprintf("/api/v1/user/keys/%d?token=%s", keyID, ctx.Token) + + req := NewRequest(t, "DELETE", urlStr) + if ctx.ExpectedCode != 0 { + ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) + return + } + ctx.Session.MakeRequest(t, req, http.StatusNoContent) + } +} + +func doAPICreateDeployKey(ctx APITestContext, keyname, keyFile string, readOnly bool) func(*testing.T) { + return func(t *testing.T) { + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", ctx.Username, ctx.Reponame, ctx.Token) + + dataPubKey, err := ioutil.ReadFile(keyFile + ".pub") + assert.NoError(t, err) + req := NewRequestWithJSON(t, "POST", urlStr, api.CreateKeyOption{ + Title: keyname, + Key: string(dataPubKey), + ReadOnly: readOnly, + }) + + if ctx.ExpectedCode != 0 { + ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) + return + } + ctx.Session.MakeRequest(t, req, http.StatusCreated) + } +} diff --git a/integrations/deploy_key_push_test.go b/integrations/deploy_key_push_test.go deleted file mode 100644 index 8b3d665629..0000000000 --- a/integrations/deploy_key_push_test.go +++ /dev/null @@ -1,160 +0,0 @@ -// 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 integrations - -import ( - "fmt" - "io/ioutil" - "log" - "net/http" - "net/url" - "os" - "os/exec" - "path/filepath" - "testing" - "time" - - "code.gitea.io/git" - - "code.gitea.io/gitea/modules/setting" - api "code.gitea.io/sdk/gitea" - "github.com/stretchr/testify/assert" -) - -func createEmptyRepository(username, reponame string) func(*testing.T) { - return func(t *testing.T) { - session := loginUser(t, username) - token := getTokenForLoggedInUser(t, session) - req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos?token="+token, &api.CreateRepoOption{ - AutoInit: false, - Description: "Temporary empty repo", - Name: reponame, - Private: false, - }) - session.MakeRequest(t, req, http.StatusCreated) - } -} - -func createDeployKey(username, reponame, keyname, keyFile string, readOnly bool) func(*testing.T) { - return func(t *testing.T) { - session := loginUser(t, username) - token := getTokenForLoggedInUser(t, session) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", username, reponame, token) - - dataPubKey, err := ioutil.ReadFile(keyFile + ".pub") - assert.NoError(t, err) - req := NewRequestWithJSON(t, "POST", urlStr, api.CreateKeyOption{ - Title: keyname, - Key: string(dataPubKey), - ReadOnly: readOnly, - }) - session.MakeRequest(t, req, http.StatusCreated) - } -} - -func initTestRepository(dstPath string) func(*testing.T) { - return func(t *testing.T) { - // Init repository in dstPath - assert.NoError(t, git.InitRepository(dstPath, false)) - assert.NoError(t, ioutil.WriteFile(filepath.Join(dstPath, "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", dstPath)), 0644)) - assert.NoError(t, git.AddChanges(dstPath, true)) - signature := git.Signature{ - Email: "test@example.com", - Name: "test", - When: time.Now(), - } - assert.NoError(t, git.CommitChanges(dstPath, git.CommitChangesOptions{ - Committer: &signature, - Author: &signature, - Message: "Initial Commit", - })) - } -} - -func pushTestRepository(dstPath, username, reponame string, u url.URL, keyFile string) func(*testing.T) { - return func(t *testing.T) { - //Setup remote link - u.Scheme = "ssh" - u.User = url.User("git") - u.Host = fmt.Sprintf("%s:%d", setting.SSH.ListenHost, setting.SSH.ListenPort) - - //Setup ssh wrapper - os.Setenv("GIT_SSH_COMMAND", - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i "+ - filepath.Join(setting.AppWorkPath, keyFile)) - os.Setenv("GIT_SSH_VARIANT", "ssh") - - log.Printf("Adding remote: %s\n", u.String()) - _, err := git.NewCommand("remote", "add", "origin", u.String()).RunInDir(dstPath) - assert.NoError(t, err) - - log.Printf("Pushing to: %s\n", u.String()) - _, err = git.NewCommand("push", "-u", "origin", "master").RunInDir(dstPath) - assert.NoError(t, err) - } -} - -func checkRepositoryEmptyStatus(username, reponame string, isEmpty bool) func(*testing.T) { - return func(t *testing.T) { - session := loginUser(t, username) - token := getTokenForLoggedInUser(t, session) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", username, reponame, token) - - req := NewRequest(t, "GET", urlStr) - resp := session.MakeRequest(t, req, http.StatusOK) - - var repository api.Repository - DecodeJSON(t, resp, &repository) - - assert.Equal(t, isEmpty, repository.Empty) - } -} - -func deleteRepository(username, reponame string) func(*testing.T) { - return func(t *testing.T) { - session := loginUser(t, username) - token := getTokenForLoggedInUser(t, session) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", username, reponame, token) - - req := NewRequest(t, "DELETE", urlStr) - session.MakeRequest(t, req, http.StatusNoContent) - } -} - -func TestPushDeployKeyOnEmptyRepo(t *testing.T) { - onGiteaRun(t, testPushDeployKeyOnEmptyRepo) -} - -func testPushDeployKeyOnEmptyRepo(t *testing.T, u *url.URL) { - reponame := "deploy-key-empty-repo-1" - username := "user2" - u.Path = fmt.Sprintf("%s/%s.git", username, reponame) - keyname := fmt.Sprintf("%s-push", reponame) - - t.Run("CreateEmptyRepository", createEmptyRepository(username, reponame)) - t.Run("CheckIsEmpty", checkRepositoryEmptyStatus(username, reponame, true)) - - //Setup the push deploy key file - keyFile := filepath.Join(setting.AppDataPath, keyname) - err := exec.Command("ssh-keygen", "-f", keyFile, "-t", "rsa", "-N", "").Run() - assert.NoError(t, err) - defer os.RemoveAll(keyFile) - defer os.RemoveAll(keyFile + ".pub") - - t.Run("CreatePushDeployKey", createDeployKey(username, reponame, keyname, keyFile, false)) - - // Setup the testing repository - dstPath, err := ioutil.TempDir("", "repo-tmp-deploy-key-empty-repo-1") - assert.NoError(t, err) - defer os.RemoveAll(dstPath) - - t.Run("InitTestRepository", initTestRepository(dstPath)) - t.Run("SSHPushTestRepository", pushTestRepository(dstPath, username, reponame, *u, keyFile)) - - log.Println("Done Push") - t.Run("CheckIsNotEmpty", checkRepositoryEmptyStatus(username, reponame, false)) - - t.Run("DeleteRepository", deleteRepository(username, reponame)) -} diff --git a/integrations/git_helper_for_declarative_test.go b/integrations/git_helper_for_declarative_test.go new file mode 100644 index 0000000000..572abe95a2 --- /dev/null +++ b/integrations/git_helper_for_declarative_test.go @@ -0,0 +1,127 @@ +// 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 integrations + +import ( + "context" + "fmt" + "io/ioutil" + "net" + "net/http" + "net/url" + "os" + "os/exec" + "path/filepath" + "testing" + "time" + + "code.gitea.io/git" + "code.gitea.io/gitea/modules/setting" + "github.com/Unknwon/com" + "github.com/stretchr/testify/assert" +) + +func withKeyFile(t *testing.T, keyname string, callback func(string)) { + keyFile := filepath.Join(setting.AppDataPath, keyname) + err := exec.Command("ssh-keygen", "-f", keyFile, "-t", "rsa", "-N", "").Run() + assert.NoError(t, err) + + //Setup ssh wrapper + os.Setenv("GIT_SSH_COMMAND", + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i "+ + filepath.Join(setting.AppWorkPath, keyFile)) + os.Setenv("GIT_SSH_VARIANT", "ssh") + + callback(keyFile) + + defer os.RemoveAll(keyFile) + defer os.RemoveAll(keyFile + ".pub") +} + +func createSSHUrl(gitPath string, u *url.URL) *url.URL { + u2 := *u + u2.Scheme = "ssh" + u2.User = url.User("git") + u2.Host = fmt.Sprintf("%s:%d", setting.SSH.ListenHost, setting.SSH.ListenPort) + u2.Path = gitPath + return &u2 +} + +func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) { + prepareTestEnv(t) + s := http.Server{ + Handler: mac, + } + + u, err := url.Parse(setting.AppURL) + assert.NoError(t, err) + listener, err := net.Listen("tcp", u.Host) + assert.NoError(t, err) + + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + s.Shutdown(ctx) + cancel() + }() + + go s.Serve(listener) + //Started by config go ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) + + callback(t, u) +} + +func doGitClone(dstLocalPath string, u *url.URL) func(*testing.T) { + return func(t *testing.T) { + assert.NoError(t, git.Clone(u.String(), dstLocalPath, git.CloneRepoOptions{})) + assert.True(t, com.IsExist(filepath.Join(dstLocalPath, "README.md"))) + } +} + +func doGitCloneFail(dstLocalPath string, u *url.URL) func(*testing.T) { + return func(t *testing.T) { + assert.Error(t, git.Clone(u.String(), dstLocalPath, git.CloneRepoOptions{})) + assert.False(t, com.IsExist(filepath.Join(dstLocalPath, "README.md"))) + } +} + +func doGitInitTestRepository(dstPath string) func(*testing.T) { + return func(t *testing.T) { + // Init repository in dstPath + assert.NoError(t, git.InitRepository(dstPath, false)) + assert.NoError(t, ioutil.WriteFile(filepath.Join(dstPath, "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", dstPath)), 0644)) + assert.NoError(t, git.AddChanges(dstPath, true)) + signature := git.Signature{ + Email: "test@example.com", + Name: "test", + When: time.Now(), + } + assert.NoError(t, git.CommitChanges(dstPath, git.CommitChangesOptions{ + Committer: &signature, + Author: &signature, + Message: "Initial Commit", + })) + } +} + +func doGitAddRemote(dstPath, remoteName string, u *url.URL) func(*testing.T) { + return func(t *testing.T) { + _, err := git.NewCommand("remote", "add", remoteName, u.String()).RunInDir(dstPath) + assert.NoError(t, err) + } +} + +func doGitPushTestRepository(dstPath, remoteName, branch string) func(*testing.T) { + return func(t *testing.T) { + _, err := git.NewCommand("push", "-u", remoteName, branch).RunInDir(dstPath) + assert.NoError(t, err) + } +} + +func doGitPushTestRepositoryFail(dstPath, remoteName, branch string) func(*testing.T) { + return func(t *testing.T) { + _, err := git.NewCommand("push", "-u", remoteName, branch).RunInDir(dstPath) + assert.Error(t, err) + } +} diff --git a/integrations/git_test.go b/integrations/git_test.go index 96d39e0519..a372525864 100644 --- a/integrations/git_test.go +++ b/integrations/git_test.go @@ -5,25 +5,17 @@ package integrations import ( - "context" "crypto/rand" "fmt" "io/ioutil" - "net" - "net/http" "net/url" "os" - "os/exec" "path/filepath" "testing" "time" "code.gitea.io/git" - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/setting" - api "code.gitea.io/sdk/gitea" - "github.com/Unknwon/com" "github.com/stretchr/testify/assert" ) @@ -32,160 +24,86 @@ const ( bigSize = 128 * 1024 * 1024 //128Mo ) -func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) { - prepareTestEnv(t) - s := http.Server{ - Handler: mac, - } +func TestGit(t *testing.T) { + onGiteaRun(t, testGit) +} - u, err := url.Parse(setting.AppURL) - assert.NoError(t, err) - listener, err := net.Listen("tcp", u.Host) - assert.NoError(t, err) +func testGit(t *testing.T, u *url.URL) { + username := "user2" + baseAPITestContext := NewAPITestContext(t, username, "repo1") - defer func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - s.Shutdown(ctx) - cancel() - }() + u.Path = baseAPITestContext.GitPath() - go s.Serve(listener) - //Started by config go ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs) + t.Run("HTTP", func(t *testing.T) { + httpContext := baseAPITestContext + httpContext.Reponame = "repo-tmp-17" - callback(t, u) -} + dstPath, err := ioutil.TempDir("", httpContext.Reponame) + assert.NoError(t, err) + defer os.RemoveAll(dstPath) + t.Run("Standard", func(t *testing.T) { + ensureAnonymousClone(t, u) -func TestGit(t *testing.T) { - onGiteaRun(t, func(t *testing.T, u *url.URL) { - u.Path = "user2/repo1.git" + t.Run("CreateRepo", doAPICreateRepository(httpContext, false)) - t.Run("HTTP", func(t *testing.T) { - dstPath, err := ioutil.TempDir("", "repo-tmp-17") - assert.NoError(t, err) - defer os.RemoveAll(dstPath) - t.Run("Standard", func(t *testing.T) { - t.Run("CloneNoLogin", func(t *testing.T) { - dstLocalPath, err := ioutil.TempDir("", "repo1") - assert.NoError(t, err) - defer os.RemoveAll(dstLocalPath) - err = git.Clone(u.String(), dstLocalPath, git.CloneRepoOptions{}) - assert.NoError(t, err) - assert.True(t, com.IsExist(filepath.Join(dstLocalPath, "README.md"))) - }) + u.Path = httpContext.GitPath() + u.User = url.UserPassword(username, userPassword) - t.Run("CreateRepo", func(t *testing.T) { - session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session) - req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos?token="+token, &api.CreateRepoOption{ - AutoInit: true, - Description: "Temporary repo", - Name: "repo-tmp-17", - Private: false, - Gitignores: "", - License: "WTFPL", - Readme: "Default", - }) - session.MakeRequest(t, req, http.StatusCreated) - }) + t.Run("Clone", doGitClone(dstPath, u)) - u.Path = "user2/repo-tmp-17.git" - u.User = url.UserPassword("user2", userPassword) - t.Run("Clone", func(t *testing.T) { - err = git.Clone(u.String(), dstPath, git.CloneRepoOptions{}) - assert.NoError(t, err) - assert.True(t, com.IsExist(filepath.Join(dstPath, "README.md"))) + t.Run("PushCommit", func(t *testing.T) { + t.Run("Little", func(t *testing.T) { + commitAndPush(t, littleSize, dstPath) }) - - t.Run("PushCommit", func(t *testing.T) { - t.Run("Little", func(t *testing.T) { - commitAndPush(t, littleSize, dstPath) - }) - t.Run("Big", func(t *testing.T) { - commitAndPush(t, bigSize, dstPath) - }) + t.Run("Big", func(t *testing.T) { + commitAndPush(t, bigSize, dstPath) }) }) - t.Run("LFS", func(t *testing.T) { - t.Run("PushCommit", func(t *testing.T) { - //Setup git LFS - _, err = git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath) - assert.NoError(t, err) - _, err = git.NewCommand("lfs").AddArguments("track", "data-file-*").RunInDir(dstPath) - assert.NoError(t, err) - err = git.AddChanges(dstPath, false, ".gitattributes") - assert.NoError(t, err) - - t.Run("Little", func(t *testing.T) { - commitAndPush(t, littleSize, dstPath) - }) - t.Run("Big", func(t *testing.T) { - commitAndPush(t, bigSize, dstPath) - }) + }) + t.Run("LFS", func(t *testing.T) { + t.Run("PushCommit", func(t *testing.T) { + //Setup git LFS + _, err = git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath) + assert.NoError(t, err) + _, err = git.NewCommand("lfs").AddArguments("track", "data-file-*").RunInDir(dstPath) + assert.NoError(t, err) + err = git.AddChanges(dstPath, false, ".gitattributes") + assert.NoError(t, err) + + t.Run("Little", func(t *testing.T) { + commitAndPush(t, littleSize, dstPath) }) - t.Run("Locks", func(t *testing.T) { - lockTest(t, u.String(), dstPath) + t.Run("Big", func(t *testing.T) { + commitAndPush(t, bigSize, dstPath) }) }) - }) - t.Run("SSH", func(t *testing.T) { - //Setup remote link - u.Scheme = "ssh" - u.User = url.User("git") - u.Host = fmt.Sprintf("%s:%d", setting.SSH.ListenHost, setting.SSH.ListenPort) - u.Path = "user2/repo-tmp-18.git" - - //Setup key - keyFile := filepath.Join(setting.AppDataPath, "my-testing-key") - err := exec.Command("ssh-keygen", "-f", keyFile, "-t", "rsa", "-N", "").Run() - assert.NoError(t, err) - defer os.RemoveAll(keyFile) - defer os.RemoveAll(keyFile + ".pub") - - session := loginUser(t, "user1") - keyOwner := models.AssertExistsAndLoadBean(t, &models.User{Name: "user2"}).(*models.User) - token := getTokenForLoggedInUser(t, session) - urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys?token=%s", keyOwner.Name, token) - - dataPubKey, err := ioutil.ReadFile(keyFile + ".pub") - assert.NoError(t, err) - req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ - "key": string(dataPubKey), - "title": "test-key", + t.Run("Locks", func(t *testing.T) { + lockTest(t, u.String(), dstPath) }) - session.MakeRequest(t, req, http.StatusCreated) + }) + }) + t.Run("SSH", func(t *testing.T) { + sshContext := baseAPITestContext + sshContext.Reponame = "repo-tmp-18" + keyname := "my-testing-key" + //Setup key the user ssh key + withKeyFile(t, keyname, func(keyFile string) { + t.Run("CreateUserKey", doAPICreateUserKey(sshContext, "test-key", keyFile)) - //Setup ssh wrapper - os.Setenv("GIT_SSH_COMMAND", - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i "+ - filepath.Join(setting.AppWorkPath, keyFile)) - os.Setenv("GIT_SSH_VARIANT", "ssh") + //Setup remote link + sshURL := createSSHUrl(sshContext.GitPath(), u) //Setup clone folder - dstPath, err := ioutil.TempDir("", "repo-tmp-18") + dstPath, err := ioutil.TempDir("", sshContext.Reponame) assert.NoError(t, err) defer os.RemoveAll(dstPath) t.Run("Standard", func(t *testing.T) { - t.Run("CreateRepo", func(t *testing.T) { - session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session) - req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos?token="+token, &api.CreateRepoOption{ - AutoInit: true, - Description: "Temporary repo", - Name: "repo-tmp-18", - Private: false, - Gitignores: "", - License: "WTFPL", - Readme: "Default", - }) - session.MakeRequest(t, req, http.StatusCreated) - }) + t.Run("CreateRepo", doAPICreateRepository(sshContext, false)) + //TODO get url from api - t.Run("Clone", func(t *testing.T) { - _, err = git.NewCommand("clone").AddArguments(u.String(), dstPath).Run() - assert.NoError(t, err) - assert.True(t, com.IsExist(filepath.Join(dstPath, "README.md"))) - }) + t.Run("Clone", doGitClone(dstPath, sshURL)) + //time.Sleep(5 * time.Minute) t.Run("PushCommit", func(t *testing.T) { t.Run("Little", func(t *testing.T) { @@ -217,10 +135,20 @@ func TestGit(t *testing.T) { lockTest(t, u.String(), dstPath) }) }) + }) + }) } +func ensureAnonymousClone(t *testing.T, u *url.URL) { + dstLocalPath, err := ioutil.TempDir("", "repo1") + assert.NoError(t, err) + defer os.RemoveAll(dstLocalPath) + t.Run("CloneAnonymous", doGitClone(dstLocalPath, u)) + +} + func lockTest(t *testing.T, remote, repoPath string) { _, err := git.NewCommand("remote").AddArguments("set-url", "origin", remote).RunInDir(repoPath) //TODO add test ssh git-lfs-creds assert.NoError(t, err) diff --git a/integrations/ssh_key_test.go b/integrations/ssh_key_test.go new file mode 100644 index 0000000000..9ad43ae226 --- /dev/null +++ b/integrations/ssh_key_test.go @@ -0,0 +1,217 @@ +// 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 integrations + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" + "os" + "path/filepath" + "testing" + "time" + + "code.gitea.io/git" + api "code.gitea.io/sdk/gitea" + "github.com/stretchr/testify/assert" +) + +func doCheckRepositoryEmptyStatus(ctx APITestContext, isEmpty bool) func(*testing.T) { + return doAPIGetRepository(ctx, func(t *testing.T, repository api.Repository) { + assert.Equal(t, isEmpty, repository.Empty) + }) +} + +func doAddChangesToCheckout(dstPath, filename string) func(*testing.T) { + return func(t *testing.T) { + assert.NoError(t, ioutil.WriteFile(filepath.Join(dstPath, filename), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s at time: %v", dstPath, time.Now())), 0644)) + assert.NoError(t, git.AddChanges(dstPath, true)) + signature := git.Signature{ + Email: "test@example.com", + Name: "test", + When: time.Now(), + } + assert.NoError(t, git.CommitChanges(dstPath, git.CommitChangesOptions{ + Committer: &signature, + Author: &signature, + Message: "Initial Commit", + })) + } +} + +func TestPushDeployKeyOnEmptyRepo(t *testing.T) { + onGiteaRun(t, testPushDeployKeyOnEmptyRepo) +} + +func testPushDeployKeyOnEmptyRepo(t *testing.T, u *url.URL) { + // OK login + ctx := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1") + keyname := fmt.Sprintf("%s-push", ctx.Reponame) + u.Path = ctx.GitPath() + + t.Run("CreateEmptyRepository", doAPICreateRepository(ctx, true)) + + t.Run("CheckIsEmpty", doCheckRepositoryEmptyStatus(ctx, true)) + + withKeyFile(t, keyname, func(keyFile string) { + t.Run("CreatePushDeployKey", doAPICreateDeployKey(ctx, keyname, keyFile, false)) + + // Setup the testing repository + dstPath, err := ioutil.TempDir("", "repo-tmp-deploy-key-empty-repo-1") + assert.NoError(t, err) + defer os.RemoveAll(dstPath) + + t.Run("InitTestRepository", doGitInitTestRepository(dstPath)) + + //Setup remote link + sshURL := createSSHUrl(ctx.GitPath(), u) + + t.Run("AddRemote", doGitAddRemote(dstPath, "origin", sshURL)) + + t.Run("SSHPushTestRepository", doGitPushTestRepository(dstPath, "origin", "master")) + + t.Run("CheckIsNotEmpty", doCheckRepositoryEmptyStatus(ctx, false)) + + t.Run("DeleteRepository", doAPIDeleteRepository(ctx)) + }) +} + +func TestKeyOnlyOneType(t *testing.T) { + onGiteaRun(t, testKeyOnlyOneType) +} + +func testKeyOnlyOneType(t *testing.T, u *url.URL) { + // Once a key is a user key we cannot use it as a deploy key + // If we delete it from the user we should be able to use it as a deploy key + reponame := "ssh-key-test-repo" + username := "user2" + u.Path = fmt.Sprintf("%s/%s.git", username, reponame) + keyname := fmt.Sprintf("%s-push", reponame) + + // OK login + ctx := NewAPITestContext(t, username, reponame) + + otherCtx := ctx + otherCtx.Reponame = "ssh-key-test-repo-2" + + failCtx := ctx + failCtx.ExpectedCode = http.StatusUnprocessableEntity + + t.Run("CreateRepository", doAPICreateRepository(ctx, false)) + t.Run("CreateOtherRepository", doAPICreateRepository(otherCtx, false)) + + withKeyFile(t, keyname, func(keyFile string) { + var userKeyPublicKeyID int64 + t.Run("KeyCanOnlyBeUser", func(t *testing.T) { + dstPath, err := ioutil.TempDir("", ctx.Reponame) + assert.NoError(t, err) + defer os.RemoveAll(dstPath) + + sshURL := createSSHUrl(ctx.GitPath(), u) + + t.Run("FailToClone", doGitCloneFail(dstPath, sshURL)) + + t.Run("CreateUserKey", doAPICreateUserKey(ctx, keyname, keyFile, func(t *testing.T, publicKey api.PublicKey) { + userKeyPublicKeyID = publicKey.ID + })) + + t.Run("FailToAddReadOnlyDeployKey", doAPICreateDeployKey(failCtx, keyname, keyFile, true)) + + t.Run("FailToAddDeployKey", doAPICreateDeployKey(failCtx, keyname, keyFile, false)) + + t.Run("Clone", doGitClone(dstPath, sshURL)) + + t.Run("AddChanges", doAddChangesToCheckout(dstPath, "CHANGES1.md")) + + t.Run("Push", doGitPushTestRepository(dstPath, "origin", "master")) + + t.Run("DeleteUserKey", doAPIDeleteUserKey(ctx, userKeyPublicKeyID)) + }) + + t.Run("KeyCanBeAnyDeployButNotUserAswell", func(t *testing.T) { + dstPath, err := ioutil.TempDir("", ctx.Reponame) + assert.NoError(t, err) + defer os.RemoveAll(dstPath) + + sshURL := createSSHUrl(ctx.GitPath(), u) + + t.Run("FailToClone", doGitCloneFail(dstPath, sshURL)) + + // Should now be able to add... + t.Run("AddReadOnlyDeployKey", doAPICreateDeployKey(ctx, keyname, keyFile, true)) + + t.Run("Clone", doGitClone(dstPath, sshURL)) + + t.Run("AddChanges", doAddChangesToCheckout(dstPath, "CHANGES2.md")) + + t.Run("FailToPush", doGitPushTestRepositoryFail(dstPath, "origin", "master")) + + otherSSHURL := createSSHUrl(otherCtx.GitPath(), u) + dstOtherPath, err := ioutil.TempDir("", otherCtx.Reponame) + assert.NoError(t, err) + defer os.RemoveAll(dstOtherPath) + + t.Run("AddWriterDeployKeyToOther", doAPICreateDeployKey(otherCtx, keyname, keyFile, false)) + + t.Run("CloneOther", doGitClone(dstOtherPath, otherSSHURL)) + + t.Run("AddChangesToOther", doAddChangesToCheckout(dstOtherPath, "CHANGES3.md")) + + t.Run("PushToOther", doGitPushTestRepository(dstOtherPath, "origin", "master")) + + t.Run("FailToCreateUserKey", doAPICreateUserKey(failCtx, keyname, keyFile)) + }) + + t.Run("DeleteRepositoryShouldReleaseKey", func(t *testing.T) { + otherSSHURL := createSSHUrl(otherCtx.GitPath(), u) + dstOtherPath, err := ioutil.TempDir("", otherCtx.Reponame) + assert.NoError(t, err) + defer os.RemoveAll(dstOtherPath) + + t.Run("DeleteRepository", doAPIDeleteRepository(ctx)) + + t.Run("FailToCreateUserKeyAsStillDeploy", doAPICreateUserKey(failCtx, keyname, keyFile)) + + t.Run("MakeSureCloneOtherStillWorks", doGitClone(dstOtherPath, otherSSHURL)) + + t.Run("AddChangesToOther", doAddChangesToCheckout(dstOtherPath, "CHANGES3.md")) + + t.Run("PushToOther", doGitPushTestRepository(dstOtherPath, "origin", "master")) + + t.Run("DeleteOtherRepository", doAPIDeleteRepository(otherCtx)) + + t.Run("RecreateRepository", doAPICreateRepository(ctx, false)) + + t.Run("CreateUserKey", doAPICreateUserKey(ctx, keyname, keyFile, func(t *testing.T, publicKey api.PublicKey) { + userKeyPublicKeyID = publicKey.ID + })) + + dstPath, err := ioutil.TempDir("", ctx.Reponame) + assert.NoError(t, err) + defer os.RemoveAll(dstPath) + + sshURL := createSSHUrl(ctx.GitPath(), u) + + t.Run("Clone", doGitClone(dstPath, sshURL)) + + t.Run("AddChanges", doAddChangesToCheckout(dstPath, "CHANGES1.md")) + + t.Run("Push", doGitPushTestRepository(dstPath, "origin", "master")) + }) + + t.Run("DeleteUserKeyShouldRemoveAbilityToClone", func(t *testing.T) { + dstPath, err := ioutil.TempDir("", ctx.Reponame) + assert.NoError(t, err) + defer os.RemoveAll(dstPath) + + sshURL := createSSHUrl(ctx.GitPath(), u) + + t.Run("DeleteUserKey", doAPIDeleteUserKey(ctx, userKeyPublicKeyID)) + + t.Run("FailToClone", doGitCloneFail(dstPath, sshURL)) + }) + }) +} |