// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. package com.microsoft.aad.msal4j; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; class DeviceCodeFlowRequest extends MsalRequest { private AtomicReference> futureReference; private DeviceCodeFlowParameters parameters; private String scopesStr; DeviceCodeFlowRequest(DeviceCodeFlowParameters parameters, AtomicReference> futureReference, PublicClientApplication application, RequestContext requestContext) { super(application, null, requestContext); this.parameters = parameters; this.scopesStr = String.join(" ", parameters.scopes()); this.futureReference = futureReference; } DeviceCode acquireDeviceCode(String url, String clientId, Map clientDataHeaders, ServiceBundle serviceBundle) { Map headers = appendToHeaders(clientDataHeaders); String bodyParams = createQueryParams(clientId); HttpRequest httpRequest = new HttpRequest(HttpMethod.POST, url, headers, bodyParams); final IHttpResponse response = serviceBundle.getHttpHelper().executeHttpRequest( httpRequest, this.requestContext(), serviceBundle); if (response.statusCode() != HttpStatus.HTTP_OK) { throw MsalServiceExceptionFactory.fromHttpResponse(response); } return parseJsonToDeviceCodeAndSetParameters(response.body(), headers, clientId); } void createAuthenticationGrant(DeviceCode deviceCode) { final Map params = new LinkedHashMap<>(); params.put(GrantConstants.GRANT_TYPE_PARAMETER, GrantConstants.DEVICE_CODE); params.put("device_code", deviceCode.deviceCode()); if (parameters.claims() != null) { params.put("claims", parameters.claims().formatAsJSONString()); } msalAuthorizationGrant = new OAuthAuthorizationGrant(params, Collections.singleton(deviceCode.scopes()), parameters.claims()); } private String createQueryParams(String clientId) { Map queryParameters = new HashMap<>(); queryParameters.put("client_id", clientId); String scopesParam = String.join(AbstractMsalAuthorizationGrant.SCOPES_DELIMITER, AbstractMsalAuthorizationGrant.COMMON_SCOPES) + AbstractMsalAuthorizationGrant.SCOPES_DELIMITER + scopesStr; queryParameters.put("scope", scopesParam); return StringHelper.serializeQueryParameters(queryParameters); } private Map appendToHeaders(Map clientDataHeaders) { Map headers = new HashMap<>(clientDataHeaders); headers.put("Accept", "application/json"); return headers; } private DeviceCode parseJsonToDeviceCodeAndSetParameters( String json, Map headers, String clientId) { DeviceCode result; result = JsonHelper.convertJsonStringToJsonSerializableObject(json, DeviceCode::fromJson); String correlationIdHeader = headers.get(HttpHeaders.CORRELATION_ID_HEADER_NAME); if (correlationIdHeader != null) { result.correlationId(correlationIdHeader); } result.clientId(clientId); result.scopes(scopesStr); return result; } AtomicReference> futureReference() { return this.futureReference; } DeviceCodeFlowParameters parameters() { return this.parameters; } String scopesStr() { return this.scopesStr; } }