Add provider name annotation to PAT secret

pull/670/head
ivinokur 2024-03-18 14:44:22 +02:00
parent ba6f30f963
commit d9ccbfba32
23 changed files with 169 additions and 51 deletions

View File

@ -63,6 +63,7 @@ public class KubernetesPersonalAccessTokenManager implements PersonalAccessToken
public static final String NAME_PATTERN = "personal-access-token-"; public static final String NAME_PATTERN = "personal-access-token-";
public static final String ANNOTATION_CHE_USERID = "che.eclipse.org/che-userid"; public static final String ANNOTATION_CHE_USERID = "che.eclipse.org/che-userid";
public static final String ANNOTATION_SCM_PROVIDER_NAME = "che.eclipse.org/scm-provider-name";
public static final String ANNOTATION_SCM_ORGANIZATION = "che.eclipse.org/scm-organization"; public static final String ANNOTATION_SCM_ORGANIZATION = "che.eclipse.org/scm-organization";
public static final String ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_ID = public static final String ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_ID =
"che.eclipse.org/scm-personal-access-token-id"; "che.eclipse.org/scm-personal-access-token-id";
@ -103,6 +104,7 @@ public class KubernetesPersonalAccessTokenManager implements PersonalAccessToken
new ImmutableMap.Builder<String, String>() new ImmutableMap.Builder<String, String>()
.put(ANNOTATION_CHE_USERID, personalAccessToken.getCheUserId()) .put(ANNOTATION_CHE_USERID, personalAccessToken.getCheUserId())
.put(ANNOTATION_SCM_URL, personalAccessToken.getScmProviderUrl()) .put(ANNOTATION_SCM_URL, personalAccessToken.getScmProviderUrl())
.put(ANNOTATION_SCM_PROVIDER_NAME, personalAccessToken.getScmProviderName())
.put( .put(
ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_ID, ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_ID,
personalAccessToken.getScmTokenId()) personalAccessToken.getScmTokenId())
@ -210,10 +212,11 @@ public class KubernetesPersonalAccessTokenManager implements PersonalAccessToken
PersonalAccessToken personalAccessToken = PersonalAccessToken personalAccessToken =
new PersonalAccessToken( new PersonalAccessToken(
personalAccessTokenParams.getScmProviderUrl(), personalAccessTokenParams.getScmProviderUrl(),
getScmProviderName(personalAccessTokenParams),
secretAnnotations.get(ANNOTATION_CHE_USERID), secretAnnotations.get(ANNOTATION_CHE_USERID),
personalAccessTokenParams.getOrganization(), personalAccessTokenParams.getOrganization(),
scmUsername.get(), scmUsername.get(),
secretAnnotations.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME), personalAccessTokenParams.getScmTokenName(),
personalAccessTokenParams.getScmTokenId(), personalAccessTokenParams.getScmTokenId(),
personalAccessTokenParams.getToken()); personalAccessTokenParams.getToken());
return Optional.of(personalAccessToken); return Optional.of(personalAccessToken);
@ -239,6 +242,20 @@ public class KubernetesPersonalAccessTokenManager implements PersonalAccessToken
return Optional.empty(); return Optional.empty();
} }
/**
* Returns the name of the SCM provider. If the name is not set, the name of the token is used.
* This is used to support back compatibility with the old token secrets, which do not have the
* 'che.eclipse.org/scm-provider-name' annotation.
*
* @param params the parameters of the personal access token
* @return the name of the SCM provider
*/
private String getScmProviderName(PersonalAccessTokenParams params) {
return isNullOrEmpty(params.getScmProviderName())
? params.getScmTokenName()
: params.getScmProviderName();
}
private boolean deleteSecretIfMisconfigured(Secret secret) throws InfrastructureException { private boolean deleteSecretIfMisconfigured(Secret secret) throws InfrastructureException {
Map<String, String> secretAnnotations = secret.getMetadata().getAnnotations(); Map<String, String> secretAnnotations = secret.getMetadata().getAnnotations();
LOG.debug("Secret annotations: {}", secretAnnotations); LOG.debug("Secret annotations: {}", secretAnnotations);
@ -270,15 +287,17 @@ public class KubernetesPersonalAccessTokenManager implements PersonalAccessToken
Map<String, String> secretAnnotations = secret.getMetadata().getAnnotations(); Map<String, String> secretAnnotations = secret.getMetadata().getAnnotations();
String token = new String(Base64.getDecoder().decode(secret.getData().get("token"))).trim(); String token = new String(Base64.getDecoder().decode(secret.getData().get("token"))).trim();
String configuredOAuthProviderName = String configuredOAuthTokenName =
secretAnnotations.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME); secretAnnotations.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME);
String configuredTokenId = secretAnnotations.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_ID); String configuredTokenId = secretAnnotations.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_ID);
String configuredScmOrganization = secretAnnotations.get(ANNOTATION_SCM_ORGANIZATION); String configuredScmOrganization = secretAnnotations.get(ANNOTATION_SCM_ORGANIZATION);
String configuredScmServerUrl = secretAnnotations.get(ANNOTATION_SCM_URL); String configuredScmServerUrl = secretAnnotations.get(ANNOTATION_SCM_URL);
String configuredScmProviderName = secretAnnotations.get(ANNOTATION_SCM_PROVIDER_NAME);
return new PersonalAccessTokenParams( return new PersonalAccessTokenParams(
trimEnd(configuredScmServerUrl, '/'), trimEnd(configuredScmServerUrl, '/'),
configuredOAuthProviderName, configuredScmProviderName,
configuredOAuthTokenName,
configuredTokenId, configuredTokenId,
token, token,
configuredScmOrganization); configuredScmOrganization);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -92,7 +92,13 @@ public class KubernetesGitCredentialManagerTest {
PersonalAccessToken token = PersonalAccessToken token =
new PersonalAccessToken( new PersonalAccessToken(
"https://bitbucket.com", "cheUser", "username", "token-name", "tid-23434", "token123"); "https://bitbucket.com",
"provider",
"cheUser",
"username",
"token-name",
"tid-23434",
"token123");
// when // when
kubernetesGitCredentialManager.createOrReplace(token); kubernetesGitCredentialManager.createOrReplace(token);
@ -174,6 +180,7 @@ public class KubernetesGitCredentialManagerTest {
PersonalAccessToken token = PersonalAccessToken token =
new PersonalAccessToken( new PersonalAccessToken(
"https://bitbucket.com", "https://bitbucket.com",
"provider",
"cheUser", "cheUser",
"username", "username",
"oauth2-token-name", "oauth2-token-name",
@ -199,6 +206,7 @@ public class KubernetesGitCredentialManagerTest {
PersonalAccessToken token = PersonalAccessToken token =
new PersonalAccessToken( new PersonalAccessToken(
"https://bitbucket.com:5648", "https://bitbucket.com:5648",
"provider",
"cheUser", "cheUser",
"username", "username",
"token-name", "token-name",

View File

@ -139,7 +139,13 @@ public class KubernetesPersonalAccessTokenManagerTest {
PersonalAccessToken token = PersonalAccessToken token =
new PersonalAccessToken( new PersonalAccessToken(
"https://bitbucket.com", "cheUser", "username", "token-name", "tid-24", "token123"); "https://bitbucket.com",
"provider",
"cheUser",
"username",
"token-name",
"tid-24",
"token123");
// when // when
personalAccessTokenManager.store(token); personalAccessTokenManager.store(token);

View File

@ -108,6 +108,7 @@ public class EmbeddedOAuthAPI implements OAuthAPI {
personalAccessTokenManager.store( personalAccessTokenManager.store(
new PersonalAccessToken( new PersonalAccessToken(
oauth.getEndpointUrl(), oauth.getEndpointUrl(),
providerName,
EnvironmentContext.getCurrent().getSubject().getUserId(), EnvironmentContext.getCurrent().getSubject().getUserId(),
null, null,
null, null,

View File

@ -165,6 +165,7 @@ public class EmbeddedOAuthAPITest {
verify(personalAccessTokenManager).store(tokenCapture.capture()); verify(personalAccessTokenManager).store(tokenCapture.capture());
PersonalAccessToken token = tokenCapture.getValue(); PersonalAccessToken token = tokenCapture.getValue();
assertEquals(token.getScmProviderUrl(), "http://eclipse.che"); assertEquals(token.getScmProviderUrl(), "http://eclipse.che");
assertEquals(token.getScmProviderName(), "bitbucket");
assertEquals(token.getCheUserId(), "0000-00-0000"); assertEquals(token.getCheUserId(), "0000-00-0000");
assertTrue(token.getScmTokenId().startsWith("id-")); assertTrue(token.getScmTokenId().startsWith("id-"));
assertTrue(token.getScmTokenName().startsWith("bitbucket-")); assertTrue(token.getScmTokenName().startsWith("bitbucket-"));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -49,6 +49,7 @@ public class AzureDevOpsPersonalAccessTokenFetcher implements PersonalAccessToke
private static final Logger LOG = private static final Logger LOG =
LoggerFactory.getLogger(AzureDevOpsPersonalAccessTokenFetcher.class); LoggerFactory.getLogger(AzureDevOpsPersonalAccessTokenFetcher.class);
private static final String OAUTH_PROVIDER_NAME = "azure-devops";
private final String cheApiEndpoint; private final String cheApiEndpoint;
private final String azureDevOpsScmApiEndpoint; private final String azureDevOpsScmApiEndpoint;
private final OAuthAPI oAuthAPI; private final OAuthAPI oAuthAPI;
@ -87,7 +88,12 @@ public class AzureDevOpsPersonalAccessTokenFetcher implements PersonalAccessToke
Optional<Pair<Boolean, String>> valid = Optional<Pair<Boolean, String>> valid =
isValid( isValid(
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
scmServerUrl, tokenName, tokenId, oAuthToken.getToken(), null)); scmServerUrl,
OAUTH_PROVIDER_NAME,
tokenName,
tokenId,
oAuthToken.getToken(),
null));
if (valid.isEmpty()) { if (valid.isEmpty()) {
throw buildScmUnauthorizedException(cheSubject); throw buildScmUnauthorizedException(cheSubject);
} else if (!valid.get().first) { } else if (!valid.get().first) {
@ -97,6 +103,7 @@ public class AzureDevOpsPersonalAccessTokenFetcher implements PersonalAccessToke
} }
return new PersonalAccessToken( return new PersonalAccessToken(
scmServerUrl, scmServerUrl,
OAUTH_PROVIDER_NAME,
cheSubject.getUserId(), cheSubject.getUserId(),
valid.get().second, valid.get().second,
tokenName, tokenName,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -51,6 +51,8 @@ public class BitbucketServerPersonalAccessTokenFetcher implements PersonalAccess
private static final Logger LOG = private static final Logger LOG =
LoggerFactory.getLogger(BitbucketServerPersonalAccessTokenFetcher.class); LoggerFactory.getLogger(BitbucketServerPersonalAccessTokenFetcher.class);
private static final String OAUTH_PROVIDER_NAME = "bitbucket-server";
private static final String TOKEN_NAME_TEMPLATE = "che-token-<%s>-<%s>"; private static final String TOKEN_NAME_TEMPLATE = "che-token-<%s>-<%s>";
public static final Set<String> DEFAULT_TOKEN_SCOPE = public static final Set<String> DEFAULT_TOKEN_SCOPE =
ImmutableSet.of("PROJECT_WRITE", "REPO_WRITE"); ImmutableSet.of("PROJECT_WRITE", "REPO_WRITE");
@ -96,6 +98,7 @@ public class BitbucketServerPersonalAccessTokenFetcher implements PersonalAccess
LOG.debug("Token created = {} for {}", token.getId(), token.getUser()); LOG.debug("Token created = {} for {}", token.getId(), token.getUser());
return new PersonalAccessToken( return new PersonalAccessToken(
scmServerUrl, scmServerUrl,
OAUTH_PROVIDER_NAME,
EnvironmentContext.getCurrent().getSubject().getUserId(), EnvironmentContext.getCurrent().getSubject().getUserId(),
user.getName(), user.getName(),
user.getSlug(), user.getSlug(),

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -43,7 +43,7 @@ public class BitbucketServerAuthorizingFileContentProviderTest {
url, urlFetcher, personalAccessTokenManager); url, urlFetcher, personalAccessTokenManager);
PersonalAccessToken token = PersonalAccessToken token =
new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "user1", "token"); new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "provider", "user1", "token");
when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(token); when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(token);
String fileURL = "https://foo.bar/scm/repo/.devfile"; String fileURL = "https://foo.bar/scm/repo/.devfile";
@ -64,7 +64,7 @@ public class BitbucketServerAuthorizingFileContentProviderTest {
url, urlFetcher, personalAccessTokenManager); url, urlFetcher, personalAccessTokenManager);
PersonalAccessToken token = PersonalAccessToken token =
new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "user1", "token"); new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "provider", "user1", "token");
when(personalAccessTokenManager.getAndStore(eq(TEST_SCHEME + "://" + TEST_HOSTNAME))) when(personalAccessTokenManager.getAndStore(eq(TEST_SCHEME + "://" + TEST_HOSTNAME)))
.thenReturn(token); .thenReturn(token);
@ -95,7 +95,7 @@ public class BitbucketServerAuthorizingFileContentProviderTest {
new BitbucketServerAuthorizingFileContentProvider( new BitbucketServerAuthorizingFileContentProvider(
url, urlFetcher, personalAccessTokenManager); url, urlFetcher, personalAccessTokenManager);
PersonalAccessToken token = PersonalAccessToken token =
new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "user1", "token"); new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "provider", "user1", "token");
when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(token); when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(token);
// when // when

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -74,7 +74,7 @@ public class BitbucketServerScmFileResolverTest {
final String rawContent = "raw_content"; final String rawContent = "raw_content";
final String filename = "devfile.yaml"; final String filename = "devfile.yaml";
when(personalAccessTokenManager.getAndStore(anyString())) when(personalAccessTokenManager.getAndStore(anyString()))
.thenReturn(new PersonalAccessToken(SCM_URL, "root", "token123")); .thenReturn(new PersonalAccessToken(SCM_URL, "provider", "root", "token123"));
when(urlFetcher.fetch(anyString(), eq("Bearer token123"))).thenReturn(rawContent); when(urlFetcher.fetch(anyString(), eq("Bearer token123"))).thenReturn(rawContent);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -97,7 +97,12 @@ public class BitbucketPersonalAccessTokenFetcher implements PersonalAccessTokenF
Optional<Pair<Boolean, String>> valid = Optional<Pair<Boolean, String>> valid =
isValid( isValid(
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
scmServerUrl, tokenName, tokenId, oAuthToken.getToken(), null)); scmServerUrl,
OAUTH_PROVIDER_NAME,
tokenName,
tokenId,
oAuthToken.getToken(),
null));
if (valid.isEmpty()) { if (valid.isEmpty()) {
throw buildScmUnauthorizedException(cheSubject); throw buildScmUnauthorizedException(cheSubject);
} else if (!valid.get().first) { } else if (!valid.get().first) {
@ -109,6 +114,7 @@ public class BitbucketPersonalAccessTokenFetcher implements PersonalAccessTokenF
} }
return new PersonalAccessToken( return new PersonalAccessToken(
scmServerUrl, scmServerUrl,
OAUTH_PROVIDER_NAME,
cheSubject.getUserId(), cheSubject.getUserId(),
valid.get().second, valid.get().second,
tokenName, tokenName,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -82,7 +82,8 @@ public class BitbucketAuthorizingFileContentProviderTest {
// given // given
URLFetcher urlFetcher = Mockito.mock(URLFetcher.class); URLFetcher urlFetcher = Mockito.mock(URLFetcher.class);
String url = "https://bitbucket.org/workspace/repository/raw/HEAD/devfile.yaml"; String url = "https://bitbucket.org/workspace/repository/raw/HEAD/devfile.yaml";
PersonalAccessToken personalAccessToken = new PersonalAccessToken(url, "che", "my-token"); PersonalAccessToken personalAccessToken =
new PersonalAccessToken(url, "provider", "che", "my-token");
when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken);
when(bitbucketApiClient.getFileContent( when(bitbucketApiClient.getFileContent(
eq("workspace"), eq("repository"), eq("HEAD"), eq("devfile.yaml"), eq("my-token"))) eq("workspace"), eq("repository"), eq("HEAD"), eq("devfile.yaml"), eq("my-token")))

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -87,7 +87,12 @@ public class BitbucketPersonalAccessTokenFetcherTest {
.withBodyFile("bitbucket/rest/user/response.json"))); .withBodyFile("bitbucket/rest/user/response.json")));
PersonalAccessTokenParams personalAccessTokenParams = PersonalAccessTokenParams personalAccessTokenParams =
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
"https://bitbucket.org/", "scmTokenName", "scmTokenId", bitbucketOauthToken, null); "https://bitbucket.org/",
"provider",
"scmTokenName",
"scmTokenId",
bitbucketOauthToken,
null);
assertTrue( assertTrue(
bitbucketPersonalAccessTokenFetcher.isValid(personalAccessTokenParams).isEmpty(), bitbucketPersonalAccessTokenFetcher.isValid(personalAccessTokenParams).isEmpty(),
"Should not validate SCM server with trailing /"); "Should not validate SCM server with trailing /");
@ -165,7 +170,12 @@ public class BitbucketPersonalAccessTokenFetcherTest {
PersonalAccessTokenParams params = PersonalAccessTokenParams params =
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
"https://bitbucket.org", "params-name", "tid-23434", bitbucketOauthToken, null); "https://bitbucket.org",
"provider",
"params-name",
"tid-23434",
bitbucketOauthToken,
null);
Optional<Pair<Boolean, String>> valid = bitbucketPersonalAccessTokenFetcher.isValid(params); Optional<Pair<Boolean, String>> valid = bitbucketPersonalAccessTokenFetcher.isValid(params);
assertTrue(valid.isPresent()); assertTrue(valid.isPresent());
@ -188,6 +198,7 @@ public class BitbucketPersonalAccessTokenFetcherTest {
PersonalAccessTokenParams params = PersonalAccessTokenParams params =
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
"https://bitbucket.org", "https://bitbucket.org",
"provider",
OAUTH_2_PREFIX + "-params-name", OAUTH_2_PREFIX + "-params-name",
"tid-23434", "tid-23434",
bitbucketOauthToken, bitbucketOauthToken,
@ -205,6 +216,7 @@ public class BitbucketPersonalAccessTokenFetcherTest {
PersonalAccessTokenParams params = PersonalAccessTokenParams params =
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
"https://bitbucket.org", "https://bitbucket.org",
"provider",
OAUTH_2_PREFIX + "-token-name", OAUTH_2_PREFIX + "-token-name",
"tid-23434", "tid-23434",
bitbucketOauthToken, bitbucketOauthToken,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -75,7 +75,7 @@ public class BitbucketScmFileResolverTest {
when(bitbucketApiClient.getFileContent( when(bitbucketApiClient.getFileContent(
eq("test"), eq("repo"), eq("HEAD"), eq("devfile.yaml"), eq("my-token"))) eq("test"), eq("repo"), eq("HEAD"), eq("devfile.yaml"), eq("my-token")))
.thenReturn(rawContent); .thenReturn(rawContent);
var personalAccessToken = new PersonalAccessToken("foo", "che", "my-token"); var personalAccessToken = new PersonalAccessToken("foo", "provider", "che", "my-token");
when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken);
String content = String content =

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -37,6 +37,7 @@ public abstract class AbstractGithubPersonalAccessTokenFetcher
private static final Logger LOG = private static final Logger LOG =
LoggerFactory.getLogger(AbstractGithubPersonalAccessTokenFetcher.class); LoggerFactory.getLogger(AbstractGithubPersonalAccessTokenFetcher.class);
private static final String OAUTH_PROVIDER_NAME = "github";
private final String apiEndpoint; private final String apiEndpoint;
private final OAuthAPI oAuthAPI; private final OAuthAPI oAuthAPI;
@ -140,7 +141,12 @@ public abstract class AbstractGithubPersonalAccessTokenFetcher
Optional<Pair<Boolean, String>> valid = Optional<Pair<Boolean, String>> valid =
isValid( isValid(
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
scmServerUrl, tokenName, tokenId, oAuthToken.getToken(), null)); scmServerUrl,
OAUTH_PROVIDER_NAME,
tokenName,
tokenId,
oAuthToken.getToken(),
null));
if (valid.isEmpty()) { if (valid.isEmpty()) {
throw buildScmUnauthorizedException(cheSubject); throw buildScmUnauthorizedException(cheSubject);
} else if (!valid.get().first) { } else if (!valid.get().first) {
@ -150,6 +156,7 @@ public abstract class AbstractGithubPersonalAccessTokenFetcher
} }
return new PersonalAccessToken( return new PersonalAccessToken(
scmServerUrl, scmServerUrl,
OAUTH_PROVIDER_NAME,
cheSubject.getUserId(), cheSubject.getUserId(),
valid.get().second, valid.get().second,
tokenName, tokenName,
@ -210,7 +217,7 @@ public abstract class AbstractGithubPersonalAccessTokenFetcher
// The url from the token has the same url as the api client, no need to create a new one. // The url from the token has the same url as the api client, no need to create a new one.
apiClient = githubApiClient; apiClient = githubApiClient;
} else { } else {
if ("github".equals(params.getScmTokenName())) { if (OAUTH_PROVIDER_NAME.equals(params.getScmTokenName())) {
apiClient = new GithubApiClient(params.getScmProviderUrl()); apiClient = new GithubApiClient(params.getScmProviderUrl());
} else { } else {
LOG.debug("not a valid url {} for current fetcher ", params.getScmProviderUrl()); LOG.debug("not a valid url {} for current fetcher ", params.getScmProviderUrl());

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -56,7 +56,7 @@ public class GithubAuthorizingFileContentProviderTest {
new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager); new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager);
when(personalAccessTokenManager.getAndStore(anyString())) when(personalAccessTokenManager.getAndStore(anyString()))
.thenReturn(new PersonalAccessToken("foo", "che", "my-token")); .thenReturn(new PersonalAccessToken("foo", "provider", "che", "my-token"));
fileContentProvider.fetchContent("devfile.yaml"); fileContentProvider.fetchContent("devfile.yaml");
@ -84,7 +84,7 @@ public class GithubAuthorizingFileContentProviderTest {
new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager); new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager);
when(personalAccessTokenManager.getAndStore(anyString())) when(personalAccessTokenManager.getAndStore(anyString()))
.thenReturn(new PersonalAccessToken(raw_url, "che", "my-token")); .thenReturn(new PersonalAccessToken(raw_url, "provider", "che", "my-token"));
fileContentProvider.fetchContent(raw_url); fileContentProvider.fetchContent(raw_url);
verify(urlFetcher).fetch(eq(raw_url), eq("token my-token")); verify(urlFetcher).fetch(eq(raw_url), eq("token my-token"));
@ -145,7 +145,7 @@ public class GithubAuthorizingFileContentProviderTest {
.withServerUrl("https://github.com"); .withServerUrl("https://github.com");
FileContentProvider fileContentProvider = FileContentProvider fileContentProvider =
new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager); new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager);
var personalAccessToken = new PersonalAccessToken(raw_url, "che", "my-token"); var personalAccessToken = new PersonalAccessToken(raw_url, "provider", "che", "my-token");
when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken);
fileContentProvider.fetchContent(raw_url); fileContentProvider.fetchContent(raw_url);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -91,7 +91,12 @@ public class GithubPersonalAccessTokenFetcherTest {
.withBodyFile("github/rest/user/response.json"))); .withBodyFile("github/rest/user/response.json")));
PersonalAccessTokenParams personalAccessTokenParams = PersonalAccessTokenParams personalAccessTokenParams =
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
"https://github.com/", "scmTokenName", "scmTokenId", githubOauthToken, null); "https://github.com/",
"provider",
"scmTokenName",
"scmTokenId",
githubOauthToken,
null);
assertTrue( assertTrue(
githubPATFetcher.isValid(personalAccessTokenParams).isEmpty(), githubPATFetcher.isValid(personalAccessTokenParams).isEmpty(),
"Should not validate SCM server with trailing /"); "Should not validate SCM server with trailing /");
@ -213,7 +218,7 @@ public class GithubPersonalAccessTokenFetcherTest {
PersonalAccessTokenParams params = PersonalAccessTokenParams params =
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
wireMockServer.url("/"), "token-name", "tid-23434", githubOauthToken, null); wireMockServer.url("/"), "provider", "token-name", "tid-23434", githubOauthToken, null);
Optional<Pair<Boolean, String>> valid = githubPATFetcher.isValid(params); Optional<Pair<Boolean, String>> valid = githubPATFetcher.isValid(params);
assertTrue(valid.isPresent()); assertTrue(valid.isPresent());
@ -236,6 +241,7 @@ public class GithubPersonalAccessTokenFetcherTest {
PersonalAccessTokenParams params = PersonalAccessTokenParams params =
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
wireMockServer.url("/"), wireMockServer.url("/"),
"provider",
OAUTH_2_PREFIX + "-params-name", OAUTH_2_PREFIX + "-params-name",
"tid-23434", "tid-23434",
githubOauthToken, githubOauthToken,
@ -253,6 +259,7 @@ public class GithubPersonalAccessTokenFetcherTest {
PersonalAccessTokenParams params = PersonalAccessTokenParams params =
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
wireMockServer.url("/"), wireMockServer.url("/"),
"provider",
OAUTH_2_PREFIX + "-token-name", OAUTH_2_PREFIX + "-token-name",
"tid-23434", "tid-23434",
githubOauthToken, githubOauthToken,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -88,7 +88,7 @@ public class GithubScmFileResolverTest {
lenient() lenient()
.when(personalAccessTokenManager.getAndStore(anyString())) .when(personalAccessTokenManager.getAndStore(anyString()))
.thenReturn(new PersonalAccessToken("foo", "che", "my-token")); .thenReturn(new PersonalAccessToken("foo", "provider", "che", "my-token"));
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true); when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any())) when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any()))

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -111,7 +111,12 @@ public class GitlabOAuthTokenFetcher implements PersonalAccessTokenFetcher {
Optional<Pair<Boolean, String>> valid = Optional<Pair<Boolean, String>> valid =
isValid( isValid(
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
scmServerUrl, tokenName, tokenId, oAuthToken.getToken(), null)); scmServerUrl,
OAUTH_PROVIDER_NAME,
tokenName,
tokenId,
oAuthToken.getToken(),
null));
if (valid.isEmpty()) { if (valid.isEmpty()) {
throw buildScmUnauthorizedException(cheSubject); throw buildScmUnauthorizedException(cheSubject);
} else if (!valid.get().first) { } else if (!valid.get().first) {
@ -121,6 +126,7 @@ public class GitlabOAuthTokenFetcher implements PersonalAccessTokenFetcher {
} }
return new PersonalAccessToken( return new PersonalAccessToken(
scmServerUrl, scmServerUrl,
OAUTH_PROVIDER_NAME,
cheSubject.getUserId(), cheSubject.getUserId(),
valid.get().second, valid.get().second,
tokenName, tokenName,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -35,7 +35,7 @@ public class GitlabAuthorizingFileContentProviderTest {
GitlabUrl gitlabUrl = new GitlabUrl().withHostName("gitlab.net").withSubGroups("eclipse/che"); GitlabUrl gitlabUrl = new GitlabUrl().withHostName("gitlab.net").withSubGroups("eclipse/che");
FileContentProvider fileContentProvider = FileContentProvider fileContentProvider =
new GitlabAuthorizingFileContentProvider(gitlabUrl, urlFetcher, personalAccessTokenManager); new GitlabAuthorizingFileContentProvider(gitlabUrl, urlFetcher, personalAccessTokenManager);
var personalAccessToken = new PersonalAccessToken("foo", "che", "my-token"); var personalAccessToken = new PersonalAccessToken("foo", "provider", "che", "my-token");
when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken);
fileContentProvider.fetchContent("devfile.yaml"); fileContentProvider.fetchContent("devfile.yaml");
verify(urlFetcher) verify(urlFetcher)
@ -53,7 +53,7 @@ public class GitlabAuthorizingFileContentProviderTest {
new GitlabAuthorizingFileContentProvider(gitlabUrl, urlFetcher, personalAccessTokenManager); new GitlabAuthorizingFileContentProvider(gitlabUrl, urlFetcher, personalAccessTokenManager);
String url = String url =
"https://gitlab.net/api/v4/projects/eclipse%2Fche/repository/files/devfile.yaml/raw"; "https://gitlab.net/api/v4/projects/eclipse%2Fche/repository/files/devfile.yaml/raw";
var personalAccessToken = new PersonalAccessToken(url, "che", "my-token"); var personalAccessToken = new PersonalAccessToken(url, "provider", "che", "my-token");
when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken);
fileContentProvider.fetchContent(url); fileContentProvider.fetchContent(url);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -179,7 +179,12 @@ public class GitlabOAuthTokenFetcherTest {
PersonalAccessTokenParams params = PersonalAccessTokenParams params =
new PersonalAccessTokenParams( new PersonalAccessTokenParams(
wireMockServer.baseUrl(), "oauth2-token-name", "tid-23434", "token123", null); wireMockServer.baseUrl(),
"provider",
"oauth2-token-name",
"tid-23434",
"token123",
null);
Optional<Pair<Boolean, String>> valid = oAuthTokenFetcher.isValid(params); Optional<Pair<Boolean, String>> valid = oAuthTokenFetcher.isValid(params);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -73,7 +73,7 @@ public class GitlabScmFileResolverTest {
final String rawContent = "raw_content"; final String rawContent = "raw_content";
final String filename = "devfile.yaml"; final String filename = "devfile.yaml";
when(personalAccessTokenManager.getAndStore(any(String.class))) when(personalAccessTokenManager.getAndStore(any(String.class)))
.thenReturn(new PersonalAccessToken(SCM_URL, "root", "token123")); .thenReturn(new PersonalAccessToken(SCM_URL, "provider", "root", "token123"));
when(urlFetcher.fetch(anyString(), eq("Bearer token123"))).thenReturn(rawContent); when(urlFetcher.fetch(anyString(), eq("Bearer token123"))).thenReturn(rawContent);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -22,6 +22,7 @@ import org.eclipse.che.commons.env.EnvironmentContext;
public class PersonalAccessToken { public class PersonalAccessToken {
private final String scmProviderUrl; private final String scmProviderUrl;
private final String scmProviderName;
private final String scmUserName; private final String scmUserName;
/** Organization that user belongs to. Can be null if user is not a member of any organization. */ /** Organization that user belongs to. Can be null if user is not a member of any organization. */
@Nullable private final String scmOrganization; @Nullable private final String scmOrganization;
@ -33,6 +34,7 @@ public class PersonalAccessToken {
public PersonalAccessToken( public PersonalAccessToken(
String scmProviderUrl, String scmProviderUrl,
String scmProviderName,
String cheUserId, String cheUserId,
String scmOrganization, String scmOrganization,
String scmUserName, String scmUserName,
@ -41,6 +43,7 @@ public class PersonalAccessToken {
String token) { String token) {
this.scmProviderUrl = scmProviderUrl; this.scmProviderUrl = scmProviderUrl;
this.scmOrganization = scmOrganization; this.scmOrganization = scmOrganization;
this.scmProviderName = scmProviderName;
this.scmUserName = scmUserName; this.scmUserName = scmUserName;
this.scmTokenName = scmTokenName; this.scmTokenName = scmTokenName;
this.scmTokenId = scmTokenId; this.scmTokenId = scmTokenId;
@ -50,17 +53,28 @@ public class PersonalAccessToken {
public PersonalAccessToken( public PersonalAccessToken(
String scmProviderUrl, String scmProviderUrl,
String scmProviderName,
String cheUserId, String cheUserId,
String scmUserName, String scmUserName,
String scmTokenName, String scmTokenName,
String scmTokenId, String scmTokenId,
String token) { String token) {
this(scmProviderUrl, cheUserId, null, scmUserName, scmTokenName, scmTokenId, token);
}
public PersonalAccessToken(String scmProviderUrl, String scmUserName, String token) {
this( this(
scmProviderUrl, scmProviderUrl,
scmProviderName,
cheUserId,
null,
scmUserName,
scmTokenName,
scmTokenId,
token);
}
public PersonalAccessToken(
String scmProviderUrl, String scmProviderName, String scmUserName, String token) {
this(
scmProviderUrl,
scmProviderName,
EnvironmentContext.getCurrent().getSubject().getUserId(), EnvironmentContext.getCurrent().getSubject().getUserId(),
null, null,
scmUserName, scmUserName,
@ -104,6 +118,7 @@ public class PersonalAccessToken {
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
PersonalAccessToken that = (PersonalAccessToken) o; PersonalAccessToken that = (PersonalAccessToken) o;
return Objects.equal(scmProviderUrl, that.scmProviderUrl) return Objects.equal(scmProviderUrl, that.scmProviderUrl)
&& Objects.equal(scmProviderName, that.scmProviderName)
&& Objects.equal(scmUserName, that.scmUserName) && Objects.equal(scmUserName, that.scmUserName)
&& Objects.equal(scmOrganization, that.scmOrganization) && Objects.equal(scmOrganization, that.scmOrganization)
&& Objects.equal(scmTokenName, that.scmTokenName) && Objects.equal(scmTokenName, that.scmTokenName)
@ -124,6 +139,9 @@ public class PersonalAccessToken {
+ "scmProviderUrl='" + "scmProviderUrl='"
+ scmProviderUrl + scmProviderUrl
+ '\'' + '\''
+ "scmProviderName='"
+ scmProviderName
+ '\''
+ ", scmUserName='" + ", scmUserName='"
+ scmUserName + scmUserName
+ '\'' + '\''
@ -143,4 +161,8 @@ public class PersonalAccessToken {
+ cheUserId + cheUserId
+ '}'; + '}';
} }
public String getScmProviderName() {
return scmProviderName;
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2023 Red Hat, Inc. * Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -14,6 +14,7 @@ package org.eclipse.che.api.factory.server.scm;
/** An object to hold parameters for creating a personal access token. */ /** An object to hold parameters for creating a personal access token. */
public class PersonalAccessTokenParams { public class PersonalAccessTokenParams {
private final String scmProviderUrl; private final String scmProviderUrl;
private final String scmProviderName;
private final String scmTokenName; private final String scmTokenName;
private final String scmTokenId; private final String scmTokenId;
private final String token; private final String token;
@ -21,11 +22,13 @@ public class PersonalAccessTokenParams {
public PersonalAccessTokenParams( public PersonalAccessTokenParams(
String scmProviderUrl, String scmProviderUrl,
String scmProviderName,
String scmTokenName, String scmTokenName,
String scmTokenId, String scmTokenId,
String token, String token,
String organization) { String organization) {
this.scmProviderUrl = scmProviderUrl; this.scmProviderUrl = scmProviderUrl;
this.scmProviderName = scmProviderName;
this.scmTokenName = scmTokenName; this.scmTokenName = scmTokenName;
this.scmTokenId = scmTokenId; this.scmTokenId = scmTokenId;
this.token = token; this.token = token;
@ -51,4 +54,8 @@ public class PersonalAccessTokenParams {
public String getOrganization() { public String getOrganization() {
return organization; return organization;
} }
public String getScmProviderName() {
return scmProviderName;
}
} }