Skip to content

Commit 7fd2a48

Browse files
Provide a way to use client with already hashed emails and phones (#24)
1 parent 2d197d4 commit 7fd2a48

File tree

3 files changed

+81
-19
lines changed

3 files changed

+81
-19
lines changed

src/main/java/com/uid2/client/InputUtil.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.uid2.client;
22

3+
import java.security.MessageDigest;
34
import java.util.Base64;
45

56
public class InputUtil { //from https://github.com/IABTechLab/uid2-operator/blob/master/src/main/java/com/uid2/operator/service/InputUtil.java
@@ -122,6 +123,21 @@ static boolean isAsciiDigit(char d)
122123

123124
static byte[] base64ToByteArray(String str) { return Base64.getDecoder().decode(str); }
124125
static String byteArrayToBase64(byte[] b) { return Base64.getEncoder().encodeToString(b); }
126+
127+
128+
static String getBase64EncodedHash(String input) {
129+
return byteArrayToBase64(getSha256Bytes(input));
130+
}
131+
132+
static byte[] getSha256Bytes(String input) {
133+
try {
134+
MessageDigest md = MessageDigest.getInstance("SHA-256");
135+
md.update(input.getBytes());
136+
return md.digest();
137+
} catch (Exception e) {
138+
throw new Uid2Exception("Trouble Generating SHA256", e);
139+
}
140+
}
125141
}
126142

127143

src/main/java/com/uid2/client/TokenGenerateInput.java

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,31 @@ public class TokenGenerateInput {
1010
* @return a TokenGenerateInput instance, to be used in {@link PublisherUid2Helper#createEnvelopeForTokenGenerateRequest}
1111
*/
1212
public static TokenGenerateInput fromEmail(String email) {
13-
return new TokenGenerateInput(IdentityType.Email, email, true);
13+
return new TokenGenerateInput(IdentityType.Email, email, true, false);
1414
}
1515

1616
/**
1717
* @param phone a <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#phone-number-normalization">normalized</a> phone number
1818
* @return a TokenGenerateInput instance, to be used in {@link PublisherUid2Helper#createEnvelopeForTokenGenerateRequest}
1919
*/
2020
public static TokenGenerateInput fromPhone(String phone) {
21-
return new TokenGenerateInput(IdentityType.Phone, phone, true);
21+
return new TokenGenerateInput(IdentityType.Phone, phone, true, false);
22+
}
23+
24+
/**
25+
* @param hashedEmail a <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#email-address-normalization">normalized</a> and <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#email-address-hash-encoding">hashed</a> email address
26+
* @return a TokenGenerateInput instance, to be used in {@link PublisherUid2Helper#createEnvelopeForTokenGenerateRequest}
27+
*/
28+
public static TokenGenerateInput fromHashedEmail(String hashedEmail) {
29+
return new TokenGenerateInput(IdentityType.Email, hashedEmail, false, true);
30+
}
31+
32+
/**
33+
* @param hashedPhone a <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#phone-number-normalization">normalized</a> and <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#phone-number-hash-encoding">hashed</a> phone number
34+
* @return a TokenGenerateInput instance, to be used in {@link PublisherUid2Helper#createEnvelopeForTokenGenerateRequest}
35+
*/
36+
public static TokenGenerateInput fromHashedPhone(String hashedPhone) {
37+
return new TokenGenerateInput(IdentityType.Phone, hashedPhone, false, true);
2238
}
2339

2440
/**
@@ -36,32 +52,22 @@ TokenGenerateInput doNotHash() {
3652
}
3753

3854
String getAsJsonString() {
39-
if (needHash) {
55+
if (alreadyHashed) {
56+
return createAlreadyHashedJsonRequestForGenerateToken(identityType, emailOrPhone, transparencyAndConsentString);
57+
} else if (needHash) {
4058
return createHashedJsonRequestForGenerateToken(identityType, emailOrPhone, transparencyAndConsentString);
4159
} else {
4260
return createJsonRequestForGenerateToken(identityType, emailOrPhone, transparencyAndConsentString);
4361
}
4462
}
4563

46-
private TokenGenerateInput(IdentityType identityType, String emailOrPhone, boolean needHash) {
64+
private TokenGenerateInput(IdentityType identityType, String emailOrPhone, boolean needHash, boolean alreadyHashed) {
4765
this.identityType = identityType;
4866
this.emailOrPhone = emailOrPhone;
4967
this.needHash = needHash;
68+
this.alreadyHashed = alreadyHashed;
5069
}
5170

52-
private static String getBase64EncodedHash(String input) {
53-
return InputUtil.byteArrayToBase64(getSha256Bytes(input));
54-
}
55-
56-
private static byte[] getSha256Bytes(String input) {
57-
try {
58-
MessageDigest md = MessageDigest.getInstance("SHA-256");
59-
md.update(input.getBytes());
60-
return md.digest();
61-
} catch (Exception e) {
62-
throw new Uid2Exception("Trouble Generating SHA256", e);
63-
}
64-
}
6571

6672

6773
private static String createJsonRequestForGenerateToken(IdentityType identityType, String value, String tcString) {
@@ -86,20 +92,31 @@ static String createHashedJsonRequestForGenerateToken(IdentityType identityType,
8692
if (normalizedEmail == null) {
8793
throw new IllegalArgumentException("invalid email address");
8894
}
89-
String hashedNormalizedEmail = getBase64EncodedHash(normalizedEmail);
95+
String hashedNormalizedEmail = InputUtil.getBase64EncodedHash(normalizedEmail);
9096
return createJsonRequestForGenerateToken("email_hash", hashedNormalizedEmail, tcString);
9197
} else { //phone
9298
if (!InputUtil.isPhoneNumberNormalized(unhashedValue)) {
9399
throw new IllegalArgumentException("phone number is not normalized");
94100
}
95101

96-
String hashedNormalizedPhone = getBase64EncodedHash(unhashedValue);
102+
String hashedNormalizedPhone = InputUtil.getBase64EncodedHash(unhashedValue);
97103
return createJsonRequestForGenerateToken("phone_hash", hashedNormalizedPhone, tcString);
98104
}
99105
}
100106

107+
static String createAlreadyHashedJsonRequestForGenerateToken(IdentityType identityType, String hashedValue, String tcString) {
108+
if (identityType == IdentityType.Email) {
109+
return createJsonRequestForGenerateToken("email_hash", hashedValue, tcString);
110+
} else { //phone
111+
return createJsonRequestForGenerateToken("phone_hash", hashedValue, tcString);
112+
}
113+
}
114+
101115
private final IdentityType identityType;
102116
private final String emailOrPhone;
103117
private boolean needHash;
118+
private boolean alreadyHashed;
104119
private String transparencyAndConsentString;
120+
121+
105122
}

src/test/java/com/uid2/client/PublisherTests.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,18 @@ private EnvelopeV2 createEnvelopeForTokenGenerateRequest(IdentityType identityTy
189189
return envelope;
190190
}
191191

192+
private EnvelopeV2 createEnvelopeFromHashedValue(IdentityType identityType, String value, String tcString) {
193+
TokenGenerateInput tokenGenerateInput;
194+
if (identityType == IdentityType.Email) {
195+
tokenGenerateInput = TokenGenerateInput.fromHashedEmail(value).withTransparencyAndConsentString(tcString);
196+
} else {
197+
tokenGenerateInput = TokenGenerateInput.fromHashedPhone(value).withTransparencyAndConsentString(tcString);
198+
}
199+
final EnvelopeV2 envelope = createEnvelopeFromIdentityInput(tokenGenerateInput);
200+
assertEquals(nonce, envelope.getNonce());
201+
return envelope;
202+
}
203+
192204
private String createEnvelopeString(IdentityType identityType, String value, String tcString, boolean hash) {
193205
return createEnvelopeForTokenGenerateRequest(identityType, value, tcString, hash).getEnvelope();
194206
}
@@ -223,6 +235,15 @@ public void hashedEmail() { //https://unifiedid.com/docs/getting-started/gs-norm
223235
assertEquals(expectedEnvelope, envelopeWhenUsingUnnormalizedEmail);
224236
}
225237

238+
@Test
239+
public void alreadyHashedEmail() { //https://unifiedid.com/docs/getting-started/gs-normalization-encoding#email-address-hash-encoding
240+
String normalizedEmail = "user@example.com";
241+
final String expectedEnvelope = createEnvelopeString(IdentityType.Email, normalizedEmail, null, true);
242+
final String envelope = createEnvelopeFromHashedValue(IdentityType.Email, InputUtil.getBase64EncodedHash(normalizedEmail), null).getEnvelope();
243+
assertEquals(expectedEnvelope, envelope);
244+
}
245+
246+
226247
@Test
227248
public void hashedGmail() { //hhttps://unifiedid.com/docs/getting-started/gs-normalization-encoding#email-address-hash-encoding
228249
final String envelope = createEnvelopeString(IdentityType.Email, "janedoe@gmail.com", null, true);
@@ -248,6 +269,14 @@ public void hashedPhone() { //https://unifiedid.com/docs/getting-started/gs-norm
248269
assertEquals("Acw8ysqYieqzgA54fifdV1TB6V+da8p/AFc8Ju/IYqX+4JXyWNFKiMt7QbMMm27H3fmEq2zPRUnXdFpLTdVdc0RNWxOruBaarHYQksdqpbkVFa+walbcj6AClILBJjbDMl1IoeqJVG2fyw==", envelope);
249270
}
250271

272+
@Test
273+
public void alreadyHashedPhone() { //https://unifiedid.com/docs/getting-started/gs-normalization-encoding#phone-number-hash-encoding
274+
String normalizedPhone = "+12345678901";
275+
final String expectedEnvelope = createEnvelopeString(IdentityType.Phone, normalizedPhone, null, true);
276+
final String envelope = createEnvelopeFromHashedValue(IdentityType.Phone, InputUtil.getBase64EncodedHash(normalizedPhone), null).getEnvelope();
277+
assertEquals(expectedEnvelope, envelope);
278+
}
279+
251280
@Test
252281
public void decryptGenerateResponse() {
253282
final EnvelopeV2 envelope = createEnvelopeForTokenGenerateRequest(IdentityType.Email, "test@example.com", null, true);

0 commit comments

Comments
 (0)