Skip to content

Commit b3da3d9

Browse files
Adding encrypted salt writer test
1 parent 249fdd0 commit b3da3d9

File tree

3 files changed

+135
-10
lines changed

3 files changed

+135
-10
lines changed

src/main/java/com/uid2/admin/store/writer/SaltStoreWriter.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@ public void upload(RotatingSaltProvider.SaltSnapshot data) throws Exception {
5050
JsonObject metadata = null;
5151
try {
5252
metadata = provider.getMetadata();
53-
} catch (Exception e) {
54-
metadata = new JsonObject();
53+
} catch (CloudStorageException e) {
54+
if (e.getMessage().contains("The specified key does not exist")) {
55+
metadata = new JsonObject();
56+
} else {
57+
throw e;
58+
}
5559
}
5660
// bump up metadata version
5761
metadata.put("version", versionGenerator.getVersion());
@@ -60,12 +64,14 @@ public void upload(RotatingSaltProvider.SaltSnapshot data) throws Exception {
6064
final JsonArray snapshotsMetadata = new JsonArray();
6165
metadata.put("salts", snapshotsMetadata);
6266

67+
List<RotatingSaltProvider.SaltSnapshot> currentSnapshots = provider.getSnapshots();
6368
List<RotatingSaltProvider.SaltSnapshot> snapshots = null;
64-
try {
65-
snapshots = Stream.concat(provider.getSnapshots().stream(), Stream.of(data))
69+
70+
if (currentSnapshots != null) {
71+
snapshots = Stream.concat(currentSnapshots.stream(), Stream.of(data))
6672
.sorted(Comparator.comparing(RotatingSaltProvider.SaltSnapshot::getEffective))
6773
.collect(Collectors.toList());
68-
} catch (Exception e) {
74+
} else {
6975
snapshots = List.of(data);
7076
}
7177
// of the currently effective snapshots keep only the most recent one
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package com.uid2.admin.store.writer;
2+
3+
import com.uid2.admin.store.FileManager;
4+
import com.uid2.admin.store.writer.EncyptedSaltStoreWriter;
5+
import com.uid2.admin.store.version.VersionGenerator;
6+
import com.uid2.shared.cloud.CloudStorageException;
7+
import com.uid2.shared.cloud.TaggableCloudStorage;
8+
import com.uid2.shared.model.CloudEncryptionKey;
9+
import com.uid2.shared.model.SaltEntry;
10+
import com.uid2.shared.store.CloudPath;
11+
import com.uid2.shared.store.RotatingSaltProvider;
12+
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
13+
import com.uid2.shared.store.scope.StoreScope;
14+
import io.vertx.core.json.JsonObject;
15+
import org.junit.jupiter.api.BeforeEach;
16+
import org.junit.jupiter.api.Test;
17+
import org.mockito.ArgumentCaptor;
18+
import org.mockito.Captor;
19+
import org.mockito.Mock;
20+
import org.mockito.MockitoAnnotations;
21+
22+
import java.io.IOException;
23+
import java.io.InputStream;
24+
import java.nio.file.Files;
25+
import java.nio.file.Paths;
26+
import java.time.Instant;
27+
import java.util.*;
28+
29+
import static org.junit.jupiter.api.Assertions.assertEquals;
30+
import static org.mockito.Mockito.*;
31+
import static com.uid2.shared.util.CloudEncryptionHelpers.decryptInputStream;
32+
33+
public class EncryptedSaltStoreWriterTest {
34+
private AutoCloseable mocks;
35+
36+
@Mock
37+
private FileManager fileManager;
38+
39+
@Mock
40+
TaggableCloudStorage taggableCloudStorage;
41+
42+
@Mock
43+
RotatingSaltProvider rotatingSaltProvider;
44+
45+
@Mock
46+
RotatingCloudEncryptionKeyProvider rotatingCloudEncryptionKeyProvider;
47+
48+
@Mock
49+
VersionGenerator versionGenerator;
50+
51+
@Mock
52+
StoreScope storeScope;
53+
54+
CloudEncryptionKey encryptionKey;
55+
56+
JsonObject config;
57+
58+
private final Integer siteId = 1;
59+
60+
@Captor
61+
private ArgumentCaptor<String> pathCaptor;
62+
63+
@BeforeEach
64+
public void setUp() throws Exception {
65+
mocks = MockitoAnnotations.openMocks(this);
66+
config = new JsonObject();
67+
config.put("salt_snapshot_location_prefix", "test");
68+
69+
when(versionGenerator.getVersion()).thenReturn(1L);
70+
when(rotatingSaltProvider.getMetadataPath()).thenReturn("test/path/");
71+
when(storeScope.resolve(any())).thenReturn(new CloudPath("test/path/"));
72+
73+
// Setup Cloud Encryption Keys
74+
byte[] keyBytes = new byte[32];
75+
new Random().nextBytes(keyBytes);
76+
String base64Key = Base64.getEncoder().encodeToString(keyBytes);
77+
encryptionKey = new CloudEncryptionKey(1, 1, 0, 0, base64Key);
78+
79+
Map<Integer, CloudEncryptionKey> mockKeyMap = new HashMap<>();
80+
mockKeyMap.put(encryptionKey.getId(), encryptionKey);
81+
when(rotatingCloudEncryptionKeyProvider.getAll()).thenReturn(mockKeyMap);
82+
when(rotatingCloudEncryptionKeyProvider.getKey(1)).thenReturn(mockKeyMap.get(1));
83+
when(rotatingCloudEncryptionKeyProvider.getEncryptionKeyForSite(siteId)).thenReturn(encryptionKey);
84+
}
85+
86+
private RotatingSaltProvider.SaltSnapshot makeSnapshot(Instant effective, Instant expires, int nsalts) {
87+
SaltEntry[] entries = new SaltEntry[nsalts];
88+
for (int i = 0; i < entries.length; ++i) {
89+
entries[i] = new SaltEntry(i, "hashed_id", effective.toEpochMilli(), "salt");
90+
}
91+
return new RotatingSaltProvider.SaltSnapshot(effective, expires, entries, "test_first_level_salt");
92+
}
93+
94+
private void verifyFile(String filelocation, RotatingSaltProvider.SaltSnapshot snapshot) throws IOException {
95+
InputStream encoded = Files.newInputStream(Paths.get(filelocation));
96+
String contents = decryptInputStream(encoded, rotatingCloudEncryptionKeyProvider);
97+
SaltEntry[] entries = snapshot.getAllRotatingSalts();
98+
Integer idx = 0;
99+
for (String line : contents.split("\n")) {
100+
String[] entrySplit = line.split(",");
101+
assertEquals(entries[idx].getId(), Long.parseLong(entrySplit[0]));
102+
assertEquals(entries[idx].getSalt(), entrySplit[2]);
103+
idx++;
104+
}
105+
}
106+
107+
@Test
108+
public void testUploadNew() throws Exception {
109+
RotatingSaltProvider.SaltSnapshot snapshot = makeSnapshot(Instant.now(), Instant.ofEpochMilli(Instant.now().toEpochMilli() + 10000), 100);
110+
111+
when(rotatingSaltProvider.getMetadata()).thenThrow(new CloudStorageException("The specified key does not exist: AmazonS3Exception: test-core-bucket"));
112+
when(rotatingSaltProvider.getSnapshots()).thenReturn(null);
113+
114+
when(taggableCloudStorage.list(anyString())).thenReturn(new ArrayList<>());
115+
116+
EncyptedSaltStoreWriter encryptedSaltStoreWriter = new EncyptedSaltStoreWriter(config, rotatingSaltProvider,
117+
fileManager, taggableCloudStorage, versionGenerator, storeScope, rotatingCloudEncryptionKeyProvider, siteId);
118+
119+
encryptedSaltStoreWriter.upload(snapshot);
120+
121+
verify(taggableCloudStorage).upload(pathCaptor.capture(), any(), any());
122+
verifyFile(pathCaptor.getValue(), snapshot);
123+
}
124+
}

src/test/java/com/uid2/admin/store/writer/SaltStoreWriterTest.java

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)