validator_test.go

  1package validate
  2
  3import (
  4	"fmt"
  5	"testing"
  6
  7	"github.com/MichaelMure/git-bug/cache"
  8	"github.com/MichaelMure/git-bug/identity"
  9	"github.com/MichaelMure/git-bug/repository"
 10	"github.com/stretchr/testify/require"
 11)
 12
 13func checkAddIdentity(t *testing.T, backend *cache.RepoCache, name, email, armoredPubkey string) *cache.IdentityCache {
 14	key, err := identity.NewKey(armoredPubkey)
 15	require.NoError(t, err)
 16
 17	id, err := backend.NewIdentityWithKeyRaw(name, email, "", "", nil, key)
 18	require.NoError(t, err)
 19
 20	return id
 21}
 22
 23func checkValidator(t *testing.T, backend *cache.RepoCache, errorMsg, firstKey string) {
 24	validator, err := NewValidator(backend)
 25	if errorMsg == "" {
 26		require.NoError(t, err)
 27		if firstKey == "" {
 28			require.Nil(t, validator.FirstKey)
 29		} else {
 30			require.Equal(t, firstKey, validator.FirstKey.ArmoredPublicKey)
 31		}
 32	} else {
 33		require.EqualError(t, err, errorMsg)
 34	}
 35}
 36
 37func checkAddKey(t *testing.T, id *cache.IdentityCache, armoredKey string) {
 38	key, err := identity.NewKey(armoredKey)
 39	require.NoError(t, err)
 40
 41	err = id.Mutate(func(m identity.Mutator) identity.Mutator {
 42		m.Keys = append(m.Keys, key)
 43		return m
 44	})
 45	require.NoError(t, err)
 46
 47	err = id.Commit()
 48	require.NoError(t, err)
 49}
 50
 51func TestNewValidator_EmptyRepo(t *testing.T) {
 52	repo := repository.CreateTestRepo(false)
 53	defer repository.CleanupTestRepos(t, repo)
 54
 55	backend, err := cache.NewRepoCache(repo)
 56	require.NoError(t, err)
 57
 58	checkValidator(t, backend, "", "")
 59	validator, err := NewValidator(backend)
 60	require.NoError(t, err)
 61	require.Nil(t, validator.FirstKey)
 62}
 63
 64func TestNewValidator_OneIdentity(t *testing.T) {
 65	repo := repository.CreateTestRepo(false)
 66	defer repository.CleanupTestRepos(t, repo)
 67
 68	backend, err := cache.NewRepoCache(repo)
 69	require.NoError(t, err)
 70
 71	armoredPubkey := repository.SetupSigningKey(t, repo, "a@e.org")
 72
 73	_ = checkAddIdentity(t, backend, "A", "a@e.org", armoredPubkey)
 74	checkValidator(t, backend, "", armoredPubkey)
 75}
 76
 77func TestNewValidator_TwoSeparateIdentities(t *testing.T) {
 78	repo := repository.CreateTestRepo(false)
 79	defer repository.CleanupTestRepos(t, repo)
 80
 81	backend, err := cache.NewRepoCache(repo)
 82	require.NoError(t, err)
 83
 84	armoredPubkey := repository.SetupSigningKey(t, repo, "a@e.org")
 85	_ = checkAddIdentity(t, backend, "A", "a@e.org", armoredPubkey)
 86
 87	armoredPubkey2 := repository.SetupSigningKey(t, repo, "b@e.org")
 88	id2 := checkAddIdentity(t, backend, "B", "b@e.org", armoredPubkey2)
 89
 90	msg := fmt.Sprintf("failed to validate identities: invalid identity %s (%s): invalid signature for commit %s: no key can verify the signature",
 91		id2.Id(), id2.Email(), id2.Versions()[0].CommitHash())
 92	checkValidator(t, backend, msg, "")
 93}
 94
 95func TestNewValidator_IdentityWithSameKeyTwice(t *testing.T) {
 96	repo := repository.CreateTestRepo(false)
 97	defer repository.CleanupTestRepos(t, repo)
 98
 99	backend, err := cache.NewRepoCache(repo)
100	require.NoError(t, err)
101
102	armoredPubkey := repository.SetupSigningKey(t, repo, "a@e.org")
103	id1 := checkAddIdentity(t, backend, "A", "a@e.org", armoredPubkey)
104
105	checkAddKey(t, id1, armoredPubkey)
106
107	msg := fmt.Sprintf("failed to read identity versions: keys with identical keyId introduced in commits %s and %s",
108		id1.Versions()[0].CommitHash(), id1.Versions()[1].CommitHash())
109	checkValidator(t, backend, msg, "")
110}
111
112func TestNewValidator_TwoIdentitiesWithSameKey(t *testing.T) {
113	repo := repository.CreateTestRepo(false)
114	defer repository.CleanupTestRepos(t, repo)
115
116	backend, err := cache.NewRepoCache(repo)
117	require.NoError(t, err)
118
119	armoredPubkey := repository.SetupSigningKey(t, repo, "a@e.org")
120	id1 := checkAddIdentity(t, backend, "A", "a@e.org", armoredPubkey)
121
122	id2 := checkAddIdentity(t, backend, "B", "b@e.org", armoredPubkey)
123
124	_, err = NewValidator(backend)
125	require.EqualError(t, err,
126		fmt.Sprintf("failed to read identity versions: keys with identical keyId introduced in commits %s and %s",
127			id1.Versions()[0].CommitHash(), id2.Versions()[0].CommitHash()))
128}
129
130func TestNewValidator_TwoIdentitiesTwoVersions(t *testing.T) {
131	repo := repository.CreateTestRepo(false)
132	defer repository.CleanupTestRepos(t, repo)
133
134	backend, err := cache.NewRepoCache(repo)
135	require.NoError(t, err)
136
137	armoredPubkey := repository.SetupSigningKey(t, repo, "a@e.org")
138	id1 := checkAddIdentity(t, backend, "A", "a@e.org", armoredPubkey)
139	checkValidator(t, backend, "", armoredPubkey)
140
141	armoredPubkey2 := repository.CreatePubkey(t)
142	id2 := checkAddIdentity(t, backend, "B", "b@e.org", armoredPubkey2)
143
144	armoredPubkey3 := repository.CreatePubkey(t)
145	checkAddKey(t, id1, armoredPubkey3)
146
147	armoredPubkey4 := repository.CreatePubkey(t)
148	checkAddKey(t, id2, armoredPubkey4)
149
150	checkValidator(t, backend, "", armoredPubkey)
151}
152
153func TestNewValidator_WrongEmail(t *testing.T) {
154	repo := repository.CreateTestRepo(false)
155	defer repository.CleanupTestRepos(t, repo)
156
157	backend, err := cache.NewRepoCache(repo)
158	require.NoError(t, err)
159
160	armoredPubkey := repository.SetupSigningKey(t, repo, "a@e.org")
161	repository.SetupKey(t, repo, "x@a.org", "", "")
162	id1 := checkAddIdentity(t, backend, "A", "a@e.org", armoredPubkey)
163
164	msg := fmt.Sprintf("failed to validate identities: invalid identity %s (%s): invalid signature for commit %s: git commit committer-email does not match the identity-email: x@a.org vs a@e.org",
165		id1.Id(), id1.Email(), id1.Versions()[0].CommitHash())
166	checkValidator(t, backend, msg, armoredPubkey)
167}