diff --git a/src/main/java/com/cloudbees/plugins/credentials/CredentialsStoreAction.java b/src/main/java/com/cloudbees/plugins/credentials/CredentialsStoreAction.java index 5cd54db4..9fd59eb9 100644 --- a/src/main/java/com/cloudbees/plugins/credentials/CredentialsStoreAction.java +++ b/src/main/java/com/cloudbees/plugins/credentials/CredentialsStoreAction.java @@ -1348,7 +1348,7 @@ public HttpResponse doDoMove(StaplerRequest2 req, @QueryParameter String destina for (CredentialsStore store : CredentialsProvider.lookupStores(context)) { if (store.getContext() == context) { for (Domain d : store.getDomains()) { - if (domainName.equals("_") ? d.getName() == null : domainName.equals(d.getName())) { + if (isDomainEqual(domainName, d)) { destinationStore = store; destinationDomain = d; break; @@ -1380,6 +1380,17 @@ public HttpResponse doDoMove(StaplerRequest2 req, @QueryParameter String destina return HttpResponses.redirectToDot(); } + private boolean isDomainEqual(String domainName, Domain d){ + final var name = d.getName(); + if (domainName.equals("_")) { + return name == null; + } + if (name == null){ + return false; + } + return domainName.equals(Util.rawEncode(name)); + } + /** * Updates the credentials. * diff --git a/src/test/java/com/cloudbees/plugins/credentials/CredentialsStoreActionTest.java b/src/test/java/com/cloudbees/plugins/credentials/CredentialsStoreActionTest.java index ada6c8a2..d27dd255 100644 --- a/src/test/java/com/cloudbees/plugins/credentials/CredentialsStoreActionTest.java +++ b/src/test/java/com/cloudbees/plugins/credentials/CredentialsStoreActionTest.java @@ -294,6 +294,74 @@ void restCRUDNonHappy() throws Exception { assertThat(con.getResponseCode(), is(HttpServletResponse.SC_CONFLICT)); } + @Test + void moveCredential() throws Exception { + JenkinsRule.WebClient wc = j.createWebClient(); + j.getInstance().setCrumbIssuer(null); + + assertThat(systemStore.getDomainByName("smokes"), nullValue()); + + // create domain + HttpURLConnection con = + postCreateByXml(systemStore, """ + + smokes + """); + assertThat(con.getResponseCode(), is(200)); + + // create domain + con = postCreateByXml(systemStore, """ + + domain with spaces, ", ), characters + """); + assertThat(con.getResponseCode(), is(200)); + + // create credential + con = postCreateByXml(systemStore, "smokes", + """ + + GLOBAL + smokey-id + created from xml + example-com-deployer + super-secret + """); + assertThat(con.getResponseCode(), is(200)); + + // read domain + WebResponse response = wc.goTo("credentials/store/system/domain/smokes/config.xml", "application/xml").getWebResponse(); + assertThat(response.getContentAsString(), CompareMatcher.isIdenticalTo( + """ + + smokes + """).ignoreWhitespace().ignoreComments()); + + // move credential + con = postMove(systemStore, "smokes", "smokey-id", "domain with spaces, \", ), characters"); + assertThat(con.getResponseCode(), is(200)); + + // read domain + response = wc.goTo("credentials/store/system/domain/domain with spaces, \", ), characters/config.xml", "application/xml").getWebResponse(); + assertThat(response.getContentAsString(), CompareMatcher.isIdenticalTo( + """ + + domain with spaces, ", ), characters + """).ignoreWhitespace().ignoreComments()); + } + + private HttpURLConnection postMove(CredentialsStore store, String domainName, String credentialsId, String targetDomain) + throws IOException { + HttpURLConnection con = (HttpURLConnection) new URL(j.getURL(), + "credentials/store/" + store.getStoreAction().getUrlName() + "/domain/" + Util + .rawEncode(StringUtils.defaultIfBlank(domainName, "_"))+ "/credential/" + Util + .rawEncode(credentialsId) + "/doMove").openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + con.setDoOutput(true); + con.getOutputStream().write(Util.rawEncode("destination=system/" + Util.rawEncode(targetDomain) + "&Submit").getBytes(StandardCharsets.UTF_8)); + return con; + } + private HttpURLConnection postCreateByXml(CredentialsStore store, String xml) throws IOException { HttpURLConnection con = (HttpURLConnection) new URL(j.getURL(),