package jetbrains.buildServer.auth.oauth; import com.intellij.openapi.util.text.StringUtil; import okhttp3.FormBody; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import org.apache.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.json.simple.JSONValue; import org.springframework.http.MediaType; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class OAuthClient { private final AuthenticationSchemeProperties properties; private static final Logger log = Logger.getLogger(OAuthClient.class); private final Map<Boolean, OkHttpClient> httpClients = new HashMap<>(); public OAuthClient(AuthenticationSchemeProperties properties) { this.properties = properties; } private OkHttpClient getHttpClient() { return httpClients.computeIfAbsent(properties.isAllowInsecureHttps(), HttpClientFactory::createClient); } public String getRedirectUrl(String state) { HttpUrl.Builder builder = HttpUrl.parse(properties.getAuthorizeEndpoint()) .newBuilder() .addQueryParameter("response_type", "code") .addQueryParameter("client_id", properties.getClientId()) .addQueryParameter("state", state) .addQueryParameter("redirect_uri", properties.getRootUrl()); if (StringUtil.isNotEmpty(properties.getScope())) { builder.addQueryParameter("scope", properties.getScope()); } return builder.build().toString(); } public String getAccessToken(String code) throws IOException { RequestBody formBody = new FormBody.Builder() .add("grant_type", "authorization_code") .add("code", code) .add("redirect_uri", properties.getRootUrl()) .add("client_id", properties.getClientId()) .add("client_secret", properties.getClientSecret()) .build(); Request request = new Request.Builder() .url(properties.getTokenEndpoint()) .addHeader("Accept", MediaType.APPLICATION_JSON_VALUE) .post(formBody) .build(); Response response = getHttpClient().newCall(request).execute(); Map jsonResponse = (Map) JSONValue.parse(response.body().string()); return (String) jsonResponse.get("access_token"); } public OAuthUser getUserData(String token) { String response = authenticatedGETCall(properties.getUserEndpoint(), token); log.debug("Fetched user data: " + response); Map parsedResponse = (Map) JSONValue.parse(response); return createUser(token, parsedResponse); } private String authenticatedGETCall(String endpoint, String token) { try { Request request = new Request.Builder() .url(endpoint) .addHeader("Authorization", "Bearer " + token) .build(); return getHttpClient().newCall(request).execute().body().string(); } catch (IOException e) { throw new RuntimeException(e); } } @NotNull private OAuthUser createUser(String token, Map parsedResponse) { if ("github".equals(properties.getPreset())) { return new GithubUser(parsedResponse, () -> authenticatedGETCall(GithubUser.ORGANIZATION_ENDPOINT, token)); } else { return new OAuthUser(parsedResponse); } } }