Skip to content

Commit 18066a7

Browse files
using local date as param
1 parent caf7025 commit 18066a7

File tree

6 files changed

+62
-56
lines changed

6 files changed

+62
-56
lines changed

src/main/java/com/uid2/admin/secret/ISaltRotation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
import com.uid2.shared.store.salt.RotatingSaltProvider;
44

55
import java.time.Duration;
6-
import java.time.Instant;
6+
import java.time.LocalDate;
77

88
public interface ISaltRotation {
99
Result rotateSalts(RotatingSaltProvider.SaltSnapshot lastSnapshot,
1010
Duration[] minAges,
1111
double fraction,
12-
Instant nextEffective) throws Exception;
12+
LocalDate nextEffective) throws Exception;
1313

1414
class Result {
1515
private RotatingSaltProvider.SaltSnapshot snapshot; // can be null if new snapshot is not needed

src/main/java/com/uid2/admin/secret/SaltRotation.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ public SaltRotation(IKeyGenerator keyGenerator) {
2020

2121
@Override
2222
public Result rotateSalts(RotatingSaltProvider.SaltSnapshot lastSnapshot,
23-
Duration[] minAges,
24-
double fraction, Instant nextEffective) throws Exception {
23+
Duration[] minAges,
24+
double fraction,
25+
LocalDate targetDate) throws Exception {
2526

27+
final Instant nextEffective = targetDate.atStartOfDay().toInstant(ZoneOffset.UTC);
2628
final Instant nextExpires = nextEffective.plus(7, ChronoUnit.DAYS);
2729
if (nextEffective.equals(lastSnapshot.getEffective()) || nextEffective.isBefore(lastSnapshot.getEffective())) {
2830
return Result.noSnapshot("cannot create a new salt snapshot with effective timestamp equal or prior to that of an existing snapshot");

src/main/java/com/uid2/admin/vertx/RequestUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,13 @@ public static Optional<Double> getDouble(RoutingContext rc, String paramName) {
231231
}
232232
}
233233

234-
public static Optional<Instant> getInstantFromDate(RoutingContext rc, String paramName, DateTimeFormatter formatter) {
234+
public static Optional<LocalDate> getDate(RoutingContext rc, String paramName, DateTimeFormatter formatter) {
235235
final List<String> values = rc.queryParam(paramName);
236236
if (values.isEmpty()) {
237237
return Optional.empty();
238238
}
239239
try {
240-
return Optional.of(LocalDate.parse(values.get(0), formatter).atStartOfDay().toInstant(ZoneOffset.UTC));
240+
return Optional.of(LocalDate.parse(values.get(0), formatter));
241241
} catch (Exception ex) {
242242
ResponseUtil.error(rc, 400, "failed to parse " + paramName + ": " + ex.getMessage());
243243
return Optional.empty();

src/main/java/com/uid2/admin/vertx/service/SaltService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ private void handleSaltRotate(RoutingContext rc) {
7878
if (!fraction.isPresent()) return;
7979
final Duration[] minAges = RequestUtil.getDurations(rc, "min_ages_in_seconds");
8080
if (minAges == null) return;
81-
final Instant targetDate = RequestUtil.getInstantFromDate(rc, "target_date", DateTimeFormatter.ISO_LOCAL_DATE)
82-
.orElse(Instant.now().plus(1, ChronoUnit.DAYS).truncatedTo(ChronoUnit.DAYS));
81+
final LocalDate targetDate = RequestUtil.getDate(rc, "target_date", DateTimeFormatter.ISO_LOCAL_DATE)
82+
.orElse(LocalDate.now(Clock.systemUTC()).plusDays(1));
8383

8484
// force refresh
8585
this.saltProvider.loadContent();

src/test/java/com/uid2/admin/secret/SaltRotationTest.java

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ public class SaltRotationTest {
2424
@Mock private IKeyGenerator keyGenerator;
2525
private SaltRotation saltRotation;
2626

27-
private final Instant targetDate = Instant.now().truncatedTo(ChronoUnit.DAYS);
27+
private final LocalDate targetDate = LocalDate.of(2025, 1, 1);
28+
private final Instant targetDateAsInstant = targetDate.atStartOfDay().toInstant(ZoneOffset.UTC);
2829

2930
@BeforeEach
3031
void setup() throws Exception {
@@ -70,13 +71,13 @@ void rotateSaltsLastSnapshotIsUpToDate() throws Exception {
7071
Duration.ofDays(2),
7172
};
7273
final RotatingSaltProvider.SaltSnapshot lastSnapshot = SnapshotBuilder.start()
73-
.withEntries(10, targetDate)
74-
.build(targetDate,
75-
targetDate.plus(7, ChronoUnit.DAYS));
74+
.withEntries(10, targetDateAsInstant)
75+
.build(targetDateAsInstant,
76+
targetDateAsInstant.plus(7, ChronoUnit.DAYS));
7677

7778
final ISaltRotation.Result result1 = saltRotation.rotateSalts(lastSnapshot, minAges, 0.2, targetDate);
7879
assertFalse(result1.hasSnapshot());
79-
final ISaltRotation.Result result2 = saltRotation.rotateSalts(lastSnapshot, minAges, 0.2, targetDate.minus(1, ChronoUnit.DAYS));
80+
final ISaltRotation.Result result2 = saltRotation.rotateSalts(lastSnapshot, minAges, 0.2, targetDate.minusDays(1));
8081
assertFalse(result2.hasSnapshot());
8182
}
8283

@@ -88,9 +89,9 @@ void rotateSaltsAllSaltsUpToDate() throws Exception {
8889
};
8990

9091
final RotatingSaltProvider.SaltSnapshot lastSnapshot = SnapshotBuilder.start()
91-
.withEntries(10, targetDate.minus(1, ChronoUnit.DAYS))
92-
.build(targetDate.minus(1, ChronoUnit.DAYS),
93-
targetDate.plus(6, ChronoUnit.DAYS));
92+
.withEntries(10, targetDateAsInstant)
93+
.build(targetDateAsInstant.minus(1, ChronoUnit.DAYS),
94+
targetDateAsInstant.plus(6, ChronoUnit.DAYS));
9495

9596
final ISaltRotation.Result result = saltRotation.rotateSalts(lastSnapshot, minAges, 0.2, targetDate);
9697
assertFalse(result.hasSnapshot());
@@ -104,17 +105,18 @@ void rotateSaltsAllSaltsOld() throws Exception {
104105
Duration.ofDays(2),
105106
};
106107

108+
final Instant entryLastUpdated = targetDateAsInstant.minus(10, ChronoUnit.DAYS);
107109
final RotatingSaltProvider.SaltSnapshot lastSnapshot = SnapshotBuilder.start()
108-
.withEntries(10, targetDate.minus(2, ChronoUnit.DAYS))
109-
.build(targetDate.minus(1, ChronoUnit.DAYS),
110-
targetDate.plus(6, ChronoUnit.DAYS));
110+
.withEntries(10, entryLastUpdated)
111+
.build(targetDateAsInstant.minus(1, ChronoUnit.DAYS),
112+
targetDateAsInstant.plus(6, ChronoUnit.DAYS));
111113

112114
final ISaltRotation.Result result = saltRotation.rotateSalts(lastSnapshot, minAges, 0.2, targetDate);
113115
assertTrue(result.hasSnapshot());
114116
assertEquals(2, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), result.getSnapshot().getEffective()));
115-
assertEquals(8, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), targetDate.minus(2, ChronoUnit.DAYS)));
116-
assertEquals(targetDate, result.getSnapshot().getEffective());
117-
assertEquals(targetDate.plus(7, ChronoUnit.DAYS), result.getSnapshot().getExpires());
117+
assertEquals(8, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), entryLastUpdated));
118+
assertEquals(targetDateAsInstant, result.getSnapshot().getEffective());
119+
assertEquals(targetDateAsInstant.plus(7, ChronoUnit.DAYS), result.getSnapshot().getExpires());
118120
verify(keyGenerator, times(2)).generateRandomKeyString(anyInt());
119121
}
120122

@@ -125,24 +127,24 @@ void rotateSaltsRotateSaltsFromOldestBucketOnly() throws Exception {
125127
Duration.ofDays(4),
126128
};
127129

128-
final Instant lastUpdated1 = targetDate.minus(6, ChronoUnit.DAYS);
129-
final Instant lastUpdated2 = targetDate.minus(5, ChronoUnit.DAYS);
130-
final Instant lastUpdated3 = targetDate.minus(4, ChronoUnit.DAYS);
130+
final Instant lastUpdated1 = targetDateAsInstant.minus(6, ChronoUnit.DAYS);
131+
final Instant lastUpdated2 = targetDateAsInstant.minus(5, ChronoUnit.DAYS);
132+
final Instant lastUpdated3 = targetDateAsInstant.minus(4, ChronoUnit.DAYS);
131133
final RotatingSaltProvider.SaltSnapshot lastSnapshot = SnapshotBuilder.start()
132134
.withEntries(3, lastUpdated1)
133135
.withEntries(5, lastUpdated2)
134136
.withEntries(2, lastUpdated3)
135-
.build(targetDate.minus(1, ChronoUnit.DAYS),
136-
targetDate.plus(6, ChronoUnit.DAYS));
137+
.build(targetDateAsInstant.minus(1, ChronoUnit.DAYS),
138+
targetDateAsInstant.plus(6, ChronoUnit.DAYS));
137139

138140
final ISaltRotation.Result result = saltRotation.rotateSalts(lastSnapshot, minAges, 0.2, targetDate);
139141
assertTrue(result.hasSnapshot());
140142
assertEquals(2, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), result.getSnapshot().getEffective()));
141143
assertEquals(1, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated1));
142144
assertEquals(5, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated2));
143145
assertEquals(2, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated3));
144-
assertEquals(targetDate, result.getSnapshot().getEffective());
145-
assertEquals(targetDate.plus(7, ChronoUnit.DAYS), result.getSnapshot().getExpires());
146+
assertEquals(targetDateAsInstant, result.getSnapshot().getEffective());
147+
assertEquals(targetDateAsInstant.plus(7, ChronoUnit.DAYS), result.getSnapshot().getExpires());
146148
verify(keyGenerator, times(2)).generateRandomKeyString(anyInt());
147149
}
148150

@@ -153,21 +155,21 @@ void rotateSaltsRotateSaltsFromNewerBucketOnly() throws Exception {
153155
Duration.ofDays(3),
154156
};
155157

156-
final Instant lastUpdated1 = targetDate.minus(4, ChronoUnit.DAYS);
157-
final Instant lastUpdated2 = targetDate.minus(3, ChronoUnit.DAYS);
158+
final Instant lastUpdated1 = targetDateAsInstant.minus(4, ChronoUnit.DAYS);
159+
final Instant lastUpdated2 = targetDateAsInstant.minus(3, ChronoUnit.DAYS);
158160
final RotatingSaltProvider.SaltSnapshot lastSnapshot = SnapshotBuilder.start()
159161
.withEntries(3, lastUpdated1)
160162
.withEntries(7, lastUpdated2)
161-
.build(targetDate.minus(1, ChronoUnit.DAYS),
162-
targetDate.plus(6, ChronoUnit.DAYS));
163+
.build(targetDateAsInstant.minus(1, ChronoUnit.DAYS),
164+
targetDateAsInstant.plus(6, ChronoUnit.DAYS));
163165

164166
final ISaltRotation.Result result = saltRotation.rotateSalts(lastSnapshot, minAges, 0.2, targetDate);
165167
assertTrue(result.hasSnapshot());
166168
assertEquals(2, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), result.getSnapshot().getEffective()));
167169
assertEquals(1, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated1));
168170
assertEquals(7, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated2));
169-
assertEquals(targetDate, result.getSnapshot().getEffective());
170-
assertEquals(targetDate.plus(7, ChronoUnit.DAYS), result.getSnapshot().getExpires());
171+
assertEquals(targetDateAsInstant, result.getSnapshot().getEffective());
172+
assertEquals(targetDateAsInstant.plus(7, ChronoUnit.DAYS), result.getSnapshot().getExpires());
171173
verify(keyGenerator, times(2)).generateRandomKeyString(anyInt());
172174
}
173175

@@ -178,24 +180,24 @@ void rotateSaltsRotateSaltsFromMultipleBuckets() throws Exception {
178180
Duration.ofDays(4),
179181
};
180182

181-
final Instant lastUpdated1 = targetDate.minus(6, ChronoUnit.DAYS);
182-
final Instant lastUpdated2 = targetDate.minus(5, ChronoUnit.DAYS);
183-
final Instant lastUpdated3 = targetDate.minus(4, ChronoUnit.DAYS);
183+
final Instant lastUpdated1 = targetDateAsInstant.minus(6, ChronoUnit.DAYS);
184+
final Instant lastUpdated2 = targetDateAsInstant.minus(5, ChronoUnit.DAYS);
185+
final Instant lastUpdated3 = targetDateAsInstant.minus(4, ChronoUnit.DAYS);
184186
final RotatingSaltProvider.SaltSnapshot lastSnapshot = SnapshotBuilder.start()
185187
.withEntries(3, lastUpdated1)
186188
.withEntries(5, lastUpdated2)
187189
.withEntries(2, lastUpdated3)
188-
.build(targetDate.minus(1, ChronoUnit.DAYS),
189-
targetDate.plus(6, ChronoUnit.DAYS));
190+
.build(targetDateAsInstant.minus(1, ChronoUnit.DAYS),
191+
targetDateAsInstant.plus(6, ChronoUnit.DAYS));
190192

191193
final ISaltRotation.Result result = saltRotation.rotateSalts(lastSnapshot, minAges, 0.45, targetDate);
192194
assertTrue(result.hasSnapshot());
193195
assertEquals(5, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), result.getSnapshot().getEffective()));
194196
assertEquals(0, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated1));
195197
assertEquals(3, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated2));
196198
assertEquals(2, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated3));
197-
assertEquals(targetDate, result.getSnapshot().getEffective());
198-
assertEquals(targetDate.plus(7, ChronoUnit.DAYS), result.getSnapshot().getExpires());
199+
assertEquals(targetDateAsInstant, result.getSnapshot().getEffective());
200+
assertEquals(targetDateAsInstant.plus(7, ChronoUnit.DAYS), result.getSnapshot().getExpires());
199201
verify(keyGenerator, times(5)).generateRandomKeyString(anyInt());
200202
}
201203

@@ -206,24 +208,24 @@ void rotateSaltsRotateSaltsInsufficientOutdatedSalts() throws Exception {
206208
Duration.ofDays(3),
207209
};
208210

209-
final Instant lastUpdated1 = targetDate.minus(5, ChronoUnit.DAYS);
210-
final Instant lastUpdated2 = targetDate.minus(4, ChronoUnit.DAYS);
211-
final Instant lastUpdated3 = targetDate.minus(2, ChronoUnit.DAYS);
211+
final Instant lastUpdated1 = targetDateAsInstant.minus(5, ChronoUnit.DAYS);
212+
final Instant lastUpdated2 = targetDateAsInstant.minus(4, ChronoUnit.DAYS);
213+
final Instant lastUpdated3 = targetDateAsInstant.minus(2, ChronoUnit.DAYS);
212214
final RotatingSaltProvider.SaltSnapshot lastSnapshot = SnapshotBuilder.start()
213215
.withEntries(1, lastUpdated1)
214216
.withEntries(2, lastUpdated2)
215217
.withEntries(7, lastUpdated3)
216-
.build(targetDate.minus(1, ChronoUnit.DAYS),
217-
targetDate.plus(6, ChronoUnit.DAYS));
218+
.build(targetDateAsInstant.minus(1, ChronoUnit.DAYS),
219+
targetDateAsInstant.plus(6, ChronoUnit.DAYS));
218220

219221
final ISaltRotation.Result result = saltRotation.rotateSalts(lastSnapshot, minAges, 0.45, targetDate);
220222
assertTrue(result.hasSnapshot());
221223
assertEquals(3, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), result.getSnapshot().getEffective()));
222224
assertEquals(0, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated1));
223225
assertEquals(0, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated2));
224226
assertEquals(7, countEntriesWithLastUpdated(result.getSnapshot().getAllRotatingSalts(), lastUpdated3));
225-
assertEquals(targetDate, result.getSnapshot().getEffective());
226-
assertEquals(targetDate.plus(7, ChronoUnit.DAYS), result.getSnapshot().getExpires());
227+
assertEquals(targetDateAsInstant, result.getSnapshot().getEffective());
228+
assertEquals(targetDateAsInstant.plus(7, ChronoUnit.DAYS), result.getSnapshot().getExpires());
227229
verify(keyGenerator, times(3)).generateRandomKeyString(anyInt());
228230
}
229231
}

src/test/java/com/uid2/admin/vertx/SaltServiceTest.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.mockito.Mock;
1515

1616
import java.time.Instant;
17+
import java.time.LocalDate;
1718
import java.time.LocalDateTime;
1819
import java.time.ZoneOffset;
1920
import java.time.temporal.ChronoUnit;
@@ -98,7 +99,7 @@ void rotateSalts(Vertx vertx, VertxTestContext testContext) throws Exception {
9899
final RotatingSaltProvider.SaltSnapshot[] addedSnapshots = {
99100
makeSnapshot(Instant.ofEpochMilli(10004), Instant.ofEpochMilli(20004), 10),
100101
};
101-
when(saltRotation.rotateSalts(any(), any(), eq(0.2), eq(Instant.now().truncatedTo(ChronoUnit.DAYS).plusSeconds(86400)))).thenReturn(ISaltRotation.Result.fromSnapshot(addedSnapshots[0]));
102+
when(saltRotation.rotateSalts(any(), any(), eq(0.2), eq(LocalDate.now().plusDays(1)))).thenReturn(ISaltRotation.Result.fromSnapshot(addedSnapshots[0]));
102103

103104
post(vertx, testContext, "api/salt/rotate?min_ages_in_seconds=50,60,70&fraction=0.2", "", response -> {
104105
assertEquals(200, response.statusCode());
@@ -120,7 +121,7 @@ void rotateSaltsNoNewSnapshot(Vertx vertx, VertxTestContext testContext) throws
120121
};
121122
setSnapshots(snapshots);
122123

123-
when(saltRotation.rotateSalts(any(), any(), eq(0.2), eq(Instant.now().truncatedTo(ChronoUnit.DAYS).plusSeconds(86400)))).thenReturn(ISaltRotation.Result.noSnapshot("test"));
124+
when(saltRotation.rotateSalts(any(), any(), eq(0.2), eq(LocalDate.now().plusDays(1)))).thenReturn(ISaltRotation.Result.noSnapshot("test"));
124125

125126
post(vertx, testContext, "api/salt/rotate?min_ages_in_seconds=50,60,70&fraction=0.2", "", response -> {
126127
assertEquals(200, response.statusCode());
@@ -135,16 +136,17 @@ void rotateSaltsNoNewSnapshot(Vertx vertx, VertxTestContext testContext) throws
135136
@Test
136137
void rotateSaltsWitnSpecificTargetDate(Vertx vertx, VertxTestContext testContext) throws Exception {
137138
fakeAuth(Role.SUPER_USER);
138-
Instant targetDate = LocalDateTime.of(2025, 5, 8, 0, 0).toInstant(ZoneOffset.UTC);
139+
LocalDate targetDate = LocalDate.of(2025, 5, 8);
140+
Instant targetDateAsInstant = targetDate.atStartOfDay().toInstant(ZoneOffset.UTC);
139141
final RotatingSaltProvider.SaltSnapshot[] snapshots = {
140-
makeSnapshot(targetDate.minus(5, ChronoUnit.DAYS), targetDate.minus(4, ChronoUnit.DAYS), 10),
141-
makeSnapshot(targetDate.minus(4, ChronoUnit.DAYS), targetDate.minus(3, ChronoUnit.DAYS), 10),
142-
makeSnapshot(targetDate.minus(3, ChronoUnit.DAYS), targetDate.minus(2, ChronoUnit.DAYS), 10),
142+
makeSnapshot(targetDateAsInstant.minus(5, ChronoUnit.DAYS), targetDateAsInstant.minus(4, ChronoUnit.DAYS), 10),
143+
makeSnapshot(targetDateAsInstant.minus(4, ChronoUnit.DAYS), targetDateAsInstant.minus(3, ChronoUnit.DAYS), 10),
144+
makeSnapshot(targetDateAsInstant.minus(3, ChronoUnit.DAYS), targetDateAsInstant.minus(2, ChronoUnit.DAYS), 10),
143145
};
144146
setSnapshots(snapshots);
145147

146148
final RotatingSaltProvider.SaltSnapshot[] addedSnapshots = {
147-
makeSnapshot(targetDate, targetDate.plus(1, ChronoUnit.DAYS), 10),
149+
makeSnapshot(targetDateAsInstant, targetDateAsInstant.plus(1, ChronoUnit.DAYS), 10),
148150
};
149151

150152
when(saltRotation.rotateSalts(any(), any(), eq(0.2), eq(targetDate))).thenReturn(ISaltRotation.Result.fromSnapshot(addedSnapshots[0]));

0 commit comments

Comments
 (0)