Skip to content

Commit f2296b6

Browse files
committed
commit
1 parent 04bd052 commit f2296b6

File tree

20 files changed

+115
-105
lines changed

20 files changed

+115
-105
lines changed

infrastructures/infrastructure-factory/pom.xml

-4
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@
5151
<groupId>jakarta.ws.rs</groupId>
5252
<artifactId>jakarta.ws.rs-api</artifactId>
5353
</dependency>
54-
<dependency>
55-
<groupId>org.eclipse.che.core</groupId>
56-
<artifactId>che-core-api-auth</artifactId>
57-
</dependency>
5854
<dependency>
5955
<groupId>org.eclipse.che.core</groupId>
6056
<artifactId>che-core-api-core</artifactId>

infrastructures/infrastructure-factory/src/main/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesGitCredentialManager.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import static com.google.common.base.Strings.isNullOrEmpty;
1515
import static java.lang.String.format;
1616
import static java.nio.charset.StandardCharsets.UTF_8;
17-
import static org.eclipse.che.api.factory.server.scm.PersonalAccessTokenFetcher.OAUTH_2_SUFFIX;
1817
import static org.eclipse.che.workspace.infrastructure.kubernetes.provision.secret.KubernetesSecretAnnotationNames.ANNOTATION_AUTOMOUNT;
1918
import static org.eclipse.che.workspace.infrastructure.kubernetes.provision.secret.KubernetesSecretAnnotationNames.ANNOTATION_DEV_WORKSPACE_MOUNT_PATH;
2019
import static org.eclipse.che.workspace.infrastructure.kubernetes.provision.secret.KubernetesSecretAnnotationNames.ANNOTATION_GIT_CREDENTIALS;
@@ -176,7 +175,7 @@ public void createOrReplace(PersonalAccessToken personalAccessToken)
176175
private String getUsernameSegment(PersonalAccessToken personalAccessToken) {
177176
// Special characters are not allowed in URL username segment, so we need to escape them.
178177
PercentEscaper percentEscaper = new PercentEscaper("", false);
179-
return personalAccessToken.getScmProviderName().startsWith(OAUTH_2_SUFFIX)
178+
return personalAccessToken.isOAuthToken()
180179
? "oauth2"
181180
: isNullOrEmpty(personalAccessToken.getScmOrganization())
182181
? percentEscaper.escape(personalAccessToken.getScmUserName())

infrastructures/infrastructure-factory/src/main/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManager.java

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
package org.eclipse.che.api.factory.server.scm.kubernetes;
1313

1414
import static com.google.common.base.Strings.isNullOrEmpty;
15+
import static java.lang.Boolean.parseBoolean;
1516
import static org.eclipse.che.commons.lang.StringUtils.trimEnd;
1617

1718
import com.google.common.annotations.VisibleForTesting;
@@ -62,6 +63,7 @@ public class KubernetesPersonalAccessTokenManager implements PersonalAccessToken
6263
public static final String NAME_PATTERN = "personal-access-token-";
6364

6465
public static final String ANNOTATION_CHE_USERID = "che.eclipse.org/che-userid";
66+
public static final String ANNOTATION_SCM_IS_OAUTH_TOKEN = "che.eclipse.org/scm-is-oauth-token";
6567
public static final String ANNOTATION_SCM_ORGANIZATION = "che.eclipse.org/scm-organization";
6668
public static final String ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_ID =
6769
"che.eclipse.org/scm-personal-access-token-id";
@@ -96,6 +98,9 @@ void save(PersonalAccessToken personalAccessToken)
9698
.withName(NameGenerator.generate(NAME_PATTERN, 5))
9799
.withAnnotations(
98100
new ImmutableMap.Builder<String, String>()
101+
.put(
102+
ANNOTATION_SCM_IS_OAUTH_TOKEN,
103+
Boolean.toString(personalAccessToken.isOAuthToken()))
99104
.put(ANNOTATION_CHE_USERID, personalAccessToken.getCheUserId())
100105
.put(ANNOTATION_SCM_URL, personalAccessToken.getScmProviderUrl())
101106
.put(
@@ -194,6 +199,7 @@ private Optional<PersonalAccessToken> doGetPersonalAccessToken(
194199

195200
PersonalAccessToken personalAccessToken =
196201
new PersonalAccessToken(
202+
parseBoolean(secretAnnotations.get(ANNOTATION_SCM_IS_OAUTH_TOKEN)),
197203
personalAccessTokenParams.getScmProviderUrl(),
198204
secretAnnotations.get(ANNOTATION_CHE_USERID),
199205
personalAccessTokenParams.getOrganization(),
@@ -278,13 +284,15 @@ private boolean deleteSecretIfMisconfigured(Secret secret) throws Infrastructure
278284
private PersonalAccessTokenParams secret2PersonalAccessTokenParams(Secret secret) {
279285
Map<String, String> secretAnnotations = secret.getMetadata().getAnnotations();
280286

287+
boolean isOauth = parseBoolean(secretAnnotations.get(ANNOTATION_SCM_IS_OAUTH_TOKEN));
281288
String token = new String(Base64.getDecoder().decode(secret.getData().get("token"))).trim();
282289
String configuredOAuthProviderName = secretAnnotations.get(ANNOTATION_SCM_PROVIDER_NAME);
283290
String configuredTokenId = secretAnnotations.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_ID);
284291
String configuredScmOrganization = secretAnnotations.get(ANNOTATION_SCM_ORGANIZATION);
285292
String configuredScmServerUrl = secretAnnotations.get(ANNOTATION_SCM_URL);
286293

287294
return new PersonalAccessTokenParams(
295+
isOauth,
288296
trimEnd(configuredScmServerUrl, '/'),
289297
configuredOAuthProviderName,
290298
configuredTokenId,

infrastructures/infrastructure-factory/src/test/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesGitCredentialManagerTest.java

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2023 Red Hat, Inc.
2+
* Copyright (c) 2012-2024 Red Hat, Inc.
33
* This program and the accompanying materials are made
44
* available under the terms of the Eclipse Public License 2.0
55
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -92,8 +92,14 @@ public void testCreateAndSaveNewPATGitCredential() throws Exception {
9292

9393
PersonalAccessToken token =
9494
new PersonalAccessToken(
95-
"https://bitbucket.com", "cheUser", "username", "token-name", "tid-23434", "token123");
96-
95+
false,
96+
"https://bitbucket.com",
97+
"cheUser",
98+
"cheOrganization",
99+
"username",
100+
"bitbucket",
101+
"tid-23434",
102+
"token123");
97103
// when
98104
kubernetesGitCredentialManager.createOrReplace(token);
99105
// then
@@ -113,6 +119,7 @@ public void shouldUseHardcodedUsernameIfScmOrganizationIsDefined() throws Except
113119
KubernetesNamespaceMeta namespaceMeta = new KubernetesNamespaceMetaImpl("test");
114120
PersonalAccessToken token =
115121
new PersonalAccessToken(
122+
false,
116123
"https://bitbucket-server.com:5648",
117124
"cheUser",
118125
"cheOrganization",
@@ -198,10 +205,12 @@ public void testUpdateTokenInExistingCredential() throws Exception {
198205
KubernetesNamespaceMeta namespaceMeta = new KubernetesNamespaceMetaImpl("test");
199206
PersonalAccessToken token =
200207
new PersonalAccessToken(
208+
false,
201209
"https://bitbucket.com:5648",
202210
"cheUser",
211+
"cheOrganization",
203212
"username",
204-
"token-name",
213+
"bitbucket",
205214
"tid-23434",
206215
"token123");
207216

infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/configurator/OAuthTokenSecretsConfigurator.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
*/
1212
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator;
1313

14+
import static java.lang.Boolean.parseBoolean;
15+
1416
import com.google.common.collect.ImmutableMap;
1517
import java.util.Map;
1618
import javax.inject.Inject;
1719
import javax.inject.Singleton;
18-
import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenFetcher;
1920
import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager;
2021
import org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationException;
2122
import org.eclipse.che.api.factory.server.scm.exception.ScmConfigurationPersistenceException;
@@ -40,6 +41,7 @@ public class OAuthTokenSecretsConfigurator implements NamespaceConfigurator {
4041
private static final String ANNOTATION_SCM_URL = "che.eclipse.org/scm-url";
4142
private static final String ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME =
4243
"che.eclipse.org/scm-personal-access-token-name";
44+
public static final String ANNOTATION_SCM_IS_OAUTH_TOKEN = "che.eclipse.org/scm-is-oauth-token";
4345

4446
private static final Map<String, String> SEARCH_LABELS =
4547
ImmutableMap.of(
@@ -66,10 +68,8 @@ public void configure(NamespaceResolutionContext namespaceResolutionContext, Str
6668
&& s.getMetadata()
6769
.getAnnotations()
6870
.containsKey(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME)
69-
&& s.getMetadata()
70-
.getAnnotations()
71-
.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME)
72-
.startsWith(PersonalAccessTokenFetcher.OAUTH_2_SUFFIX))
71+
&& parseBoolean(
72+
s.getMetadata().getAnnotations().get(ANNOTATION_SCM_IS_OAUTH_TOKEN)))
7373
.forEach(
7474
s -> {
7575
try {

wsmaster/che-core-api-auth/src/main/java/org/eclipse/che/security/oauth/EmbeddedOAuthAPI.java

+11-15
Original file line numberDiff line numberDiff line change
@@ -184,35 +184,31 @@ public OAuthToken getToken(String oauthProvider)
184184
if (token != null) {
185185
return token;
186186
}
187-
Optional<PersonalAccessToken> tokenOptional =
188-
personalAccessTokenManager.get(subject, oauthProvider, null);
189-
if (tokenOptional.isPresent()) {
190-
PersonalAccessToken tokenDto = tokenOptional.get();
191-
return newDto(OAuthToken.class).withToken(tokenDto.getToken());
192-
}
193187
throw new UnauthorizedException(
194188
"OAuth token for user " + subject.getUserId() + " was not found");
195189
} catch (IOException e) {
196190
throw new ServerException(e.getLocalizedMessage(), e);
197-
} catch (ScmCommunicationException
198-
| ScmUnauthorizedException
199-
| ScmConfigurationPersistenceException e) {
200-
throw new RuntimeException(e);
201191
}
202192
}
203193

204194
@Override
205195
public void invalidateToken(String oauthProvider)
206-
throws NotFoundException, UnauthorizedException, ServerException {
196+
throws NotFoundException, UnauthorizedException {
207197
OAuthAuthenticator oauth = getAuthenticator(oauthProvider);
208-
OAuthToken oauthToken = getToken(oauthProvider);
209198
try {
210-
if (!oauth.invalidateToken(oauthToken.getToken())) {
199+
Optional<PersonalAccessToken> tokenOptional =
200+
personalAccessTokenManager.get(
201+
EnvironmentContext.getCurrent().getSubject(), oauthProvider, null);
202+
if (tokenOptional.isPresent() && !oauth.invalidateToken(tokenOptional.get().getToken())) {
211203
throw new UnauthorizedException(
212204
"OAuth token for provider " + oauthProvider + " was not found");
213205
}
214-
} catch (IOException e) {
215-
throw new ServerException(e.getMessage());
206+
} catch (ScmConfigurationPersistenceException
207+
| ScmUnauthorizedException
208+
| ScmCommunicationException
209+
| IOException e) {
210+
throw new UnauthorizedException(
211+
"OAuth token for provider " + oauthProvider + " was not found");
216212
}
217213
}
218214

wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsPersonalAccessTokenFetcher.java

+4-7
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,11 @@ public PersonalAccessToken fetchPersonalAccessToken(Subject cheSubject, String s
8282

8383
try {
8484
oAuthToken = oAuthAPI.getToken(AzureDevOps.PROVIDER_NAME);
85-
String tokenName = NameGenerator.generate(OAUTH_2_SUFFIX, 5);
8685
String tokenId = NameGenerator.generate("id-", 5);
8786
Optional<Pair<Boolean, String>> valid =
8887
isValid(
8988
new PersonalAccessTokenParams(
90-
scmServerUrl, tokenName, tokenId, oAuthToken.getToken(), null));
89+
true, scmServerUrl, "azure-devops", tokenId, oAuthToken.getToken(), null));
9190
if (valid.isEmpty()) {
9291
throw buildScmUnauthorizedException(cheSubject);
9392
} else if (!valid.get().first) {
@@ -99,7 +98,7 @@ public PersonalAccessToken fetchPersonalAccessToken(Subject cheSubject, String s
9998
scmServerUrl,
10099
cheSubject.getUserId(),
101100
valid.get().second,
102-
tokenName,
101+
"azure-devops",
103102
tokenId,
104103
oAuthToken.getToken());
105104
} catch (UnauthorizedException e) {
@@ -132,8 +131,7 @@ public Optional<Boolean> isValid(PersonalAccessToken personalAccessToken) {
132131

133132
try {
134133
AzureDevOpsUser user;
135-
if (personalAccessToken.getScmProviderName() != null
136-
&& personalAccessToken.getScmProviderName().startsWith(OAUTH_2_SUFFIX)) {
134+
if (personalAccessToken.getScmProviderName() != null && personalAccessToken.isOAuthToken()) {
137135
user = azureDevOpsApiClient.getUserWithOAuthToken(personalAccessToken.getToken());
138136
} else {
139137
user =
@@ -155,8 +153,7 @@ public Optional<Pair<Boolean, String>> isValid(PersonalAccessTokenParams params)
155153

156154
try {
157155
AzureDevOpsUser user;
158-
if (params.getScmProviderName() != null
159-
&& params.getScmProviderName().startsWith(OAUTH_2_SUFFIX)) {
156+
if (params.isOAuthToken()) {
160157
user = azureDevOpsApiClient.getUserWithOAuthToken(params.getToken());
161158
} else {
162159
user = azureDevOpsApiClient.getUserWithPAT(params.getToken(), params.getOrganization());

wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerPersonalAccessTokenFetcher.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,12 @@ public PersonalAccessToken fetchPersonalAccessToken(Subject cheUser, String scmS
9595
bitbucketServerApiClient.createPersonalAccessTokens(tokenName, DEFAULT_TOKEN_SCOPE);
9696
LOG.debug("Token created = {} for {}", token.getId(), token.getUser());
9797
return new PersonalAccessToken(
98+
true,
9899
scmServerUrl,
99100
EnvironmentContext.getCurrent().getSubject().getUserId(),
100101
user.getName(),
101102
user.getSlug(),
102-
token.getName(),
103+
"bitbucket-server",
103104
valueOf(token.getId()),
104105
token.getToken());
105106
} catch (ScmBadRequestException | ScmItemNotFoundException e) {

wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketPersonalAccessTokenFetcher.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public PersonalAccessToken fetchPersonalAccessToken(Subject cheSubject, String s
9797
Optional<Pair<Boolean, String>> valid =
9898
isValid(
9999
new PersonalAccessTokenParams(
100-
scmServerUrl, tokenName, tokenId, oAuthToken.getToken(), null));
100+
true, scmServerUrl, tokenName, tokenId, oAuthToken.getToken(), null));
101101
if (valid.isEmpty()) {
102102
throw buildScmUnauthorizedException(cheSubject);
103103
} else if (!valid.get().first) {

wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketPersonalAccessTokenFetcherTest.java

+9-13
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
1919
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
2020
import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
21-
import static org.eclipse.che.api.factory.server.scm.PersonalAccessTokenFetcher.OAUTH_2_SUFFIX;
2221
import static org.eclipse.che.dto.server.DtoFactory.newDto;
2322
import static org.mockito.ArgumentMatchers.anyString;
2423
import static org.mockito.Mockito.when;
@@ -87,7 +86,12 @@ public void shouldNotValidateSCMServerWithTrailingSlash() throws Exception {
8786
.withBodyFile("bitbucket/rest/user/response.json")));
8887
PersonalAccessTokenParams personalAccessTokenParams =
8988
new PersonalAccessTokenParams(
90-
"https://bitbucket.org/", "scmTokenName", "scmTokenId", bitbucketOauthToken, null);
89+
true,
90+
"https://bitbucket.org/",
91+
"scmTokenName",
92+
"scmTokenId",
93+
bitbucketOauthToken,
94+
null);
9195
assertTrue(
9296
bitbucketPersonalAccessTokenFetcher.isValid(personalAccessTokenParams).isEmpty(),
9397
"Should not validate SCM server with trailing /");
@@ -165,7 +169,7 @@ public void shouldValidatePersonalToken() throws Exception {
165169

166170
PersonalAccessTokenParams params =
167171
new PersonalAccessTokenParams(
168-
"https://bitbucket.org", "params-name", "tid-23434", bitbucketOauthToken, null);
172+
false, "https://bitbucket.org", "params-name", "tid-23434", bitbucketOauthToken, null);
169173

170174
Optional<Pair<Boolean, String>> valid = bitbucketPersonalAccessTokenFetcher.isValid(params);
171175
assertTrue(valid.isPresent());
@@ -187,11 +191,7 @@ public void shouldValidateOauthToken() throws Exception {
187191

188192
PersonalAccessTokenParams params =
189193
new PersonalAccessTokenParams(
190-
"https://bitbucket.org",
191-
OAUTH_2_SUFFIX + "-params-name",
192-
"tid-23434",
193-
bitbucketOauthToken,
194-
null);
194+
true, "https://bitbucket.org", "azure-devops", "tid-23434", bitbucketOauthToken, null);
195195

196196
Optional<Pair<Boolean, String>> valid = bitbucketPersonalAccessTokenFetcher.isValid(params);
197197
assertTrue(valid.isPresent());
@@ -204,11 +204,7 @@ public void shouldNotValidateExpiredOauthToken() throws Exception {
204204

205205
PersonalAccessTokenParams params =
206206
new PersonalAccessTokenParams(
207-
"https://bitbucket.org",
208-
OAUTH_2_SUFFIX + "-token-name",
209-
"tid-23434",
210-
bitbucketOauthToken,
211-
null);
207+
true, "https://bitbucket.org", "azure-devops", "tid-23434", bitbucketOauthToken, null);
212208

213209
assertFalse(bitbucketPersonalAccessTokenFetcher.isValid(params).isPresent());
214210
}

wsmaster/che-core-api-factory-github-common/src/main/java/org/eclipse/che/api/factory/server/github/AbstractGithubPersonalAccessTokenFetcher.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public PersonalAccessToken fetchPersonalAccessToken(Subject cheSubject, String s
139139
Optional<Pair<Boolean, String>> valid =
140140
isValid(
141141
new PersonalAccessTokenParams(
142-
scmServerUrl, providerName, tokenId, oAuthToken.getToken(), null));
142+
true, scmServerUrl, providerName, tokenId, oAuthToken.getToken(), null));
143143
if (valid.isEmpty()) {
144144
throw buildScmUnauthorizedException(cheSubject);
145145
} else if (!valid.get().first) {
@@ -184,8 +184,7 @@ public Optional<Boolean> isValid(PersonalAccessToken personalAccessToken) {
184184
}
185185

186186
try {
187-
if (personalAccessToken.getScmProviderName() != null
188-
&& personalAccessToken.getScmProviderName().startsWith(OAUTH_2_SUFFIX)) {
187+
if (personalAccessToken.isOAuthToken()) {
189188
String[] scopes = githubApiClient.getTokenScopes(personalAccessToken.getToken()).second;
190189
return Optional.of(containsScopes(scopes, DEFAULT_TOKEN_SCOPES));
191190
} else {
@@ -217,8 +216,7 @@ public Optional<Pair<Boolean, String>> isValid(PersonalAccessTokenParams params)
217216
}
218217
}
219218
try {
220-
if (params.getScmProviderName() != null
221-
&& params.getScmProviderName().startsWith(OAUTH_2_SUFFIX)) {
219+
if (params.getScmProviderName() != null && params.isOAuthToken()) {
222220
Pair<String, String[]> pair = apiClient.getTokenScopes(params.getToken());
223221
return Optional.of(
224222
Pair.of(

0 commit comments

Comments
 (0)