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(),