package org.jenkinsci.plugins.servicenow; import com.cloudbees.plugins.credentials.Credentials; import hudson.model.Item; import org.apache.http.Header; import org.apache.http.auth.AuthScope; import org.apache.http.client.AuthCache; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPatch; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.URIUtils; import org.apache.http.entity.ContentType; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.jenkinsci.plugins.servicenow.credentials.CredentialsLocatorStrategy; import org.jenkinsci.plugins.servicenow.credentials.CredentialsUtilCredentialsProvider; import org.jenkinsci.plugins.servicenow.model.ServiceNowConfiguration; import org.jenkinsci.plugins.servicenow.model.ServiceNowItem; import org.jenkinsci.plugins.servicenow.model.VaultConfiguration; import org.jenkinsci.plugins.servicenow.util.CredentialsUtil; import org.jenkinsci.plugins.servicenow.workflow.AbstractServiceNowStep; import java.io.IOException; import java.io.InputStream; public class ServiceNowExecution { private final Credentials credentials; private final ServiceNowConfiguration serviceNowConfiguration; private final VaultConfiguration vaultConfiguration; private ServiceNowItem serviceNowItem; private HttpClientBuilder clientBuilder; public static ServiceNowExecution from(AbstractServiceNowStep step, Item project) { return new ServiceNowExecution(step.getServiceNowConfiguration(), step.getServiceNowItem(), step.getCredentialsId(), step.vaultConfiguration, project); } public static ServiceNowExecution from(AbstractServiceNowStep step, Item project, HttpClientBuilder httpClientBuilder, CredentialsLocatorStrategy locatorStrategy) { return new ServiceNowExecution(step.getServiceNowConfiguration(), step.getServiceNowItem(), step.getCredentialsId(), step.vaultConfiguration, project, httpClientBuilder, locatorStrategy); } private ServiceNowExecution(ServiceNowConfiguration serviceNowConfiguration, ServiceNowItem serviceNowItem, String credentialsId, VaultConfiguration vaultConfiguration, Item project) { this(serviceNowConfiguration, serviceNowItem, credentialsId, vaultConfiguration, project, HttpClientBuilder.create().useSystemProperties(), new CredentialsUtilCredentialsProvider()); } private ServiceNowExecution(ServiceNowConfiguration serviceNowConfiguration, ServiceNowItem serviceNowItem, String credentialsId, VaultConfiguration vaultConfiguration, Item project, HttpClientBuilder clientBuilder, CredentialsLocatorStrategy locatorStrategy) { this.serviceNowConfiguration = serviceNowConfiguration; this.vaultConfiguration = vaultConfiguration; this.serviceNowItem = serviceNowItem; this.clientBuilder = clientBuilder; this.credentials = locatorStrategy.getCredentials(serviceNowConfiguration.getBaseUrl(), credentialsId, vaultConfiguration, project); } public void updateItem(ServiceNowItem item) { this.serviceNowItem = item; } public CloseableHttpResponse createChange() throws IOException { HttpPost requestBase = new HttpPost(serviceNowConfiguration.getProducerRequestUrl()); setJsonContentType(requestBase); return sendRequest(requestBase); } public CloseableHttpResponse updateChange() throws IOException { HttpPatch requestBase = new HttpPatch(serviceNowConfiguration.getPatchUrl(serviceNowItem)); setJsonContentType(requestBase); requestBase.setEntity(buildEntity(serviceNowItem.getBody())); return sendRequest(requestBase); } public CloseableHttpResponse getChangeState() throws IOException { HttpGet requestBase = new HttpGet(serviceNowConfiguration.getCurrentStateUrl(serviceNowItem.getSysId())); setJsonContentType(requestBase); return sendRequest(requestBase); } public CloseableHttpResponse getCTask() throws IOException { HttpGet requestBase = new HttpGet(serviceNowConfiguration.getCTasksUrl(serviceNowItem)); setJsonContentType(requestBase); return sendRequest(requestBase); } public CloseableHttpResponse attachFile() throws IOException { HttpPost requestBase = new HttpPost(serviceNowConfiguration.getAttachmentUrl(serviceNowItem)); requestBase.setHeaders(new Header[]{getContentTypeHeader("text/plain")}); requestBase.setEntity(buildEntity(serviceNowItem.getBody())); return sendRequest(requestBase); } public CloseableHttpResponse attachZip(InputStream zipStream) throws IOException { HttpPost requestBase = new HttpPost(serviceNowConfiguration.getAttachmentUrl(serviceNowItem)); requestBase.setHeaders(new Header[]{getContentTypeHeader("application/zip")}); requestBase.setEntity(buildZipEntity(zipStream)); return sendRequest(requestBase); } private CloseableHttpResponse sendRequest(HttpRequestBase requestBase) throws IOException { HttpContext httpContext = new BasicHttpContext(); CloseableHttpClient httpClient = auth(requestBase, clientBuilder, httpContext); return httpClient.execute(requestBase, httpContext); } private CloseableHttpClient auth(HttpRequestBase requestBase, HttpClientBuilder clientBuilder, HttpContext httpContext) { if(credentials != null) { return authenticate(clientBuilder, requestBase, httpContext); } return clientBuilder.build(); } private void setJsonContentType(HttpRequestBase requestBase) { requestBase.setHeaders(new Header[]{getContentTypeHeader("application/json")}); } private CloseableHttpClient authenticate(HttpClientBuilder clientBuilder, HttpRequestBase requestBase, HttpContext httpContext) { CredentialsProvider provider = new BasicCredentialsProvider(); provider.setCredentials( new AuthScope(requestBase.getURI().getHost(), requestBase.getURI().getPort()), CredentialsUtil.readCredentials(credentials, vaultConfiguration)); clientBuilder.setDefaultCredentialsProvider(provider); AuthCache authCache = new BasicAuthCache(); authCache.put(URIUtils.extractHost(requestBase.getURI()), new BasicScheme()); httpContext.setAttribute(HttpClientContext.AUTH_CACHE, authCache); return clientBuilder.build(); } private StringEntity buildEntity(String body) { return new StringEntity(body, ContentType.create("application/json")); } private InputStreamEntity buildZipEntity(InputStream zipStream) { return new InputStreamEntity(zipStream, ContentType.create("application/zip")); } private Header getContentTypeHeader(String contentType) { return new BasicHeader("Content-Type", contentType); } }