in core/src/main/java/com/microsoft/alm/auth/oauth/DeviceFlowImpl.java [71:142]
public TokenPair requestToken(final URI tokenEndpoint, final String clientId, final DeviceFlowResponse deviceFlowResponse) throws AuthorizationException {
final QueryString bodyParameters = new QueryString();
bodyParameters.put(OAuthParameter.GRANT_TYPE, OAuthParameter.DEVICE_CODE);
bodyParameters.put(OAuthParameter.CODE, deviceFlowResponse.getDeviceCode());
bodyParameters.put(OAuthParameter.CLIENT_ID, clientId);
contributeTokenRequestParameters(bodyParameters);
final StringContent requestBody = StringContent.createUrlEncoded(bodyParameters);
final int intervalSeconds = deviceFlowResponse.getInterval();
int intervalMilliseconds = intervalSeconds * 1000;
final HttpClient client = Global.getHttpClientFactory().createHttpClient();
String responseText = null;
final Calendar expiresAt = deviceFlowResponse.getExpiresAt();
do {
if (deviceFlowResponse.cancelRequestedByUser()) {
throw new AuthorizationException("request_cancelled", "Stop polling for Token.", null, null);
}
try {
final HttpResponse response = client.getPostResponse(tokenEndpoint, requestBody);
if (response.status == HttpURLConnection.HTTP_OK) {
responseText = response.responseText;
break;
}
else {
final String errorResponseText = response.errorText;
if (response.status == HttpURLConnection.HTTP_BAD_REQUEST) {
final PropertyBag bag = PropertyBag.fromJson(errorResponseText);
final String errorCode = bag.readOptionalString(OAuthParameter.ERROR_CODE, "unknown_error");
if (OAuthParameter.ERROR_AUTHORIZATION_PENDING.equals(errorCode)) {
try {
Thread.sleep(intervalMilliseconds);
} catch (final InterruptedException e) {
throw new Error(e);
}
continue;
}
else if (OAuthParameter.ERROR_SLOW_DOWN.equals(errorCode)) {
intervalMilliseconds *= 2;
try {
Thread.sleep(intervalMilliseconds);
} catch (final InterruptedException e) {
throw new Error(e);
}
continue;
}
final String errorDescription = bag.readOptionalString(OAuthParameter.ERROR_DESCRIPTION, null);
final String errorUriString = bag.readOptionalString(OAuthParameter.ERROR_URI, null);
final URI errorUri = errorUriString == null ? null : URI.create(errorUriString);
throw new AuthorizationException(errorCode, errorDescription, errorUri, null);
}
else {
throw new Error("Token endpoint returned HTTP " + response.status + ":\n" + errorResponseText);
}
}
}
catch (final IOException e) {
throw new Error(e);
}
}
while (Calendar.getInstance().compareTo(expiresAt) <= 0);
if (responseText == null) {
throw new AuthorizationException("code_expired", "The verification code expired.", null, null);
}
final TokenPair tokenPair = buildTokenPair(responseText);
deviceFlowResponse.setTokenAcquired();
return tokenPair;
}