You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

deploy_key_push_test.go 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package integrations
  5. import (
  6. "fmt"
  7. "io/ioutil"
  8. "log"
  9. "net/http"
  10. "net/url"
  11. "os"
  12. "os/exec"
  13. "path/filepath"
  14. "testing"
  15. "time"
  16. "code.gitea.io/git"
  17. "code.gitea.io/gitea/modules/setting"
  18. api "code.gitea.io/sdk/gitea"
  19. "github.com/stretchr/testify/assert"
  20. )
  21. func createEmptyRepository(username, reponame string) func(*testing.T) {
  22. return func(t *testing.T) {
  23. session := loginUser(t, username)
  24. token := getTokenForLoggedInUser(t, session)
  25. req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos?token="+token, &api.CreateRepoOption{
  26. AutoInit: false,
  27. Description: "Temporary empty repo",
  28. Name: reponame,
  29. Private: false,
  30. })
  31. session.MakeRequest(t, req, http.StatusCreated)
  32. }
  33. }
  34. func createDeployKey(username, reponame, keyname, keyFile string, readOnly bool) func(*testing.T) {
  35. return func(t *testing.T) {
  36. session := loginUser(t, username)
  37. token := getTokenForLoggedInUser(t, session)
  38. urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", username, reponame, token)
  39. dataPubKey, err := ioutil.ReadFile(keyFile + ".pub")
  40. assert.NoError(t, err)
  41. req := NewRequestWithJSON(t, "POST", urlStr, api.CreateKeyOption{
  42. Title: keyname,
  43. Key: string(dataPubKey),
  44. ReadOnly: readOnly,
  45. })
  46. session.MakeRequest(t, req, http.StatusCreated)
  47. }
  48. }
  49. func initTestRepository(dstPath string) func(*testing.T) {
  50. return func(t *testing.T) {
  51. // Init repository in dstPath
  52. assert.NoError(t, git.InitRepository(dstPath, false))
  53. assert.NoError(t, ioutil.WriteFile(filepath.Join(dstPath, "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", dstPath)), 0644))
  54. assert.NoError(t, git.AddChanges(dstPath, true))
  55. signature := git.Signature{
  56. Email: "test@example.com",
  57. Name: "test",
  58. When: time.Now(),
  59. }
  60. assert.NoError(t, git.CommitChanges(dstPath, git.CommitChangesOptions{
  61. Committer: &signature,
  62. Author: &signature,
  63. Message: "Initial Commit",
  64. }))
  65. }
  66. }
  67. func pushTestRepository(dstPath, username, reponame string, u url.URL, keyFile string) func(*testing.T) {
  68. return func(t *testing.T) {
  69. //Setup remote link
  70. u.Scheme = "ssh"
  71. u.User = url.User("git")
  72. u.Host = fmt.Sprintf("%s:%d", setting.SSH.ListenHost, setting.SSH.ListenPort)
  73. //Setup ssh wrapper
  74. os.Setenv("GIT_SSH_COMMAND",
  75. "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i "+
  76. filepath.Join(setting.AppWorkPath, keyFile))
  77. os.Setenv("GIT_SSH_VARIANT", "ssh")
  78. log.Printf("Adding remote: %s\n", u.String())
  79. _, err := git.NewCommand("remote", "add", "origin", u.String()).RunInDir(dstPath)
  80. assert.NoError(t, err)
  81. log.Printf("Pushing to: %s\n", u.String())
  82. _, err = git.NewCommand("push", "-u", "origin", "master").RunInDir(dstPath)
  83. assert.NoError(t, err)
  84. }
  85. }
  86. func checkRepositoryEmptyStatus(username, reponame string, isEmpty bool) func(*testing.T) {
  87. return func(t *testing.T) {
  88. session := loginUser(t, username)
  89. token := getTokenForLoggedInUser(t, session)
  90. urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", username, reponame, token)
  91. req := NewRequest(t, "GET", urlStr)
  92. resp := session.MakeRequest(t, req, http.StatusOK)
  93. var repository api.Repository
  94. DecodeJSON(t, resp, &repository)
  95. assert.Equal(t, isEmpty, repository.Empty)
  96. }
  97. }
  98. func deleteRepository(username, reponame string) func(*testing.T) {
  99. return func(t *testing.T) {
  100. session := loginUser(t, username)
  101. token := getTokenForLoggedInUser(t, session)
  102. urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", username, reponame, token)
  103. req := NewRequest(t, "DELETE", urlStr)
  104. session.MakeRequest(t, req, http.StatusNoContent)
  105. }
  106. }
  107. func TestPushDeployKeyOnEmptyRepo(t *testing.T) {
  108. onGiteaRun(t, testPushDeployKeyOnEmptyRepo)
  109. }
  110. func testPushDeployKeyOnEmptyRepo(t *testing.T, u *url.URL) {
  111. reponame := "deploy-key-empty-repo-1"
  112. username := "user2"
  113. u.Path = fmt.Sprintf("%s/%s.git", username, reponame)
  114. keyname := fmt.Sprintf("%s-push", reponame)
  115. t.Run("CreateEmptyRepository", createEmptyRepository(username, reponame))
  116. t.Run("CheckIsEmpty", checkRepositoryEmptyStatus(username, reponame, true))
  117. //Setup the push deploy key file
  118. keyFile := filepath.Join(setting.AppDataPath, keyname)
  119. err := exec.Command("ssh-keygen", "-f", keyFile, "-t", "rsa", "-N", "").Run()
  120. assert.NoError(t, err)
  121. defer os.RemoveAll(keyFile)
  122. defer os.RemoveAll(keyFile + ".pub")
  123. t.Run("CreatePushDeployKey", createDeployKey(username, reponame, keyname, keyFile, false))
  124. // Setup the testing repository
  125. dstPath, err := ioutil.TempDir("", "repo-tmp-deploy-key-empty-repo-1")
  126. assert.NoError(t, err)
  127. defer os.RemoveAll(dstPath)
  128. t.Run("InitTestRepository", initTestRepository(dstPath))
  129. t.Run("SSHPushTestRepository", pushTestRepository(dstPath, username, reponame, *u, keyFile))
  130. log.Println("Done Push")
  131. t.Run("CheckIsNotEmpty", checkRepositoryEmptyStatus(username, reponame, false))
  132. t.Run("DeleteRepository", deleteRepository(username, reponame))
  133. }