CVE-2018-1000104
Description
Jenkins Coverity Plugin ≤1.10.0 stores keystore and private key passwords in plaintext in CIMInstance.java, enabling local access or browser control to retrieve them.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Jenkins Coverity Plugin ≤1.10.0 stores keystore and private key passwords in plaintext in CIMInstance.java, enabling local access or browser control to retrieve them.
Vulnerability
Jenkins Coverity Plugin version 1.10.0 and earlier stores the configured keystore and private key passwords in plaintext within the CIMInstance.java class [1][3]. No special configuration is required to reach the vulnerable code path; the passwords are persisted as plain-text fields in the plugin's configuration.
Exploitation
An attacker with local file system access to the Jenkins master, or who can control a Jenkins administrator's web browser (e.g., via a malicious browser extension), can retrieve the stored passwords by reading the plugin's configuration files or inspecting the user interface elements that expose these values [2][3].
Impact
Successful exploitation allows the attacker to obtain the keystore and private key passwords, potentially compromising encrypted communications or enabling unauthorized access to Coverity services using those credentials.
Mitigation
The vulnerability is fixed in Coverity Plugin version 1.11, as shown in the commit that migrates to the Jenkins Credentials API [4]. The plugin is deprecated and no longer maintained; users are encouraged to migrate to the Synopsys Coverity Jenkins Plugin [1]. For users unable to upgrade immediately, careful management of file system access and browser extensions is recommended.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.jenkins-ci.plugins:coverityMaven | < 1.11.0 | 1.11.0 |
Affected products
1Patches
134b7c2b07014Fix Jenkins issue SECURITY-260 - credentials stored in plaintext. Removed the "user" and "password" which were stored as plain text. If the previous configuration still contains plaintext user and password, these information will be migrated into Credentials once.
15 files changed · +264 −184
src/main/java/jenkins/plugins/coverity/CIMInstance.java+37 −44 modified@@ -27,12 +27,17 @@ import javax.xml.ws.WebServiceException; import javax.xml.ws.soap.SOAPFaultException; +import com.cloudbees.plugins.credentials.*; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.domains.Domain; +import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import hudson.util.Secret; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; -import com.cloudbees.plugins.credentials.CredentialsMatchers; -import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.common.StandardCredentials; import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; import com.cloudbees.plugins.credentials.domains.DomainRequirement; @@ -65,7 +70,13 @@ * Represents one Coverity Integrity Manager server. Abstracts functions like getting streams and defects. */ public class CIMInstance { + + // deprecated fields which were removed in plugin version 1.11 + private transient String user; + private transient String password; + private static final Logger logger = Logger.getLogger(CIMStream.class.getName()); + private static final String migratedCredentialId = "Migrated-Coverity-Credential"; /** * The id for this instance, used as a key in CoverityPublisher */ @@ -81,20 +92,6 @@ public class CIMInstance { */ private final int port; - /** - * Username for connecting to the CIM server - * Deprecated since 1.10 - */ - @Deprecated - private String user; - - /** - * Password for connecting to the CIM server - * Deprecated since 1.10 - */ - @Deprecated - private String password; - /** * Use SSL */ @@ -120,6 +117,17 @@ public CIMInstance(String name, String host, int port, String credentialId) { this.credentialId = credentialId; } + protected Object readResolve() { + createCredentials(user, password); + + // Setting the migrated credential to use + if (StringUtils.isEmpty(credentialId)) { + credentialId = migratedCredentialId; + } + + return this; + } + public String getHost() { return host; } @@ -132,32 +140,6 @@ public String getName() { return name; } - /* - * Deprecated since 1.10. Use credentialId - */ - @Deprecated - public String getUser() { - return user; - } - - @DataBoundSetter - public void setUser(String user){ - this.user = user; - } - - /* - * Deprecated since 1.10. Use credentialId - */ - @Deprecated - public String getPassword() { - return password; - } - - @DataBoundSetter - public void setPassword(String password){ - this.password = password; - } - public boolean isUseSSL() { return useSSL; } @@ -510,10 +492,21 @@ private String retrieveCredentialInfo(boolean getUsername){ return StringUtils.EMPTY; } + private void createCredentials(String username, String password) { + try{ + UsernamePasswordCredentialsImpl credential = new UsernamePasswordCredentialsImpl( + CredentialsScope.GLOBAL, name + "_" + username, "Migrated Coverity Credential", username, password); + + CredentialsStore store = CredentialsProvider.lookupStores(Jenkins.getInstance()).iterator().next(); + store.addCredentials(Domain.global(), credential); + } catch (IOException ioe) { + logger.warning("Migrating username and password into credentials encountered IOException" + + "\nPlease try to resolve this issue by adding credentials manually"); + } + } + public CIMInstance cloneWithCredential(String credentialId) { CIMInstance instance = new CIMInstance(name, host, port, credentialId); - instance.setUser(user); - instance.setPassword(password); instance.setUseSSL(useSSL); return instance; }
src/main/java/jenkins/plugins/coverity/CoverityPublisher.java+0 −3 modified@@ -475,11 +475,8 @@ public String getDisplayName() { * This is called when the user clicks the 'Validate' button for an instance. */ public FormValidation doCheckInstance(@QueryParameter String host, @QueryParameter int port, - @QueryParameter String user, @QueryParameter String password, @QueryParameter boolean useSSL, @QueryParameter String credentialId) { CIMInstance instance = new CIMInstance("", host, port, credentialId); - instance.setUser(user); - instance.setPassword(password); instance.setUseSSL(useSSL); return instance.doCheck(); }
src/main/resources/jenkins/plugins/coverity/CoverityPublisher/global.jelly+2 −8 modified@@ -29,18 +29,12 @@ <f:entry title="Use SSL" field="useSSL"> <f:checkbox/> </f:entry> - <f:entry title="Credentials (Recommended)" field="credentialId"> + <f:entry title="Credentials" field="credentialId"> <c:select/> </f:entry> - <f:entry title="Username (Deprecated)" field="user"> - <f:textbox/> - </f:entry> - <f:entry title="Password (Deprecated)" field="password"> - <f:password/> - </f:entry> <f:validateButton method="checkInstance" title="Check" progress="Checking..." - with="host,port,user,password,useSSL,credentialId"/> + with="host,port,useSSL,credentialId"/> <f:entry title=""> <div align="right"> <f:repeatableDeleteButton value="Delete"/>
src/test/java/jenkins/plugins/coverity/CheckConfigTest.java+42 −3 modified@@ -10,37 +10,51 @@ *******************************************************************************/ package jenkins.plugins.coverity; +import com.cloudbees.plugins.credentials.Credentials; +import com.cloudbees.plugins.credentials.CredentialsMatcher; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.domains.DomainRequirement; +import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; import hudson.Launcher; import hudson.model.Executor; import hudson.model.FreeStyleBuild; +import hudson.model.ItemGroup; import hudson.model.TaskListener; import hudson.remoting.LocalChannel; import hudson.tools.ToolLocationNodeProperty; import hudson.util.FormValidation; +import hudson.util.Secret; import jenkins.model.Jenkins; import jenkins.plugins.coverity.Utils.*; import jenkins.plugins.coverity.ws.TestWebServiceFactory; import jenkins.plugins.coverity.ws.TestWebServiceFactory.TestConfigurationService; import jenkins.plugins.coverity.ws.WebServiceFactory; +import org.acegisecurity.Authentication; import org.apache.commons.lang.StringUtils; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.io.IOException; +import java.util.ArrayList; import static org.junit.Assert.*; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(PowerMockRunner.class) -@PrepareForTest({Jenkins.class, Executor.class, ToolLocationNodeProperty.class, WebServiceFactory.class}) +@PrepareForTest({Jenkins.class, Executor.class, ToolLocationNodeProperty.class, WebServiceFactory.class, Secret.class, CredentialsMatchers.class, CredentialsProvider.class}) public class CheckConfigTest { @Mock @@ -58,6 +72,9 @@ public class CheckConfigTest { private WebServiceFactory testWsFactory; private TestableConsoleLogger testLogger; + @Mock + UsernamePasswordCredentials credentials; + @Before public void setup() throws IOException { // setup web service factory @@ -116,10 +133,10 @@ public void checkStreamTest_NoCIMInstance() { @Test public void checkStreamTest_NoStreamConfiguredForCIMStream() { + setCredentialManager("admin", "password"); CoverityPublisher publisher = new CoverityPublisherBuilder().build(); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test-cim-instance").withHost("test-cim-instance").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("") - .build(); + .withUseSSL(false).withDefaultCredentialId().build(); CIMStream cimStream = new CIMStream("test-cim-instance", StringUtils.EMPTY, StringUtils.EMPTY); when(descriptor.getInstance(any(CoverityPublisher.class))).thenReturn(cimInstance); @@ -268,4 +285,26 @@ public void checkNode_withInstallation() throws IOException, InterruptedExceptio assertTrue(result.isValid()); assertEquals("[Node] " + nodeName + " : version 2017.07", result.getStatus()); } + + protected void setCredentialManager(String username, String password) { + PowerMockito.mockStatic(CredentialsMatchers.class); + PowerMockito.mockStatic(CredentialsProvider.class); + credentials = Mockito.mock(UsernamePasswordCredentialsImpl.class); + + Secret secret = PowerMockito.mock(Secret.class); + PowerMockito.when(secret.getPlainText()).thenReturn(password); + PowerMockito.when(credentials.getPassword()).thenReturn(secret); + PowerMockito.when(credentials.getUsername()).thenReturn(username); + + PowerMockito.when(CredentialsProvider.lookupCredentials( + Matchers.<Class<Credentials>>any(), + Matchers.any(ItemGroup.class), + Matchers.any(Authentication.class), + Matchers.anyListOf(DomainRequirement.class) + )).thenReturn(new ArrayList<Credentials>() { + }); + + PowerMockito.when(CredentialsMatchers.firstOrNull(Matchers.anyListOf(StandardCredentials.class), + Matchers.any(CredentialsMatcher.class))).thenReturn((StandardUsernamePasswordCredentials) credentials); + } }
src/test/java/jenkins/plugins/coverity/CIMInstanceTest.java+61 −24 modified@@ -25,7 +25,11 @@ import javax.net.ssl.SSLContext; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import hudson.util.Secret; import jenkins.plugins.coverity.Utils.CIMInstanceBuilder; +import jenkins.plugins.coverity.Utils.CredentialUtil; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.junit.Before; @@ -53,7 +57,7 @@ @RunWith(PowerMockRunner.class) -@PrepareForTest({WebServiceFactory.class, Client.class, SSLContext.class}) +@PrepareForTest({WebServiceFactory.class, Client.class, SSLContext.class, Secret.class, CredentialsMatchers.class, CredentialsProvider.class}) @PowerMockIgnore({"org.apache.http.conn.ssl.*", "javax.net.ssl.*" , "javax.crypto.*"}) public class CIMInstanceTest { private TestWebServiceFactory testWsFactory; @@ -71,8 +75,9 @@ public void setup() throws IOException { @Test public void getProjectKey_forExistingProject() throws IOException, CovRemoteServiceException_Exception { + CredentialUtil.setCredentialManager("admin", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); testConfigurationService.setupProjects("project", 3, "stream", 1); @@ -84,8 +89,9 @@ public void getProjectKey_forExistingProject() throws IOException, CovRemoteServ @Test public void getProjectKey_forUnknownProject() throws IOException, CovRemoteServiceException_Exception { + CredentialUtil.setCredentialManager("admin", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); testConfigurationService.setupProjects("project", 3, "stream", 1); @@ -98,9 +104,10 @@ public void getProjectKey_forUnknownProject() throws IOException, CovRemoteServi @Test public void getStream_returnsMatchingStream() throws IOException, CovRemoteServiceException_Exception { final String streamId = "stream0"; + CredentialUtil.setCredentialManager("admin", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); testConfigurationService.setupProjects("project", 3, "stream", 1); @@ -115,9 +122,10 @@ public void getStream_returnsMatchingStream() throws IOException, CovRemoteServi @Test public void getStreams_throwsWithNoStreams() throws IOException, CovRemoteServiceException_Exception { final String streamId = "stream1"; + CredentialUtil.setCredentialManager("admin", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); exception.expect(IOException.class); exception.expectMessage("An error occurred while retrieving streams for the given project. Could not find stream: " + streamId); @@ -131,9 +139,10 @@ public void doCheck_invalidWSResponseCode() { "Check Coverity Web Service Response: { Code=401, Message=\"failed response message\" }" + System.lineSeparator() + "(check that the values entered for this instance are correct and ensure the Coverity Connect version is at least " + CoverityVersion.MINIMUM_SUPPORTED_VERSION.toString() + ")"; + CredentialUtil.setCredentialManager("admin", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); FormValidation result = cimInstance.doCheck(); @@ -144,8 +153,10 @@ public void doCheck_invalidWSResponseCode() { @Test public void doCheck_superUser() throws IOException { final String expectedSuccessMessage = "Successfully connected to the instance."; + CredentialUtil.setCredentialManager("admin", "password"); + CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); testConfigurationService.setupUser("cim-user", true, new HashMap<String, String[]>()); @@ -159,9 +170,10 @@ public void doCheck_superUser() throws IOException { @Test public void doCheck_missingCommitPermission() throws IOException { final String expectedErrorMessage ="\"cim-user\" does not have following permission(s): \"Commit to a stream\" "; + CredentialUtil.setCredentialManager("cim-user", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -177,9 +189,10 @@ public void doCheck_missingCommitPermission() throws IOException { @Test public void doCheck_missingViewIssuesPermission() throws IOException { final String expectedErrorMessage ="\"cim-user\" does not have following permission(s): \"View issues\" "; + CredentialUtil.setCredentialManager("cim-user", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -195,9 +208,10 @@ public void doCheck_missingViewIssuesPermission() throws IOException { @Test public void doCheck_missingInvokeWebServicesPermission() throws IOException, CovRemoteServiceException_Exception { final String expectedErrorMessage ="\"cim-user\" does not have following permission(s): \"Access web services\""; + CredentialUtil.setCredentialManager("cim-user", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -213,8 +227,10 @@ public void doCheck_missingInvokeWebServicesPermission() throws IOException, Cov @Test public void doCheck_allRoleAssignments() throws IOException { final String expectedSuccessMessage = "Successfully connected to the instance."; + CredentialUtil.setCredentialManager("cim-user", "password"); + CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -230,8 +246,10 @@ public void doCheck_allRoleAssignments() throws IOException { @Test public void doCheck_builtInRoleServerAdmin() throws IOException { final String expectedSuccessMessage = "Successfully connected to the instance."; + CredentialUtil.setCredentialManager("cim-user", "password"); + CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -247,8 +265,10 @@ public void doCheck_builtInRoleServerAdmin() throws IOException { @Test public void doCheck_builtInRoleProjectOwner() throws IOException { final String expectedSuccessMessage = "Successfully connected to the instance."; + CredentialUtil.setCredentialManager("cim-user", "password"); + CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -264,8 +284,10 @@ public void doCheck_builtInRoleProjectOwner() throws IOException { @Test public void doCheck_builtInRoleStreamOwner() throws IOException { final String expectedSuccessMessage = "Successfully connected to the instance."; + CredentialUtil.setCredentialManager("cim-user", "password"); + CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -281,8 +303,10 @@ public void doCheck_builtInRoleStreamOwner() throws IOException { @Test public void doCheck_allGroupRoleAssignments() throws IOException { final String expectedSuccessMessage = "Successfully connected to the instance."; + CredentialUtil.setCredentialManager("cim-user", "password"); + CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -300,8 +324,10 @@ public void doCheck_allGroupRoleAssignments() throws IOException { @Test public void doCheck_groupBuiltInRoleServerAdmin() throws IOException { final String expectedSuccessMessage = "Successfully connected to the instance."; + CredentialUtil.setCredentialManager("cim-user", "password"); + CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -319,8 +345,10 @@ public void doCheck_groupBuiltInRoleServerAdmin() throws IOException { @Test public void doCheck_nonGlobalRoleAssignments() throws IOException { final String expectedWarningMessage ="\"cim-user\" does not have following global permission(s): \"Commit to a stream\" \"View issues\" "; + CredentialUtil.setCredentialManager("cim-user", "password"); + CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -336,8 +364,10 @@ public void doCheck_nonGlobalRoleAssignments() throws IOException { @Test public void doCheck_nonGlobalBuiltInRole() throws IOException { final String expectedWarningMessage ="\"cim-user\" does not have following global permission(s): \"Commit to a stream\" \"View issues\" "; + CredentialUtil.setCredentialManager("cim-user", "password"); + CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("cim-user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); Map<String, String[]> rolePermissions = new HashMap<>(); @@ -429,8 +459,10 @@ public void getViews_returnsAvailableIssuesViews() throws MalformedURLException, " }" + "]}"; TestableViewsService.setupWithViewApi(viewApiJsonResult); + CredentialUtil.setCredentialManager("user", "password"); + CIMInstance cimInstance = new CIMInstanceBuilder().withName("instance").withHost("host").withPort(8080) - .withUser("user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); final ImmutableSortedMap<Long, String> result = cimInstance.getViews(); @@ -496,8 +528,9 @@ public void getViews_withSSL_returnsAvailableIssuesViews() throws MalformedURLEx " }" + "]}"; TestableViewsService.setupWithViewApi(viewApiJsonResult); + CredentialUtil.setCredentialManager("user", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("instance").withHost("ssl-host").withPort(8443) - .withUser("user").withPassword("password").withUseSSL(true).withCredentialId("").build(); + .withUseSSL(true).withDefaultCredentialId().build(); final ImmutableSortedMap<Long, String> result = cimInstance.getViews(); @@ -512,9 +545,10 @@ public void getViews_withSSL_returnsAvailableIssuesViews() throws MalformedURLEx public void getViews_handlesExceptions() throws NoSuchAlgorithmException { PowerMockito.mockStatic(SSLContext.class); when(SSLContext.getInstance("SSL")).thenThrow(new NoSuchAlgorithmException()); + CredentialUtil.setCredentialManager("user", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("instance").withHost("host").withPort(8080) - .withUser("user").withPassword("password").withUseSSL(true).withCredentialId("").build(); + .withUseSSL(true).withDefaultCredentialId().build(); final ImmutableSortedMap<Long, String> result = cimInstance.getViews(); @@ -591,8 +625,9 @@ public void getIssuesForView_returnIssues() throws Exception { " ]" + "}}"; TestableViewsService.setupViewContentsApi("view0", 200, viewContentsApiJsonResult); + CredentialUtil.setCredentialManager("user", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("instance").withHost("host").withPort(8080) - .withUser("user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); final List<CoverityDefect> issuesVorView = cimInstance.getIssuesVorView("project0", "view0", testableConsoleLogger.getPrintStream()); @@ -627,8 +662,9 @@ public void getIssuesForView_logsMissingColumns() throws Exception { " ]" + "}}"; TestableViewsService.setupViewContentsApi("view0", 200, viewContentsApiJsonResult); + CredentialUtil.setCredentialManager("user", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("instance").withHost("host").withPort(8080) - .withUser("user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); final List<CoverityDefect> issuesVorView = cimInstance.getIssuesVorView("project0", "view0", testableConsoleLogger.getPrintStream()); @@ -688,8 +724,9 @@ public void getIssuesForView_handlesPagingAndLogsProgess() throws Exception { " ]" + "}}"); TestableViewsService.setupViewContentsApi("view0", 200, viewContentsApiJsonResult.toString()); + CredentialUtil.setCredentialManager("user", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("instance").withHost("host").withPort(8080) - .withUser("user").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); final List<CoverityDefect> issuesVorView = cimInstance.getIssuesVorView("project0", "view0", testableConsoleLogger.getPrintStream());
src/test/java/jenkins/plugins/coverity/CoverityBuildActionTest.java+7 −2 modified@@ -10,17 +10,21 @@ *******************************************************************************/ package jenkins.plugins.coverity; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; import com.coverity.ws.v9.CovRemoteServiceException_Exception; import com.thoughtworks.xstream.XStream; import hudson.model.AbstractBuild; import hudson.model.Action; import hudson.model.FreeStyleBuild; import hudson.model.Run; +import hudson.util.Secret; import hudson.util.XStream2; import jenkins.model.Jenkins; import jenkins.plugins.coverity.CoverityPublisher.DescriptorImpl; import jenkins.plugins.coverity.Utils.CIMInstanceBuilder; import jenkins.plugins.coverity.Utils.CoverityPublisherBuilder; +import jenkins.plugins.coverity.Utils.CredentialUtil; import jenkins.plugins.coverity.Utils.TestUtils; import jenkins.plugins.coverity.ws.TestWebServiceFactory; import jenkins.plugins.coverity.ws.TestWebServiceFactory.TestConfigurationService; @@ -46,7 +50,7 @@ import static org.mockito.Mockito.when; @RunWith(PowerMockRunner.class) -@PrepareForTest({Jenkins.class, WebServiceFactory.class}) +@PrepareForTest({Jenkins.class, WebServiceFactory.class, Secret.class, CredentialsMatchers.class, CredentialsProvider.class}) public class CoverityBuildActionTest { @Mock private Jenkins jenkins; @@ -64,8 +68,9 @@ public void setup() throws IOException { PowerMockito.mockStatic(Jenkins.class); when(Jenkins.getInstance()).thenReturn(jenkins); DescriptorImpl descriptor = mock(CoverityPublisher.DescriptorImpl.class); + CredentialUtil.setCredentialManager("admin", "password"); cimInstance = new CIMInstanceBuilder().withName("test-cim-instance").withHost("test-cim-instance").withPort(8443) - .withUser("admin").withPassword("password").withUseSSL(true).withCredentialId("").build(); + .withUseSSL(true).withDefaultCredentialId().build(); when(descriptor.getInstance(any(String.class))).thenReturn(cimInstance); when(jenkins.getDescriptorByType(CoverityPublisher.DescriptorImpl.class)).thenReturn(descriptor); }
src/test/java/jenkins/plugins/coverity/CoverityPublisherDescriptorImplTests.java+7 −3 modified@@ -10,17 +10,21 @@ *******************************************************************************/ package jenkins.plugins.coverity; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; import com.coverity.ws.v9.CovRemoteServiceException_Exception; import com.thoughtworks.xstream.XStream; import hudson.model.Descriptor; import hudson.model.listeners.SaveableListener; import hudson.util.FormValidation; import hudson.util.ListBoxModel; +import hudson.util.Secret; import hudson.util.XStream2; import jenkins.model.Jenkins; import jenkins.plugins.coverity.CoverityPublisher.DescriptorImpl; import jenkins.plugins.coverity.Utils.CIMInstanceBuilder; import jenkins.plugins.coverity.Utils.CoverityPublisherBuilder; +import jenkins.plugins.coverity.Utils.CredentialUtil; import jenkins.plugins.coverity.ws.TestWebServiceFactory; import jenkins.plugins.coverity.ws.TestWebServiceFactory.TestConfigurationService; import jenkins.plugins.coverity.ws.WebServiceFactory; @@ -53,7 +57,7 @@ import static org.mockito.Mockito.when; @RunWith(PowerMockRunner.class) -@PrepareForTest({Jenkins.class, SaveableListener.class, WebServiceFactory.class}) +@PrepareForTest({Jenkins.class, SaveableListener.class, WebServiceFactory.class, Secret.class, CredentialsMatchers.class, CredentialsProvider.class}) public class CoverityPublisherDescriptorImplTests { private static final JSONObject PUBLISHER_FORM_OBJECT_JSON = JSONObject.fromObject("{\"name\":\"test-job\",\"publisher\":{\"kind\":\"jenkins.plugins.coverity.CoverityPublisher\",\"unstable\":false,\"hideChart\":false,\"invocationAssistance\":{\"buildArguments\":\"\",\"intermediateDir\":\"\",\"csharpMsvsca\":false,\"analyzeArguments\":\"\",\"saOverride\":\"\",\"commitArguments\":\"\",\"javaWarFile\":\"\"},\"keepIntDir\":false,\"cimStream\":{\"instance\":\"test-cim-instance\",\"id\":null,\"defectFilters\":{\"cutOffDate\":\"\"},\"project\":\"test-cim-project\",\"stream\":\"test-cim-stream\"},\"skipFetchingDefects\":false,\"failBuild\":false,\"stapler-class\":\"jenkins.plugins.coverity.CoverityPublisher\"},\"properties\":{\"hudson-model-ParametersDefinitionProperty\":{},\"stapler-class-bag\":\"true\"}}"); @@ -76,9 +80,9 @@ public void setup() throws IOException { PowerMockito.mockStatic(Jenkins.class); when(Jenkins.getInstance()).thenReturn(jenkins); when(jenkins.getRootDir()).thenReturn(tempJenkinsRoot.getRoot()); + CredentialUtil.setCredentialManager("admin", "password"); cimInstance = new CIMInstanceBuilder().withName("test-cim-instance").withHost("test-cim-instance").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("") - .build(); + .withUseSSL(false).withDefaultCredentialId().build(); } @Test
src/test/java/jenkins/plugins/coverity/CoverityTool/CommandTestBase.java+0 −34 modified@@ -10,29 +10,19 @@ *******************************************************************************/ package jenkins.plugins.coverity.CoverityTool; -import com.cloudbees.plugins.credentials.Credentials; -import com.cloudbees.plugins.credentials.CredentialsMatcher; import com.cloudbees.plugins.credentials.CredentialsMatchers; import com.cloudbees.plugins.credentials.CredentialsProvider; -import com.cloudbees.plugins.credentials.common.StandardCredentials; -import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; -import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; -import com.cloudbees.plugins.credentials.domains.DomainRequirement; -import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; import hudson.EnvVars; import hudson.Launcher; import hudson.model.AbstractBuild; -import hudson.model.ItemGroup; import hudson.model.TaskListener; import hudson.util.Secret; import jenkins.plugins.coverity.CoverityUtils; import jenkins.plugins.coverity.Utils.TestableConsoleLogger; -import org.acegisecurity.Authentication; import org.junit.Before; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -63,9 +53,6 @@ public abstract class CommandTestBase { @Mock protected TaskListener listener; - @Mock - UsernamePasswordCredentials credentials; - protected EnvVars envVars; protected String[] expectedArguments; protected List<String> actualArguments; @@ -166,25 +153,4 @@ protected void setCoverityUtils_listFiles(Collection<File> expectedFiles) { protected boolean verifyNumberOfExecutedCommands(int expectedNum) { return expectedNum == noExecutedCommands; } - - protected void setCredentialManager(String username, String password){ - PowerMockito.mockStatic(CredentialsMatchers.class); - PowerMockito.mockStatic(CredentialsProvider.class); - credentials = Mockito.mock(UsernamePasswordCredentialsImpl.class); - - Secret secret = PowerMockito.mock(Secret.class); - when(secret.getPlainText()).thenReturn(password); - when(credentials.getPassword()).thenReturn(secret); - when(credentials.getUsername()).thenReturn(username); - - when(CredentialsProvider.lookupCredentials( - Matchers.<Class<Credentials>>any(), - Matchers.any(ItemGroup.class), - Matchers.any(Authentication.class), - Matchers.anyListOf(DomainRequirement.class) - )).thenReturn(new ArrayList<Credentials>() {}); - - when(CredentialsMatchers.firstOrNull(Matchers.anyListOf(StandardCredentials.class), - Matchers.any(CredentialsMatcher.class))).thenReturn((StandardUsernamePasswordCredentials) credentials); - } }
src/test/java/jenkins/plugins/coverity/CoverityTool/CovCommitDefectsCommandTest.java+11 −32 modified@@ -13,6 +13,7 @@ import jenkins.plugins.coverity.*; import jenkins.plugins.coverity.Utils.CIMInstanceBuilder; import jenkins.plugins.coverity.Utils.CoverityPublisherBuilder; +import jenkins.plugins.coverity.Utils.CredentialUtil; import jenkins.plugins.coverity.Utils.InvocationAssistanceBuilder; import org.apache.commons.lang.StringUtils; import org.junit.Test; @@ -28,10 +29,10 @@ public class CovCommitDefectsCommandTest extends CommandTestBase { @Test public void prepareCommandTest() throws IOException, InterruptedException { + CredentialUtil.setCredentialManager("TestUser", "TestPassword"); CIMStream cimStream = new CIMStream("TestInstance", "TestProject", "TestStream"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("TestInstance").withHost("Localhost").withPort(8080) - .withUser("TestUser").withPassword("TestPassword").withUseSSL(false).withCredentialId("") - .build(); + .withUseSSL(false).withDefaultCredentialId().build(); InvocationAssistance invocationAssistance = new InvocationAssistanceBuilder().build(); CoverityPublisher publisher = @@ -50,10 +51,10 @@ public void prepareCommandTest() throws IOException, InterruptedException { @Test public void addHttpsPortTest() throws IOException, InterruptedException { + CredentialUtil.setCredentialManager("TestUser", "TestPassword"); CIMStream cimStream = new CIMStream("TestInstance", "TestProject", "TestStream"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("TestInstance").withHost("Localhost").withPort(8080) - .withUser("TestUser").withPassword("TestPassword").withUseSSL(true).withCredentialId("") - .build(); + .withUseSSL(true).withDefaultCredentialId().build(); InvocationAssistance invocationAssistance = new InvocationAssistanceBuilder().build(); SSLConfigurations sslConfigurations = new SSLConfigurations(true, null); @@ -81,34 +82,10 @@ public void addHttpsPortTest() throws IOException, InterruptedException { @Test public void addCommitArgumentsTest() throws IOException, InterruptedException { + CredentialUtil.setCredentialManager("TestUser", "TestPassword"); CIMStream cimStream = new CIMStream("TestInstance", "TestProject", "TestStream"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("TestInstance").withHost("Localhost").withPort(8080) - .withUser("TestUser").withPassword("TestPassword").withUseSSL(false).withCredentialId("") - .build(); - - InvocationAssistance invocationAssistance = new InvocationAssistanceBuilder().withCommitArguments("AdditionalCommitArguments").build(); - CoverityPublisher publisher = - new CoverityPublisherBuilder().withCimStream(cimStream). - withInvocationAssistance(invocationAssistance).build(); - - Command covCommitDefectsCommand = new CovCommitDefectsCommand(build, launcher, listener, publisher, StringUtils.EMPTY, envVars, cimStream, cimInstance); - setExpectedArguments(new String[] { - "cov-commit-defects", "--dir", "TestDir", "--host", "Localhost", - "--port", "8080", "--stream", "TestStream", "--user", "TestUser", "AdditionalCommitArguments" - }); - covCommitDefectsCommand.runCommand(); - assertEquals("TestPassword", envVars.get("COVERITY_PASSPHRASE")); - consoleLogger.verifyLastMessage("[Coverity] cov-commit-defects command line arguments: " + actualArguments.toString()); - } - - @Test - public void addCommitArgumentsTest_WithCredentials() throws IOException, InterruptedException { - - setCredentialManager("TestUser", "TestPassword"); - CIMStream cimStream = new CIMStream("TestInstance", "TestProject", "TestStream"); - CIMInstance cimInstance = new CIMInstanceBuilder().withName("TestInstance").withHost("Localhost").withPort(8080) - .withUser("").withPassword("").withUseSSL(false).withCredentialId("TestCredentialId") - .build(); + .withUseSSL(false).withDefaultCredentialId().build(); InvocationAssistance invocationAssistance = new InvocationAssistanceBuilder().withCommitArguments("AdditionalCommitArguments").build(); CoverityPublisher publisher = @@ -127,9 +104,10 @@ public void addCommitArgumentsTest_WithCredentials() throws IOException, Interru @Test public void addCommitArgumentsTest_WithParseException() throws IOException, InterruptedException { + CredentialUtil.setCredentialManager("TestUser", "TestPassword"); CIMStream cimStream = new CIMStream("TestInstance", "TestProject", "TestStream"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("TestInstance").withHost("Localhost").withPort(8080) - .withUser("TestUser").withPassword("TestPassword").withUseSSL(false).withCredentialId("") + .withUseSSL(false).withDefaultCredentialId() .build(); InvocationAssistance invocationAssistance = new InvocationAssistanceBuilder().withCommitArguments("\'").build(); @@ -148,9 +126,10 @@ public void addCommitArgumentsTest_WithParseException() throws IOException, Inte @Test public void doesNotExecute_WithoutInvocationAssistance() throws IOException, InterruptedException { + CredentialUtil.setCredentialManager("TestUser", "TestPassword"); CIMStream cimStream = new CIMStream("TestInstance", "TestProject", "TestStream"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("TestInstance").withHost("Localhost").withPort(8080) - .withUser("TestUser").withPassword("TestPassword").withUseSSL(false).withCredentialId("") + .withUseSSL(false).withDefaultCredentialId() .build(); CoverityPublisher publisher = new CoverityPublisherBuilder().build();
src/test/java/jenkins/plugins/coverity/CoverityViewResultsDescriptorTest.java+7 −3 modified@@ -21,7 +21,11 @@ import java.util.HashMap; import java.util.List; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import hudson.util.Secret; import jenkins.plugins.coverity.Utils.CIMInstanceBuilder; +import jenkins.plugins.coverity.Utils.CredentialUtil; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.hamcrest.CoreMatchers; @@ -45,7 +49,7 @@ import jenkins.plugins.coverity.ws.WebServiceFactory; @RunWith(PowerMockRunner.class) -@PrepareForTest({Jenkins.class, WebServiceFactory.class, Client.class}) +@PrepareForTest({Jenkins.class, WebServiceFactory.class, Client.class, Secret.class, CredentialsMatchers.class, CredentialsProvider.class}) public class CoverityViewResultsDescriptorTest { private CIMInstance cimInstance; @@ -56,9 +60,9 @@ public void setup() { PowerMockito.mockStatic(Jenkins.class); when(Jenkins.getInstance()).thenReturn(jenkins); DescriptorImpl descriptor = mock(CoverityPublisher.DescriptorImpl.class); + CredentialUtil.setCredentialManager("admin", "password"); cimInstance = new CIMInstanceBuilder().withName("test-cim-instance").withHost("test-cim-instance").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("") - .build(); + .withUseSSL(false).withDefaultCredentialId().build(); final List<CIMInstance> cimInstances = Arrays.asList(cimInstance); when(descriptor.getInstances()).thenReturn(cimInstances); when(jenkins.getDescriptorByType(CoverityPublisher.DescriptorImpl.class)).thenReturn(descriptor);
src/test/java/jenkins/plugins/coverity/CoverityViewResultsPublisherTest.java+7 −2 modified@@ -22,8 +22,12 @@ import java.util.Arrays; import java.util.List; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; import hudson.AbortException; +import hudson.util.Secret; import jenkins.plugins.coverity.Utils.CIMInstanceBuilder; +import jenkins.plugins.coverity.Utils.CredentialUtil; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -48,7 +52,7 @@ import jenkins.plugins.coverity.ws.WebServiceFactory; @RunWith(PowerMockRunner.class) -@PrepareForTest({Jenkins.class, WebServiceFactory.class, Client.class}) +@PrepareForTest({Jenkins.class, WebServiceFactory.class, Client.class, Secret.class, CredentialsMatchers.class, CredentialsProvider.class}) public class CoverityViewResultsPublisherTest { private CIMInstance cimInstance; private TestableConsoleLogger consoleLogger; @@ -68,8 +72,9 @@ public void setup() throws IOException { PowerMockito.mockStatic(Jenkins.class); when(Jenkins.getInstance()).thenReturn(jenkins); final DescriptorImpl globalDescriptor = mock(CoverityPublisher.DescriptorImpl.class); + CredentialUtil.setCredentialManager("admin", "password"); cimInstance = new CIMInstanceBuilder().withName("pipeline-instance").withHost("test-cim-instance").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("").build(); + .withUseSSL(false).withDefaultCredentialId().build(); final List<CIMInstance> cimInstances = Arrays.asList(cimInstance); when(globalDescriptor.getInstances()).thenReturn(cimInstances); when(jenkins.getDescriptorByType(CoverityPublisher.DescriptorImpl.class)).thenReturn(globalDescriptor);
src/test/java/jenkins/plugins/coverity/Utils/CIMInstanceBuilder.java+2 −11 modified@@ -17,8 +17,6 @@ public class CIMInstanceBuilder { private String host; private int port; private String credentialId; - private String user; - private String password; private boolean useSSL; public CIMInstanceBuilder withName(String name){ @@ -41,13 +39,8 @@ public CIMInstanceBuilder withCredentialId(String credentialId){ return this; } - public CIMInstanceBuilder withUser(String user){ - this.user = user; - return this; - } - - public CIMInstanceBuilder withPassword(String password){ - this.password = password; + public CIMInstanceBuilder withDefaultCredentialId() { + this.credentialId = "DefaultCredentialId"; return this; } @@ -59,8 +52,6 @@ public CIMInstanceBuilder withUseSSL(boolean useSSL){ public CIMInstance build(){ CIMInstance instance = new CIMInstance(name, host, port, credentialId); instance.setUseSSL(useSSL); - instance.setUser(user); - instance.setPassword(password); return instance; }
src/test/java/jenkins/plugins/coverity/Utils/CredentialUtil.java+54 −0 added@@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2018 Synopsys, Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Synopsys, Inc - initial implementation and documentation + *******************************************************************************/ +package jenkins.plugins.coverity.Utils; + +import com.cloudbees.plugins.credentials.Credentials; +import com.cloudbees.plugins.credentials.CredentialsMatcher; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.domains.DomainRequirement; +import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; +import hudson.model.ItemGroup; +import hudson.util.Secret; +import org.acegisecurity.Authentication; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; + +import java.util.ArrayList; + +public class CredentialUtil { + + public static void setCredentialManager(String username, String password) { + PowerMockito.mockStatic(CredentialsMatchers.class); + PowerMockito.mockStatic(CredentialsProvider.class); + UsernamePasswordCredentials credentials = Mockito.mock(UsernamePasswordCredentialsImpl.class); + + Secret secret = PowerMockito.mock(Secret.class); + PowerMockito.when(secret.getPlainText()).thenReturn(password); + PowerMockito.when(credentials.getPassword()).thenReturn(secret); + PowerMockito.when(credentials.getUsername()).thenReturn(username); + + PowerMockito.when(CredentialsProvider.lookupCredentials( + Matchers.<Class<Credentials>>any(), + Matchers.any(ItemGroup.class), + Matchers.any(Authentication.class), + Matchers.anyListOf(DomainRequirement.class) + )).thenReturn(new ArrayList<Credentials>() { + }); + + PowerMockito.when(CredentialsMatchers.firstOrNull(Matchers.anyListOf(StandardCredentials.class), + Matchers.any(CredentialsMatcher.class))).thenReturn((StandardUsernamePasswordCredentials) credentials); + } +}
src/test/java/jenkins/plugins/coverity/ws/CimCacheTest.java+11 −9 modified@@ -18,7 +18,11 @@ import java.util.Arrays; import java.util.List; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import hudson.util.Secret; import jenkins.plugins.coverity.Utils.CIMInstanceBuilder; +import jenkins.plugins.coverity.Utils.CredentialUtil; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,7 +34,7 @@ import jenkins.plugins.coverity.ws.TestWebServiceFactory.TestConfigurationService; @RunWith(PowerMockRunner.class) -@PrepareForTest(WebServiceFactory.class) +@PrepareForTest({WebServiceFactory.class, Secret.class, CredentialsMatchers.class, CredentialsProvider.class}) public class CimCacheTest { @Before public void setup() throws IOException { @@ -42,9 +46,9 @@ public void setup() throws IOException { @Test public void getProjects_returnsProjectsForInstances() throws IOException { + CredentialUtil.setCredentialManager("admin", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("") - .build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); testConfigurationService.setupProjects("project", 3, "stream", 1); @@ -58,8 +62,7 @@ public void getProjects_returnsProjectsForInstances() throws IOException { assertEquals(expectedProjectNames, projects); cimInstance = new CIMInstanceBuilder().withName("test-instance-2").withHost("test.coverity2.").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("") - .build(); + .withUseSSL(false).withDefaultCredentialId().build(); testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); testConfigurationService.setupProjects("project", 2, "stream", 1); @@ -71,9 +74,9 @@ public void getProjects_returnsProjectsForInstances() throws IOException { @Test public void getStreams_returnsStreamsForInstances() throws IOException { + CredentialUtil.setCredentialManager("admin", "password"); CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("test.coverity").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("") - .build(); + .withUseSSL(false).withDefaultCredentialId().build(); TestConfigurationService testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); testConfigurationService.setupProjects("project", 3, "stream", 2); @@ -87,8 +90,7 @@ public void getStreams_returnsStreamsForInstances() throws IOException { assertEquals(expectedStreamNames, streams); cimInstance = new CIMInstanceBuilder().withName("test-instance-2").withHost("test.coverity2.").withPort(8080) - .withUser("admin").withPassword("password").withUseSSL(false).withCredentialId("") - .build(); + .withUseSSL(false).withDefaultCredentialId().build(); testConfigurationService = (TestConfigurationService)WebServiceFactory.getInstance().getConfigurationService(cimInstance); testConfigurationService.setupProjects("project", 1, "stream", 4);
src/test/java/jenkins/plugins/coverity/ws/WebServiceFactoryTest.java+16 −6 modified@@ -9,11 +9,16 @@ * Synopsys, Inc - initial implementation and documentation *******************************************************************************/ package jenkins.plugins.coverity.ws; + import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import hudson.util.Secret; import jenkins.plugins.coverity.Utils.CIMInstanceBuilder; +import jenkins.plugins.coverity.Utils.CredentialUtil; import org.junit.Assert; import org.junit.Test; @@ -23,18 +28,23 @@ import jenkins.plugins.coverity.CIMInstance; import jenkins.plugins.coverity.ws.TestWebServiceFactory.TestConfigurationService; import jenkins.plugins.coverity.ws.TestWebServiceFactory.TestDefectService; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +@RunWith(PowerMockRunner.class) +@PrepareForTest({Secret.class, CredentialsMatchers.class, CredentialsProvider.class}) public class WebServiceFactoryTest { private CIMInstance cimInstance = new CIMInstanceBuilder().withName("test").withHost("cim-host").withPort(8080) - .withUser("test-user").withPassword("password").withUseSSL(false).withCredentialId("") - .build(); + .withUseSSL(false).withDefaultCredentialId().build(); private URL getExpectedUrl(CIMInstance cim, String wsdl) throws MalformedURLException { return new URL(cim.isUseSSL() ? "https" : "http", cim.getHost(), cim.getPort(), wsdl); } @Test public void getDefectService_returns_DefectService_instance() throws IOException { + CredentialUtil.setCredentialManager("test-user", "password"); WebServiceFactory factory = new TestWebServiceFactory(); DefectService result = factory.getDefectService(cimInstance); @@ -64,9 +74,9 @@ public void getDefectService_returns_new_instance() throws IOException { Assert.assertNotNull(result); + CredentialUtil.setCredentialManager("test-user", "password"); cimInstance = new CIMInstanceBuilder().withName("test instance 2").withHost("other-cim-host").withPort(8443) - .withUser("test-user").withPassword("password").withUseSSL(true).withCredentialId("") - .build(); + .withUseSSL(true).withDefaultCredentialId().build(); DefectService result2 = factory.getDefectService(cimInstance); @@ -106,9 +116,9 @@ public void getConfigurationService_returns_new_instance() throws IOException { Assert.assertNotNull(result); + CredentialUtil.setCredentialManager("test-user", "password"); cimInstance = new CIMInstanceBuilder().withName("test instance 2").withHost("other-cim-host").withPort(8443) - .withUser("test-user").withPassword("password").withUseSSL(true).withCredentialId("") - .build(); + .withUseSSL(true).withDefaultCredentialId().build(); ConfigurationService result2 = factory.getConfigurationService(cimInstance);
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-cghg-jcv6-4v5mghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-1000104ghsaADVISORY
- github.com/jenkinsci/coverity-plugin/commit/34b7c2b07014b8e1e708361170146600db172491ghsaWEB
- jenkins.io/security/advisory/2018-02-26/ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.