Issue Summary
I have been working with Becca and Ryan at SendGrid to try to fix an issue we have been experiencing where we are trying to create an API key for a SendGrid subuser, but the API key is not associated to that subuser. The CURL command Ryan sent over works fine:
cURL API Keys - on behalf of a subuser
curl -X POST
https://api.sendgrid.com/v3/api_keys
-H 'authorization: Basic [BASE64 PARENT USER/PASS]' \
-H 'content-type: application/json'
-H 'on-behalf-of: SUBUSER USERNAME'
-d '{
"name": "API KEY NAME",
"scopes": [
"mail.send",
"alerts.create",
"alerts.read"
]
}'
But, when trying to perform the same HTTP POST with the SendGrid Java client, this is failing.
Here is the code I wrote to create a SendGrid subuser's API key:
public String createApiKey(String username) {
if (StringUtils.isNullOrEmpty(username)) return null;
ObjectNode objectNode = MAPPER.createObjectNode();
objectNode.put("name", "API key for " + username);
ArrayNode scopes = MAPPER.createArrayNode();
scopes.add("mail.send");
objectNode.putArray("scopes").addAll(scopes);
Request sendGridRequest = new Request();
sendGridRequest.setMethod(Method.POST);
sendGridRequest.setEndpoint(API_KEYS_ENDPOINT);
sendGridRequest.setBody(objectNode.toString());
// HERE!!
sendGridRequest.addHeader("on-behalf-of", username);
try {
Response response = sendGrid.api(sendGridRequest);
int responseStatusCode = response.getStatusCode();
if (responseStatusCode != HttpStatus.SC_CREATED) {
LOG.error("Error while creating API key for subuser. Http status: {}", responseStatusCode);
return null;
}
String responseBody = response.getBody();
LOG.debug("SendGrid API key '{}' created for: {}", responseBody, username);
return responseBody;
} catch (IOException e) {
LOG.error("Error while creating API key for subuser: {}", e);
return null;
}
}
But, while debugging through the request, the headers added to the SendGrid request are not being added to the request that actually gets sent to SendGrid:
SendGrid class:
/**
* Class api sets up the request to the SendGrid API, this is main interface.
*/
public Response api(Request request) throws IOException {
Request req = new Request();
req.setMethod(request.getMethod());
req.setBaseUri(this.host);
req.setEndpoint("/" + version + "/" + request.getEndpoint());
req.setBody(request.getBody());
// HERE!!
for (Map.Entry <String, String> header : this.requestHeaders.entrySet()) {
req.addHeader(header.getKey(), header.getValue());
}
for (Map.Entry <String, String> queryParam : request.getQueryParams().entrySet()) {
req.addQueryParam(queryParam.getKey(), queryParam.getValue());
}
return makeCall(req);
}
So the bug is that any headers I add to my SendGrid request object are not being added to the actual request headers sent to SendGrid. To correct this, the headers from the SendGrid request object need to be added to the actual request object being sent to SendGrid.
Fixed SendGrid class:
/**
* Class api sets up the request to the SendGrid API, this is main interface.
*/
public Response api(Request request) throws IOException {
Request req = new Request();
req.setMethod(request.getMethod());
req.setBaseUri(this.host);
req.setEndpoint("/" + version + "/" + request.getEndpoint());
req.setBody(request.getBody());
// HERE!!
req.getHeaders().putAll(request.getHeaders);
for (Map.Entry <String, String> header : this.requestHeaders.entrySet()) {
req.addHeader(header.getKey(), header.getValue());
}
for (Map.Entry <String, String> queryParam : request.getQueryParams().entrySet()) {
req.addQueryParam(queryParam.getKey(), queryParam.getValue());
}
return makeCall(req);
}
Here is my current workaround until this issue is fixed:
public String createApiKey(String username) {
if (StringUtils.isNullOrEmpty(username)) return null;
ObjectNode objectNode = MAPPER.createObjectNode();
objectNode.put("name", "API key for " + username);
ArrayNode scopes = MAPPER.createArrayNode();
scopes.add("mail.send");
objectNode.putArray("scopes").addAll(scopes);
Request sendGridRequest = new Request();
sendGridRequest.setMethod(Method.POST);
sendGridRequest.setEndpoint(API_KEYS_ENDPOINT);
sendGridRequest.setBody(objectNode.toString());
//sendGridRequest.addHeader("on-behalf-of", username);
try {
// HERE!!
sendGrid.getRequestHeaders().put("on-behalf-of", username);
Response response = sendGrid.api(sendGridRequest);
int responseStatusCode = response.getStatusCode();
if (responseStatusCode != HttpStatus.SC_CREATED) {
LOG.error("Error while creating API key for subuser. Http status: {}", responseStatusCode);
return null;
}
String responseBody = response.getBody();
LOG.debug("SendGrid API key '{}' created for: {}", responseBody, username);
return responseBody;
} catch (IOException e) {
LOG.error("Error while creating API key for subuser: {}", e);
return null;
}
}
Please help us fix this issue!
Steps to Reproduce
- This is the first step
Add the "on-behalf-of" header to the SendGrid request object via the .addHeader() method with the subuser's username.
- This is the second step
Run the code to create the API key for the subuser. Notice, the "on-behalf-of" header is never sent and the API key created is not associated with the subuser.
Technical details:
- sendgrid-java Version: 4.0.1
- Java Version: 1.8.0_74
Issue Summary
I have been working with Becca and Ryan at SendGrid to try to fix an issue we have been experiencing where we are trying to create an API key for a SendGrid subuser, but the API key is not associated to that subuser. The CURL command Ryan sent over works fine:
cURL API Keys - on behalf of a subuser
curl -X POST
https://api.sendgrid.com/v3/api_keys
-H 'authorization: Basic [BASE64 PARENT USER/PASS]' \
-H 'content-type: application/json'
-H 'on-behalf-of: SUBUSER USERNAME'
-d '{
"name": "API KEY NAME",
"scopes": [
"mail.send",
"alerts.create",
"alerts.read"
]
}'
But, when trying to perform the same HTTP POST with the SendGrid Java client, this is failing.
Here is the code I wrote to create a SendGrid subuser's API key:
But, while debugging through the request, the headers added to the SendGrid request are not being added to the request that actually gets sent to SendGrid:
SendGrid class:
So the bug is that any headers I add to my SendGrid request object are not being added to the actual request headers sent to SendGrid. To correct this, the headers from the SendGrid request object need to be added to the actual request object being sent to SendGrid.
Fixed SendGrid class:
Here is my current workaround until this issue is fixed:
Please help us fix this issue!
Steps to Reproduce
Add the "on-behalf-of" header to the SendGrid request object via the .addHeader() method with the subuser's username.
Run the code to create the API key for the subuser. Notice, the "on-behalf-of" header is never sent and the API key created is not associated with the subuser.
Technical details: