public TokenPair requestToken()

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;
    }