Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 3725 Bitbucket Cloud - Support App passwords authentication #3726

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions api/src/main/java/com/epam/pipeline/entity/git/AuthType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2024 EPAM Systems, Inc. (https://www.epam.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.epam.pipeline.entity.git;

public enum AuthType {
TOKEN, BASIC;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.epam.pipeline.common.MessageHelper;
import com.epam.pipeline.controller.vo.PipelineSourceItemsVO;
import com.epam.pipeline.controller.vo.UploadFileMetadata;
import com.epam.pipeline.entity.git.AuthType;
import com.epam.pipeline.entity.git.GitCommitEntry;
import com.epam.pipeline.entity.git.GitCredentials;
import com.epam.pipeline.entity.git.GitProject;
Expand All @@ -41,7 +42,6 @@
import com.epam.pipeline.manager.preference.PreferenceManager;
import com.epam.pipeline.manager.preference.SystemPreferences;
import com.epam.pipeline.mapper.git.BitbucketCloudMapper;
import com.epam.pipeline.utils.AuthorizationUtils;
import com.epam.pipeline.utils.GitUtils;
import joptsimple.internal.Strings;
import lombok.RequiredArgsConstructor;
Expand All @@ -59,16 +59,22 @@
import java.util.stream.Collectors;

import static com.epam.pipeline.manager.git.PipelineRepositoryService.NOT_SUPPORTED_PATTERN;
import static com.epam.pipeline.utils.AuthorizationUtils.buildBasicAuth;
import static com.epam.pipeline.utils.AuthorizationUtils.buildBearerTokenAuth;

@Service
@RequiredArgsConstructor
public class BitbucketCloudService implements GitClientService {

private static final String REPOSITORY_NAME = "repository name";
private static final String PROJECT_NAME = "project name";
private static final String USER_NAME = "user name";
private static final String X_TOKEN_AUTH = "x-token-auth";
private static final String BITBUCKET_CLOUD_FOLDER_MARKER = "commit_directory";
private static final String BITBUCKET_CLOUD_FILE_MARKER = "commit_file";
private static final int MAX_DEPTH = 20;
private static final String PAGE_PARAMETER = "page=";
private static final int MAX_DEPTH = 20;

private final BitbucketCloudMapper mapper;
private final MessageHelper messageHelper;
private final PreferenceManager preferenceManager;
Expand Down Expand Up @@ -201,7 +207,9 @@ public GitCredentials getCloneCredentials(final Pipeline pipeline, final boolean
final boolean issueToken, final Long duration) {
final GitRepositoryUrl repositoryUrl = GitRepositoryUrl.from(pipeline.getRepository());
final String token = pipeline.getRepositoryToken();
final String username = preferenceManager.getPreference(SystemPreferences.BITBUCKET_CLOUD_USER_NAME);
final AuthType authType = preferenceManager.getPreference(SystemPreferences.BITBUCKET_CLOUD_AUTH_TYPE);
final String username = AuthType.TOKEN.equals(authType) ? X_TOKEN_AUTH :
repositoryUrl.getUsername().orElseThrow(() -> buildUrlParseError(USER_NAME));
final String host = repositoryUrl.getHost();
return GitCredentials.builder()
.url(GitRepositoryUrl.asString(repositoryUrl.getProtocol(), username, token, host,
Expand Down Expand Up @@ -351,7 +359,11 @@ private BitbucketCloudClient buildClient(final String repositoryPath, final Stri

Assert.isTrue(StringUtils.isNotBlank(token), messageHelper
.getMessage(MessageConstants.ERROR_BITBUCKET_CLOUD_TOKEN_NOT_FOUND));
final String credentials = AuthorizationUtils.BEARER_AUTH + token;
final AuthType authType = preferenceManager.getPreference(SystemPreferences.BITBUCKET_CLOUD_AUTH_TYPE);
final String credentials = AuthType.TOKEN.equals(authType) ?
buildBearerTokenAuth(token) :
buildBasicAuth(repositoryUrl.getUsername().orElseThrow(() -> buildUrlParseError(USER_NAME)), token);

final String apiVersion = preferenceManager.getPreference(SystemPreferences.BITBUCKET_CLOUD_API_VERSION);

return new BitbucketCloudClient(bitbucketHost, credentials, null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.epam.pipeline.entity.datastorage.StorageQuotaAction;
import com.epam.pipeline.entity.datastorage.nfs.NFSMountPolicy;
import com.epam.pipeline.entity.execution.OSSpecificLaunchCommandTemplate;
import com.epam.pipeline.entity.git.AuthType;
import com.epam.pipeline.entity.git.GitlabIssueLabelsFilter;
import com.epam.pipeline.entity.git.GitlabIssueVisibility;
import com.epam.pipeline.entity.git.GitlabVersion;
Expand Down Expand Up @@ -361,11 +362,11 @@ public class SystemPreferences {
public static final StringPreference BITBUCKET_DEFAULT_DOC_DIRECTORY = new StringPreference(
"bitbucket.default.doc.directory", null, GIT_GROUP, pass, true);

public static final StringPreference GITHUB_USER_NAME =
new StringPreference("github.user.name", null, GIT_GROUP, pass);
public static final StringPreference GITHUB_USER_NAME = new StringPreference(
"github.user.name", null, GIT_GROUP, pass);

public static final StringPreference BITBUCKET_CLOUD_USER_NAME =
new StringPreference("bitbucket.cloud.user.name", null, GIT_GROUP, pass);
public static final EnumPreference<AuthType> BITBUCKET_CLOUD_AUTH_TYPE = new EnumPreference<>(
"bitbucket.cloud.auth.type", AuthType.BASIC, GIT_GROUP, pass);
public static final StringPreference BITBUCKET_CLOUD_API_VERSION = new StringPreference(
"bitbucket.cloud.api.version", "2.0", GIT_GROUP, pass);
public static final StringPreference GITLAB_PROJECT_VISIBILITY = new StringPreference(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,50 @@
package com.epam.pipeline.manager.git;

import com.epam.pipeline.AbstractSpringTest;
import com.epam.pipeline.entity.git.AuthType;
import com.epam.pipeline.entity.git.GitCommitEntry;
import com.epam.pipeline.entity.git.GitProject;
import com.epam.pipeline.entity.git.GitRepositoryEntry;
import com.epam.pipeline.entity.git.GitTagEntry;
import com.epam.pipeline.entity.pipeline.Pipeline;
import com.epam.pipeline.entity.pipeline.Revision;
import com.epam.pipeline.entity.preference.Preference;
import com.epam.pipeline.exception.git.GitClientException;
import com.epam.pipeline.manager.git.bitbucketcloud.BitbucketCloudService;
import com.epam.pipeline.manager.preference.PreferenceManager;
import com.epam.pipeline.manager.preference.SystemPreferences;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.Collections;
import java.util.List;

public class BitbucketCloudServiceTest extends AbstractSpringTest {

private static final String BRANCH = "test";
private static final String TAG = "test_tag10";
private static final String TAG = "test_tag1";
private static final String MESSAGE = "message";
private static final String COMMIT_ID = "d468da2";
private static final String COMMIT_ID = "c4cbce0";
private static final String FILE_PATH = "/test2/test_file.txt";
private static final String FOLDER_PATH = "test2";
private static final String CONTENT = "content123";

/*
Authentication type should be set up in System Preferences(bitbucket.cloud.auth.type).
If Authentication type is BASIC:
repositoryPath should contain user name (like https://[email protected]/workspace/repository.git)
token should contain app password
Clone url looks like https://user_name:[email protected]/workspace/repository.git

If Authentication type is TOKEN:
repositoryPath should look like https://bitbucket.org/workspace/repository.git
token should contain secure token
Clone url looks like https://x-token-auth:[email protected]/workspace/repository.git
*/
@Value("${bitbucket.cloud.repository.path}")
private String repositoryPath;
@Value("${bitbucket.cloud.token}")
Expand All @@ -50,6 +69,16 @@ public class BitbucketCloudServiceTest extends AbstractSpringTest {
@Autowired
private BitbucketCloudService service;

@Autowired
private PreferenceManager preferenceManager;

@Before
public void setup() {
final Preference preference = SystemPreferences.BITBUCKET_CLOUD_AUTH_TYPE.toPreference();
preference.setValue(AuthType.TOKEN.name());
preferenceManager.update(Collections.singletonList(preference));
}

@Ignore
@Test
public void testGetRepository() throws GitClientException {
Expand Down
Loading