From 55ba7ffb85a0ec1905b57d29631d5a3b8480332d Mon Sep 17 00:00:00 2001 From: Igor Vinokur Date: Thu, 7 Mar 2024 11:08:33 +0200 Subject: [PATCH] Do not pass oauth2 as a username to Git credentials for Bitbucket (#662) Set bitbucket-***** as a token name annotation for bitbucket token secret. This is needed to pass username instead of oauth2 for bitbucket credentials --- .../che/security/oauth/EmbeddedOAuthAPI.java | 14 +++++++++- .../security/oauth/EmbeddedOAuthAPITest.java | 28 +++++++++++++++++++ .../server/scm/GitCredentialManager.java | 5 ++-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/wsmaster/che-core-api-auth/src/main/java/org/eclipse/che/security/oauth/EmbeddedOAuthAPI.java b/wsmaster/che-core-api-auth/src/main/java/org/eclipse/che/security/oauth/EmbeddedOAuthAPI.java index 455f1d01600..ef644e7a679 100644 --- a/wsmaster/che-core-api-auth/src/main/java/org/eclipse/che/security/oauth/EmbeddedOAuthAPI.java +++ b/wsmaster/che-core-api-auth/src/main/java/org/eclipse/che/security/oauth/EmbeddedOAuthAPI.java @@ -111,7 +111,7 @@ public Response callback(UriInfo uriInfo, @Nullable List errorValues) EnvironmentContext.getCurrent().getSubject().getUserId(), null, null, - NameGenerator.generate(OAUTH_2_PREFIX, 5), + generateTokenName(providerName), NameGenerator.generate("id-", 5), token)); } catch (OAuthAuthenticationException e) { @@ -135,6 +135,18 @@ public Response callback(UriInfo uriInfo, @Nullable List errorValues) return Response.temporaryRedirect(uri).build(); } + /* + * This value is used for generating git credentials. Most of the git providers work with git + * credentials with OAuth token in format "ouath2:" but bitbucket requires username + * to be explicitly set: ":, see {@link + * GitCredentialManager#createOrReplace} + * TODO: needs to be moved to the specific bitbucket implementation. + */ + private String generateTokenName(String providerName) { + return NameGenerator.generate( + "bitbucket".equals(providerName) ? providerName + "-" : OAUTH_2_PREFIX, 5); + } + /** * Encode the redirect URL query parameters to avoid the error when the redirect URL contains * JSON, as a query parameter. This prevents passing unsupported characters, like '{' and '}' to diff --git a/wsmaster/che-core-api-auth/src/test/java/org/eclipse/che/security/oauth/EmbeddedOAuthAPITest.java b/wsmaster/che-core-api-auth/src/test/java/org/eclipse/che/security/oauth/EmbeddedOAuthAPITest.java index f016473046c..53d765be703 100644 --- a/wsmaster/che-core-api-auth/src/test/java/org/eclipse/che/security/oauth/EmbeddedOAuthAPITest.java +++ b/wsmaster/che-core-api-auth/src/test/java/org/eclipse/che/security/oauth/EmbeddedOAuthAPITest.java @@ -143,6 +143,34 @@ public void shouldStoreTokenOnCallback() throws Exception { assertEquals(token.getToken(), "token"); } + @Test + public void shouldStoreBitbucketTokenOnCallback() throws Exception { + // given + UriInfo uriInfo = mock(UriInfo.class); + OAuthAuthenticator authenticator = mock(OAuthAuthenticator.class); + when(authenticator.getEndpointUrl()).thenReturn("http://eclipse.che"); + when(authenticator.callback(any(URL.class), anyList())).thenReturn("token"); + when(uriInfo.getRequestUri()) + .thenReturn( + new URI( + "http://eclipse.che?state=oauth_provider%3Dbitbucket%26redirect_after_login%3DredirectUrl")); + when(oauth2Providers.getAuthenticator("bitbucket")).thenReturn(authenticator); + ArgumentCaptor tokenCapture = + ArgumentCaptor.forClass(PersonalAccessToken.class); + + // when + embeddedOAuthAPI.callback(uriInfo, emptyList()); + + // then + verify(personalAccessTokenManager).store(tokenCapture.capture()); + PersonalAccessToken token = tokenCapture.getValue(); + assertEquals(token.getScmProviderUrl(), "http://eclipse.che"); + assertEquals(token.getCheUserId(), "0000-00-0000"); + assertTrue(token.getScmTokenId().startsWith("id-")); + assertTrue(token.getScmTokenName().startsWith("bitbucket-")); + assertEquals(token.getToken(), "token"); + } + @Test public void shouldEncodeRedirectUrl() throws Exception { // given diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/GitCredentialManager.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/GitCredentialManager.java index 62deec42c1f..e681fadaee5 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/GitCredentialManager.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/GitCredentialManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2021 Red Hat, Inc. + * Copyright (c) 2012-2024 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/ @@ -16,7 +16,8 @@ public interface GitCredentialManager { /** - * Persists PersonalAccessToken for the future usage. + * Propagates git credentials in format: "username:" if the token is Personal Access + * Token or "oauth2: if oAuth token. * * @param personalAccessToken * @throws UnsatisfiedScmPreconditionException - some storage preconditions aren't met.