diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml
index ad1befadac..c231fef264 100644
--- a/assembly/assembly-wsmaster-war/pom.xml
+++ b/assembly/assembly-wsmaster-war/pom.xml
@@ -139,10 +139,6 @@
org.eclipse.che.core
che-core-api-factory-bitbucket-server
-
- org.eclipse.che.core
- che-core-api-factory-git-ssh
-
org.eclipse.che.core
che-core-api-factory-github
diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java
index 97867dfe71..274c1ff2f8 100644
--- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java
+++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java
@@ -44,8 +44,6 @@ import org.eclipse.che.api.factory.server.bitbucket.BitbucketFactoryParametersRe
import org.eclipse.che.api.factory.server.bitbucket.BitbucketScmFileResolver;
import org.eclipse.che.api.factory.server.bitbucket.BitbucketServerAuthorizingFactoryParametersResolver;
import org.eclipse.che.api.factory.server.bitbucket.BitbucketServerScmFileResolver;
-import org.eclipse.che.api.factory.server.git.ssh.GitSshFactoryParametersResolver;
-import org.eclipse.che.api.factory.server.git.ssh.GitSshScmFileResolver;
import org.eclipse.che.api.factory.server.github.GithubFactoryParametersResolver;
import org.eclipse.che.api.factory.server.github.GithubScmFileResolver;
import org.eclipse.che.api.factory.server.gitlab.GitlabFactoryParametersResolver;
@@ -177,7 +175,6 @@ public class WsMasterModule extends AbstractModule {
factoryParametersResolverMultibinder
.addBinding()
.to(AzureDevOpsFactoryParametersResolver.class);
- factoryParametersResolverMultibinder.addBinding().to(GitSshFactoryParametersResolver.class);
Multibinder scmFileResolverResolverMultibinder =
Multibinder.newSetBinder(binder(), ScmFileResolver.class);
@@ -186,7 +183,6 @@ public class WsMasterModule extends AbstractModule {
scmFileResolverResolverMultibinder.addBinding().to(GitlabScmFileResolver.class);
scmFileResolverResolverMultibinder.addBinding().to(BitbucketServerScmFileResolver.class);
scmFileResolverResolverMultibinder.addBinding().to(AzureDevOpsScmFileResolver.class);
- scmFileResolverResolverMultibinder.addBinding().to(GitSshScmFileResolver.class);
install(new org.eclipse.che.api.factory.server.scm.KubernetesScmModule());
install(new org.eclipse.che.api.factory.server.bitbucket.BitbucketServerModule());
diff --git a/pom.xml b/pom.xml
index 2b8ffd1433..4531d77341 100644
--- a/pom.xml
+++ b/pom.xml
@@ -759,11 +759,6 @@
che-core-api-factory-bitbucket-server
${che.version}
-
- org.eclipse.che.core
- che-core-api-factory-git-ssh
- ${che.version}
-
org.eclipse.che.core
che-core-api-factory-github
diff --git a/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParser.java b/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParser.java
index 6bfd60016c..807c400398 100644
--- a/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParser.java
+++ b/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParser.java
@@ -40,6 +40,8 @@ public class AzureDevOpsURLParser {
*/
private final Pattern azureDevOpsPattern;
+ private final Pattern azureSSHDevOpsPattern;
+
@Inject
public AzureDevOpsURLParser(
DevfileFilenamesProvider devfileFilenamesProvider,
@@ -58,14 +60,22 @@ public class AzureDevOpsURLParser {
+ "([?&]version=GB(?[^&]++))?"
+ "(.*)",
azureDevOpsScmApiEndpointHost));
+ this.azureSSHDevOpsPattern =
+ compile(
+ format(
+ "^git@ssh\\.%s:v3/(?.*)/(?.*)/(?.*)$",
+ azureDevOpsScmApiEndpointHost));
}
public boolean isValid(@NotNull String url) {
- return azureDevOpsPattern.matcher(url).matches();
+ return azureDevOpsPattern.matcher(url).matches()
+ || azureSSHDevOpsPattern.matcher(url).matches();
}
public AzureDevOpsUrl parse(String url) {
- Matcher matcher = azureDevOpsPattern.matcher(url);
+ boolean isHTTPSUrl = azureDevOpsPattern.matcher(url).matches();
+ Matcher matcher =
+ isHTTPSUrl ? azureDevOpsPattern.matcher(url) : azureSSHDevOpsPattern.matcher(url);
if (!matcher.matches()) {
throw new IllegalArgumentException(format("The given url %s is not a valid.", url));
}
@@ -83,23 +93,28 @@ public class AzureDevOpsURLParser {
project = repoName;
}
- String organization = matcher.group("organization");
- String branch = matcher.group("branch");
- String tag = matcher.group("tag");
+ String branch = null;
+ String tag = null;
- // The url might have the following formats:
- // - https://@///_git/
- // - https://@///_git/
- // For the first case we need to remove the `organization` from the url to distinguish it from
- // `credentials`
- // TODO: return empty credentials like the BitBucketUrl
- String organizationCanIgnore = matcher.group("organizationCanIgnore");
- if (!isNullOrEmpty(organization) && organization.equals(organizationCanIgnore)) {
- url = url.replace(organizationCanIgnore + "@", "");
+ String organization = matcher.group("organization");
+ if (isHTTPSUrl) {
+ branch = matcher.group("branch");
+ tag = matcher.group("tag");
+ // The url might have the following formats:
+ // - https://@///_git/
+ // - https://@///_git/
+ // For the first case we need to remove the `organization` from the url to distinguish it from
+ // `credentials`
+ // TODO: return empty credentials like the BitBucketUrl
+ String organizationCanIgnore = matcher.group("organizationCanIgnore");
+ if (!isNullOrEmpty(organization) && organization.equals(organizationCanIgnore)) {
+ url = url.replace(organizationCanIgnore + "@", "");
+ }
}
return new AzureDevOpsUrl()
.withHostName(azureDevOpsScmApiEndpointHost)
+ .setIsHTTPSUrl(isHTTPSUrl)
.withProject(project)
.withRepository(repoName)
.withOrganization(organization)
diff --git a/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsUrl.java b/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsUrl.java
index ac25cf9655..11a3954d25 100644
--- a/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsUrl.java
+++ b/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsUrl.java
@@ -30,6 +30,7 @@ import org.eclipse.che.api.factory.server.urlfactory.DefaultFactoryUrl;
*/
public class AzureDevOpsUrl extends DefaultFactoryUrl {
+ private boolean isHTTPSUrl;
private String hostName;
private String repository;
@@ -145,7 +146,17 @@ public class AzureDevOpsUrl extends DefaultFactoryUrl {
}
public String getRepositoryLocation() {
- return getRepoPathJoiner().add("_git").add(repository).toString();
+ if (isHTTPSUrl) {
+ return getRepoPathJoiner().add("_git").add(repository).toString();
+ }
+ return "git@ssh."
+ + hostName.substring(8)
+ + ":v3/"
+ + organization
+ + "/"
+ + project
+ + "/"
+ + repository;
}
private StringJoiner getRepoPathJoiner() {
@@ -157,6 +168,11 @@ public class AzureDevOpsUrl extends DefaultFactoryUrl {
return hostName;
}
+ public AzureDevOpsUrl setIsHTTPSUrl(boolean isHTTPSUrl) {
+ this.isHTTPSUrl = isHTTPSUrl;
+ return this;
+ }
+
public AzureDevOpsUrl withHostName(String hostName) {
this.hostName = "https://" + hostName;
return this;
diff --git a/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParserTest.java b/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParserTest.java
index 3ef9faade6..56e29dc0a6 100644
--- a/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParserTest.java
+++ b/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParserTest.java
@@ -109,6 +109,48 @@ public class AzureDevOpsURLParserTest {
"main",
null
},
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo",
+ "MyOrg",
+ "MyProject",
+ "MyRepo",
+ null,
+ null
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.git",
+ "MyOrg",
+ "MyProject",
+ "MyRepo",
+ null,
+ null
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.dot.git",
+ "MyOrg",
+ "MyProject",
+ "MyRepo.dot",
+ null,
+ null
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo",
+ "MyOrg",
+ "MyProject",
+ "MyRepo",
+ null,
+ null
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo-with-hypen",
+ "MyOrg",
+ "MyProject",
+ "MyRepo-with-hypen",
+ null,
+ null
+ },
+ {"git@ssh.dev.azure.com:v3/MyOrg/MyProject/-", "MyOrg", "MyProject", "-", null, null},
+ {"git@ssh.dev.azure.com:v3/MyOrg/MyProject/-j.git", "MyOrg", "MyProject", "-j", null, null},
{
"https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GBmain",
"MyOrg",
diff --git a/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLTest.java b/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLTest.java
new file mode 100644
index 0000000000..55e2b44677
--- /dev/null
+++ b/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2012-2023 Red Hat, Inc.
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ */
+package org.eclipse.che.api.factory.server.azure.devops;
+
+import static java.lang.String.format;
+import static org.mockito.Mockito.mock;
+import static org.testng.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider;
+import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl;
+import org.mockito.testng.MockitoTestNGListener;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+
+@Listeners(MockitoTestNGListener.class)
+public class AzureDevOpsURLTest {
+ private AzureDevOpsURLParser azureDevOpsURLParser;
+
+ @BeforeMethod
+ protected void init() {
+ azureDevOpsURLParser =
+ new AzureDevOpsURLParser(mock(DevfileFilenamesProvider.class), "https://dev.azure.com/");
+ }
+
+ @Test(dataProvider = "urlsProvider")
+ public void checkDevfileLocation(String repoUrl, String fileUrl) {
+
+ AzureDevOpsUrl azureDevOpsUrl =
+ azureDevOpsURLParser
+ .parse(repoUrl)
+ .withDevfileFilenames(Arrays.asList("devfile.yaml", "foo.bar"));
+ assertEquals(azureDevOpsUrl.devfileFileLocations().size(), 2);
+ Iterator iterator =
+ azureDevOpsUrl.devfileFileLocations().iterator();
+ String location = iterator.next().location();
+ assertEquals(location, format(fileUrl, "devfile.yaml"));
+ assertEquals(location, format(fileUrl, "foo.bar"));
+ }
+
+ @DataProvider
+ public static Object[][] urlsProvider() {
+ return new Object[][] {
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo.git",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo.dot.git",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo.dot/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo-with-hypen",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo-with-hypen/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "https://dev.azure.com/MyOrg/MyProject/_git/-",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/-/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "https://dev.azure.com/MyOrg/MyProject/_git/-j.git",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/-j/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.git",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.dot.git",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo.dot/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo-with-hypen",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo-with-hypen/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/-/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-j.git",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/-j/items?path=/devfile.yaml&api-version=7.0"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GBmain&_a=contents",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&versionType=branch&version=main&api-version=7.0"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GBmain",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&versionType=branch&version=main&api-version=7.0"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GTMyTag&_a=contents",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&versionType=tag&version=MyTag&api-version=7.0"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GTMyTag",
+ "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&versionType=tag&version=MyTag&api-version=7.0"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/_git/MyRepo",
+ "https://dev.azure.com/MyOrg/MyRepo/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0"
+ }
+ };
+ }
+
+ @Test(dataProvider = "repoProvider")
+ public void checkRepositoryLocation(String rawUrl, String repoUrl) {
+ AzureDevOpsUrl azureDevOpsUrl = azureDevOpsURLParser.parse(rawUrl);
+ assertEquals(azureDevOpsUrl.getRepositoryLocation(), repoUrl);
+ }
+
+ @DataProvider
+ public static Object[][] repoProvider() {
+ return new Object[][] {
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo",
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo.git",
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo.dot.git",
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo.dot"
+ },
+ {
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo",
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo"
+ },
+ {
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo-with-hypen",
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo-with-hypen"
+ },
+ {
+ "https://dev.azure.com/MyOrg/MyProject/_git/-",
+ "https://dev.azure.com/MyOrg/MyProject/_git/-"
+ },
+ {
+ "https://dev.azure.com/MyOrg/MyProject/_git/-j.git",
+ "https://dev.azure.com/MyOrg/MyProject/_git/-j"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo",
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.git",
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.dot.git",
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.dot"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo",
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo"
+ },
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo-with-hypen",
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo-with-hypen"
+ },
+ {"git@ssh.dev.azure.com:v3/MyOrg/MyProject/-", "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-"},
+ {
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-j.git",
+ "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-j"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GBmain&_a=contents",
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GBmain",
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GTMyTag&_a=contents",
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GTMyTag",
+ "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo"
+ },
+ {
+ "https://MyOrg@dev.azure.com/MyOrg/_git/MyRepo",
+ "https://dev.azure.com/MyOrg/MyRepo/_git/MyRepo"
+ }
+ };
+ }
+}
diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParser.java b/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParser.java
index b76d4d517a..f275b6b5f3 100644
--- a/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParser.java
+++ b/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParser.java
@@ -16,6 +16,7 @@ import static java.util.regex.Pattern.compile;
import com.google.common.base.Splitter;
import jakarta.validation.constraints.NotNull;
+import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -50,11 +51,13 @@ public class BitbucketServerURLParser {
private final PersonalAccessTokenManager personalAccessTokenManager;
private static final List bitbucketUrlPatternTemplates =
List.of(
- "^(?%s)/scm/~(?[^/]+)/(?.*).git$",
- "^(?%s)/users/(?[^/]+)/repos/(?[^/]+)/browse(\\?at=(?.*))?",
- "^(?%s)/users/(?[^/]+)/repos/(?[^/]+)/?",
- "^(?%s)/scm/(?[^/~]+)/(?[^/]+).git",
- "^(?%s)/projects/(?[^/]+)/repos/(?[^/]+)/browse(\\?at=(?.*))?");
+ "^(?%s)://(?%s)/scm/~(?[^/]+)/(?.*).git$",
+ "^(?%s)://(?%s)/users/(?[^/]+)/repos/(?[^/]+)/browse(\\?at=(?.*))?",
+ "^(?%s)://(?%s)/users/(?[^/]+)/repos/(?[^/]+)/?",
+ "^(?%s)://(?%s)/scm/(?[^/~]+)/(?[^/]+).git",
+ "^(?%s)://(?%s)/projects/(?[^/]+)/repos/(?[^/]+)/browse(\\?at=(?.*))?",
+ "^(?%s)://git@(?%s):(?\\d*)/~(?[^/]+)/(?.*).git$",
+ "^(?%s)://git@(?%s):(?\\d*)/(?[^/]+)/(?.*).git$");
private final List bitbucketUrlPatterns = new ArrayList<>();
private static final String OAUTH_PROVIDER_NAME = "bitbucket-server";
@@ -70,16 +73,24 @@ public class BitbucketServerURLParser {
if (bitbucketEndpoints != null) {
for (String bitbucketEndpoint : Splitter.on(",").split(bitbucketEndpoints)) {
String trimmedEndpoint = StringUtils.trimEnd(bitbucketEndpoint, '/');
+ URI uri = URI.create(trimmedEndpoint);
bitbucketUrlPatternTemplates.forEach(
- t -> bitbucketUrlPatterns.add(Pattern.compile(format(t, trimmedEndpoint))));
+ t -> {
+ String scheme = t.contains("git@") ? "ssh" : uri.getScheme();
+ String host = uri.getHost();
+ bitbucketUrlPatterns.add(Pattern.compile(format(t, scheme, host)));
+ });
}
}
}
private boolean isUserTokenPresent(String repositoryUrl) {
String serverUrl = getServerUrl(repositoryUrl);
+ URI uri = URI.create(repositoryUrl);
+ String schema = uri.getScheme();
+ String host = uri.getHost();
if (bitbucketUrlPatternTemplates.stream()
- .anyMatch(t -> Pattern.compile(format(t, serverUrl)).matcher(repositoryUrl).matches())) {
+ .anyMatch(t -> Pattern.compile(format(t, schema, host)).matcher(repositoryUrl).matches())) {
try {
Optional token =
personalAccessTokenManager.get(EnvironmentContext.getCurrent().getSubject(), serverUrl);
@@ -94,7 +105,9 @@ public class BitbucketServerURLParser {
}
public boolean isValid(@NotNull String url) {
- if (!bitbucketUrlPatterns.isEmpty()) {
+ if (!url.contains("://")) {
+ return false;
+ } else if (!bitbucketUrlPatterns.isEmpty()) {
return bitbucketUrlPatterns.stream().anyMatch(pattern -> pattern.matcher(url).matches());
} else {
return
@@ -126,18 +139,27 @@ public class BitbucketServerURLParser {
}
private String getServerUrl(String repositoryUrl) {
+ if (repositoryUrl.startsWith("ssh://git@")) {
+ String substring = repositoryUrl.substring(10);
+ return "https://" + substring.substring(0, substring.indexOf(":"));
+ }
return repositoryUrl.substring(
0,
repositoryUrl.indexOf("/scm") > 0
? repositoryUrl.indexOf("/scm")
: repositoryUrl.indexOf("/users") > 0
? repositoryUrl.indexOf("/users")
- : repositoryUrl.length());
+ : repositoryUrl.indexOf("/projects") > 0
+ ? repositoryUrl.indexOf("/projects")
+ : repositoryUrl.length());
}
private Optional getPatternMatcherByUrl(String url) {
+ URI uri = URI.create(url);
+ String scheme = uri.getScheme();
+ String host = uri.getHost();
return bitbucketUrlPatternTemplates.stream()
- .map(t -> compile(format(t, getServerUrl(url))).matcher(url))
+ .map(t -> compile(format(t, scheme, host)).matcher(url))
.filter(Matcher::matches)
.findAny();
}
@@ -174,7 +196,14 @@ public class BitbucketServerURLParser {
}
private BitbucketServerUrl parse(Matcher matcher) {
+ String scheme = matcher.group("scheme");
String host = matcher.group("host");
+ String port = null;
+ try {
+ port = matcher.group("port");
+ } catch (IllegalArgumentException e) {
+ // keep port with null, as the pattern doesn't have the port group
+ }
String user = null;
String project = null;
try {
@@ -191,7 +220,9 @@ public class BitbucketServerURLParser {
}
return new BitbucketServerUrl()
+ .withScheme(scheme)
.withHostName(host)
+ .withPort(port)
.withProject(project)
.withUser(user)
.withRepository(repoName)
diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerUrl.java b/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerUrl.java
index 74afa28c80..458f332daf 100644
--- a/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerUrl.java
+++ b/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerUrl.java
@@ -29,6 +29,9 @@ public class BitbucketServerUrl extends DefaultFactoryUrl {
/** Hostname of bitbucket URL */
private String hostName;
+ private String scheme;
+ private String port;
+
/** Project part of bitbucket URL */
private String project;
@@ -54,6 +57,11 @@ public class BitbucketServerUrl extends DefaultFactoryUrl {
return NAME;
}
+ @Override
+ public String getProviderUrl() {
+ return (scheme.equals("ssh") ? "https" : scheme) + "://" + hostName;
+ }
+
/**
* Gets hostname of this bitbucket server url
*
@@ -68,6 +76,16 @@ public class BitbucketServerUrl extends DefaultFactoryUrl {
return this;
}
+ public BitbucketServerUrl withScheme(String scheme) {
+ this.scheme = scheme;
+ return this;
+ }
+
+ public BitbucketServerUrl withPort(String port) {
+ this.port = port;
+ return this;
+ }
+
/**
* Gets project of this bitbucket server url
*
@@ -171,7 +189,7 @@ public class BitbucketServerUrl extends DefaultFactoryUrl {
public String rawFileLocation(String fileName) {
StringJoiner joiner =
new StringJoiner("/")
- .add(hostName)
+ .add((scheme.equals("ssh") ? "https" : scheme) + "://" + hostName)
.add("rest/api/1.0")
.add(!isNullOrEmpty(user) && isNullOrEmpty(project) ? "users" : "projects")
.add(firstNonNull(user, project))
@@ -192,7 +210,14 @@ public class BitbucketServerUrl extends DefaultFactoryUrl {
* @return location of the repository.
*/
protected String repositoryLocation() {
- return hostName
+ if (scheme.equals("ssh")) {
+ return String.format(
+ "%s://git@%s:%s/%s/%s.git",
+ scheme, hostName, port, (isNullOrEmpty(user) ? project : "~" + user), repository);
+ }
+ return scheme
+ + "://"
+ + hostName
+ "/scm/"
+ (isNullOrEmpty(user) ? project : "~" + user)
+ "/"
diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFileContentProviderTest.java b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFileContentProviderTest.java
index 62819f3ea0..2a52b60ae0 100644
--- a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFileContentProviderTest.java
+++ b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFileContentProviderTest.java
@@ -29,18 +29,21 @@ import org.testng.annotations.Test;
@Listeners(MockitoTestNGListener.class)
public class BitbucketServerAuthorizingFileContentProviderTest {
- public static final String TEST_HOSTNAME = "https://foo.bar";
+ public static final String TEST_HOSTNAME = "foo.bar";
+ public static final String TEST_SCHEME = "https";
@Mock private URLFetcher urlFetcher;
@Mock private PersonalAccessTokenManager personalAccessTokenManager;
@Test
public void shouldFetchContentWithTokenIfPresent() throws Exception {
- BitbucketServerUrl url = new BitbucketServerUrl().withHostName(TEST_HOSTNAME);
+ BitbucketServerUrl url =
+ new BitbucketServerUrl().withHostName(TEST_HOSTNAME).withScheme(TEST_SCHEME);
BitbucketServerAuthorizingFileContentProvider fileContentProvider =
new BitbucketServerAuthorizingFileContentProvider(
url, urlFetcher, personalAccessTokenManager);
- PersonalAccessToken token = new PersonalAccessToken(TEST_HOSTNAME, "user1", "token");
+ PersonalAccessToken token =
+ new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "user1", "token");
when(personalAccessTokenManager.get(anyString())).thenReturn(token);
String fileURL = "https://foo.bar/scm/repo/.devfile";
@@ -54,13 +57,15 @@ public class BitbucketServerAuthorizingFileContentProviderTest {
@Test
public void shouldFetchTokenIfNotYetPresent() throws Exception {
- BitbucketServerUrl url = new BitbucketServerUrl().withHostName(TEST_HOSTNAME);
+ BitbucketServerUrl url =
+ new BitbucketServerUrl().withHostName(TEST_HOSTNAME).withScheme(TEST_SCHEME);
BitbucketServerAuthorizingFileContentProvider fileContentProvider =
new BitbucketServerAuthorizingFileContentProvider(
url, urlFetcher, personalAccessTokenManager);
- PersonalAccessToken token = new PersonalAccessToken(TEST_HOSTNAME, "user1", "token");
- when(personalAccessTokenManager.get(eq(TEST_HOSTNAME))).thenReturn(token);
+ PersonalAccessToken token =
+ new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "user1", "token");
+ when(personalAccessTokenManager.get(eq(TEST_SCHEME + "://" + TEST_HOSTNAME))).thenReturn(token);
String fileURL = "https://foo.bar/scm/repo/.devfile";
@@ -68,7 +73,7 @@ public class BitbucketServerAuthorizingFileContentProviderTest {
fileContentProvider.fetchContent(fileURL);
// then
- verify(personalAccessTokenManager).get(eq(TEST_HOSTNAME));
+ verify(personalAccessTokenManager).get(eq(TEST_SCHEME + "://" + TEST_HOSTNAME));
verify(urlFetcher).fetch(eq(fileURL), eq("Bearer token"));
}
@@ -78,6 +83,7 @@ public class BitbucketServerAuthorizingFileContentProviderTest {
BitbucketServerUrl url =
new BitbucketServerUrl()
.withHostName(TEST_HOSTNAME)
+ .withScheme(TEST_SCHEME)
.withProject("proj")
.withRepository("repo")
.withDevfileFilenames(Collections.singletonList(".devfile"));
@@ -87,7 +93,8 @@ public class BitbucketServerAuthorizingFileContentProviderTest {
BitbucketServerAuthorizingFileContentProvider fileContentProvider =
new BitbucketServerAuthorizingFileContentProvider(
url, urlFetcher, personalAccessTokenManager);
- PersonalAccessToken token = new PersonalAccessToken(TEST_HOSTNAME, "user1", "token");
+ PersonalAccessToken token =
+ new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "user1", "token");
when(personalAccessTokenManager.get(anyString())).thenReturn(token);
// when
diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParserTest.java b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParserTest.java
index 4af35e693f..8cdd21ead6 100644
--- a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParserTest.java
+++ b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParserTest.java
@@ -83,6 +83,24 @@ public class BitbucketServerURLParserTest {
assertEquals(bitbucketServerUrl.getBranch(), branch);
}
+ @Test(dataProvider = "parsing")
+ public void shouldParseWithoutPredefinedEndpoint(
+ String url, String user, String project, String repository, String branch) {
+ // given
+ bitbucketURLParser =
+ new BitbucketServerURLParser(
+ null, devfileFilenamesProvider, oAuthAPI, mock(PersonalAccessTokenManager.class));
+
+ // when
+ BitbucketServerUrl bitbucketServerUrl = bitbucketURLParser.parse(url);
+
+ // then
+ assertEquals(bitbucketServerUrl.getUser(), user);
+ assertEquals(bitbucketServerUrl.getProject(), project);
+ assertEquals(bitbucketServerUrl.getRepository(), repository);
+ assertEquals(bitbucketServerUrl.getBranch(), branch);
+ }
+
@Test(
expectedExceptions = IllegalArgumentException.class,
expectedExceptionsMessageRegExp =
@@ -134,6 +152,8 @@ public class BitbucketServerURLParserTest {
{"https://bitbucket.2mcl.com/users/user/repos/repo"},
{"https://bitbucket.2mcl.com/users/user/repos/repo/"},
{"https://bbkt.com/scm/project/test1.git"},
+ {"ssh://git@bitbucket.2mcl.com:12345/~user/repo.git"},
+ {"ssh://git@bitbucket.2mcl.com:12345/project/test1.git"}
};
}
@@ -141,6 +161,8 @@ public class BitbucketServerURLParserTest {
public Object[][] expectedParsing() {
return new Object[][] {
{"https://bitbucket.2mcl.com/scm/project/test1.git", null, "project", "test1", null},
+ {"ssh://git@bitbucket.2mcl.com:12345/project/test1.git", null, "project", "test1", null},
+ {"ssh://git@bitbucket.2mcl.com:12345/~user/test1.git", "user", null, "test1", null},
{
"https://bitbucket.2mcl.com/projects/project/repos/test1/browse?at=refs%2Fheads%2Fbranch",
null,
diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLTest.java b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLTest.java
new file mode 100644
index 0000000000..49b9e51c4a
--- /dev/null
+++ b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2012-2023 Red Hat, Inc.
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ */
+package org.eclipse.che.api.factory.server.bitbucket;
+
+import static java.lang.String.format;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager;
+import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider;
+import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl;
+import org.eclipse.che.security.oauth.OAuthAPI;
+import org.mockito.Mock;
+import org.mockito.testng.MockitoTestNGListener;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+
+@Listeners(MockitoTestNGListener.class)
+public class BitbucketServerURLTest {
+ private BitbucketServerURLParser bitbucketServerURLParser;
+ @Mock private DevfileFilenamesProvider devfileFilenamesProvider;
+
+ @BeforeMethod
+ protected void init() {
+ when(devfileFilenamesProvider.getConfiguredDevfileFilenames())
+ .thenReturn(Arrays.asList("devfile.yaml", "foo.bar"));
+ bitbucketServerURLParser =
+ new BitbucketServerURLParser(
+ "https://bitbucket.net",
+ devfileFilenamesProvider,
+ mock(OAuthAPI.class),
+ mock(PersonalAccessTokenManager.class));
+ }
+
+ @Test(dataProvider = "urlsProvider")
+ public void checkDevfileLocation(String repoUrl, String fileUrl) {
+ lenient()
+ .when(devfileFilenamesProvider.getConfiguredDevfileFilenames())
+ .thenReturn(Arrays.asList("devfile.yaml", "foo.bar"));
+
+ BitbucketServerUrl gitlabUrl = bitbucketServerURLParser.parse(repoUrl);
+ assertEquals(gitlabUrl.devfileFileLocations().size(), 2);
+ Iterator iterator =
+ gitlabUrl.devfileFileLocations().iterator();
+ assertEquals(iterator.next().location(), format(fileUrl, "devfile.yaml"));
+ assertEquals(iterator.next().location(), format(fileUrl, "foo.bar"));
+ }
+
+ @DataProvider
+ public static Object[][] urlsProvider() {
+ return new Object[][] {
+ {
+ "https://bitbucket.net/scm/~user/repo.git",
+ "https://bitbucket.net/rest/api/1.0/users/user/repos/repo/raw/%s"
+ },
+ {
+ "https://bitbucket.net/users/user/repos/repo/browse?at=branch",
+ "https://bitbucket.net/rest/api/1.0/users/user/repos/repo/raw/%s?at=branch"
+ },
+ {
+ "https://bitbucket.net/users/user/repos/repo",
+ "https://bitbucket.net/rest/api/1.0/users/user/repos/repo/raw/%s"
+ },
+ {
+ "https://bitbucket.net/scm/project/repo.git",
+ "https://bitbucket.net/rest/api/1.0/projects/project/repos/repo/raw/%s"
+ },
+ {
+ "https://bitbucket.net/projects/project/repos/repo/browse?at=branch",
+ "https://bitbucket.net/rest/api/1.0/projects/project/repos/repo/raw/%s?at=branch"
+ },
+ {
+ "ssh://git@bitbucket.net:12345/project/repo.git",
+ "https://bitbucket.net/rest/api/1.0/projects/project/repos/repo/raw/%s"
+ },
+ {
+ "ssh://git@bitbucket.net:12345/~user/repo.git",
+ "https://bitbucket.net/rest/api/1.0/users/user/repos/repo/raw/%s"
+ }
+ };
+ }
+
+ @Test(dataProvider = "repoProvider")
+ public void checkRepositoryLocation(String rawUrl, String repoUrl) {
+ BitbucketServerUrl bitbucketServerUrl = bitbucketServerURLParser.parse(rawUrl);
+ assertEquals(bitbucketServerUrl.repositoryLocation(), repoUrl);
+ }
+
+ @Test(dataProvider = "urlsProvider")
+ public void shouldReturnProviderUrl(String repoUrl, String ignored) {
+ // when
+ BitbucketServerUrl bitbucketServerUrl = bitbucketServerURLParser.parse(repoUrl);
+
+ // then
+ assertEquals(bitbucketServerUrl.getProviderUrl(), "https://bitbucket.net");
+ }
+
+ @DataProvider
+ public static Object[][] repoProvider() {
+ return new Object[][] {
+ {"https://bitbucket.net/scm/~user/repo.git", "https://bitbucket.net/scm/~user/repo.git"},
+ {
+ "https://bitbucket.net/users/user/repos/repo/browse?at=branch",
+ "https://bitbucket.net/scm/~user/repo.git"
+ },
+ {"https://bitbucket.net/users/user/repos/repo", "https://bitbucket.net/scm/~user/repo.git"},
+ {"https://bitbucket.net/scm/project/repo.git", "https://bitbucket.net/scm/project/repo.git"},
+ {
+ "https://bitbucket.net/projects/project/repos/repo/browse?at=branch",
+ "https://bitbucket.net/scm/project/repo.git"
+ },
+ {
+ "ssh://git@bitbucket.net:12345/project/repo.git",
+ "ssh://git@bitbucket.net:12345/project/repo.git"
+ },
+ {
+ "ssh://git@bitbucket.net:12345/~user/repo.git",
+ "ssh://git@bitbucket.net:12345/~user/repo.git"
+ },
+ };
+ }
+}
diff --git a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParser.java b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParser.java
index fb70810d69..8eb541794e 100644
--- a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParser.java
+++ b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParser.java
@@ -36,29 +36,39 @@ public class BitbucketURLParser {
Pattern.compile(
"^https?://(?[^/@]+)?@?bitbucket\\.org/(?[^/]+)/(?[^/]+)/?(\\.git)?(/(src|branch)/(?[^/]+)/?)?$");
+ protected static final Pattern BITBUCKET_SSH_PATTERN =
+ Pattern.compile("^git@bitbucket.org:(?.*)/(?.*)$");
+
public boolean isValid(@NotNull String url) {
- return BITBUCKET_PATTERN.matcher(url).matches();
+ return BITBUCKET_PATTERN.matcher(url).matches() || BITBUCKET_SSH_PATTERN.matcher(url).matches();
}
public BitbucketUrl parse(String url) {
// Apply bitbucket url to the regexp
- Matcher matcher = BITBUCKET_PATTERN.matcher(url);
+ boolean isHTTPSUrl = BITBUCKET_PATTERN.matcher(url).matches();
+ Matcher matcher =
+ isHTTPSUrl ? BITBUCKET_PATTERN.matcher(url) : BITBUCKET_SSH_PATTERN.matcher(url);
if (!matcher.matches()) {
throw new IllegalArgumentException(
String.format("The given bitbucket url %s is not a valid URL bitbucket url. ", url));
}
- String username = matcher.group("username");
+ String workspaceId = matcher.group("workspaceId");
String repoName = matcher.group("repoName");
if (repoName.matches("^[\\w-][\\w.-]*?\\.git$")) {
repoName = repoName.substring(0, repoName.length() - 4);
}
- String workspaceId = matcher.group("workspaceId");
- String branchName = matcher.group("branchName");
+ String username = null;
+ String branchName = null;
+ if (isHTTPSUrl) {
+ username = matcher.group("username");
+ branchName = matcher.group("branchName");
+ }
return new BitbucketUrl()
.withUsername(username)
.withRepository(repoName)
+ .setIsHTTPSUrl(isHTTPSUrl)
.withBranch(branchName)
.withWorkspaceId(workspaceId)
.withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames())
diff --git a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrl.java b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrl.java
index 08f18c3335..f8491987ef 100644
--- a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrl.java
+++ b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrl.java
@@ -41,6 +41,8 @@ public class BitbucketUrl extends DefaultFactoryUrl {
/** Repository part of the URL. */
private String repository;
+ private boolean isHTTPSUrl;
+
/** Branch name */
private String branch;
@@ -81,6 +83,11 @@ public class BitbucketUrl extends DefaultFactoryUrl {
return this;
}
+ public BitbucketUrl setIsHTTPSUrl(boolean isHTTPSUrl) {
+ this.isHTTPSUrl = isHTTPSUrl;
+ return this;
+ }
+
public String getWorkspaceId() {
return workspaceId;
}
@@ -164,13 +171,16 @@ public class BitbucketUrl extends DefaultFactoryUrl {
* @return location of the repository.
*/
protected String repositoryLocation() {
- return "https://"
- + (this.username != null ? this.username + '@' : "")
- + HOSTNAME
- + "/"
- + this.workspaceId
- + "/"
- + this.repository
- + ".git";
+ if (isHTTPSUrl) {
+ return "https://"
+ + (this.username != null ? this.username + '@' : "")
+ + HOSTNAME
+ + "/"
+ + workspaceId
+ + "/"
+ + repository
+ + ".git";
+ }
+ return String.format("git@%s:%s/%s.git", HOSTNAME, workspaceId, repository);
}
}
diff --git a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParserTest.java b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParserTest.java
index 1a3ee3c61e..348d579d70 100644
--- a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParserTest.java
+++ b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParserTest.java
@@ -76,6 +76,15 @@ public class BitbucketURLParserTest {
{"https://bitbucket.org/eclipse/che.with.dots.git"},
{"https://bitbucket.org/eclipse/che-with-hyphen"},
{"https://bitbucket.org/eclipse/che-with-hyphen.git"},
+ {"git@bitbucket.org:eclipse/che"},
+ {"git@bitbucket.org:eclipse/che123"},
+ {"git@bitbucket.org:eclipse/che/"},
+ {"git@bitbucket.org:eclipse/che/src/4.2.x"},
+ {"git@bitbucket.org:eclipse/che/src/master/"},
+ {"git@bitbucket.org:eclipse/che.git"},
+ {"git@bitbucket.org:eclipse/che.with.dots.git"},
+ {"git@bitbucket.org:eclipse/che-with-hyphen"},
+ {"git@bitbucket.org:eclipse/che-with-hyphen.git"},
{"https://username@bitbucket.org/eclipse/che"},
{"https://username@bitbucket.org/eclipse/che123"},
{"https://username@bitbucket.org/eclipse/che/"},
@@ -102,6 +111,16 @@ public class BitbucketURLParserTest {
{"https://bitbucket.org/eclipse/che-with-hyphen.git", "eclipse", "che-with-hyphen", null},
{"https://bitbucket.org/eclipse/che/", "eclipse", "che", null},
{"https://bitbucket.org/eclipse/repositorygit", "eclipse", "repositorygit", null},
+ {"git@bitbucket.org:eclipse/che", "eclipse", "che", null},
+ {"git@bitbucket.org:eclipse/che123", "eclipse", "che123", null},
+ {"git@bitbucket.org:eclipse/che.git", "eclipse", "che", null},
+ {"git@bitbucket.org:eclipse/che.with.dot.git", "eclipse", "che.with.dot", null},
+ {"git@bitbucket.org:eclipse/-.git", "eclipse", "-", null},
+ {"git@bitbucket.org:eclipse/-j.git", "eclipse", "-j", null},
+ {"git@bitbucket.org:eclipse/-", "eclipse", "-", null},
+ {"git@bitbucket.org:eclipse/che-with-hyphen", "eclipse", "che-with-hyphen", null},
+ {"git@bitbucket.org:eclipse/che-with-hyphen.git", "eclipse", "che-with-hyphen", null},
+ {"git@bitbucket.org:eclipse/repositorygit", "eclipse", "repositorygit", null},
{"https://bitbucket.org/eclipse/che/src/4.2.x", "eclipse", "che", "4.2.x"},
{"https://bitbucket.org/eclipse/che/src/master/", "eclipse", "che", "master"}
};
@@ -117,7 +136,15 @@ public class BitbucketURLParserTest {
{"https://bitbucket.org/eclipse/івапівап.git", "івапівап.git"},
{"https://bitbucket.org/eclipse/ ", " "},
{"https://bitbucket.org/eclipse/.", "."},
- {"https://bitbucket.org/eclipse/ .git", " .git"}
+ {"https://bitbucket.org/eclipse/ .git", " .git"},
+ {"git@bitbucket.org:eclipse/che .git", "che .git"},
+ {"git@bitbucket.org:eclipse/.git", ".git"},
+ {"git@bitbucket.org:eclipse/myB@dR&pository.git", "myB@dR&pository.git"},
+ {"git@bitbucket.org:eclipse/.", "."},
+ {"git@bitbucket.org:eclipse/івапівап.git", "івапівап.git"},
+ {"git@bitbucket.org:eclipse/ ", " "},
+ {"git@bitbucket.org:eclipse/.", "."},
+ {"git@bitbucket.org:eclipse/ .git", " .git"}
};
}
}
diff --git a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrlTest.java b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrlTest.java
index 8b589d2030..cdce9e5954 100644
--- a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrlTest.java
+++ b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrlTest.java
@@ -64,6 +64,22 @@ public class BitbucketUrlTest {
assertEquals(iterator.next().location(), "https://bitbucket.org/eclipse/che/raw/HEAD/foo.bar");
}
+ @Test
+ public void shouldReturnDevfileLocationBySSHUrl() {
+ bitbucketUrl = bitbucketURLParser.parse("git@bitbucket.org:eclipse/che");
+
+ lenient()
+ .when(devfileFilenamesProvider.getConfiguredDevfileFilenames())
+ .thenReturn(Arrays.asList("devfile.yaml", "foo.bar"));
+
+ assertEquals(bitbucketUrl.devfileFileLocations().size(), 2);
+ Iterator iterator = bitbucketUrl.devfileFileLocations().iterator();
+ assertEquals(
+ iterator.next().location(), "https://bitbucket.org/eclipse/che/raw/HEAD/devfile.yaml");
+
+ assertEquals(iterator.next().location(), "https://bitbucket.org/eclipse/che/raw/HEAD/foo.bar");
+ }
+
@Test
public void shouldReturnEmptyCredentials() {
// when
@@ -77,4 +93,11 @@ public class BitbucketUrlTest {
public void checkRepositoryLocation() {
assertEquals(bitbucketUrl.repositoryLocation(), "https://bitbucket.org/eclipse/che.git");
}
+
+ @Test
+ public void shouldReturnRepositoryLocationBySSHUrl() {
+ bitbucketUrl = bitbucketURLParser.parse("git@bitbucket.org:eclipse/che");
+
+ assertEquals(bitbucketUrl.repositoryLocation(), "git@bitbucket.org:eclipse/che.git");
+ }
}
diff --git a/wsmaster/che-core-api-factory-git-ssh/pom.xml b/wsmaster/che-core-api-factory-git-ssh/pom.xml
deleted file mode 100644
index 7069c8ba1a..0000000000
--- a/wsmaster/che-core-api-factory-git-ssh/pom.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-
-
-
- 4.0.0
-
- che-master-parent
- org.eclipse.che.core
- 7.73.0-SNAPSHOT
-
- che-core-api-factory-git-ssh
- jar
- Che Core :: API :: Factory Resolver Git Ssh
-
- true
-
-
-
- jakarta.inject
- jakarta.inject-api
-
-
- jakarta.validation
- jakarta.validation-api
-
-
- org.eclipse.che.core
- che-core-api-core
-
-
- org.eclipse.che.core
- che-core-api-dto
-
-
- org.eclipse.che.core
- che-core-api-factory
-
-
- org.eclipse.che.core
- che-core-api-factory-shared
-
-
- org.eclipse.che.core
- che-core-api-workspace
-
-
- org.eclipse.che.core
- che-core-api-workspace-shared
-
-
- ch.qos.logback
- logback-classic
- test
-
-
- com.github.tomakehurst
- wiremock-jre8-standalone
- test
-
-
- jakarta.servlet
- jakarta.servlet-api
- test
-
-
- jakarta.ws.rs
- jakarta.ws.rs-api
- test
-
-
- org.eclipse.che.core
- che-core-commons-json
- test
-
-
- org.hamcrest
- hamcrest-core
- test
-
-
- org.mockito
- mockito-core
- test
-
-
- org.mockito
- mockito-testng
- test
-
-
- org.slf4j
- jcl-over-slf4j
- test
-
-
- org.testng
- testng
- test
-
-
-
diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshAuthorizingFileContentProvider.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshAuthorizingFileContentProvider.java
deleted file mode 100644
index 094a2a2575..0000000000
--- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshAuthorizingFileContentProvider.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012-2023 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.api.factory.server.git.ssh;
-
-import org.eclipse.che.api.factory.server.scm.AuthorizingFileContentProvider;
-import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager;
-import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
-
-/**
- * Git Ssh specific authorizing file content provider.
- *
- * @author Anatolii Bazko
- */
-class GitSshAuthorizingFileContentProvider extends AuthorizingFileContentProvider {
-
- GitSshAuthorizingFileContentProvider(
- GitSshUrl gitSshUrl,
- URLFetcher urlFetcher,
- PersonalAccessTokenManager personalAccessTokenManager) {
- super(gitSshUrl, urlFetcher, personalAccessTokenManager);
- }
-}
diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java
deleted file mode 100644
index 0d5add093e..0000000000
--- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2012-2023 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.api.factory.server.git.ssh;
-
-import static org.eclipse.che.api.factory.shared.Constants.CURRENT_VERSION;
-import static org.eclipse.che.api.factory.shared.Constants.URL_PARAMETER_NAME;
-import static org.eclipse.che.dto.server.DtoFactory.newDto;
-
-import jakarta.validation.constraints.NotNull;
-import java.util.Map;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.ApiException;
-import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver;
-import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager;
-import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl;
-import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder;
-import org.eclipse.che.api.factory.shared.dto.FactoryDevfileV2Dto;
-import org.eclipse.che.api.factory.shared.dto.FactoryDto;
-import org.eclipse.che.api.factory.shared.dto.FactoryMetaDto;
-import org.eclipse.che.api.factory.shared.dto.FactoryVisitor;
-import org.eclipse.che.api.factory.shared.dto.ScmInfoDto;
-import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
-import org.eclipse.che.api.workspace.shared.dto.devfile.ProjectDto;
-import org.eclipse.che.api.workspace.shared.dto.devfile.SourceDto;
-
-/**
- * Provides Factory Parameters resolver for Git Ssh repositories.
- *
- * @author Anatolii Bazko
- */
-@Singleton
-public class GitSshFactoryParametersResolver extends RawDevfileUrlFactoryParameterResolver {
-
- private final GitSshURLParser gitSshURLParser;
-
- private final PersonalAccessTokenManager personalAccessTokenManager;
-
- @Inject
- public GitSshFactoryParametersResolver(
- GitSshURLParser gitSshURLParser,
- URLFetcher urlFetcher,
- URLFactoryBuilder urlFactoryBuilder,
- PersonalAccessTokenManager personalAccessTokenManager) {
- super(urlFactoryBuilder, urlFetcher);
- this.gitSshURLParser = gitSshURLParser;
- this.personalAccessTokenManager = personalAccessTokenManager;
- }
-
- @Override
- public boolean accept(@NotNull final Map factoryParameters) {
- return factoryParameters.containsKey(URL_PARAMETER_NAME)
- && gitSshURLParser.isValid(factoryParameters.get(URL_PARAMETER_NAME));
- }
-
- @Override
- public FactoryMetaDto createFactory(@NotNull final Map factoryParameters)
- throws ApiException {
- // no need to check null value of url parameter as accept() method has performed the check
- final GitSshUrl gitSshUrl = gitSshURLParser.parse(factoryParameters.get(URL_PARAMETER_NAME));
-
- // create factory from the following location if location exists, else create default factory
- return urlFactoryBuilder
- .createFactoryFromDevfile(
- gitSshUrl,
- new GitSshAuthorizingFileContentProvider(
- gitSshUrl, urlFetcher, personalAccessTokenManager),
- extractOverrideParams(factoryParameters),
- true)
- .orElseGet(() -> newDto(FactoryDto.class).withV(CURRENT_VERSION).withSource("repo"))
- .acceptVisitor(new GitSshFactoryVisitor(gitSshUrl));
- }
-
- /**
- * Visitor that puts the default devfile or updates devfile projects into the Git Ssh Factory, if
- * needed.
- */
- private class GitSshFactoryVisitor implements FactoryVisitor {
-
- private final GitSshUrl gitSshUrl;
-
- private GitSshFactoryVisitor(GitSshUrl gitSshUrl) {
- this.gitSshUrl = gitSshUrl;
- }
-
- @Override
- public FactoryDevfileV2Dto visit(FactoryDevfileV2Dto factoryDto) {
- ScmInfoDto scmInfo =
- newDto(ScmInfoDto.class)
- .withScmProviderName(gitSshUrl.getProviderName())
- .withRepositoryUrl(gitSshUrl.getRepositoryLocation());
- return factoryDto.withScmInfo(scmInfo);
- }
-
- @Override
- public FactoryDto visit(FactoryDto factory) {
- if (factory.getDevfile() == null) {
- factory.setDevfile(urlFactoryBuilder.buildDefaultDevfile(gitSshUrl.getRepository()));
- }
-
- updateProjects(
- factory.getDevfile(),
- () ->
- newDto(ProjectDto.class)
- .withSource(
- newDto(SourceDto.class)
- .withLocation(gitSshUrl.getRepositoryLocation())
- .withType("git"))
- .withName(gitSshUrl.getRepository()),
- project -> {});
-
- return factory;
- }
- }
-
- @Override
- public RemoteFactoryUrl parseFactoryUrl(String factoryUrl) {
- return gitSshURLParser.parse(factoryUrl);
- }
-}
diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshScmFileResolver.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshScmFileResolver.java
deleted file mode 100644
index a28b208cb8..0000000000
--- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshScmFileResolver.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2012-2023 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.api.factory.server.git.ssh;
-
-import jakarta.validation.constraints.NotNull;
-import javax.inject.Inject;
-import org.eclipse.che.api.factory.server.ScmFileResolver;
-
-/**
- * Git Ssh specific SCM file resolver.
- *
- * @author Anatolii Bazko
- */
-public class GitSshScmFileResolver implements ScmFileResolver {
-
- private final GitSshURLParser gitSshURLParser;
-
- @Inject
- public GitSshScmFileResolver(GitSshURLParser gitSshURLParser) {
- this.gitSshURLParser = gitSshURLParser;
- }
-
- @Override
- public boolean accept(@NotNull String repository) {
- return gitSshURLParser.isValid(repository);
- }
-
- /**
- * There is no way to get a file content from a git repository via ssh protocol. So this method
- * always returns an empty string. It allows to start a workspace from an empty devfile.
- */
- @Override
- public String fileContent(@NotNull String repository, @NotNull String filePath) {
- return "";
- }
-}
diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParser.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParser.java
deleted file mode 100644
index 9c25e825b7..0000000000
--- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParser.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2012-2023 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.api.factory.server.git.ssh;
-
-import static java.lang.String.format;
-import static java.util.regex.Pattern.compile;
-
-import jakarta.validation.constraints.NotNull;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider;
-
-/**
- * Parser of String Git Ssh URLs and provide {@link GitSshUrl} objects.
- *
- * @author Anatolii Bazko
- */
-@Singleton
-public class GitSshURLParser {
-
- private final Pattern gitSshPattern;
-
- private final DevfileFilenamesProvider devfileFilenamesProvider;
-
- @Inject
- public GitSshURLParser(DevfileFilenamesProvider devfileFilenamesProvider) {
- this.devfileFilenamesProvider = devfileFilenamesProvider;
- this.gitSshPattern = compile("^git@(?[^:]++):(.*)/(?[^/]++)$");
- }
-
- public boolean isValid(@NotNull String url) {
- return gitSshPattern.matcher(url).matches();
- }
-
- public GitSshUrl parse(String url) {
- Matcher matcher = gitSshPattern.matcher(url);
- if (!matcher.matches()) {
- throw new IllegalArgumentException(
- format("The given url %s is not a valid. It should start with git@", url));
- }
-
- String hostName = matcher.group("hostName");
- String repoName = matcher.group("repoName");
- if (repoName.endsWith(".git")) {
- repoName = repoName.substring(0, repoName.length() - 4);
- }
-
- return new GitSshUrl()
- .withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames())
- .withHostName(hostName)
- .withRepository(repoName)
- .withRepositoryLocation(url)
- .withUrl(url);
- }
-}
diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshUrl.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshUrl.java
deleted file mode 100644
index ae180c9e07..0000000000
--- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshUrl.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2012-2023 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.api.factory.server.git.ssh;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import org.eclipse.che.api.factory.server.urlfactory.DefaultFactoryUrl;
-
-/**
- * Representation of Git Ssh URL, allowing to get details from it.
- *
- * @author Anatolii Bazko
- */
-public class GitSshUrl extends DefaultFactoryUrl {
-
- private String repository;
- private String hostName;
-
- private String repositoryLocation;
-
- private final List devfileFilenames = new ArrayList<>();
-
- protected GitSshUrl() {}
-
- @Override
- public String getProviderName() {
- return "git-ssh";
- }
-
- @Override
- public String getBranch() {
- return null;
- }
-
- public GitSshUrl withDevfileFilenames(List devfileFilenames) {
- this.devfileFilenames.addAll(devfileFilenames);
- return this;
- }
-
- @Override
- public void setDevfileFilename(String devfileName) {
- this.devfileFilenames.clear();
- this.devfileFilenames.add(devfileName);
- }
-
- @Override
- public List devfileFileLocations() {
- return devfileFilenames.stream().map(this::createDevfileLocation).collect(Collectors.toList());
- }
-
- @Override
- public String rawFileLocation(String filename) {
- return filename;
- }
-
- private DevfileLocation createDevfileLocation(String devfileFilename) {
- return new DevfileLocation() {
- @Override
- public Optional filename() {
- return Optional.of(devfileFilename);
- }
-
- @Override
- public String location() {
- return devfileFilename;
- }
- };
- }
-
- @Override
- public String getHostName() {
- return hostName;
- }
-
- public GitSshUrl withHostName(String hostName) {
- this.hostName = hostName;
- return this;
- }
-
- public String getRepositoryLocation() {
- return repositoryLocation;
- }
-
- public GitSshUrl withRepositoryLocation(String repositoryLocation) {
- this.repositoryLocation = repositoryLocation;
- return this;
- }
-
- public String getRepository() {
- return repository;
- }
-
- public GitSshUrl withRepository(String repository) {
- this.repository = repository;
- return this;
- }
-}
diff --git a/wsmaster/che-core-api-factory-git-ssh/src/test/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParserTest.java b/wsmaster/che-core-api-factory-git-ssh/src/test/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParserTest.java
deleted file mode 100644
index 715e5f544b..0000000000
--- a/wsmaster/che-core-api-factory-git-ssh/src/test/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParserTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2012-2023 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.api.factory.server.git.ssh;
-
-import static org.mockito.Mockito.mock;
-import static org.testng.Assert.assertEquals;
-
-import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/** @author Anatalii Bazko */
-@Listeners(MockitoTestNGListener.class)
-public class GitSshURLParserTest {
-
- private GitSshURLParser gitSshURLParser;
-
- @BeforeMethod
- protected void start() {
- gitSshURLParser = new GitSshURLParser(mock(DevfileFilenamesProvider.class));
- }
-
- @Test(dataProvider = "parsing")
- public void testParse(String url, String hostName, String repository) {
- GitSshUrl gitSshUrl = gitSshURLParser.parse(url);
-
- assertEquals(gitSshUrl.getHostName(), hostName);
- assertEquals(gitSshUrl.getRepository(), repository);
- }
-
- @DataProvider(name = "parsing")
- public Object[][] expectedParsing() {
- return new Object[][] {
- {"git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo", "ssh.dev.azure.com", "MyRepo"},
- {"git@github.com:MyOrg/MyRepo.git", "github.com", "MyRepo"},
- };
- }
-}
diff --git a/wsmaster/che-core-api-factory-git-ssh/src/test/resources/logback-test.xml b/wsmaster/che-core-api-factory-git-ssh/src/test/resources/logback-test.xml
deleted file mode 100644
index 704cbbf50f..0000000000
--- a/wsmaster/che-core-api-factory-git-ssh/src/test/resources/logback-test.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
- %-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n%nopex
-
-
-
-
-
-
-
-
diff --git a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java
index 811853e51d..a8ea88b991 100644
--- a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java
+++ b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java
@@ -20,6 +20,7 @@ import static org.eclipse.che.api.factory.server.github.GithubApiClient.GITHUB_S
import static org.eclipse.che.commons.lang.StringUtils.trimEnd;
import jakarta.validation.constraints.NotNull;
+import java.net.URI;
import java.net.URISyntaxException;
import java.util.Optional;
import java.util.regex.Matcher;
@@ -63,6 +64,8 @@ public class GithubURLParser {
*/
private final Pattern githubPattern;
+ private final Pattern githubSSHPattern;
+
private final boolean disableSubdomainIsolation;
@Inject
@@ -101,10 +104,14 @@ public class GithubURLParser {
format(
"^%s/(?[^/]+)/(?[^/]++)((/)|(?:/tree/(?.++))|(/pull/(?\\d++)))?$",
endpoint));
+ this.githubSSHPattern =
+ compile(format("^git@%s:(?.*)/(?.*)$", URI.create(endpoint).getHost()));
}
public boolean isValid(@NotNull String url) {
- return githubPattern.matcher(trimEnd(url, '/')).matches();
+ String trimmedUrl = trimEnd(url, '/');
+ return githubPattern.matcher(trimmedUrl).matches()
+ || githubSSHPattern.matcher(trimmedUrl).matches();
}
public GithubUrl parseWithoutAuthentication(String url) throws ApiException {
@@ -116,13 +123,11 @@ public class GithubURLParser {
}
private GithubUrl parse(String url, boolean authenticationRequired) throws ApiException {
- // Apply github url to the regexp
- Matcher matcher = githubPattern.matcher(url);
+ boolean isHTTPSUrl = githubPattern.matcher(url).matches();
+ Matcher matcher = isHTTPSUrl ? githubPattern.matcher(url) : githubSSHPattern.matcher(url);
if (!matcher.matches()) {
throw new IllegalArgumentException(
- format(
- "The given github url %s is not a valid URL github url. It should start with https://github.com//",
- url));
+ format("The given url %s is not a valid github URL. ", url));
}
String serverUrl =
@@ -135,9 +140,12 @@ public class GithubURLParser {
repoName = repoName.substring(0, repoName.length() - 4);
}
- String branchName = matcher.group("branchName");
-
- String pullRequestId = matcher.group("pullRequestId");
+ String branchName = null;
+ String pullRequestId = null;
+ if (isHTTPSUrl) {
+ branchName = matcher.group("branchName");
+ pullRequestId = matcher.group("pullRequestId");
+ }
if (pullRequestId != null) {
GithubPullRequest pullRequest =
@@ -169,6 +177,7 @@ public class GithubURLParser {
return new GithubUrl()
.withUsername(repoUser)
.withRepository(repoName)
+ .setIsHTTPSUrl(isHTTPSUrl)
.withServerUrl(serverUrl)
.withDisableSubdomainIsolation(disableSubdomainIsolation)
.withBranch(branchName)
diff --git a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java
index 46ea5be275..148bae9bf4 100644
--- a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java
+++ b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java
@@ -37,6 +37,8 @@ public class GithubUrl extends DefaultFactoryUrl {
/** Username part of github URL */
private String username;
+ private boolean isHTTPSUrl = true;
+
/** Repository part of the URL. */
private String repository;
@@ -78,6 +80,11 @@ public class GithubUrl extends DefaultFactoryUrl {
return this;
}
+ public GithubUrl setIsHTTPSUrl(boolean isHTTPSUrl) {
+ this.isHTTPSUrl = isHTTPSUrl;
+ return this;
+ }
+
/**
* Gets repository of this github url
*
@@ -209,8 +216,17 @@ public class GithubUrl extends DefaultFactoryUrl {
* @return location of the repository.
*/
protected String repositoryLocation() {
- return (isNullOrEmpty(serverUrl) ? HOSTNAME : serverUrl)
- + "/"
+ if (isHTTPSUrl) {
+ return (isNullOrEmpty(serverUrl) ? HOSTNAME : serverUrl)
+ + "/"
+ + this.username
+ + "/"
+ + this.repository
+ + ".git";
+ }
+ return "git@"
+ + getHostName().substring(getHostName().indexOf("://") + 3)
+ + ":"
+ this.username
+ "/"
+ this.repository
diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubURLParserTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubURLParserTest.java
index 42a97931a4..3183546cac 100644
--- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubURLParserTest.java
+++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubURLParserTest.java
@@ -108,7 +108,13 @@ public class GithubURLParserTest {
{"https://github.com/eclipse/che.git"},
{"https://github.com/eclipse/che.with.dots.git"},
{"https://github.com/eclipse/che-with-hyphen"},
- {"https://github.com/eclipse/che-with-hyphen.git"}
+ {"https://github.com/eclipse/che-with-hyphen.git"},
+ {"git@github.com:eclipse/che.git)"},
+ {"git@github.com:eclipse/che)"},
+ {"git@github.com:eclipse/che123)"},
+ {"git@github.com:eclipse/che.with.dots.git)"},
+ {"git@github.com:eclipse/che-with-hyphen)"},
+ {"git@github.com:eclipse/che-with-hyphen.git)"}
};
}
@@ -133,7 +139,18 @@ public class GithubURLParserTest {
"eclipse",
"che",
"branch/with/slash"
- }
+ },
+ {"git@github.com:eclipse/che", "eclipse", "che", null},
+ {"git@github.com:eclipse/che123", "eclipse", "che123", null},
+ {"git@github.com:eclipse/che.git", "eclipse", "che", null},
+ {"git@github.com:eclipse/che.with.dot.git", "eclipse", "che.with.dot", null},
+ {"git@github.com:eclipse/-.git", "eclipse", "-", null},
+ {"git@github.com:eclipse/-j.git", "eclipse", "-j", null},
+ {"git@github.com:eclipse/-", "eclipse", "-", null},
+ {"git@github.com:eclipse/che-with-hyphen", "eclipse", "che-with-hyphen", null},
+ {"git@github.com:eclipse/che-with-hyphen.git", "eclipse", "che-with-hyphen", null},
+ {"git@github.com:eclipse/che/", "eclipse", "che", null},
+ {"git@github.com:eclipse/repositorygit", "eclipse", "repositorygit", null},
};
}
@@ -147,7 +164,15 @@ public class GithubURLParserTest {
{"https://github.com/eclipse/івапівап.git", "івапівап.git"},
{"https://github.com/eclipse/ ", " "},
{"https://github.com/eclipse/.", "."},
- {"https://github.com/eclipse/ .git", " .git"}
+ {"https://github.com/eclipse/ .git", " .git"},
+ {"git@github.com:eclipse/che .git", "che .git"},
+ {"git@github.com:eclipse/.git", ".git"},
+ {"git@github.com:eclipse/myB@dR&pository.git", "myB@dR&pository.git"},
+ {"git@github.com:eclipse/.", "."},
+ {"git@github.com:eclipse/івапівап.git", "івапівап.git"},
+ {"git@github.com:eclipse/ ", " "},
+ {"git@github.com:eclipse/.", "."},
+ {"git@github.com:eclipse/ .git", " .git"}
};
}
diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubUrlTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubUrlTest.java
index cdb5aeaf00..8c0ff82e14 100644
--- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubUrlTest.java
+++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubUrlTest.java
@@ -64,6 +64,34 @@ public class GithubUrlTest {
iterator.next().location(), "https://raw.githubusercontent.com/eclipse/che/HEAD/foo.bar");
}
+ @Test
+ public void shouldReturnDevfileLocationFromSSHUrl() throws Exception {
+ DevfileFilenamesProvider devfileFilenamesProvider = mock(DevfileFilenamesProvider.class);
+
+ /** Parser used to create the url. */
+ GithubURLParser githubUrlParser =
+ new GithubURLParser(
+ mock(PersonalAccessTokenManager.class),
+ devfileFilenamesProvider,
+ githubApiClient,
+ null,
+ false);
+
+ when(devfileFilenamesProvider.getConfiguredDevfileFilenames())
+ .thenReturn(Arrays.asList("devfile.yaml", "foo.bar"));
+
+ GithubUrl githubUrl = githubUrlParser.parse("git@github.com:eclipse/che");
+
+ assertEquals(githubUrl.devfileFileLocations().size(), 2);
+ Iterator iterator = githubUrl.devfileFileLocations().iterator();
+ assertEquals(
+ iterator.next().location(),
+ "https://raw.githubusercontent.com/eclipse/che/HEAD/devfile.yaml");
+
+ assertEquals(
+ iterator.next().location(), "https://raw.githubusercontent.com/eclipse/che/HEAD/foo.bar");
+ }
+
/** Check the original repository */
@Test
public void checkRepositoryLocation() throws Exception {
@@ -86,6 +114,27 @@ public class GithubUrlTest {
assertEquals(githubUrl.repositoryLocation(), "https://github.com/eclipse/che.git");
}
+ @Test
+ public void shouldReturnRepositoryLocationFromSSHUrl() throws Exception {
+ DevfileFilenamesProvider devfileFilenamesProvider = mock(DevfileFilenamesProvider.class);
+
+ /** Parser used to create the url. */
+ GithubURLParser githubUrlParser =
+ new GithubURLParser(
+ mock(PersonalAccessTokenManager.class),
+ devfileFilenamesProvider,
+ githubApiClient,
+ null,
+ false);
+
+ when(devfileFilenamesProvider.getConfiguredDevfileFilenames())
+ .thenReturn(Arrays.asList("devfile.yaml", "foo.bar"));
+
+ GithubUrl githubUrl = githubUrlParser.parse("git@github.com:eclipse/che.git");
+
+ assertEquals(githubUrl.repositoryLocation(), "git@github.com:eclipse/che.git");
+ }
+
@Test
public void testRawFileLocationWithDefaultBranchName() {
String file = ".che/che-theia-plugins.yaml";
diff --git a/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrl.java b/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrl.java
index 057630821a..74f3f108c3 100644
--- a/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrl.java
+++ b/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrl.java
@@ -11,10 +11,10 @@
*/
package org.eclipse.che.api.factory.server.gitlab;
+import static com.google.common.base.Strings.isNullOrEmpty;
import static java.net.URLEncoder.encode;
import com.google.common.base.Charsets;
-import com.google.common.base.Strings;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -37,6 +37,9 @@ public class GitlabUrl extends DefaultFactoryUrl {
/** Hostname of the gitlab URL */
private String hostName;
+ /** Scheme of the gitlab URL */
+ private String scheme;
+
/** Project part of the gitlab URL */
private String project;
@@ -63,6 +66,11 @@ public class GitlabUrl extends DefaultFactoryUrl {
return NAME;
}
+ @Override
+ public String getProviderUrl() {
+ return (isNullOrEmpty(scheme) ? "https" : scheme) + "://" + hostName;
+ }
+
/**
* Gets hostname of this gitlab url
*
@@ -77,6 +85,11 @@ public class GitlabUrl extends DefaultFactoryUrl {
return this;
}
+ public GitlabUrl withScheme(String scheme) {
+ this.scheme = scheme;
+ return this;
+ }
+
/**
* Gets project of this bitbucket url
*
@@ -120,7 +133,7 @@ public class GitlabUrl extends DefaultFactoryUrl {
}
protected GitlabUrl withBranch(String branch) {
- if (!Strings.isNullOrEmpty(branch)) {
+ if (!isNullOrEmpty(branch)) {
this.branch = branch;
}
return this;
@@ -158,7 +171,7 @@ public class GitlabUrl extends DefaultFactoryUrl {
public String rawFileLocation(String fileName) {
String resultUrl =
new StringJoiner("/")
- .add(hostName)
+ .add((isNullOrEmpty(scheme) ? "https" : scheme) + "://" + hostName)
.add("api/v4/projects")
// use URL-encoded path to the project as a selector instead of id
.add(encode(subGroups, Charsets.UTF_8))
@@ -180,6 +193,9 @@ public class GitlabUrl extends DefaultFactoryUrl {
* @return location of the repository.
*/
protected String repositoryLocation() {
- return hostName + "/" + subGroups + ".git";
+ if (isNullOrEmpty(scheme)) {
+ return "git@" + hostName + ":" + subGroups + ".git";
+ }
+ return scheme + "://" + hostName + "/" + subGroups + ".git";
}
}
diff --git a/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParser.java b/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParser.java
index 7545ab38ee..952bd5c6b3 100644
--- a/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParser.java
+++ b/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParser.java
@@ -18,6 +18,7 @@ import static org.eclipse.che.commons.lang.StringUtils.trimEnd;
import com.google.common.base.Splitter;
import jakarta.validation.constraints.NotNull;
+import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -46,8 +47,10 @@ public class GitlabUrlParser {
private final PersonalAccessTokenManager personalAccessTokenManager;
private static final List gitlabUrlPatternTemplates =
List.of(
- "^(?%s)/(?([^/]++/?)+)/-/tree/(?.++)(/)?",
- "^(?%s)/(?.*)"); // a wider one, should be the last in the
+ "^(?%s)://(?%s)/(?([^/]++/?)+)/-/tree/(?.++)(/)?",
+ "^(?%s)://(?%s)/(?.*)"); // a wider one, should be the last in
+ // the list
+ private final String gitlabSSHPatternTemplate = "^git@(?%s):(?.*)$";
// list
private final List gitlabUrlPatterns = new ArrayList<>();
private static final String OAUTH_PROVIDER_NAME = "gitlab";
@@ -62,13 +65,18 @@ public class GitlabUrlParser {
if (gitlabEndpoints != null) {
for (String gitlabEndpoint : Splitter.on(",").split(gitlabEndpoints)) {
String trimmedEndpoint = trimEnd(gitlabEndpoint, '/');
+ URI uri = URI.create(trimmedEndpoint);
+ String schema = uri.getScheme();
+ String host = uri.getHost();
for (String gitlabUrlPatternTemplate : gitlabUrlPatternTemplates) {
- gitlabUrlPatterns.add(compile(format(gitlabUrlPatternTemplate, trimmedEndpoint)));
+ gitlabUrlPatterns.add(compile(format(gitlabUrlPatternTemplate, schema, host)));
}
+ gitlabUrlPatterns.add(compile(format(gitlabSSHPatternTemplate, host)));
}
} else {
gitlabUrlPatternTemplates.forEach(
- t -> gitlabUrlPatterns.add(compile(format(t, "https://gitlab.com"))));
+ t -> gitlabUrlPatterns.add(compile(format(t, "https", "gitlab.com"))));
+ gitlabUrlPatterns.add(compile(format(gitlabSSHPatternTemplate, "gitlab.com")));
}
}
@@ -112,7 +120,7 @@ public class GitlabUrlParser {
gitlabApiClient.getOAuthTokenInfo("");
} catch (ScmCommunicationException e) {
return e.getStatusCode() == HTTP_UNAUTHORIZED;
- } catch (ScmItemNotFoundException e) {
+ } catch (ScmItemNotFoundException | IllegalArgumentException e) {
return false;
}
}
@@ -120,18 +128,32 @@ public class GitlabUrlParser {
}
private Optional getPatternMatcherByUrl(String url) {
- Optional serverUrlOptional = getServerUrl(url);
- if (serverUrlOptional.isPresent()) {
- String serverUrl = serverUrlOptional.get();
- return gitlabUrlPatternTemplates.stream()
- .map(t -> compile(format(t, serverUrl)).matcher(url))
- .filter(Matcher::matches)
- .findAny();
- }
- return Optional.empty();
+ URI uri =
+ URI.create(
+ url.matches(format(gitlabSSHPatternTemplate, ".*"))
+ ? "ssh://" + url.replace(":", "/")
+ : url);
+ String scheme = uri.getScheme();
+ String host = uri.getHost();
+ return gitlabUrlPatternTemplates.stream()
+ .map(t -> compile(format(t, scheme, host)).matcher(url))
+ .filter(Matcher::matches)
+ .findAny()
+ .or(
+ () -> {
+ Matcher matcher = compile(format(gitlabSSHPatternTemplate, host)).matcher(url);
+ if (matcher.matches()) {
+ return Optional.of(matcher);
+ }
+ return Optional.empty();
+ });
}
private Optional getServerUrl(String repositoryUrl) {
+ if (repositoryUrl.startsWith("git@")) {
+ String substring = repositoryUrl.substring(4);
+ return Optional.of("https://" + substring.substring(0, substring.indexOf(":")));
+ }
Matcher serverUrlMatcher = compile("[^/|:]/").matcher(repositoryUrl);
if (serverUrlMatcher.find()) {
return Optional.of(
@@ -162,6 +184,12 @@ public class GitlabUrlParser {
}
private GitlabUrl parse(Matcher matcher) {
+ String scheme = null;
+ try {
+ scheme = matcher.group("scheme");
+ } catch (IllegalArgumentException e) {
+ // ok no such group
+ }
String host = matcher.group("host");
String subGroups = trimEnd(matcher.group("subgroups"), '/');
if (subGroups.endsWith(".git")) {
@@ -177,6 +205,7 @@ public class GitlabUrlParser {
return new GitlabUrl()
.withHostName(host)
+ .withScheme(scheme)
.withSubGroups(subGroups)
.withBranch(branch)
.withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames());
diff --git a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabAuthorizingFileContentProviderTest.java b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabAuthorizingFileContentProviderTest.java
index 0c784206ac..9685b6cf55 100644
--- a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabAuthorizingFileContentProviderTest.java
+++ b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabAuthorizingFileContentProviderTest.java
@@ -32,8 +32,7 @@ public class GitlabAuthorizingFileContentProviderTest {
@Test
public void shouldExpandRelativePaths() throws Exception {
URLFetcher urlFetcher = Mockito.mock(URLFetcher.class);
- GitlabUrl gitlabUrl =
- new GitlabUrl().withHostName("https://gitlab.net").withSubGroups("eclipse/che");
+ GitlabUrl gitlabUrl = new GitlabUrl().withHostName("gitlab.net").withSubGroups("eclipse/che");
FileContentProvider fileContentProvider =
new GitlabAuthorizingFileContentProvider(gitlabUrl, urlFetcher, personalAccessTokenManager);
var personalAccessToken = new PersonalAccessToken("foo", "che", "my-token");
diff --git a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParserTest.java b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParserTest.java
index 27aadf7c2a..e8022fd043 100644
--- a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParserTest.java
+++ b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParserTest.java
@@ -79,6 +79,22 @@ public class GitlabUrlParserTest {
assertEquals(gitlabUrl.getBranch(), branch);
}
+ /** Compare parsing */
+ @Test(dataProvider = "parsing")
+ public void shouldParseWithoutPredefinedEndpoint(
+ String url, String project, String subGroups, String branch) {
+ // given
+ gitlabUrlParser =
+ new GitlabUrlParser(null, devfileFilenamesProvider, mock(PersonalAccessTokenManager.class));
+ // when
+ GitlabUrl gitlabUrl = gitlabUrlParser.parse(url);
+
+ // then
+ assertEquals(gitlabUrl.getProject(), project);
+ assertEquals(gitlabUrl.getSubGroups(), subGroups);
+ assertEquals(gitlabUrl.getBranch(), branch);
+ }
+
@Test
public void shouldValidateUrlByApiRequest() {
// given
@@ -114,7 +130,12 @@ public class GitlabUrlParserTest {
{"https://gitlab1.com/user/project/"},
{"https://gitlab1.com/user/project/repo/"},
{"https://gitlab1.com/user/project/-/tree/master/"},
- {"https://gitlab1.com/user/project/repo/-/tree/master/subfolder"}
+ {"https://gitlab1.com/user/project/repo/-/tree/master/subfolder"},
+ {"git@gitlab1.com:user/project/test1.git"},
+ {"git@gitlab1.com:user/project1.git"},
+ {"git@gitlab.foo.xxx:scm/project/test1.git"},
+ {"git@gitlab1.com:user/project/"},
+ {"git@gitlab1.com:user/project/repo/"},
};
}
@@ -131,6 +152,16 @@ public class GitlabUrlParserTest {
},
{"https://gitlab1.com/user/project/", "project", "user/project", null},
{"https://gitlab1.com/user/project/repo/", "repo", "user/project/repo", null},
+ {"git@gitlab1.com:user/project1.git", "project1", "user/project1", null},
+ {"git@gitlab1.com:user/project/test1.git", "test1", "user/project/test1", null},
+ {
+ "git@gitlab1.com:user/project/group1/group2/test1.git",
+ "test1",
+ "user/project/group1/group2/test1",
+ null
+ },
+ {"git@gitlab1.com:user/project/", "project", "user/project", null},
+ {"git@gitlab1.com:user/project/repo/", "repo", "user/project/repo", null},
{"https://gitlab1.com/user/project/-/tree/master/", "project", "user/project", "master"},
{"https://gitlab1.com/user/project/repo/-/tree/foo", "repo", "user/project/repo", "foo"},
{
diff --git a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlTest.java b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlTest.java
index e03e5b49f1..c392362af6 100644
--- a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlTest.java
+++ b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlTest.java
@@ -66,6 +66,15 @@ public class GitlabUrlTest {
assertEquals(iterator.next().location(), format(fileUrl, "foo.bar"));
}
+ @Test(dataProvider = "urlsProvider")
+ public void shouldReturnProviderUrl(String repoUrl, String ignored) {
+ // when
+ GitlabUrl gitlabUrl = gitlabUrlParser.parse(repoUrl);
+
+ // then
+ assertEquals(gitlabUrl.getProviderUrl(), "https://gitlab.net");
+ }
+
@DataProvider
public static Object[][] urlsProvider() {
return new Object[][] {
@@ -77,6 +86,14 @@ public class GitlabUrlTest {
"https://gitlab.net/eclipse/fooproj/che.git",
"https://gitlab.net/api/v4/projects/eclipse%%2Ffooproj%%2Fche/repository/files/%s/raw"
},
+ {
+ "git@gitlab.net:eclipse/che.git",
+ "https://gitlab.net/api/v4/projects/eclipse%%2Fche/repository/files/%s/raw"
+ },
+ {
+ "git@gitlab.net:eclipse/fooproj/che.git",
+ "https://gitlab.net/api/v4/projects/eclipse%%2Ffooproj%%2Fche/repository/files/%s/raw"
+ },
{
"https://gitlab.net/eclipse/fooproj/-/tree/master/",
"https://gitlab.net/api/v4/projects/eclipse%%2Ffooproj/repository/files/%s/raw?ref=master"
@@ -100,6 +117,8 @@ public class GitlabUrlTest {
return new Object[][] {
{"https://gitlab.net/eclipse/che.git", "https://gitlab.net/eclipse/che.git"},
{"https://gitlab.net/eclipse/foo/che.git", "https://gitlab.net/eclipse/foo/che.git"},
+ {"git@gitlab.net:eclipse/che.git", "git@gitlab.net:eclipse/che.git"},
+ {"git@gitlab.net:eclipse/foo/che.git", "git@gitlab.net:eclipse/foo/che.git"},
{
"https://gitlab.net/eclipse/fooproj/che/-/tree/master/",
"https://gitlab.net/eclipse/fooproj/che.git"
diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java
index aa5de7bf30..14cf3fc176 100644
--- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java
+++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java
@@ -80,7 +80,7 @@ public class AuthorizingFileContentProvider
String authorization;
if (isNullOrEmpty(credentials)) {
PersonalAccessToken token =
- personalAccessTokenManager.get(remoteFactoryUrl.getHostName());
+ personalAccessTokenManager.get(remoteFactoryUrl.getProviderUrl());
authorization =
formatAuthorization(
token.getToken(),
diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java
index 16078985ff..6560435f68 100644
--- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java
+++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java
@@ -61,6 +61,11 @@ public class DefaultFactoryUrl implements RemoteFactoryUrl {
return URI.create(devfileFileLocation).getHost();
}
+ @Override
+ public String getProviderUrl() {
+ return getHostName();
+ }
+
@Override
public String getBranch() {
return null;
diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java
index 213be2cbd2..7a8f3e25b7 100644
--- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java
+++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java
@@ -39,6 +39,9 @@ public interface RemoteFactoryUrl {
/** Remote hostname */
String getHostName();
+ /** Remote provider URL */
+ String getProviderUrl();
+
/** Remote branch */
String getBranch();
diff --git a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java
index 6853e1a735..6b10db9cc5 100644
--- a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java
+++ b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java
@@ -46,7 +46,7 @@ public class AuthorizingFactoryParameterResolverTest {
@Test
public void shouldFetchContentWithAuthentication() throws Exception {
// given
- when(remoteFactoryUrl.getHostName()).thenReturn("hostName");
+ when(remoteFactoryUrl.getProviderUrl()).thenReturn("https://provider.url");
when(urlFetcher.fetch(anyString(), anyString())).thenReturn("content");
when(personalAccessTokenManager.get(anyString())).thenReturn(personalAccessToken);
diff --git a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/urlfactory/URLFactoryBuilderTest.java b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/urlfactory/URLFactoryBuilderTest.java
index bc24344372..324eb6fa79 100644
--- a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/urlfactory/URLFactoryBuilderTest.java
+++ b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/urlfactory/URLFactoryBuilderTest.java
@@ -214,6 +214,11 @@ public class URLFactoryBuilderTest {
return null;
}
+ @Override
+ public String getProviderUrl() {
+ return null;
+ }
+
@Override
public String getBranch() {
return null;
@@ -286,6 +291,11 @@ public class URLFactoryBuilderTest {
return null;
}
+ @Override
+ public String getProviderUrl() {
+ return null;
+ }
+
@Override
public String getBranch() {
return null;
diff --git a/wsmaster/pom.xml b/wsmaster/pom.xml
index 0b3699f0d3..fad46c1a16 100644
--- a/wsmaster/pom.xml
+++ b/wsmaster/pom.xml
@@ -40,7 +40,6 @@
che-core-api-account
che-core-api-user
che-core-api-factory-azure-devops
- che-core-api-factory-git-ssh
che-core-api-factory-shared
che-core-api-factory
che-core-api-factory-github