Skip to content

Commit 39b6fcc

Browse files
feat: Sanitize request body in BoxAPIError (box/box-codegen#948) (#1844)
1 parent aa439b4 commit 39b6fcc

6 files changed

Lines changed: 99 additions & 5 deletions

File tree

.codegen.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "engineHash": "0f85d1e", "specHash": "576cd17", "version": "10.11.0" }
1+
{ "engineHash": "78a8dc0", "specHash": "576cd17", "version": "10.11.0" }

src/main/java/com/box/sdkgen/box/errors/BoxAPIError.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,16 @@ public static BoxAPIError fromAPICall(
2727
FetchResponse fetchResponse,
2828
String rawResponseBody,
2929
DataSanitizer dataSanitizer) {
30-
RequestInfo requestInfo = RequestInfo.fromRequest(request);
30+
return fromAPICall(request, fetchResponse, rawResponseBody, dataSanitizer, null);
31+
}
32+
33+
public static BoxAPIError fromAPICall(
34+
Request request,
35+
FetchResponse fetchResponse,
36+
String rawResponseBody,
37+
DataSanitizer dataSanitizer,
38+
String contentType) {
39+
RequestInfo requestInfo = RequestInfo.fromRequest(request, contentType);
3140
ResponseInfo responseInfo = ResponseInfo.fromResponse(fetchResponse, rawResponseBody);
3241

3342
String requestId =

src/main/java/com/box/sdkgen/box/errors/RequestInfo.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public class RequestInfo {
1919

2020
public String body;
2121

22+
public String contentType;
23+
2224
public RequestInfo(
2325
String method, String url, Map<String, String> queryParams, Map<String, String> headers) {
2426
this.method = method;
@@ -33,6 +35,7 @@ protected RequestInfo(Builder builder) {
3335
this.queryParams = builder.queryParams;
3436
this.headers = builder.headers;
3537
this.body = builder.body;
38+
this.contentType = builder.contentType;
3639
}
3740

3841
public String getMethod() {
@@ -55,6 +58,10 @@ public String getBody() {
5558
return body;
5659
}
5760

61+
public String getContentType() {
62+
return contentType;
63+
}
64+
5865
public static class Builder {
5966

6067
protected final String method;
@@ -67,6 +74,8 @@ public static class Builder {
6774

6875
protected String body;
6976

77+
protected String contentType;
78+
7079
public Builder(
7180
String method, String url, Map<String, String> queryParams, Map<String, String> headers) {
7281
this.method = method;
@@ -80,12 +89,21 @@ public Builder body(String body) {
8089
return this;
8190
}
8291

92+
public Builder contentType(String contentType) {
93+
this.contentType = contentType;
94+
return this;
95+
}
96+
8397
public RequestInfo build() {
8498
return new RequestInfo(this);
8599
}
86100
}
87101

88102
public static RequestInfo fromRequest(Request request) {
103+
return fromRequest(request, null);
104+
}
105+
106+
public static RequestInfo fromRequest(Request request, String contentType) {
89107
Builder requestInfoBuilder =
90108
new Builder(
91109
request.method(),
@@ -95,7 +113,8 @@ public static RequestInfo fromRequest(Request request) {
95113
Collectors.toMap(name -> name, name -> request.url().queryParameter(name))),
96114
request.headers().toMultimap().entrySet().stream()
97115
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get(0))))
98-
.body(getRequestBodyAsString(request.body()));
116+
.body(getRequestBodyAsString(request.body()))
117+
.contentType(contentType);
99118

100119
return new RequestInfo(requestInfoBuilder);
101120
}
@@ -116,6 +135,12 @@ private static String getRequestBodyAsString(RequestBody requestBody) {
116135
String print(DataSanitizer dataSanitizer) {
117136
Map<String, String> sanitizedHeaders =
118137
dataSanitizer == null ? headers : dataSanitizer.sanitizeHeaders(headers);
138+
String sanitizedBody;
139+
if (dataSanitizer == null || body == null) {
140+
sanitizedBody = body;
141+
} else {
142+
sanitizedBody = dataSanitizer.sanitizeStringBody(body, contentType);
143+
}
119144
return "RequestInfo{"
120145
+ "\n\tmethod='"
121146
+ method
@@ -128,7 +153,7 @@ String print(DataSanitizer dataSanitizer) {
128153
+ ", \n\theaders="
129154
+ sanitizedHeaders
130155
+ ", \n\tbody='"
131-
+ body
156+
+ sanitizedBody
132157
+ '\''
133158
+ '}';
134159
}

src/main/java/com/box/sdkgen/internal/logging/DataSanitizer.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import static com.box.sdkgen.internal.utils.UtilsManager.entryOf;
44
import static com.box.sdkgen.internal.utils.UtilsManager.mapOf;
55
import static com.box.sdkgen.internal.utils.UtilsManager.sanitizeMap;
6+
import static com.box.sdkgen.serialization.json.JsonManager.jsonToSerializedData;
7+
import static com.box.sdkgen.serialization.json.JsonManager.sanitizeFormEncodedBodyFromString;
68
import static com.box.sdkgen.serialization.json.JsonManager.sanitizeSerializedData;
9+
import static com.box.sdkgen.serialization.json.JsonManager.sdToJson;
710

811
import com.fasterxml.jackson.databind.JsonNode;
912
import java.util.Map;
@@ -36,4 +39,27 @@ public Map<String, String> sanitizeHeaders(Map<String, String> headers) {
3639
public JsonNode sanitizeBody(JsonNode body) {
3740
return sanitizeSerializedData(body, this.keysToSanitize);
3841
}
42+
43+
public String sanitizeFormEncodedBody(String body) {
44+
return sanitizeFormEncodedBodyFromString(body, this.keysToSanitize);
45+
}
46+
47+
public String sanitizeStringBody(String body) {
48+
return sanitizeStringBody(body, null);
49+
}
50+
51+
public String sanitizeStringBody(String body, String contentType) {
52+
if (contentType.equals("application/json")
53+
|| contentType.equals("application/json-patch+json")) {
54+
try {
55+
return sdToJson(this.sanitizeBody(jsonToSerializedData(body)));
56+
} catch (Exception exception) {
57+
return body;
58+
}
59+
}
60+
if (contentType.equals("application/x-www-form-urlencoded")) {
61+
return this.sanitizeFormEncodedBody(body);
62+
}
63+
return body;
64+
}
3965
}

src/main/java/com/box/sdkgen/networking/boxnetworkclient/BoxNetworkClient.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ public FetchResponse fetch(FetchOptions options) {
255255
fetchResponse,
256256
rawResponseBody,
257257
exceptionThrown,
258+
fetchOptions.getContentType(),
258259
networkSession.getDataSanitizer());
259260
}
260261
}
@@ -367,12 +368,14 @@ private static void throwOnUnsuccessfulResponse(
367368
FetchResponse fetchResponse,
368369
String rawResponseBody,
369370
Exception exceptionThrown,
371+
String contentType,
370372
DataSanitizer dataSanitizer) {
371373
if (fetchResponse.getStatus() == 0 && exceptionThrown != null) {
372374
throw new BoxSDKError(exceptionThrown.getMessage(), exceptionThrown);
373375
}
374376
try {
375-
throw BoxAPIError.fromAPICall(request, fetchResponse, rawResponseBody, dataSanitizer);
377+
throw BoxAPIError.fromAPICall(
378+
request, fetchResponse, rawResponseBody, dataSanitizer, contentType);
376379
} finally {
377380
try {
378381
if (fetchResponse.getContent() != null) {

src/main/java/com/box/sdkgen/serialization/json/JsonManager.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,35 @@ public static JsonNode sanitizeSerializedData(JsonNode sd, Map<String, String> k
113113

114114
return new ObjectMapper().valueToTree(sanitizedDictionary);
115115
}
116+
117+
public static String sanitizeFormEncodedBodyFromString(
118+
String body, Map<String, String> keysToSanitize) {
119+
if (body == null) {
120+
return null;
121+
}
122+
123+
String[] parameters = body.split("&", -1);
124+
StringBuilder sanitizedBodyBuilder = new StringBuilder();
125+
for (int i = 0; i < parameters.length; i++) {
126+
if (i > 0) {
127+
sanitizedBodyBuilder.append("&");
128+
}
129+
sanitizedBodyBuilder.append(sanitizeFormEncodedParameter(parameters[i], keysToSanitize));
130+
}
131+
return sanitizedBodyBuilder.toString();
132+
}
133+
134+
private static String sanitizeFormEncodedParameter(
135+
String parameter, Map<String, String> keysToSanitize) {
136+
int separatorIndex = parameter.indexOf("=");
137+
if (separatorIndex < 0) {
138+
return parameter;
139+
}
140+
141+
String key = parameter.substring(0, separatorIndex);
142+
String value = parameter.substring(separatorIndex + 1);
143+
String sanitizedValue =
144+
keysToSanitize.containsKey(key.toLowerCase(Locale.ROOT)) ? sanitizedValue() : value;
145+
return key + "=" + sanitizedValue;
146+
}
116147
}

0 commit comments

Comments
 (0)