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.

217 lines
6.8 KiB

  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. "net/http"
  9. "net/url"
  10. "os"
  11. "path/filepath"
  12. "testing"
  13. "time"
  14. "code.gitea.io/gitea/modules/git"
  15. api "code.gitea.io/gitea/modules/structs"
  16. "github.com/stretchr/testify/assert"
  17. )
  18. func doCheckRepositoryEmptyStatus(ctx APITestContext, isEmpty bool) func(*testing.T) {
  19. return doAPIGetRepository(ctx, func(t *testing.T, repository api.Repository) {
  20. assert.Equal(t, isEmpty, repository.Empty)
  21. })
  22. }
  23. func doAddChangesToCheckout(dstPath, filename string) func(*testing.T) {
  24. return func(t *testing.T) {
  25. 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))
  26. assert.NoError(t, git.AddChanges(dstPath, true))
  27. signature := git.Signature{
  28. Email: "test@example.com",
  29. Name: "test",
  30. When: time.Now(),
  31. }
  32. assert.NoError(t, git.CommitChanges(dstPath, git.CommitChangesOptions{
  33. Committer: &signature,
  34. Author: &signature,
  35. Message: "Initial Commit",
  36. }))
  37. }
  38. }
  39. func TestPushDeployKeyOnEmptyRepo(t *testing.T) {
  40. onGiteaRun(t, testPushDeployKeyOnEmptyRepo)
  41. }
  42. func testPushDeployKeyOnEmptyRepo(t *testing.T, u *url.URL) {
  43. // OK login
  44. ctx := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1")
  45. keyname := fmt.Sprintf("%s-push", ctx.Reponame)
  46. u.Path = ctx.GitPath()
  47. t.Run("CreateEmptyRepository", doAPICreateRepository(ctx, true))
  48. t.Run("CheckIsEmpty", doCheckRepositoryEmptyStatus(ctx, true))
  49. withKeyFile(t, keyname, func(keyFile string) {
  50. t.Run("CreatePushDeployKey", doAPICreateDeployKey(ctx, keyname, keyFile, false))
  51. // Setup the testing repository
  52. dstPath, err := ioutil.TempDir("", "repo-tmp-deploy-key-empty-repo-1")
  53. assert.NoError(t, err)
  54. defer os.RemoveAll(dstPath)
  55. t.Run("InitTestRepository", doGitInitTestRepository(dstPath))
  56. //Setup remote link
  57. sshURL := createSSHUrl(ctx.GitPath(), u)
  58. t.Run("AddRemote", doGitAddRemote(dstPath, "origin", sshURL))
  59. t.Run("SSHPushTestRepository", doGitPushTestRepository(dstPath, "origin", "master"))
  60. t.Run("CheckIsNotEmpty", doCheckRepositoryEmptyStatus(ctx, false))
  61. t.Run("DeleteRepository", doAPIDeleteRepository(ctx))
  62. })
  63. }
  64. func TestKeyOnlyOneType(t *testing.T) {
  65. onGiteaRun(t, testKeyOnlyOneType)
  66. }
  67. func testKeyOnlyOneType(t *testing.T, u *url.URL) {
  68. // Once a key is a user key we cannot use it as a deploy key
  69. // If we delete it from the user we should be able to use it as a deploy key
  70. reponame := "ssh-key-test-repo"
  71. username := "user2"
  72. u.Path = fmt.Sprintf("%s/%s.git", username, reponame)
  73. keyname := fmt.Sprintf("%s-push", reponame)
  74. // OK login
  75. ctx := NewAPITestContext(t, username, reponame)
  76. otherCtx := ctx
  77. otherCtx.Reponame = "ssh-key-test-repo-2"
  78. failCtx := ctx
  79. failCtx.ExpectedCode = http.StatusUnprocessableEntity
  80. t.Run("CreateRepository", doAPICreateRepository(ctx, false))
  81. t.Run("CreateOtherRepository", doAPICreateRepository(otherCtx, false))
  82. withKeyFile(t, keyname, func(keyFile string) {
  83. var userKeyPublicKeyID int64
  84. t.Run("KeyCanOnlyBeUser", func(t *testing.T) {
  85. dstPath, err := ioutil.TempDir("", ctx.Reponame)
  86. assert.NoError(t, err)
  87. defer os.RemoveAll(dstPath)
  88. sshURL := createSSHUrl(ctx.GitPath(), u)
  89. t.Run("FailToClone", doGitCloneFail(dstPath, sshURL))
  90. t.Run("CreateUserKey", doAPICreateUserKey(ctx, keyname, keyFile, func(t *testing.T, publicKey api.PublicKey) {
  91. userKeyPublicKeyID = publicKey.ID
  92. }))
  93. t.Run("FailToAddReadOnlyDeployKey", doAPICreateDeployKey(failCtx, keyname, keyFile, true))
  94. t.Run("FailToAddDeployKey", doAPICreateDeployKey(failCtx, keyname, keyFile, false))
  95. t.Run("Clone", doGitClone(dstPath, sshURL))
  96. t.Run("AddChanges", doAddChangesToCheckout(dstPath, "CHANGES1.md"))
  97. t.Run("Push", doGitPushTestRepository(dstPath, "origin", "master"))
  98. t.Run("DeleteUserKey", doAPIDeleteUserKey(ctx, userKeyPublicKeyID))
  99. })
  100. t.Run("KeyCanBeAnyDeployButNotUserAswell", func(t *testing.T) {
  101. dstPath, err := ioutil.TempDir("", ctx.Reponame)
  102. assert.NoError(t, err)
  103. defer os.RemoveAll(dstPath)
  104. sshURL := createSSHUrl(ctx.GitPath(), u)
  105. t.Run("FailToClone", doGitCloneFail(dstPath, sshURL))
  106. // Should now be able to add...
  107. t.Run("AddReadOnlyDeployKey", doAPICreateDeployKey(ctx, keyname, keyFile, true))
  108. t.Run("Clone", doGitClone(dstPath, sshURL))
  109. t.Run("AddChanges", doAddChangesToCheckout(dstPath, "CHANGES2.md"))
  110. t.Run("FailToPush", doGitPushTestRepositoryFail(dstPath, "origin", "master"))
  111. otherSSHURL := createSSHUrl(otherCtx.GitPath(), u)
  112. dstOtherPath, err := ioutil.TempDir("", otherCtx.Reponame)
  113. assert.NoError(t, err)
  114. defer os.RemoveAll(dstOtherPath)
  115. t.Run("AddWriterDeployKeyToOther", doAPICreateDeployKey(otherCtx, keyname, keyFile, false))
  116. t.Run("CloneOther", doGitClone(dstOtherPath, otherSSHURL))
  117. t.Run("AddChangesToOther", doAddChangesToCheckout(dstOtherPath, "CHANGES3.md"))
  118. t.Run("PushToOther", doGitPushTestRepository(dstOtherPath, "origin", "master"))
  119. t.Run("FailToCreateUserKey", doAPICreateUserKey(failCtx, keyname, keyFile))
  120. })
  121. t.Run("DeleteRepositoryShouldReleaseKey", func(t *testing.T) {
  122. otherSSHURL := createSSHUrl(otherCtx.GitPath(), u)
  123. dstOtherPath, err := ioutil.TempDir("", otherCtx.Reponame)
  124. assert.NoError(t, err)
  125. defer os.RemoveAll(dstOtherPath)
  126. t.Run("DeleteRepository", doAPIDeleteRepository(ctx))
  127. t.Run("FailToCreateUserKeyAsStillDeploy", doAPICreateUserKey(failCtx, keyname, keyFile))
  128. t.Run("MakeSureCloneOtherStillWorks", doGitClone(dstOtherPath, otherSSHURL))
  129. t.Run("AddChangesToOther", doAddChangesToCheckout(dstOtherPath, "CHANGES3.md"))
  130. t.Run("PushToOther", doGitPushTestRepository(dstOtherPath, "origin", "master"))
  131. t.Run("DeleteOtherRepository", doAPIDeleteRepository(otherCtx))
  132. t.Run("RecreateRepository", doAPICreateRepository(ctx, false))
  133. t.Run("CreateUserKey", doAPICreateUserKey(ctx, keyname, keyFile, func(t *testing.T, publicKey api.PublicKey) {
  134. userKeyPublicKeyID = publicKey.ID
  135. }))
  136. dstPath, err := ioutil.TempDir("", ctx.Reponame)
  137. assert.NoError(t, err)
  138. defer os.RemoveAll(dstPath)
  139. sshURL := createSSHUrl(ctx.GitPath(), u)
  140. t.Run("Clone", doGitClone(dstPath, sshURL))
  141. t.Run("AddChanges", doAddChangesToCheckout(dstPath, "CHANGES1.md"))
  142. t.Run("Push", doGitPushTestRepository(dstPath, "origin", "master"))
  143. })
  144. t.Run("DeleteUserKeyShouldRemoveAbilityToClone", func(t *testing.T) {
  145. dstPath, err := ioutil.TempDir("", ctx.Reponame)
  146. assert.NoError(t, err)
  147. defer os.RemoveAll(dstPath)
  148. sshURL := createSSHUrl(ctx.GitPath(), u)
  149. t.Run("DeleteUserKey", doAPIDeleteUserKey(ctx, userKeyPublicKeyID))
  150. t.Run("FailToClone", doGitCloneFail(dstPath, sshURL))
  151. })
  152. })
  153. }