forked from NYANDEV/forgejo
[GITEA] Add noreply email address as verified for SSH signed Git commits
- When someone really wants to avoid sharing their email, they could configure git to use the noreply email for git commits. However if they also wanted to use SSH signing, it would not show up as verified as the noreply email address was technically not an activated email address for the user. - Add unit tests for the `ParseCommitWithSSHSignature` function. - Resolves https://codeberg.org/Codeberg/Community/issues/946 (cherry picked from commit1685de7eba
) (cherry picked from commitb1e8858de9
) (cherry picked from commit 1a6bf24d28522d57a56dcbdcf23ef19508ac39c8) (cherry picked from commit 01229433456aa0836adbaafa06bcbefcf4111451) (cherry picked from commit cc836148534ecf6e007eeb913cd94264fda171d3) (cherry picked from commit 429febe0dc2e49bae6ce747c318e68a99b1da9a8) (cherry picked from commit 58a9c2ebe9518576a1b399cce9089fd4894a5c38) (cherry picked from commit fef94aff1c8b35d9a10cf735d4c7ba05f82c95b4) (cherry picked from commit 5c6ecd757992f117d3aafc3a2034807cfccbf5a6)
This commit is contained in:
parent
03d00b11ac
commit
ffa33a82bf
4 changed files with 166 additions and 0 deletions
|
@ -14,6 +14,7 @@ func TestMain(m *testing.M) {
|
|||
FixtureFiles: []string{
|
||||
"gpg_key.yml",
|
||||
"public_key.yml",
|
||||
"TestParseCommitWithSSHSignature/public_key.yml",
|
||||
"deploy_key.yml",
|
||||
"gpg_key_import.yml",
|
||||
"user.yml",
|
||||
|
|
|
@ -39,6 +39,12 @@ func ParseCommitWithSSHSignature(ctx context.Context, c *git.Commit, committer *
|
|||
log.Error("GetEmailAddresses: %v", err)
|
||||
}
|
||||
|
||||
// Add the noreply email address as verified address.
|
||||
committerEmailAddresses = append(committerEmailAddresses, &user_model.EmailAddress{
|
||||
IsActivated: true,
|
||||
Email: committer.GetPlaceholderEmail(),
|
||||
})
|
||||
|
||||
activated := false
|
||||
for _, e := range committerEmailAddresses {
|
||||
if e.IsActivated && strings.EqualFold(e.Email, c.Committer.Email) {
|
||||
|
|
146
models/asymkey/ssh_key_commit_verification_test.go
Normal file
146
models/asymkey/ssh_key_commit_verification_test.go
Normal file
|
@ -0,0 +1,146 @@
|
|||
// Copyright 2023 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package asymkey
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseCommitWithSSHSignature(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
sshKey := unittest.AssertExistsAndLoadBean(t, &PublicKey{ID: 1000, OwnerID: 2})
|
||||
|
||||
t.Run("No commiter", func(t *testing.T) {
|
||||
commitVerification := ParseCommitWithSSHSignature(db.DefaultContext, &git.Commit{}, &user_model.User{})
|
||||
assert.False(t, commitVerification.Verified)
|
||||
assert.Equal(t, NoKeyFound, commitVerification.Reason)
|
||||
})
|
||||
|
||||
t.Run("Commiter without keys", func(t *testing.T) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
|
||||
commitVerification := ParseCommitWithSSHSignature(db.DefaultContext, &git.Commit{Committer: &git.Signature{Email: user.Email}}, user)
|
||||
assert.False(t, commitVerification.Verified)
|
||||
assert.Equal(t, NoKeyFound, commitVerification.Reason)
|
||||
})
|
||||
|
||||
t.Run("Correct signature with wrong email", func(t *testing.T) {
|
||||
gitCommit := &git.Commit{
|
||||
Committer: &git.Signature{
|
||||
Email: "non-existent",
|
||||
},
|
||||
Signature: &git.CommitGPGSignature{
|
||||
Payload: `tree 2d491b2985a7ff848d5c02748e7ea9f9f7619f9f
|
||||
parent 45b03601635a1f463b81963a4022c7f87ce96ef9
|
||||
author user2 <non-existent> 1699710556 +0100
|
||||
committer user2 <non-existent> 1699710556 +0100
|
||||
|
||||
Using email that isn't known to Forgejo
|
||||
`,
|
||||
Signature: `-----BEGIN SSH SIGNATURE-----
|
||||
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgoGSe9Zy7Ez9bSJcaTNjh/Y7p95
|
||||
f5DujjqkpzFRtw6CEAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
|
||||
AAAAQIMufOuSjZeDUujrkVK4sl7ICa0WwEftas8UAYxx0Thdkiw2qWjR1U1PKfTLm16/w8
|
||||
/bS1LX1lZNuzm2LR2qEgw=
|
||||
-----END SSH SIGNATURE-----
|
||||
`,
|
||||
},
|
||||
}
|
||||
commitVerification := ParseCommitWithSSHSignature(db.DefaultContext, gitCommit, user2)
|
||||
assert.False(t, commitVerification.Verified)
|
||||
assert.Equal(t, NoKeyFound, commitVerification.Reason)
|
||||
})
|
||||
|
||||
t.Run("Incorrect signature with correct email", func(t *testing.T) {
|
||||
gitCommit := &git.Commit{
|
||||
Committer: &git.Signature{
|
||||
Email: "user2@example.com",
|
||||
},
|
||||
Signature: &git.CommitGPGSignature{
|
||||
Payload: `tree 853694aae8816094a0d875fee7ea26278dbf5d0f
|
||||
parent c2780d5c313da2a947eae22efd7dacf4213f4e7f
|
||||
author user2 <user2@example.com> 1699707877 +0100
|
||||
committer user2 <user2@example.com> 1699707877 +0100
|
||||
|
||||
Add content
|
||||
`,
|
||||
Signature: `-----BEGIN SSH SIGNATURE-----`,
|
||||
},
|
||||
}
|
||||
|
||||
commitVerification := ParseCommitWithSSHSignature(db.DefaultContext, gitCommit, user2)
|
||||
assert.False(t, commitVerification.Verified)
|
||||
assert.Equal(t, NoKeyFound, commitVerification.Reason)
|
||||
})
|
||||
|
||||
t.Run("Valid signature with correct email", func(t *testing.T) {
|
||||
gitCommit := &git.Commit{
|
||||
Committer: &git.Signature{
|
||||
Email: "user2@example.com",
|
||||
},
|
||||
Signature: &git.CommitGPGSignature{
|
||||
Payload: `tree 853694aae8816094a0d875fee7ea26278dbf5d0f
|
||||
parent c2780d5c313da2a947eae22efd7dacf4213f4e7f
|
||||
author user2 <user2@example.com> 1699707877 +0100
|
||||
committer user2 <user2@example.com> 1699707877 +0100
|
||||
|
||||
Add content
|
||||
`,
|
||||
Signature: `-----BEGIN SSH SIGNATURE-----
|
||||
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgoGSe9Zy7Ez9bSJcaTNjh/Y7p95
|
||||
f5DujjqkpzFRtw6CEAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
|
||||
AAAAQBe2Fwk/FKY3SBCnG6jSYcO6ucyahp2SpQ/0P+otslzIHpWNW8cQ0fGLdhhaFynJXQ
|
||||
fs9cMpZVM9BfIKNUSO8QY=
|
||||
-----END SSH SIGNATURE-----
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
commitVerification := ParseCommitWithSSHSignature(db.DefaultContext, gitCommit, user2)
|
||||
assert.True(t, commitVerification.Verified)
|
||||
assert.Equal(t, "user2 / SHA256:TKfwbZMR7e9OnlV2l1prfah1TXH8CmqR0PvFEXVCXA4", commitVerification.Reason)
|
||||
assert.Equal(t, sshKey, commitVerification.SigningSSHKey)
|
||||
})
|
||||
|
||||
t.Run("Valid signature with noreply email", func(t *testing.T) {
|
||||
defer test.MockVariableValue(&setting.Service.NoReplyAddress, "noreply.example.com")()
|
||||
|
||||
gitCommit := &git.Commit{
|
||||
Committer: &git.Signature{
|
||||
Email: "user2@noreply.example.com",
|
||||
},
|
||||
Signature: &git.CommitGPGSignature{
|
||||
Payload: `tree 4836c7f639f37388bab4050ef5c97bbbd54272fc
|
||||
parent 795be1b0117ea5c65456050bb9fd84744d4fd9c6
|
||||
author user2 <user2@noreply.example.com> 1699709594 +0100
|
||||
committer user2 <user2@noreply.example.com> 1699709594 +0100
|
||||
|
||||
Commit with noreply
|
||||
`,
|
||||
Signature: `-----BEGIN SSH SIGNATURE-----
|
||||
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgoGSe9Zy7Ez9bSJcaTNjh/Y7p95
|
||||
f5DujjqkpzFRtw6CEAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
|
||||
AAAAQJz83KKxD6Bz/ZvNpqkA3RPOSQ4LQ5FfEItbtoONkbwV9wAWMnmBqgggo/lnXCJ3oq
|
||||
muPLbvEduU+Ze/1Ol1pgk=
|
||||
-----END SSH SIGNATURE-----
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
commitVerification := ParseCommitWithSSHSignature(db.DefaultContext, gitCommit, user2)
|
||||
assert.True(t, commitVerification.Verified)
|
||||
assert.Equal(t, "user2 / SHA256:TKfwbZMR7e9OnlV2l1prfah1TXH8CmqR0PvFEXVCXA4", commitVerification.Reason)
|
||||
assert.Equal(t, sshKey, commitVerification.SigningSSHKey)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
-
|
||||
id: 1000
|
||||
owner_id: 2
|
||||
name: user2@localhost
|
||||
fingerprint: "SHA256:TKfwbZMR7e9OnlV2l1prfah1TXH8CmqR0PvFEXVCXA4"
|
||||
content: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKBknvWcuxM/W0iXGkzY4f2O6feX+Q7o46pKcxUbcOgh user2@localhost"
|
||||
# private key (base64-ed) LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFNd0FBQUF0emMyZ3RaVwpReU5UVXhPUUFBQUNDZ1pKNzFuTHNUUDF0SWx4cE0yT0g5anVuM2wva082T09xU25NVkczRG9JUUFBQUpocG43YTZhWisyCnVnQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDQ2daSjcxbkxzVFAxdElseHBNMk9IOWp1bjNsL2tPNk9PcVNuTVZHM0RvSVEKQUFBRUFxVm12bmo1LzZ5TW12ck9Ub29xa3F5MmUrc21aK0tBcEtKR0crRnY5MlA2QmtudldjdXhNL1cwaVhHa3pZNGYyTwo2ZmVYK1E3bzQ2cEtjeFViY09naEFBQUFFMmQxYzNSbFpFQm5kWE4wWldRdFltVmhjM1FCQWc9PQotLS0tLUVORCBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0=
|
||||
mode: 2
|
||||
type: 1
|
||||
verified: true
|
||||
created_unix: 1559593109
|
||||
updated_unix: 1565224552
|
||||
login_source_id: 0
|
Loading…
Reference in a new issue