1- package com .uid2 .shared .store ;
1+ package com .uid2 .shared .store . salt ;
22
33import com .uid2 .shared .Utils ;
44import com .uid2 .shared .attest .UidCoreClient ;
1010import lombok .Getter ;
1111import org .slf4j .Logger ;
1212import org .slf4j .LoggerFactory ;
13- import org .hashids .Hashids ;
1413
1514import java .io .BufferedReader ;
1615import java .io .IOException ;
4140 ]
4241 }
4342
44- 2. salt file format
45- <id>, <hash_id>, <salt >
46- 9000099,1614556800000,salt
43+ 2. currentSalt file format
44+ <id>, <hash_id>, <currentSalt >
45+ 9000099,1614556800000,currentSalt
4746 */
4847public class RotatingSaltProvider implements ISaltProvider , IMetadataVersionedStore {
4948 private static final Logger LOGGER = LoggerFactory .getLogger (RotatingSaltProvider .class );
@@ -80,14 +79,14 @@ public long getVersion(JsonObject metadata) {
8079 public long loadContent (JsonObject metadata ) throws Exception {
8180 final JsonArray salts = metadata .getJsonArray ("salts" );
8281 final String firstLevelSalt = metadata .getString ("first_level" );
83- final SaltEntryBuilder entryBuilder = new SaltEntryBuilder (
82+ final SaltFileParser saltFileParser = new SaltFileParser (
8483 new IdHashingScheme (metadata .getString ("id_prefix" ), metadata .getString ("id_secret" )));
8584 final Instant now = Instant .now ();
8685 final List <SaltSnapshot > snapshots = new ArrayList <>();
8786
8887 int saltCount = 0 ;
8988 for (int i = 0 ; i < salts .size (); ++i ) {
90- final SaltSnapshot snapshot = this .loadSnapshot (salts .getJsonObject (i ), firstLevelSalt , entryBuilder , now );
89+ final SaltSnapshot snapshot = this .loadSnapshot (salts .getJsonObject (i ), firstLevelSalt , saltFileParser , now );
9190 if (snapshot == null ) continue ;
9291 snapshots .add (snapshot );
9392
@@ -120,33 +119,26 @@ public ISaltSnapshot getSnapshot(Instant asOf) {
120119 if (!snapshot .isEffective (asOf )) break ;
121120 current = snapshot ;
122121 }
123- return current != null ? current : snapshots .get ( snapshots . size () - 1 );
122+ return current != null ? current : snapshots .getLast ( );
124123 }
125124
126- private SaltSnapshot loadSnapshot (JsonObject spec , String firstLevelSalt , SaltEntryBuilder entryBuilder , Instant now ) throws Exception {
125+ private SaltSnapshot loadSnapshot (JsonObject spec , String firstLevelSalt , SaltFileParser saltFileParser , Instant now ) throws Exception {
127126 final Instant defaultExpires = now .plus (365 , ChronoUnit .DAYS );
128127 final Instant effective = Instant .ofEpochMilli (spec .getLong ("effective" ));
129128 final Instant expires = Instant .ofEpochMilli (spec .getLong ("expires" , defaultExpires .toEpochMilli ()));
130129
131130 final String path = spec .getString ("location" );
132131 Integer size = spec .getInteger ("size" );
133- SaltEntry [] entries = readInputStream (this .contentStreamProvider .download (path ), entryBuilder , size );
132+ SaltEntry [] entries = readInputStream (this .contentStreamProvider .download (path ), saltFileParser , size );
134133
135134 LOGGER .info ("Loaded {} salts" , size );
136135 return new SaltSnapshot (effective , expires , entries , firstLevelSalt );
137136 }
138137
139- protected SaltEntry [] readInputStream (InputStream inputStream , SaltEntryBuilder entryBuilder , Integer size ) throws IOException {
138+ protected SaltEntry [] readInputStream (InputStream inputStream , SaltFileParser saltFileParser , Integer size ) throws IOException {
140139 try (BufferedReader reader = new BufferedReader (new InputStreamReader (inputStream , StandardCharsets .UTF_8 ))) {
141- String line ;
142- SaltEntry [] entries = new SaltEntry [size ];
143- int idx = 0 ;
144- while ((line = reader .readLine ()) != null ) {
145- final SaltEntry entry = entryBuilder .toEntry (line );
146- entries [idx ] = entry ;
147- idx ++;
148- }
149- return entries ;
140+ String [] saltFileLines = reader .lines ().toArray (String []::new );
141+ return saltFileParser .parseFileLines (saltFileLines , size );
150142 }
151143 }
152144
@@ -167,10 +159,10 @@ public SaltSnapshot(Instant effective, Instant expires, SaltEntry[] entries, Str
167159 this .entries = entries ;
168160 this .firstLevelSalt = firstLevelSalt ;
169161 if (entries .length == 1_048_576 ) {
170- LOGGER .info ("Total salt entries 1 million, {}, special production salt entry indexer" , entries .length );
162+ LOGGER .info ("Total currentSalt entries 1 million, {}, special production currentSalt entry indexer" , entries .length );
171163 this .saltEntryIndexer = MILLION_ENTRY_INDEXER ;
172164 } else {
173- LOGGER .warn ("Total salt entries {}, using slower mod-based indexer" , entries .length );
165+ LOGGER .warn ("Total currentSalt entries {}, using slower mod-based indexer" , entries .length );
174166 this .saltEntryIndexer = MOD_BASED_INDEXER ;
175167 }
176168 }
@@ -203,42 +195,8 @@ public SaltEntry getRotatingSalt(byte[] identity) {
203195 @ Override
204196 public List <SaltEntry > getModifiedSince (Instant timestamp ) {
205197 final long timestampMillis = timestamp .toEpochMilli ();
206- return Arrays .stream (this .entries ).filter (e -> e .getLastUpdated () >= timestampMillis ).collect (Collectors .toList ());
207- }
208- }
209-
210- protected static final class IdHashingScheme {
211- private final String prefix ;
212- private final Hashids hasher ;
213-
214- public IdHashingScheme (final String prefix , final String secret ) {
215- this .prefix = prefix ;
216- this .hasher = new Hashids (secret , 9 );
217- }
218-
219- public String encode (long id ) {
220- return prefix + this .hasher .encode (id );
198+ return Arrays .stream (this .entries ).filter (e -> e .lastUpdated () >= timestampMillis ).collect (Collectors .toList ());
221199 }
222200 }
223201
224- protected static final class SaltEntryBuilder {
225- private final IdHashingScheme idHashingScheme ;
226-
227- public SaltEntryBuilder (IdHashingScheme idHashingScheme ) {
228- this .idHashingScheme = idHashingScheme ;
229- }
230-
231- public SaltEntry toEntry (String line ) {
232- try {
233- final String [] fields = line .split ("," );
234- final long id = Integer .parseInt (fields [0 ]);
235- final String hashedId = this .idHashingScheme .encode (id );
236- final long lastUpdated = Long .parseLong (fields [1 ]);
237- final String salt = fields [2 ];
238- return new SaltEntry (id , hashedId , lastUpdated , salt );
239- } catch (Exception e ) {
240- throw new RuntimeException ("Trouble parsing Salt Entry " + line , e );
241- }
242- }
243- }
244202}
0 commit comments