package com.sap.cloud.security.xsuaa.mock; import java.io.IOException; import java.nio.charset.StandardCharsets; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import okhttp3.mockwebserver.Dispatcher; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.RecordedRequest; public class XsuaaRequestDispatcher extends Dispatcher { protected static final String RESPONSE_404 = "Xsuaa mock authorization server does not support this request"; protected static final String RESPONSE_401 = "Xsuaa mock authorization server can't authenticate client/user"; protected static final String RESPONSE_500 = "Xsuaa mock authorization server can't process request"; protected static final String PATH_TOKEN_KEYS_TEMPLATE = "/mock/token_keys_template.json"; protected static final String PATH_PUBLIC_KEY = "/mock/publicKey.txt"; protected final Logger logger = LoggerFactory.getLogger(XsuaaRequestDispatcher.class); private static int callCount = 0; @Override public MockResponse dispatch(RecordedRequest request) { callCount++; if ("/testdomain/token_keys".equals(request.getPath())) { String subdomain = "testdomain"; return getTokenKeyForKeyId(PATH_TOKEN_KEYS_TEMPLATE, "legacy-token-key-" + subdomain); } if (request.getPath().endsWith("/token_keys")) { return getTokenKeyForKeyId(PATH_TOKEN_KEYS_TEMPLATE, "legacy-token-key"); } return getResponse(RESPONSE_404, HttpStatus.NOT_FOUND); } protected MockResponse getResponseFromFile(String path, HttpStatus status) { try { String body = readFromFile(path); return getResponse(body, status); } catch (Exception e) { return getInternalErrorResponse(e.getMessage()); } } protected MockResponse getResponse(String message, HttpStatus status) { return new MockResponse() .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .setResponseCode(status.value()) .setBody(message); } protected MockResponse getTokenKeyForKeyId(String pathToTemplate, String keyId) { try { String publicKey = readFromFile(PATH_PUBLIC_KEY); String body = readFromFile(pathToTemplate) .replace("$kid", keyId) .replace("$public_key", publicKey); return getResponse(body, HttpStatus.OK); } catch (Exception e) { return getInternalErrorResponse(e.getMessage()); } } protected String readFromFile(String path) throws IOException { return IOUtils.resourceToString(path, StandardCharsets.UTF_8); } protected MockResponse getInternalErrorResponse(String message) { logger.warn(message); return getResponse(RESPONSE_500 + ": " + message, HttpStatus.INTERNAL_SERVER_ERROR); } public static int getCallCount() { return callCount; } }