From 8021b08aa4a274d61a29e1c31ea1932af6c56856 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Mon, 27 Mar 2023 21:15:08 +0200 Subject: [PATCH 01/29] Added JiraRestService construct that accept bearer token authentication --- .../java/hudson/plugins/jira/JiraRestService.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/hudson/plugins/jira/JiraRestService.java b/src/main/java/hudson/plugins/jira/JiraRestService.java index 592fe7ab..a64e5dd2 100644 --- a/src/main/java/hudson/plugins/jira/JiraRestService.java +++ b/src/main/java/hudson/plugins/jira/JiraRestService.java @@ -116,7 +116,19 @@ public JiraRestService(URI uri, ExtendedJiraRestClient jiraRestClient, String us throw new RuntimeException("failed to encode username:password using Base64"); } this.jiraRestClient = jiraRestClient; + baseApiPath = buildBaseApiPath(uri); + } + + public JiraRestService(URI uri, ExtendedJiraRestClient jiraRestClient, String token, int timeout) { + this.uri = uri; + this.objectMapper = new ObjectMapper(); + this.timeout = timeout; + this.authHeader = "Bearer " + token; + this.jiraRestClient = jiraRestClient; + baseApiPath = buildBaseApiPath(uri); + } + private String buildBaseApiPath(URI uri) { final StringBuilder builder = new StringBuilder(); if (uri.getPath() != null) { builder.append(uri.getPath()); @@ -127,7 +139,7 @@ public JiraRestService(URI uri, ExtendedJiraRestClient jiraRestClient, String us builder.append('/'); } builder.append(BASE_API_PATH); - baseApiPath = builder.toString(); + return builder.toString(); } public void addComment(String issueId, String commentBody, From ee90ba24759230f493515365313b634e67782080 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Mon, 27 Mar 2023 21:15:23 +0200 Subject: [PATCH 02/29] Added class BearerHttpAuthenticationHandler --- .../BearerHttpAuthenticationHandler.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/main/java/hudson/plugins/jira/authenticationhandler/BearerHttpAuthenticationHandler.java diff --git a/src/main/java/hudson/plugins/jira/authenticationhandler/BearerHttpAuthenticationHandler.java b/src/main/java/hudson/plugins/jira/authenticationhandler/BearerHttpAuthenticationHandler.java new file mode 100644 index 00000000..d0f44261 --- /dev/null +++ b/src/main/java/hudson/plugins/jira/authenticationhandler/BearerHttpAuthenticationHandler.java @@ -0,0 +1,29 @@ +package hudson.plugins.jira.authenticationhandler; + +import com.atlassian.jira.rest.client.api.AuthenticationHandler; +import com.atlassian.httpclient.api.Request.Builder; + +/** + * Authentication handler for bearer authentication + * + * @author Elia Bracci + */ +public class BearerHttpAuthenticationHandler implements AuthenticationHandler { + + private static final String AUTHORIZATION_HEADER = "Authorization"; + private final String token; + + /** + * Bearer http authentication handler constructor + * @param token pat or api token to use for bearer authentication + */ + public BearerHttpAuthenticationHandler(final String token) { + this.token = token; + } + + + @Override + public void configure(Builder builder) { + builder.setHeader(AUTHORIZATION_HEADER, "Bearer " + token); + } +} \ No newline at end of file From 74958604cc0edd4e76dab61ef18364ea54336fd1 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Mon, 27 Mar 2023 21:15:48 +0200 Subject: [PATCH 03/29] Added token in JiraConfig and added bearer auth tests class --- src/test/java/JiraConfig.java | 4 + src/test/java/JiraTesterBearerAuth.java | 123 ++++++++++++++++++++++++ src/test/resources/jira.properties | 3 +- 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/test/java/JiraTesterBearerAuth.java diff --git a/src/test/java/JiraConfig.java b/src/test/java/JiraConfig.java index 3e3d526e..62008c3a 100644 --- a/src/test/java/JiraConfig.java +++ b/src/test/java/JiraConfig.java @@ -16,4 +16,8 @@ public static String getUsername() { public static String getPassword() { return CONFIG.getString("password"); } + + public static String getToken() { + return CONFIG.getString("token"); + } } diff --git a/src/test/java/JiraTesterBearerAuth.java b/src/test/java/JiraTesterBearerAuth.java new file mode 100644 index 00000000..ec36fa32 --- /dev/null +++ b/src/test/java/JiraTesterBearerAuth.java @@ -0,0 +1,123 @@ + +import com.atlassian.jira.rest.client.api.domain.Component; +import com.atlassian.jira.rest.client.api.domain.Issue; +import com.atlassian.jira.rest.client.api.domain.IssueType; +import com.atlassian.jira.rest.client.api.domain.Status; +import com.atlassian.jira.rest.client.api.domain.Transition; +import com.atlassian.jira.rest.client.api.domain.User; +import hudson.plugins.jira.JiraRestService; +import hudson.plugins.jira.JiraSite; +import hudson.plugins.jira.extension.ExtendedJiraRestClient; +import hudson.plugins.jira.extension.ExtendedVersion; +import hudson.plugins.jira.authenticationhandler.BearerHttpAuthenticationHandler; + +import java.net.URI; +import java.net.URL; +import java.util.List; + +import static hudson.plugins.jira.JiraSite.ExtendedAsynchronousJiraRestClientFactory; + +/** + * Test bed to play with Jira. + * + * @author Elia Bracci + */ +public class JiraTesterBearerAuth { + public static void main(String[] args) throws Exception { + + final URI uri = new URL(JiraConfig.getUrl()).toURI(); + final BearerHttpAuthenticationHandler handler = new BearerHttpAuthenticationHandler(JiraConfig.getToken()); + final ExtendedJiraRestClient jiraRestClient = new ExtendedAsynchronousJiraRestClientFactory() + .createWithAuthenticationHandler(uri, handler); + + final JiraRestService restService = new JiraRestService(uri, jiraRestClient, JiraConfig.getToken(), JiraSite.DEFAULT_TIMEOUT); + + final String projectKey = "TESTPROJECT"; + final String issueId = "TESTPROJECT-425"; + final Integer actionId = 21; + + final Issue issue = restService.getIssue(issueId); + System.out.println("issue:" + issue); + + + final List availableActions = restService.getAvailableActions(issueId); + for (Transition action : availableActions) { + System.out.println("Action:" + action); + } + + for (IssueType issueType : restService.getIssueTypes()) { + System.out.println(" issue type: " + issueType); + } + +// restService.addVersion("TESTPROJECT", "0.0.2"); + + final List components = restService.getComponents(projectKey); + for (Component component : components) { + System.out.println("component: " + component); + } + +// BasicComponent backendComponent = null; +// final Iterable components1 = Lists.newArrayList(backendComponent); +// restService.createIssue("TESTPROJECT", "This is a test issue created using Jira jenkins plugin. Please ignore it.", "TESTUSER", components1, "test issue from Jira jenkins plugin"); + + final List searchResults = restService.getIssuesFromJqlSearch("project = \"TESTPROJECT\"", 3); + for (Issue searchResult : searchResults) { + System.out.println("JQL search result: " + searchResult); + } + + final List projectsKeys = restService.getProjectsKeys(); + for (String projectsKey : projectsKeys) { + System.out.println("project key: " + projectsKey); + } + + final List statuses = restService.getStatuses(); + for (Status status : statuses) { + System.out.println("status:" + status); + } + + final User user = restService.getUser("TESTUSER"); + System.out.println("user: " + user); + + final List versions = restService.getVersions(projectKey); + for (ExtendedVersion version : versions) { + System.out.println("version: " + version); + } + +// Version releaseVersion = new Version(version.getSelf(), version.getId(), version.getName(), +// version.getDescription(), version.isArchived(), true, new DateTime()); +// System.out.println(" >>>> release version 0.0.2"); +// restService.releaseVersion("TESTPROJECT", releaseVersion); + +// System.out.println(" >>> update issue TESTPROJECT-425"); +// restService.updateIssue(issueId, Collections.singletonList(releaseVersion)); + +// final Issue updatedIssue = restService.progressWorkflowAction(issueId, actionId); +// System.out.println("Updated issue:" + updatedIssue); + + + + for(int i=0;i<10;i++){ + callUniq( restService ); + } + + for(int i=0;i<10;i++){ + callDuplicate( restService ); + } + + } + + private static void callUniq(final JiraRestService restService) throws Exception { + long start = System.currentTimeMillis(); + List issues = restService.getIssuesFromJqlSearch( "key in ('JENKINS-53320','JENKINS-51057')", Integer.MAX_VALUE ); + long end = System.currentTimeMillis(); + System.out.println( "time uniq " + (end -start) ); + } + + private static void callDuplicate(final JiraRestService restService) throws Exception { + long start = System.currentTimeMillis(); + List issues = restService.getIssuesFromJqlSearch( "key in ('JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-51057','JENKINS-51057','JENKINS-51057','JENKINS-51057','JENKINS-51057')", Integer.MAX_VALUE ); + long end = System.currentTimeMillis(); + System.out.println( "time duplicate " + (end -start) ); + } + +} diff --git a/src/test/resources/jira.properties b/src/test/resources/jira.properties index 1da1c3f5..506185cf 100644 --- a/src/test/resources/jira.properties +++ b/src/test/resources/jira.properties @@ -1,3 +1,4 @@ url=http://host/jira/rpc/soap/jirasoapservice-v2 username=user -password=passwd \ No newline at end of file +password=passwd +token=token \ No newline at end of file From a9d9ab6ccbf945ff0e566477a27da40d4798cf3f Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Tue, 28 Mar 2023 00:40:23 +0200 Subject: [PATCH 04/29] Updated config.jelly. --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index 2d56f709..ab16a2ad 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -24,6 +24,9 @@ + + + @@ -50,7 +53,7 @@ + method="validate" with="url,credentialsId,groupVisibility,roleVisibility,useHTTPAuth,alternativeUrl,timeout,readTimeout,threadExecutorNumber,useBearerAuth" />
From 049406c5f531527e9c5d6ee24058ac56d5335a64 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Tue, 28 Mar 2023 00:40:39 +0200 Subject: [PATCH 05/29] Moved BearerHttpAuthenticationHandler to auth folder --- .../BearerHttpAuthenticationHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/hudson/plugins/jira/{authenticationhandler => auth}/BearerHttpAuthenticationHandler.java (93%) diff --git a/src/main/java/hudson/plugins/jira/authenticationhandler/BearerHttpAuthenticationHandler.java b/src/main/java/hudson/plugins/jira/auth/BearerHttpAuthenticationHandler.java similarity index 93% rename from src/main/java/hudson/plugins/jira/authenticationhandler/BearerHttpAuthenticationHandler.java rename to src/main/java/hudson/plugins/jira/auth/BearerHttpAuthenticationHandler.java index d0f44261..ff4043dc 100644 --- a/src/main/java/hudson/plugins/jira/authenticationhandler/BearerHttpAuthenticationHandler.java +++ b/src/main/java/hudson/plugins/jira/auth/BearerHttpAuthenticationHandler.java @@ -1,4 +1,4 @@ -package hudson.plugins.jira.authenticationhandler; +package hudson.plugins.jira.auth; import com.atlassian.jira.rest.client.api.AuthenticationHandler; import com.atlassian.httpclient.api.Request.Builder; From 85bbe68973e7fd917c95570d6f846c3a96a00de4 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Tue, 28 Mar 2023 00:41:13 +0200 Subject: [PATCH 06/29] Created JiraSessionFactory class --- .../plugins/jira/JiraSessionFactory.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/main/java/hudson/plugins/jira/JiraSessionFactory.java diff --git a/src/main/java/hudson/plugins/jira/JiraSessionFactory.java b/src/main/java/hudson/plugins/jira/JiraSessionFactory.java new file mode 100644 index 00000000..b614d3cc --- /dev/null +++ b/src/main/java/hudson/plugins/jira/JiraSessionFactory.java @@ -0,0 +1,71 @@ +package hudson.plugins.jira; + +import java.net.URI; + +import com.atlassian.jira.rest.client.auth.BasicHttpAuthenticationHandler; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; + +import hudson.plugins.jira.JiraSite.ExtendedAsynchronousJiraRestClientFactory; +import hudson.plugins.jira.auth.BearerHttpAuthenticationHandler; +import hudson.plugins.jira.extension.ExtendedJiraRestClient; + +/** + * Jira Session factory implementation + * + * @author Elia Bracci + */ +public class JiraSessionFactory { + + /** + * This method takes as parameters the JiraSite class, the jira URI and + * credentials and returns a JiraSession with Basic authentication if + * useBearerAuth is set to false, otherwise it returns a JiraSession with Bearer + * authentication if useBearerAuth is set to true. + * + * @param jiraSite jiraSite class + * @param uri jira uri + * @param credentials Jenkins credentials + * @return JiraSession instance + */ + public static JiraSession create(JiraSite jiraSite, URI uri, + StandardUsernamePasswordCredentials credentials) { + ExtendedJiraRestClient jiraRestClient; + JiraRestService jiraRestService; + + if (jiraSite.isUseBearerAuth()) { + BearerHttpAuthenticationHandler bearerHttpAuthenticationHandler = new BearerHttpAuthenticationHandler( + credentials.getPassword().getPlainText()); + + jiraRestClient = new ExtendedAsynchronousJiraRestClientFactory() + .create( + uri, + bearerHttpAuthenticationHandler, + jiraSite.getHttpClientOptions()); + + jiraRestService = new JiraRestService( + uri, + jiraRestClient, + credentials.getPassword().getPlainText(), + jiraSite.getReadTimeout()); + + } else { + jiraRestClient = new ExtendedAsynchronousJiraRestClientFactory() + .create( + uri, + new BasicHttpAuthenticationHandler( + credentials.getUsername(), + credentials.getPassword().getPlainText()), + jiraSite.getHttpClientOptions()); + + jiraRestService = new JiraRestService( + uri, + jiraRestClient, + credentials.getUsername(), + credentials.getPassword().getPlainText(), + jiraSite.getReadTimeout()); + } + + return new JiraSession(jiraSite, jiraRestService); + } + +} From 702e60d3082f4b0b3f8e52c2433d435b960b9f4c Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Tue, 28 Mar 2023 00:41:29 +0200 Subject: [PATCH 07/29] Updated JiraSite logic with useBearerAuth --- .../java/hudson/plugins/jira/JiraSite.java | 43 +++++++++++++++---- src/test/java/JiraTesterBearerAuth.java | 2 +- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/main/java/hudson/plugins/jira/JiraSite.java b/src/main/java/hudson/plugins/jira/JiraSite.java index 569cb821..63228afd 100644 --- a/src/main/java/hudson/plugins/jira/JiraSite.java +++ b/src/main/java/hudson/plugins/jira/JiraSite.java @@ -34,6 +34,7 @@ import hudson.plugins.jira.extension.ExtendedJiraRestClient; import hudson.plugins.jira.extension.ExtendedVersion; import hudson.plugins.jira.model.JiraIssue; +import hudson.plugins.jira.JiraSessionFactory; import hudson.security.ACL; import hudson.util.FormValidation; import hudson.util.ListBoxModel; @@ -139,6 +140,11 @@ public class JiraSite extends AbstractDescribableImpl { */ public String credentialsId; + /** + * Jira requires Bearer Authentication for login + */ + public boolean useBearerAuth; + /** * User name needed to login. Optional. * @deprecated use credentialsId @@ -322,6 +328,15 @@ public JiraSite(URL url, URL alternativeUrl, StandardUsernamePasswordCredentials updateJiraIssueForAllStatus, groupVisibility, roleVisibility, useHTTPAuth, timeout, readTimeout, threadExecutorNumber); } + // Deprecate the previous constructor but leave it in place for Java-level compatibility. + @Deprecated + public JiraSite(URL url, URL alternativeUrl, StandardUsernamePasswordCredentials credentials, boolean supportsWikiStyleComment, boolean recordScmChanges, String userPattern, + boolean updateJiraIssueForAllStatus, String groupVisibility, String roleVisibility, boolean useHTTPAuth, int timeout, int readTimeout, int threadExecutorNumber, boolean useBearerAuth) { + this(url, alternativeUrl, credentials==null?null:credentials.getId(), supportsWikiStyleComment, recordScmChanges, userPattern, + updateJiraIssueForAllStatus, groupVisibility, roleVisibility, useHTTPAuth, timeout, readTimeout, threadExecutorNumber); + this.useBearerAuth = useBearerAuth; + } + static URL toURL(String url) { url = Util.fixEmptyAndTrim(url); if (url == null) return null; @@ -414,6 +429,10 @@ public boolean isUseHTTPAuth() { return useHTTPAuth; } + public boolean isUseBearerAuth() { + return useBearerAuth; + } + public String getGroupVisibility() { return groupVisibility; } @@ -444,6 +463,11 @@ public void setUseHTTPAuth(boolean useHTTPAuth) { this.useHTTPAuth = useHTTPAuth; } + @DataBoundSetter + public void setUseBearerAuth(boolean useBearerAuth) { + this.useBearerAuth = useBearerAuth; + } + @DataBoundSetter public void setGroupVisibility(String groupVisibility) { this.groupVisibility = Util.fixEmptyAndTrim(groupVisibility); @@ -553,14 +577,7 @@ JiraSession createSession(Item item) { } LOGGER.fine("creating Jira Session: " + uri); - ExtendedJiraRestClient jiraRestClient = new ExtendedAsynchronousJiraRestClientFactory() - .create(uri, new BasicHttpAuthenticationHandler( - credentials.getUsername(), credentials.getPassword().getPlainText() - ), - getHttpClientOptions() - ); - return new JiraSession(this, new JiraRestService(uri, jiraRestClient, credentials.getUsername(), - credentials.getPassword().getPlainText(), readTimeout)); + return JiraSessionFactory.create(this, uri, credentials); } Lock getProjectUpdateLock() { @@ -599,7 +616,7 @@ private StandardUsernamePasswordCredentials resolveCredentials(Item item) { } - private HttpClientOptions getHttpClientOptions() { + protected HttpClientOptions getHttpClientOptions() { final HttpClientOptions options = new HttpClientOptions(); options.setRequestTimeout(readTimeout, TimeUnit.SECONDS); options.setSocketTimeout(timeout, TimeUnit.SECONDS); @@ -1161,6 +1178,7 @@ public FormValidation doValidate(@QueryParameter String url, @QueryParameter int timeout, @QueryParameter int readTimeout, @QueryParameter int threadExecutorNumber, + @QueryParameter boolean useBearerAuth, @AncestorInPath Item item) { if (item == null) { @@ -1198,6 +1216,7 @@ public FormValidation doValidate(@QueryParameter String url, .withGroupVisibility(groupVisibility) .withRoleVisibility(roleVisibility) .withUseHTTPAuth(useHTTPAuth) + .withUseBearerAuth(useBearerAuth) .build(); if(threadExecutorNumber<1){ @@ -1261,6 +1280,7 @@ static class Builder { private String groupVisibility; private String roleVisibility; private boolean useHTTPAuth; + private boolean useBearerAuth; public Builder withMainURL( URL mainURL) { this.mainURL = mainURL; @@ -1312,6 +1332,11 @@ public Builder withUseHTTPAuth( boolean useHTTPAuth) { return this; } + public Builder withUseBearerAuth( boolean useBearerAuth) { + this.useBearerAuth = useBearerAuth; + return this; + } + public JiraSite build() { return new JiraSite(mainURL, alternativeURL, credentialsId, supportsWikiStyleComment, recordScmChanges, userPattern, updateJiraIssueForAllStatus, groupVisibility, roleVisibility, useHTTPAuth); diff --git a/src/test/java/JiraTesterBearerAuth.java b/src/test/java/JiraTesterBearerAuth.java index ec36fa32..4b1b9db7 100644 --- a/src/test/java/JiraTesterBearerAuth.java +++ b/src/test/java/JiraTesterBearerAuth.java @@ -7,9 +7,9 @@ import com.atlassian.jira.rest.client.api.domain.User; import hudson.plugins.jira.JiraRestService; import hudson.plugins.jira.JiraSite; +import hudson.plugins.jira.auth.BearerHttpAuthenticationHandler; import hudson.plugins.jira.extension.ExtendedJiraRestClient; import hudson.plugins.jira.extension.ExtendedVersion; -import hudson.plugins.jira.authenticationhandler.BearerHttpAuthenticationHandler; import java.net.URI; import java.net.URL; From 8cb07a86ff94d0e8b1c993e1e8211473c6bfde0f Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Tue, 28 Mar 2023 00:43:23 +0200 Subject: [PATCH 08/29] Added JiraRestServiceBearerAuthTest class --- .../auth/JiraRestServiceBearerAuthTest.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/test/java/hudson/plugins/jira/auth/JiraRestServiceBearerAuthTest.java diff --git a/src/test/java/hudson/plugins/jira/auth/JiraRestServiceBearerAuthTest.java b/src/test/java/hudson/plugins/jira/auth/JiraRestServiceBearerAuthTest.java new file mode 100644 index 00000000..e8f7181f --- /dev/null +++ b/src/test/java/hudson/plugins/jira/auth/JiraRestServiceBearerAuthTest.java @@ -0,0 +1,63 @@ +package hudson.plugins.jira.auth; + +import com.atlassian.jira.rest.client.api.SearchRestClient; +import com.atlassian.jira.rest.client.api.domain.SearchResult; +import io.atlassian.util.concurrent.Promise; +import hudson.plugins.jira.JiraRestService; +import hudson.plugins.jira.JiraSite; +import hudson.plugins.jira.extension.ExtendedJiraRestClient; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.net.URI; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.doReturn; + +public class JiraRestServiceBearerAuthTest { + + private final URI JIRA_URI = URI.create("http://example.com:8080/"); + private final String TOKEN = "token"; + private ExtendedJiraRestClient client; + private SearchRestClient searchRestClient; + private Promise promise; + private SearchResult searchResult; + + @Before + public void createMocks() throws InterruptedException, ExecutionException, TimeoutException { + client = mock(ExtendedJiraRestClient.class); + searchRestClient = mock(SearchRestClient.class); + promise = mock(Promise.class); + searchResult = mock(SearchResult.class); + + doReturn(searchRestClient).when(client).getSearchClient(); + doReturn(promise).when(searchRestClient).searchJql(any(), any(), anyInt(), any()); + doReturn(searchResult).when(promise).get(anyLong(), any()); + } + + @Test + public void baseApiPath() { + JiraRestService service = new JiraRestService(JIRA_URI, client, TOKEN, JiraSite.DEFAULT_TIMEOUT); + assertEquals("/" + JiraRestService.BASE_API_PATH, service.getBaseApiPath()); + + URI uri = URI.create("https://example.com/path/to/jira"); + service = new JiraRestService(uri, client, TOKEN, JiraSite.DEFAULT_TIMEOUT); + assertEquals("/path/to/jira/" + JiraRestService.BASE_API_PATH, service.getBaseApiPath()); + } + + @Test(expected = TimeoutException.class) + public void getIssuesFromJqlSearchTimeout() throws TimeoutException, InterruptedException, ExecutionException { + JiraRestService service = spy(new JiraRestService(JIRA_URI, client, TOKEN, JiraSite.DEFAULT_TIMEOUT)); + doThrow(new TimeoutException()).when(promise).get(Mockito.anyLong(), Mockito.any()); + service.getIssuesFromJqlSearch("*", null); + } +} From 322d22f9f7dde43fd089b2434385e0f72a89f126 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Tue, 28 Mar 2023 00:52:32 +0200 Subject: [PATCH 09/29] Fixed DescriptorImpltest --- .../java/hudson/plugins/jira/DescriptorImplTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/hudson/plugins/jira/DescriptorImplTest.java b/src/test/java/hudson/plugins/jira/DescriptorImplTest.java index 8f483a7c..f31c5eff 100644 --- a/src/test/java/hudson/plugins/jira/DescriptorImplTest.java +++ b/src/test/java/hudson/plugins/jira/DescriptorImplTest.java @@ -137,7 +137,7 @@ public void validateFormConnectionErrors() throws Exception { FormValidation validation = descriptor.doValidate("http://localhost:8080", null, null, null, false, null, JiraSite.DEFAULT_TIMEOUT, JiraSite.DEFAULT_READ_TIMEOUT, JiraSite.DEFAULT_THREAD_EXECUTOR_NUMBER, - project); + false, project); assertEquals(FormValidation.Kind.ERROR, validation.kind); verify(site).getSession(project); @@ -145,7 +145,7 @@ public void validateFormConnectionErrors() throws Exception { validation = descriptor.doValidate("http://localhost:8080", null, null, null, false, null, -1, JiraSite.DEFAULT_READ_TIMEOUT, JiraSite.DEFAULT_THREAD_EXECUTOR_NUMBER, - project); + false, project); assertEquals(Messages.JiraSite_timeoutMinimunValue("1"), validation.getLocalizedMessage()); assertEquals(FormValidation.Kind.ERROR, validation.kind); verify(site).getSession(project); @@ -153,7 +153,7 @@ public void validateFormConnectionErrors() throws Exception { validation = descriptor.doValidate("http://localhost:8080", null, null, null, false, null, JiraSite.DEFAULT_TIMEOUT, -1, JiraSite.DEFAULT_THREAD_EXECUTOR_NUMBER, - project); + false, project); assertEquals(Messages.JiraSite_readTimeoutMinimunValue("1"), validation.getMessage()); assertEquals(FormValidation.Kind.ERROR, validation.kind); @@ -162,7 +162,7 @@ public void validateFormConnectionErrors() throws Exception { validation = descriptor.doValidate("http://localhost:8080", null, null, null, false, null, JiraSite.DEFAULT_TIMEOUT, JiraSite.DEFAULT_READ_TIMEOUT, -1, - project); + false, project); assertEquals(Messages.JiraSite_threadExecutorMinimunSize("1"), validation.getMessage()); assertEquals(FormValidation.Kind.ERROR, validation.kind); verify(site).getSession(project); @@ -180,7 +180,7 @@ public void validateFormConnectionOK() throws Exception { FormValidation validation = descriptor.doValidate("http://localhost:8080", null, null, null, false, null, JiraSite.DEFAULT_TIMEOUT, JiraSite.DEFAULT_READ_TIMEOUT, JiraSite.DEFAULT_THREAD_EXECUTOR_NUMBER, - project); + false, project); verify(builder).build(); verify(site).getSession(project); From b94659e1b8550b0d1dbdf315041f712111a4796a Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Tue, 28 Mar 2023 11:06:01 +0200 Subject: [PATCH 10/29] Fixed typo --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index ab16a2ad..c0ff9c99 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -25,7 +25,7 @@ - + From 8714cf6c76ec04d2ef2698bce3b674ec8aa4a9a9 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Tue, 28 Mar 2023 11:06:37 +0200 Subject: [PATCH 11/29] Updated doValidate JiraSite method --- src/main/java/hudson/plugins/jira/JiraSite.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/hudson/plugins/jira/JiraSite.java b/src/main/java/hudson/plugins/jira/JiraSite.java index 63228afd..c7d4e527 100644 --- a/src/main/java/hudson/plugins/jira/JiraSite.java +++ b/src/main/java/hudson/plugins/jira/JiraSite.java @@ -1216,7 +1216,6 @@ public FormValidation doValidate(@QueryParameter String url, .withGroupVisibility(groupVisibility) .withRoleVisibility(roleVisibility) .withUseHTTPAuth(useHTTPAuth) - .withUseBearerAuth(useBearerAuth) .build(); if(threadExecutorNumber<1){ @@ -1232,6 +1231,7 @@ public FormValidation doValidate(@QueryParameter String url, site.setTimeout(timeout); site.setReadTimeout(readTimeout); site.setThreadExecutorNumber(threadExecutorNumber); + site.setUseBearerAuth(useBearerAuth); JiraSession session = null; try { session = site.getSession(item); @@ -1280,7 +1280,6 @@ static class Builder { private String groupVisibility; private String roleVisibility; private boolean useHTTPAuth; - private boolean useBearerAuth; public Builder withMainURL( URL mainURL) { this.mainURL = mainURL; @@ -1332,11 +1331,6 @@ public Builder withUseHTTPAuth( boolean useHTTPAuth) { return this; } - public Builder withUseBearerAuth( boolean useBearerAuth) { - this.useBearerAuth = useBearerAuth; - return this; - } - public JiraSite build() { return new JiraSite(mainURL, alternativeURL, credentialsId, supportsWikiStyleComment, recordScmChanges, userPattern, updateJiraIssueForAllStatus, groupVisibility, roleVisibility, useHTTPAuth); From e831f45a5266bc481a75e99468daeeba53922002 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Tue, 28 Mar 2023 12:10:33 +0200 Subject: [PATCH 12/29] Added BearerHttpAuthenticationHandlerTest class --- .../plugins/jira/JiraSessionFactory.java | 1 - .../BearerHttpAuthenticationHandlerTest.java | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/test/java/hudson/plugins/jira/auth/BearerHttpAuthenticationHandlerTest.java diff --git a/src/main/java/hudson/plugins/jira/JiraSessionFactory.java b/src/main/java/hudson/plugins/jira/JiraSessionFactory.java index b614d3cc..c505980c 100644 --- a/src/main/java/hudson/plugins/jira/JiraSessionFactory.java +++ b/src/main/java/hudson/plugins/jira/JiraSessionFactory.java @@ -47,7 +47,6 @@ public static JiraSession create(JiraSite jiraSite, URI uri, jiraRestClient, credentials.getPassword().getPlainText(), jiraSite.getReadTimeout()); - } else { jiraRestClient = new ExtendedAsynchronousJiraRestClientFactory() .create( diff --git a/src/test/java/hudson/plugins/jira/auth/BearerHttpAuthenticationHandlerTest.java b/src/test/java/hudson/plugins/jira/auth/BearerHttpAuthenticationHandlerTest.java new file mode 100644 index 00000000..4e3c966f --- /dev/null +++ b/src/test/java/hudson/plugins/jira/auth/BearerHttpAuthenticationHandlerTest.java @@ -0,0 +1,21 @@ +package hudson.plugins.jira.auth; + +import com.atlassian.httpclient.api.Request; +import org.junit.Test; +import static org.mockito.Mockito.mock; + +import static org.mockito.Mockito.verify; + +public class BearerHttpAuthenticationHandlerTest { + + @Test + public void testConfigure() { + String token = "token"; + BearerHttpAuthenticationHandler handler = new BearerHttpAuthenticationHandler(token); + Request.Builder builder = mock(Request.Builder.class); + + handler.configure(builder); + + verify(builder).setHeader("Authorization", "Bearer " + token); + } +} \ No newline at end of file From e9f6ed26215015d0f67df5edab3b4df866751eab Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Thu, 30 Mar 2023 12:25:38 +0200 Subject: [PATCH 13/29] Updated config.jelly --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index c0ff9c99..1eb0aebb 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -9,6 +9,9 @@ + + + From e7f942596219ce9bd40853eecd85c0e7805569a7 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Thu, 30 Mar 2023 14:21:13 +0200 Subject: [PATCH 14/29] Testing config.jelly radio button on authentication method --- .../hudson/plugins/jira/JiraSite/config.jelly | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index 1eb0aebb..b2a12174 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -12,6 +12,14 @@ + + + + + + + + @@ -27,9 +35,6 @@ - - - From 34ab5d07904e2ca979e5f3e1b2c05e558df3dfee Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Thu, 30 Mar 2023 14:38:39 +0200 Subject: [PATCH 15/29] Fixed config.jelly error --- .../resources/hudson/plugins/jira/JiraSite/config.jelly | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index b2a12174..94f9a00d 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -12,14 +12,6 @@ - - - - - - - - From ebb5203c3c915814315d0553c42a2673cd3f63d0 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Thu, 30 Mar 2023 14:50:11 +0200 Subject: [PATCH 16/29] Testing jelly config --- .../resources/hudson/plugins/jira/JiraSite/config.jelly | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index 94f9a00d..34938cc0 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -12,6 +12,12 @@ + + + @@ -53,7 +59,7 @@ + method="validate" with="url,credentialsId,groupVisibility,roleVisibility,${authenticationMethod.value == 'useHTTPAuth'},alternativeUrl,timeout,readTimeout,threadExecutorNumber,${authenticationMethod.value == 'useBearerAuth'}" />
From 81369ce5b9c9093319954e8386df3ec7b26593da Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Thu, 30 Mar 2023 14:50:38 +0200 Subject: [PATCH 17/29] Fix jelly config --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index 34938cc0..9912d6fe 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -59,7 +59,7 @@ + method="validate" with="url,credentialsId,groupVisibility,roleVisibility,${authenticationMethod == 'useHTTPAuth'},alternativeUrl,timeout,readTimeout,threadExecutorNumber,${authenticationMethod == 'useBearerAuth'}" />
From e62e3ffaeecff89b3e0f6a2357fafae5da48375f Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Thu, 30 Mar 2023 15:46:34 +0200 Subject: [PATCH 18/29] Testing default value for authentication method --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index 9912d6fe..d1326075 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -14,8 +14,8 @@ - - + - - - - - - - - + + @@ -59,7 +53,7 @@ + method="validate" with="url,credentialsId,groupVisibility,roleVisibility,useBearerAuth,alternativeUrl,timeout,readTimeout,threadExecutorNumber,useBearerAuth" />
From 66d7d204a52bea7b50b7a4da149b2025883669d3 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Thu, 30 Mar 2023 16:51:21 +0200 Subject: [PATCH 21/29] Hide useHTTPAuth entry --- .../hudson/plugins/jira/JiraSite/config.jelly | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index 30edc351..1fd8773f 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -6,12 +6,12 @@ - - - + + + + + + @@ -53,7 +53,7 @@ + method="validate" with="url,credentialsId,groupVisibility,roleVisibility,useHTTPAuth,alternativeUrl,timeout,readTimeout,threadExecutorNumber,useBearerAuth" />
From a41e9018fee0bd3cef5115d400e3894c0b797d82 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Thu, 30 Mar 2023 17:26:59 +0200 Subject: [PATCH 22/29] Updated use Bearer authentication title --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index 1fd8773f..ddf885e6 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -10,7 +10,7 @@ - + From 7c6d4ba10be719167cfcc74dc3f83857054e729b Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Fri, 7 Apr 2023 16:04:18 +0200 Subject: [PATCH 23/29] Testing apache.httpcomponentns library --- pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pom.xml b/pom.xml index 6c071707..7ff0180e 100644 --- a/pom.xml +++ b/pom.xml @@ -161,10 +161,6 @@ javax.activation activation - - org.apache.httpcomponents - httpmime - com.atlassian.httpclient atlassian-httpclient-plugin From e4628e65aa8014f22cc928c2c487c4cc550a6c39 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Fri, 7 Apr 2023 16:16:01 +0200 Subject: [PATCH 24/29] Revert "Testing apache.httpcomponentns library" This reverts commit 7c6d4ba10be719167cfcc74dc3f83857054e729b. --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 7ff0180e..6c071707 100644 --- a/pom.xml +++ b/pom.xml @@ -161,6 +161,10 @@ javax.activation activation + + org.apache.httpcomponents + httpmime + com.atlassian.httpclient atlassian-httpclient-plugin From 7329d312ae458fcc34ee178cf3571d7f4eaccf5d Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Thu, 11 May 2023 17:24:28 +0200 Subject: [PATCH 25/29] Added note on http authentication bearer checkbox --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index ddf885e6..8bf668c8 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -10,7 +10,7 @@ - + From c2d7a9d13afc3701a3c97ae87f351f65d1526344 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Fri, 12 May 2023 09:17:17 +0200 Subject: [PATCH 26/29] Moved useBearerAuth note to description --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index 8bf668c8..af3c6c2a 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -10,7 +10,8 @@ - + From ff1a63cd56dfeda69d2386f68d72bd96fe42050b Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Fri, 12 May 2023 09:35:40 +0200 Subject: [PATCH 27/29] Fixing config.jelly --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index af3c6c2a..7e9702af 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -10,8 +10,7 @@ - + From 3cb87dd9d2fb2ae5e2c16177869fcc945513483c Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Fri, 12 May 2023 14:58:50 +0200 Subject: [PATCH 28/29] Moved descriptio to config.properties --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 2 +- .../resources/hudson/plugins/jira/JiraSite/config.properties | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index 7e9702af..482c9f88 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -10,7 +10,7 @@ - + diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.properties b/src/main/resources/hudson/plugins/jira/JiraSite/config.properties index 9f227308..ed396508 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.properties +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.properties @@ -1,2 +1,3 @@ site.alternativeUrl=Jira alternative URL site.timeout=in seconds +site.useBearerAuth=Note: Bearer authentication is only supported in Jira Server, for Jira Cloud leave this unchecked \ No newline at end of file From 03b244067c7da34f12359e3bd9f1366624355e67 Mon Sep 17 00:00:00 2001 From: Elia Bracci Date: Wed, 17 May 2023 14:26:06 -0500 Subject: [PATCH 29/29] Moved description to entry tag --- src/main/resources/hudson/plugins/jira/JiraSite/config.jelly | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly index 482c9f88..7e939f4e 100644 --- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly +++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly @@ -9,8 +9,8 @@ - - + +