1// Copyright (C) 2019 Storj Labs, Inc.
2// See LICENSE for copying information.
3
4package testidentity
5
6import (
7	"context"
8	"fmt"
9	"testing"
10
11	"github.com/stretchr/testify/require"
12
13	"storj.io/common/identity"
14	"storj.io/common/storj"
15)
16
17// IdentityTest is a function that takes a testing struct, an identity version
18// and a full identity.
19type IdentityTest func(*testing.T, storj.IDVersion, *identity.FullIdentity)
20
21// SignerTest is a function that takes a testing struct, an identity version
22// and a full certificate authority.
23type SignerTest func(*testing.T, storj.IDVersion, *identity.FullCertificateAuthority)
24
25// NewTestIdentity is a helper function to generate new node identities with
26// correct difficulty and concurrency.
27func NewTestIdentity(ctx context.Context) (*identity.FullIdentity, error) {
28	ca, err := NewTestCA(ctx)
29	if err != nil {
30		return nil, err
31	}
32	return ca.NewIdentity()
33}
34
35// NewTestCA returns a ca with a default difficulty and concurrency for use in tests.
36func NewTestCA(ctx context.Context) (*identity.FullCertificateAuthority, error) {
37	return identity.NewCA(ctx, identity.NewCAOptions{
38		VersionNumber: storj.LatestIDVersion().Number,
39		Difficulty:    9,
40		Concurrency:   4,
41	})
42}
43
44// IdentityVersionsTest runs the `IdentityTest` for each identity
45// version, with an unsigned identity.
46func IdentityVersionsTest(t *testing.T, test IdentityTest) {
47	for vn, v := range storj.IDVersions {
48		versionNumber := vn
49		version := v
50		t.Run(fmt.Sprintf("identity version %d", versionNumber), func(t *testing.T) {
51			idents := IdentityVersions[versionNumber].Clone()
52			ident, err := idents.NewIdentity()
53			require.NoError(t, err)
54
55			test(t, version, ident)
56		})
57	}
58}
59
60// SignedIdentityVersionsTest runs the `IdentityTest` for each identity
61// version, with an signed identity.
62func SignedIdentityVersionsTest(t *testing.T, test IdentityTest) {
63	for vn, v := range storj.IDVersions {
64		versionNumber := vn
65		version := v
66		t.Run(fmt.Sprintf("identity version %d", versionNumber), func(t *testing.T) {
67			idents := SignedIdentityVersions[versionNumber].Clone()
68			ident, err := idents.NewIdentity()
69			require.NoError(t, err)
70
71			test(t, version, ident)
72		})
73	}
74}
75
76// CompleteIdentityVersionsTest runs the `IdentityTest` for each identity
77// version, with both signed dn unsigned identities.
78func CompleteIdentityVersionsTest(t *testing.T, test IdentityTest) {
79	t.Run("unsigned identity", func(t *testing.T) {
80		IdentityVersionsTest(t, test)
81	})
82
83	t.Run("signed identity", func(t *testing.T) {
84		SignedIdentityVersionsTest(t, test)
85	})
86}
87
88// SignerVersionsTest runs the `SignerTest` for each identity version, with the
89// respective signer used to sign pregenerated, signed  identities.
90func SignerVersionsTest(t *testing.T, test SignerTest) {
91	for vn, v := range storj.IDVersions {
92		var (
93			versionNumber = vn
94			version       = v
95		)
96		t.Run(fmt.Sprintf("identity version %d", versionNumber), func(t *testing.T) {
97			ca := SignerVersions[versionNumber]
98
99			test(t, version, ca)
100		})
101	}
102}
103
104// NewTestManageablePeerIdentity returns a new manageable peer identity for use in tests.
105func NewTestManageablePeerIdentity(ctx context.Context) (*identity.ManageablePeerIdentity, error) {
106	ca, err := NewTestCA(ctx)
107	if err != nil {
108		return nil, err
109	}
110
111	ident, err := ca.NewIdentity()
112	if err != nil {
113		return nil, err
114	}
115	return identity.NewManageablePeerIdentity(ident.PeerIdentity(), ca), nil
116}
117
118// NewTestManageableFullIdentity returns a new manageable full identity for use in tests.
119func NewTestManageableFullIdentity(ctx context.Context) (*identity.ManageableFullIdentity, error) {
120	ca, err := NewTestCA(ctx)
121	if err != nil {
122		return nil, err
123	}
124
125	ident, err := ca.NewIdentity()
126	if err != nil {
127		return nil, err
128	}
129	return identity.NewManageableFullIdentity(ident, ca), nil
130}
131