Skip to content

Commit 61f6333

Browse files
Token generation policy (#26)
* Provide a way to pass token generation policy * Added generateTokenResponse methods to allow for handling optout Old 'generateToken' method was not capable of handling optout responses when user requested that no tokens should be generated if user had optedout. The new class TokenGenerateResponse works in similar way as TokenRefreshResponse, providing a way to check if response is opted out or successful * Fixed javadoc for PublisherUid2Client * Added integration test for not generating tokens on optout
1 parent 6ee9102 commit 61f6333

File tree

5 files changed

+207
-40
lines changed

5 files changed

+207
-40
lines changed

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import okhttp3.*;
44

5-
import java.io.*;
5+
import java.io.IOException;
66

77

88
public class PublisherUid2Client {
@@ -21,7 +21,9 @@ public PublisherUid2Client(String uid2BaseUrl, String clientApiKey, String base6
2121
* @param tokenGenerateInput represents the input required for <a href="https://unifiedid.com/docs/endpoints/post-token-generate#unencrypted-json-body-parameters">/token/generate</a>
2222
* @return an IdentityTokens instance
2323
* @throws Uid2Exception if the response did not contain a "success" status, or the response code was not 200, or there was an error communicating with the provided UID2 Base URL
24+
* @deprecated Use {@link PublisherUid2Client#generateTokenResponse}
2425
*/
26+
@Deprecated
2527
public IdentityTokens generateToken(TokenGenerateInput tokenGenerateInput) {
2628
EnvelopeV2 envelope = publisherUid2Helper.createEnvelopeForTokenGenerateRequest(tokenGenerateInput);
2729

@@ -44,6 +46,33 @@ public IdentityTokens generateToken(TokenGenerateInput tokenGenerateInput) {
4446
}
4547
}
4648

49+
/**
50+
* @param tokenGenerateInput represents the input required for <a href="https://unifiedid.com/docs/endpoints/post-token-generate#unencrypted-json-body-parameters">/token/generate</a>
51+
* @return an TokenGenerateResponse instance, which will contain an IdentityTokens instance, if successful.
52+
* @throws Uid2Exception if the response did not contain a "success" or "optout" status, or the response code was not 200, or there was an error communicating with the provided UID2 Base URL
53+
*/
54+
public TokenGenerateResponse generateTokenResponse(TokenGenerateInput tokenGenerateInput) {
55+
EnvelopeV2 envelope = publisherUid2Helper.createEnvelopeForTokenGenerateRequest(tokenGenerateInput);
56+
57+
Request request = new Request.Builder()
58+
.url(uid2BaseUrl + "/v2/token/generate")
59+
.headers(headers)
60+
.post(RequestBody.create(envelope.getEnvelope(), FORM))
61+
.build();
62+
63+
64+
try (Response response = client.newCall(request).execute()) {
65+
if (!response.isSuccessful()) {
66+
throw new Uid2Exception("Unexpected code " + response);
67+
}
68+
69+
String responseString = response.body() != null ? response.body().string() : "";
70+
return publisherUid2Helper.createTokenGenerateResponse(responseString, envelope);
71+
} catch (IOException e) {
72+
throw new Uid2Exception("Error communicating with api endpoint", e);
73+
}
74+
}
75+
4776
/**
4877
* @param currentIdentity the current IdentityTokens instance, typically retrieved from a user's session
4978
* @return the refreshed IdentityTokens instance (with a new advertising token and updated expiry times). Typically, this will be used to replace the current identity in the user's session

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ public EnvelopeV2 createEnvelopeForTokenGenerateRequest(TokenGenerateInput token
3434
}
3535

3636
/**
37+
* @deprecated Use {@link PublisherUid2Helper#createTokenGenerateResponse}
3738
* @param response the response body returned by a call to <a href="https://unifiedid.com/docs/endpoints/post-token-generate">/token/generate</a>
3839
* @param envelope the EnvelopeV2 instance returned by {@link #createEnvelopeForTokenGenerateRequest}
3940
* @return an IdentityTokens instance
4041
* @throws Uid2Exception if the response did not contain a "success" status
4142
*/
43+
@Deprecated
4244
public IdentityTokens createIdentityfromTokenGenerateResponse(String response, EnvelopeV2 envelope) {
4345
String identityJsonString = decrypt(response, secretKey, false, envelope.getNonce());
4446
JsonObject responseJson = new Gson().fromJson(identityJsonString, JsonObject.class);
@@ -50,6 +52,18 @@ public IdentityTokens createIdentityfromTokenGenerateResponse(String response, E
5052
return IdentityTokens.fromJson(TokenRefreshResponse.getBodyAsJson(responseJson));
5153
}
5254

55+
/**
56+
* @param response the response body returned by a call to <a href="https://unifiedid.com/docs/endpoints/post-token-generate">/token/generate</a>
57+
* @param envelope the EnvelopeV2 instance returned by {@link #createEnvelopeForTokenGenerateRequest}
58+
* @return an TokenGenerateResponse instance
59+
* @throws Uid2Exception if the response did not contain a "success" or "optout" status
60+
*/
61+
public TokenGenerateResponse createTokenGenerateResponse(String response, EnvelopeV2 envelope) {
62+
String identityJsonString = decrypt(response, secretKey, false, envelope.getNonce());
63+
64+
return new TokenGenerateResponse(identityJsonString);
65+
}
66+
5367
/**
5468
* @param encryptedResponse the response body returned by a call to <a href="https://unifiedid.com/docs/endpoints/post-token-refresh">/token/refresh</a>
5569
* @param currentIdentity the current IdentityTokens instance, typically retrieved from a user's session

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

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,18 @@ TokenGenerateInput doNotHash() {
5151
return this;
5252
}
5353

54+
public TokenGenerateInput doNotGenerateTokensForOptedOut() {
55+
generateForOptedOut = false;
56+
return this;
57+
}
58+
5459
String getAsJsonString() {
5560
if (alreadyHashed) {
56-
return createAlreadyHashedJsonRequestForGenerateToken(identityType, emailOrPhone, transparencyAndConsentString);
61+
return createAlreadyHashedJsonRequestForGenerateToken(identityType, emailOrPhone, transparencyAndConsentString, generateForOptedOut);
5762
} else if (needHash) {
58-
return createHashedJsonRequestForGenerateToken(identityType, emailOrPhone, transparencyAndConsentString);
63+
return createHashedJsonRequestForGenerateToken(identityType, emailOrPhone, transparencyAndConsentString, generateForOptedOut);
5964
} else {
60-
return createJsonRequestForGenerateToken(identityType, emailOrPhone, transparencyAndConsentString);
65+
return createJsonRequestForGenerateToken(identityType, emailOrPhone, transparencyAndConsentString, generateForOptedOut);
6166
}
6267
}
6368

@@ -70,52 +75,55 @@ private TokenGenerateInput(IdentityType identityType, String emailOrPhone, boole
7075

7176

7277

73-
private static String createJsonRequestForGenerateToken(IdentityType identityType, String value, String tcString) {
78+
private static String createJsonRequestForGenerateToken(IdentityType identityType, String value, String tcString, boolean generateForOptedOut) {
7479
final String property = (identityType == IdentityType.Email) ? "email" : "phone";
75-
return createJsonRequestForGenerateToken(property, value, tcString);
80+
return createJsonRequestForGenerateToken(property, value, tcString, generateForOptedOut);
7681
}
7782

78-
private static String createJsonRequestForGenerateToken(String property, String value, String tcString) {
83+
private static String createJsonRequestForGenerateToken(String property, String value, String tcString, boolean generateForOptedOut) {
7984
JsonObject json = new JsonObject();
8085

8186
json.addProperty(property, value);
8287
if (tcString != null) {
8388
json.addProperty("tcf_consent_string", tcString);
8489
}
85-
90+
if(!generateForOptedOut){
91+
json.addProperty("policy", 1);
92+
}
8693
return json.toString();
8794
}
8895

89-
static String createHashedJsonRequestForGenerateToken(IdentityType identityType, String unhashedValue, String tcString) {
96+
static String createHashedJsonRequestForGenerateToken(IdentityType identityType, String unhashedValue, String tcString, boolean generateForOptedOut) {
9097
if (identityType == IdentityType.Email) {
9198
String normalizedEmail = InputUtil.normalizeEmailString(unhashedValue);
9299
if (normalizedEmail == null) {
93100
throw new IllegalArgumentException("invalid email address");
94101
}
95102
String hashedNormalizedEmail = InputUtil.getBase64EncodedHash(normalizedEmail);
96-
return createJsonRequestForGenerateToken("email_hash", hashedNormalizedEmail, tcString);
103+
return createJsonRequestForGenerateToken("email_hash", hashedNormalizedEmail, tcString, generateForOptedOut);
97104
} else { //phone
98105
if (!InputUtil.isPhoneNumberNormalized(unhashedValue)) {
99106
throw new IllegalArgumentException("phone number is not normalized");
100107
}
101108

102109
String hashedNormalizedPhone = InputUtil.getBase64EncodedHash(unhashedValue);
103-
return createJsonRequestForGenerateToken("phone_hash", hashedNormalizedPhone, tcString);
110+
return createJsonRequestForGenerateToken("phone_hash", hashedNormalizedPhone, tcString, generateForOptedOut);
104111
}
105112
}
106113

107-
static String createAlreadyHashedJsonRequestForGenerateToken(IdentityType identityType, String hashedValue, String tcString) {
114+
static String createAlreadyHashedJsonRequestForGenerateToken(IdentityType identityType, String hashedValue, String tcString, boolean generateForOptedOut) {
108115
if (identityType == IdentityType.Email) {
109-
return createJsonRequestForGenerateToken("email_hash", hashedValue, tcString);
116+
return createJsonRequestForGenerateToken("email_hash", hashedValue, tcString, generateForOptedOut);
110117
} else { //phone
111-
return createJsonRequestForGenerateToken("phone_hash", hashedValue, tcString);
118+
return createJsonRequestForGenerateToken("phone_hash", hashedValue, tcString, generateForOptedOut);
112119
}
113120
}
114121

115122
private final IdentityType identityType;
116123
private final String emailOrPhone;
117124
private boolean needHash;
118-
private boolean alreadyHashed;
125+
private final boolean alreadyHashed;
126+
private boolean generateForOptedOut = true;
119127
private String transparencyAndConsentString;
120128

121129

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.uid2.client;
2+
3+
import com.google.gson.Gson;
4+
import com.google.gson.JsonObject;
5+
6+
import java.time.Instant;
7+
8+
public class TokenGenerateResponse {
9+
/**
10+
* @return {@link IdentityTokens#getJsonString()} if this was a successful response ({@link #isSuccess}), otherwise null
11+
*/
12+
public String getIdentityJsonString() {
13+
return isSuccess() ? getIdentity().getJsonString() : null;
14+
}
15+
16+
/**
17+
* @return whether this was a successful response
18+
*/
19+
public boolean isSuccess() {
20+
return "success".equals(status);
21+
}
22+
23+
/**
24+
* @return whether the user has opted out. See <a href="https://unifiedid.com/docs/endpoints/post-token-generate#optout">Optout</a>
25+
*/
26+
public boolean isOptout() {
27+
return "optout".equals(status);
28+
}
29+
30+
/**
31+
* @return the refreshed IdentityTokens instance if {@link #isSuccess} is true, otherwise null
32+
*/
33+
public IdentityTokens getIdentity() {
34+
return tokens;
35+
}
36+
37+
static JsonObject getBodyAsJson(JsonObject jsonResponse) {
38+
return jsonResponse.get("body").getAsJsonObject();
39+
}
40+
41+
TokenGenerateResponse(String response) {
42+
JsonObject responseJson = new Gson().fromJson(response, JsonObject.class);
43+
status = responseJson.get("status").getAsString();
44+
45+
if (isOptout()) {
46+
return;
47+
} else if (!isSuccess()) {
48+
throw new Uid2Exception("Got unexpected token generate status: " + status);
49+
}
50+
51+
tokens = IdentityTokens.fromJson(getBodyAsJson(responseJson));
52+
}
53+
54+
55+
private final String status;
56+
private IdentityTokens tokens;
57+
}

0 commit comments

Comments
 (0)