diff --git a/java/code/src/com/redhat/rhn/domain/scc/SCCRepositoryCloudRmtAuth.java b/java/code/src/com/redhat/rhn/domain/scc/SCCRepositoryCloudRmtAuth.java index d9d1558f002d..43bd7a4c6097 100644 --- a/java/code/src/com/redhat/rhn/domain/scc/SCCRepositoryCloudRmtAuth.java +++ b/java/code/src/com/redhat/rhn/domain/scc/SCCRepositoryCloudRmtAuth.java @@ -78,7 +78,7 @@ public String getUrl() { String newQuery = StringUtils.join(sourceParams, "&"); URI newURI = new URI(credUrl.getScheme(), url.getUserInfo(), credUrl.getHost(), credUrl.getPort(), - credUrl.getPath() + url.getPath(), newQuery, credUrl.getFragment()); + mergeUrls(credUrl, url), newQuery, credUrl.getFragment()); return newURI.toString(); } catch (URISyntaxException ex) { @@ -87,6 +87,18 @@ public String getUrl() { return null; } + private static String mergeUrls(URI credentialUrl, URI repositoryUrl) { + // If the paths start in the same way we have a clashing folder to remove. + // This happens when the credential url is https://host/repo/ and the repo path is /repo/whatever/dir/ + // We DON'T want to end up with https://host/repo/repo/whatever/dir/ + if (repositoryUrl.getPath().startsWith(credentialUrl.getPath())) { + return credentialUrl.resolve(repositoryUrl.getPath()).getPath(); + } + + // Otherwise Just combine the two paths + return credentialUrl.getPath() + repositoryUrl.getPath(); + } + @Override public T fold( Function basicAuth, diff --git a/java/code/src/com/redhat/rhn/domain/scc/test/SCCRepositoryCloudRmtAuthTest.java b/java/code/src/com/redhat/rhn/domain/scc/test/SCCRepositoryCloudRmtAuthTest.java new file mode 100644 index 000000000000..199a2d7d9e8d --- /dev/null +++ b/java/code/src/com/redhat/rhn/domain/scc/test/SCCRepositoryCloudRmtAuthTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023 SUSE LLC + * + * This software is licensed to you under the GNU General Public License, + * version 2 (GPLv2). There is NO WARRANTY for this software, express or + * implied, including the implied warranties of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 + * along with this software; if not, see + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * Red Hat trademarks are not licensed under GPLv2. No permission is + * granted to use or replicate Red Hat trademarks that are incorporated + * in this software or its documentation. + */ + +package com.redhat.rhn.domain.scc.test; + +import static org.jmock.AbstractExpectations.returnValue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.redhat.rhn.domain.credentials.Credentials; +import com.redhat.rhn.domain.scc.SCCRepository; +import com.redhat.rhn.domain.scc.SCCRepositoryCloudRmtAuth; +import com.redhat.rhn.testing.MockObjectTestCase; + +import org.jmock.imposters.ByteBuddyClassImposteriser; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class SCCRepositoryCloudRmtAuthTest extends MockObjectTestCase { + + @BeforeEach + public void setUp() { + setImposteriser(ByteBuddyClassImposteriser.INSTANCE); + } + + @Test + public void canCombineUrlsCorrectly() { + + SCCRepositoryCloudRmtAuth repoAuth = createAuthFor( + "https://updates.suse.com/SUSE/Products/RES/8-CLIENT-TOOLS/x86_64/product/", + 1L, "https://smt-ec2.susecloud.net/repo" + ); + + assertEquals( + "https://smt-ec2.susecloud.net/repo/SUSE/Products/RES/8-CLIENT-TOOLS/x86_64/product/" + + "?credentials=mirrcred_1", + repoAuth.getUrl() + ); + } + + @Test + public void doesNotDuplicateFolderWhenPathIsRepeated() { + + SCCRepositoryCloudRmtAuth repoAuth = createAuthFor( + "https://updates.suse.com/repo/$RCE/RES7-SUSE-Manager-Tools/x86_64/", + 1L, "https://smt-ec2.susecloud.net/repo" + ); + + assertEquals( + "https://smt-ec2.susecloud.net/repo/$RCE/RES7-SUSE-Manager-Tools/x86_64/?credentials=mirrcred_1", + repoAuth.getUrl() + ); + } + + @Test + public void doesNotAlterPathWhenUrlIsExternalToCredentialBase() { + + SCCRepositoryCloudRmtAuth repoAuth = createAuthFor( + "https://developer.download.nvidia.com/compute/cuda/repos/sles15/sbsa/", + 1L, "https://smt-ec2.susecloud.net/repo" + ); + + assertEquals( + "https://developer.download.nvidia.com/compute/cuda/repos/sles15/sbsa/", + repoAuth.getUrl() + ); + } + + private SCCRepositoryCloudRmtAuth createAuthFor(String repoUrl, long credentialId, String credentialUrl) { + SCCRepository repository = mock(SCCRepository.class); + Credentials credentials = mock(Credentials.class); + + SCCRepositoryCloudRmtAuth auth1 = new SCCRepositoryCloudRmtAuth(); + auth1.setCredentials(credentials); + auth1.setRepo(repository); + + checking(expectations -> { + expectations.allowing(repository).getUrl(); + expectations.will(returnValue(repoUrl)); + + expectations.allowing(credentials).getUrl(); + expectations.will(returnValue(credentialUrl)); + + expectations.allowing(credentials).getId(); + expectations.will(returnValue(credentialId)); + }); + return auth1; + } +} diff --git a/java/spacewalk-java.changes.mackdk.payg-combine-clashing-path b/java/spacewalk-java.changes.mackdk.payg-combine-clashing-path new file mode 100644 index 000000000000..fb2152aaecb3 --- /dev/null +++ b/java/spacewalk-java.changes.mackdk.payg-combine-clashing-path @@ -0,0 +1,2 @@ +- Combine the PAYG credentials and the repository paths when they + collide (bsc#1215413)