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.

104 lines
3.1 KiB

Sign merges, CRUD, Wiki and Repository initialisation with gpg key (#7631) This PR fixes #7598 by providing a configurable way of signing commits across the Gitea instance. Per repository configurability and import/generation of trusted secure keys is not provided by this PR - from a security PoV that's probably impossible to do properly. Similarly web-signing, that is asking the user to sign something, is not implemented - this could be done at a later stage however. ## Features - [x] If commit.gpgsign is set in .gitconfig sign commits and files created through repofiles. (merges should already have been signed.) - [x] Verify commits signed with the default gpg as valid - [x] Signer, Committer and Author can all be different - [x] Allow signer to be arbitrarily different - We still require the key to have an activated email on Gitea. A more complete implementation would be to use a keyserver and mark external-or-unactivated with an "unknown" trust level icon. - [x] Add a signing-key.gpg endpoint to get the default gpg pub key if available - Rather than add a fake web-flow user I've added this as an endpoint on /api/v1/signing-key.gpg - [x] Try to match the default key with a user on gitea - this is done at verification time - [x] Make things configurable? - app.ini configuration done - [x] when checking commits are signed need to check if they're actually verifiable too - [x] Add documentation I have decided that adjusting the docker to create a default gpg key is not the correct thing to do and therefore have not implemented this.
5 years ago
  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 repofiles
  5. import (
  6. "testing"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/git"
  9. "code.gitea.io/gitea/modules/setting"
  10. api "code.gitea.io/gitea/modules/structs"
  11. "code.gitea.io/gitea/modules/test"
  12. "github.com/stretchr/testify/assert"
  13. )
  14. func getExpectedFileResponse() *api.FileResponse {
  15. treePath := "README.md"
  16. sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f"
  17. encoding := "base64"
  18. content := "IyByZXBvMQoKRGVzY3JpcHRpb24gZm9yIHJlcG8x"
  19. selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=master"
  20. htmlURL := setting.AppURL + "user2/repo1/src/branch/master/" + treePath
  21. gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha
  22. downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath
  23. return &api.FileResponse{
  24. Content: &api.ContentsResponse{
  25. Name: treePath,
  26. Path: treePath,
  27. SHA: sha,
  28. Type: "file",
  29. Size: 30,
  30. Encoding: &encoding,
  31. Content: &content,
  32. URL: &selfURL,
  33. HTMLURL: &htmlURL,
  34. GitURL: &gitURL,
  35. DownloadURL: &downloadURL,
  36. Links: &api.FileLinksResponse{
  37. Self: &selfURL,
  38. GitURL: &gitURL,
  39. HTMLURL: &htmlURL,
  40. },
  41. },
  42. Commit: &api.FileCommitResponse{
  43. CommitMeta: api.CommitMeta{
  44. URL: "https://try.gitea.io/api/v1/repos/user2/repo1/git/commits/65f1bf27bc3bf70f64657658635e66094edbcb4d",
  45. SHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
  46. },
  47. HTMLURL: "https://try.gitea.io/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d",
  48. Author: &api.CommitUser{
  49. Identity: api.Identity{
  50. Name: "user1",
  51. Email: "address1@example.com",
  52. },
  53. Date: "2017-03-19T20:47:59Z",
  54. },
  55. Committer: &api.CommitUser{
  56. Identity: api.Identity{
  57. Name: "Ethan Koenig",
  58. Email: "ethantkoenig@gmail.com",
  59. },
  60. Date: "2017-03-19T20:47:59Z",
  61. },
  62. Parents: []*api.CommitMeta{},
  63. Message: "Initial commit\n",
  64. Tree: &api.CommitMeta{
  65. URL: "https://try.gitea.io/api/v1/repos/user2/repo1/git/trees/2a2f1d4670728a2e10049e345bd7a276468beab6",
  66. SHA: "2a2f1d4670728a2e10049e345bd7a276468beab6",
  67. },
  68. },
  69. Verification: &api.PayloadCommitVerification{
  70. Verified: false,
  71. Reason: "gpg.error.not_signed_commit",
  72. Signature: "",
  73. Payload: "",
  74. },
  75. }
  76. }
  77. func TestGetFileResponseFromCommit(t *testing.T) {
  78. models.PrepareTestEnv(t)
  79. ctx := test.MockContext(t, "user2/repo1")
  80. ctx.SetParams(":id", "1")
  81. test.LoadRepo(t, ctx, 1)
  82. test.LoadRepoCommit(t, ctx)
  83. test.LoadUser(t, ctx, 2)
  84. test.LoadGitRepo(t, ctx)
  85. defer ctx.Repo.GitRepo.Close()
  86. repo := ctx.Repo.Repository
  87. branch := repo.DefaultBranch
  88. treePath := "README.md"
  89. gitRepo, _ := git.OpenRepository(repo.RepoPath())
  90. defer gitRepo.Close()
  91. commit, _ := gitRepo.GetBranchCommit(branch)
  92. expectedFileResponse := getExpectedFileResponse()
  93. fileResponse, err := GetFileResponseFromCommit(repo, commit, branch, treePath)
  94. assert.Nil(t, err)
  95. assert.EqualValues(t, expectedFileResponse, fileResponse)
  96. }