...
1 package crypto_test
2
3 import (
4 "bytes"
5 "context"
6 "encoding/json"
7 "testing"
8 "time"
9
10 "github.com/go-kivik/kivik/v4"
11 "github.com/go-kivik/kivik/v4/driver"
12 kivikmock "github.com/go-kivik/kivik/v4/mockdb"
13
14 "edge-infra.dev/pkg/edge/iam/crypto"
15 "edge-infra.dev/pkg/edge/iam/storage/database"
16 )
17
18
19
20 func TestCouchDBSwapFunction(t *testing.T) {
21 oldKey := []byte("my-32bit-super-extra-secret-key!")
22 newKey := []byte("my-32bit-super-extra-secret-key2")
23
24 client, mock, err := kivikmock.New()
25 if err != nil {
26 panic(err)
27 }
28
29
30 s, err := NewCouchStoreWithMock(client)
31 if err != nil {
32 t.Errorf("Unable create mock store with couchdb %s\n", err)
33 return
34 }
35
36
37 db := mock.NewDB()
38
39
40 document, err := createCouchData(oldKey)
41 if err != nil {
42 t.Errorf("Unable to create couch document %s\n", err)
43 return
44 }
45
46
47 docAsBytes, err := json.Marshal(document)
48 if err != nil {
49 t.Errorf("Unable to marshal document %s\n", err)
50 return
51 }
52
53 docReader := bytes.NewReader(docAsBytes)
54
55 row := &driver.Row{
56 ID: "test-doc",
57 Doc: docReader,
58 }
59
60
61 rows := kivikmock.NewRows().AddRow(row)
62
63
64 mock.ExpectDB().WillReturn(db)
65 db.ExpectAllDocs().WillReturn(rows)
66 mock.ExpectDB().WillReturn(db)
67 db.ExpectGet().WillReturn(document)
68 mock.ExpectDB().WillReturn(db)
69 db.ExpectPut()
70
71
72 err = s.RotateCouchEncryptionKey(context.Background(), oldKey, newKey)
73 if err != nil {
74 t.Errorf("Unable to update couchdb data with new key %s\n", err)
75 return
76 }
77 }
78
79
80
81 func TestInnerUpdateFunction(t *testing.T) {
82 value := []byte(`{"number": 1,"title": "test","url": "https://google.com"}`)
83 key := []byte("my-32bit-super-extra-secret-key!")
84 client, mock, err := kivikmock.New()
85 if err != nil {
86 panic(err)
87 }
88
89 s, err := NewCouchStoreWithMock(client)
90 if err != nil {
91 t.Errorf("Unable create mock store with couchdb %s\n", err)
92 return
93 }
94
95 db := mock.NewDB()
96
97
98 document, err := createCouchData(key)
99 if err != nil {
100 t.Errorf("Unable to create couch document %s\n", err)
101 return
102 }
103
104
105 mock.ExpectDB().WillReturn(db)
106 db.ExpectGet().WillReturn(document)
107
108
109 unencryptedDoc, err := s.GetDocWithKey(context.Background(), "test-doc", key)
110 if err != nil {
111 t.Errorf("Unable to get test data with new key %s\n", err)
112 return
113 }
114
115
116 if unencryptedDoc == nil {
117 t.Errorf("Was not able to retrieve and decrypt doc %s\n", err)
118 return
119 }
120
121
122 if !bytes.Equal(unencryptedDoc.Value, value) {
123 t.Errorf("Unable to get test data with new key %s\n", err)
124 return
125 }
126 }
127
128
129 func createCouchData(key []byte) (*driver.Document, error) {
130 value := []byte(`{"number": 1,"title": "test","url": "https://google.com"}`)
131
132 encrypted, err := crypto.EncryptJSON(value, key)
133 if err != nil {
134 return &driver.Document{}, err
135 }
136
137 doc := database.Doc{
138 ID: "test-doc",
139 Value: encrypted,
140 Expiration: time.Now().Add(time.Hour).Unix(),
141 }
142
143
144 kivikDoc, err := kivikmock.Document(&doc)
145 if err != nil {
146 return &driver.Document{}, err
147 }
148
149 return kivikDoc, err
150 }
151
152
153 func NewCouchStoreWithMock(client *kivik.Client) (*database.Store, error) {
154 store := &database.Store{
155 CouchDB: client,
156 }
157 return store, nil
158 }
159
View as plain text