diff --git a/CommitStatusPublisher.xml b/CommitStatusPublisher.xml index 716624e9..69b5c145 100644 --- a/CommitStatusPublisher.xml +++ b/CommitStatusPublisher.xml @@ -47,15 +47,35 @@ Bitbucket Server URL - - + + + Type of authentication + + + + Authentication using personal token + + + + Personal token to use + + + + + + Password authentication + + + A username for Bitbucket Server connection - - - - + + + + A password for Bitbucket Server connection - + + + diff --git a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/Constants.java b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/Constants.java index c9748e68..532ec3f1 100644 --- a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/Constants.java +++ b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/Constants.java @@ -24,6 +24,8 @@ public class Constants { public static final String STASH_PUBLISHER_ID = "atlassianStashPublisher"; public static final String STASH_BASE_URL = "stashBaseUrl"; + public static final String STASH_AUTH_TYPE = "stashAuthType"; + public static final String STASH_TOKEN = "secure:stashToken"; public static final String STASH_USERNAME = "stashUsername"; public static final String STASH_PASSWORD = "secure:stashPassword"; @@ -90,21 +92,6 @@ public String getSshKey() { return ServerSshKeyManager.TEAMCITY_SSH_KEY_PROP; } - @NotNull - public String getStashBaseUrl() { - return STASH_BASE_URL; - } - - @NotNull - public String getStashUsername() { - return STASH_USERNAME; - } - - @NotNull - public String getStashPassword() { - return STASH_PASSWORD; - } - @NotNull public String getGerritServer() { return GERRIT_SERVER; diff --git a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashAuthenticationType.java b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashAuthenticationType.java new file mode 100644 index 00000000..8b664094 --- /dev/null +++ b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashAuthenticationType.java @@ -0,0 +1,35 @@ +package jetbrains.buildServer.commitPublisher.stash; + +import jetbrains.buildServer.util.StringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public enum StashAuthenticationType { + TOKEN_AUTH("token"), + PASSWORD_AUTH("password"), + ; + + private final String myValue; + + + StashAuthenticationType(@NotNull final String value) { + myValue = value; + } + + @NotNull + public String getValue() { + return myValue; + } + + @NotNull + public static StashAuthenticationType parse(@Nullable final String value) { + //migration + if (value == null || StringUtil.isEmptyOrSpaces(value)) return PASSWORD_AUTH; + + for (StashAuthenticationType v : values()) { + if (v.getValue().equals(value)) return v; + } + + throw new IllegalArgumentException("Failed to parse StashAuthenticationType: " + value); + } +} diff --git a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashPublisher.java b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashPublisher.java index d805d70f..49a75d2b 100644 --- a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashPublisher.java +++ b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashPublisher.java @@ -19,6 +19,9 @@ import java.io.IOException; import java.util.Map; +import static com.google.common.base.Joiner.on; +import static com.google.common.collect.ImmutableMap.of; + class StashPublisher extends HttpBasedCommitStatusPublisher { public static final String PUBLISH_QUEUED_BUILD_STATUS = "teamcity.stashCommitStatusPublisher.publishQueuedBuildStatus"; @@ -150,7 +153,8 @@ private String createMessage(@NotNull StashBuildStatus status, private void vote(@NotNull String commit, @NotNull String data, @NotNull String buildDescription) { String url = getBaseUrl() + "/rest/build-status/1.0/commits/" + commit; - postAsync(url, getUsername(), getPassword(), data, ContentType.APPLICATION_JSON, null, buildDescription); + postAsync(url, getUsername(), getPassword(), data, ContentType.APPLICATION_JSON, + of("Authorization", on(' ').join("Bearer", getToken())), buildDescription); } @Override @@ -206,6 +210,10 @@ private String getBaseUrl() { return HttpHelper.stripTrailingSlash(myParams.get(Constants.STASH_BASE_URL)); } + private String getToken() { + return myParams.get(Constants.STASH_TOKEN); + } + private String getUsername() { return myParams.get(Constants.STASH_USERNAME); } diff --git a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashSettings.java b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashSettings.java index 1bba5ba6..2260e7e4 100644 --- a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashSettings.java +++ b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/StashSettings.java @@ -3,6 +3,7 @@ import jetbrains.buildServer.commitPublisher.*; import jetbrains.buildServer.commitPublisher.stash.data.StashError; import jetbrains.buildServer.commitPublisher.stash.data.StashRepoInfo; +import jetbrains.buildServer.commitPublisher.stash.ui.UpdateChangesConstants; import jetbrains.buildServer.serverSide.*; import jetbrains.buildServer.serverSide.executors.ExecutorServices; import jetbrains.buildServer.vcs.VcsRoot; @@ -18,10 +19,16 @@ import java.io.IOException; import java.util.*; +import static com.google.common.base.Joiner.on; +import static com.google.common.collect.ImmutableMap.of; +import static java.lang.String.format; import static jetbrains.buildServer.commitPublisher.stash.StashPublisher.PUBLISH_QUEUED_BUILD_STATUS; +import static org.apache.http.entity.ContentType.APPLICATION_JSON; public class StashSettings extends BasePublisherSettings implements CommitStatusPublisherSettings { + private static final UpdateChangesConstants C = new UpdateChangesConstants(); + private static final Set mySupportedEvents = new HashSet() {{ if (TeamCityProperties.getBoolean(PUBLISH_QUEUED_BUILD_STATUS)) { add(Event.QUEUED); @@ -65,7 +72,7 @@ public CommitStatusPublisher createPublisher(@NotNull SBuildType buildType, @Not @NotNull public String describeParameters(@NotNull Map params) { - String url = params.get(Constants.STASH_BASE_URL); + String url = params.get(C.getStashBaseUrl()); return super.describeParameters(params) + (url != null ? ": " + WebUtil.escapeXml(url) : ""); } @@ -74,8 +81,8 @@ public PropertiesProcessor getParametersProcessor() { return new PropertiesProcessor() { public Collection process(Map params) { List errors = new ArrayList(); - if (params.get(Constants.STASH_BASE_URL) == null) - errors.add(new InvalidProperty(Constants.STASH_BASE_URL, "Server URL must be specified")); + if (params.get(C.getStashBaseUrl()) == null) + errors.add(new InvalidProperty(C.getStashBaseUrl(), "Server URL must be specified")); return errors; } }; @@ -97,7 +104,7 @@ public void testConnection(@NotNull BuildTypeIdentity buildTypeOrTemplate, @NotN Repository repository = GitRepositoryParser.parseRepository(vcsRootUrl); if (null == repository) throw new PublisherException("Cannot parse repository URL from VCS root " + root.getName()); - String apiUrl = params.get(Constants.STASH_BASE_URL); + String apiUrl = params.get(C.getStashBaseUrl()); if (null == apiUrl || apiUrl.length() == 0) throw new PublisherException("Missing Bitbucket Server API URL parameter"); String url = apiUrl + "/rest/api/1.0/projects/" + repository.owner() + "/repos/" + repository.repositoryName(); @@ -127,15 +134,27 @@ public void processResponse(HttpResponse response) throws HttpPublisherException String pluralS = ""; if (repoInfo.errors.size() > 1) pluralS = "s"; - throw new HttpPublisherException(String.format("Bitbucket Server publisher error%s:%s", pluralS, sb.toString())); + throw new HttpPublisherException(format("Bitbucket Server publisher error%s:%s", pluralS, sb.toString())); } } }; - HttpHelper.get(url, params.get(Constants.STASH_USERNAME), params.get(Constants.STASH_PASSWORD), - Collections.singletonMap("Accept", "application/json"), BaseCommitStatusPublisher.DEFAULT_CONNECTION_TIMEOUT, processor); + switch (StashAuthenticationType.parse(params.get(C.getAuthenticationTypeKey()))) { + case PASSWORD_AUTH: + HttpHelper.get(url, params.get(C.getStashUsername()), params.get(C.getStashPassword()), of("Accept", APPLICATION_JSON.getMimeType()), + BaseCommitStatusPublisher.DEFAULT_CONNECTION_TIMEOUT, processor); + break; + + case TOKEN_AUTH: + HttpHelper.get(url, "", "", of("Accept", APPLICATION_JSON.getMimeType(), "Authorization", on(' ').join("Bearer", params.get(C.getStashToken()))), + BaseCommitStatusPublisher.DEFAULT_CONNECTION_TIMEOUT, processor); + break; + + default: + throw new IllegalArgumentException("Failed to parse authentication type."); + } } catch (Exception ex) { - throw new PublisherException(String.format("Bitbucket Server publisher has failed to connect to %s/%s repository", repository.owner(), repository.repositoryName()), ex); + throw new PublisherException(format("Bitbucket Server publisher has failed to connect to %s/%s repository", repository.owner(), repository.repositoryName()), ex); } } diff --git a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/ui/UpdateChangesConstants.java b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/ui/UpdateChangesConstants.java new file mode 100644 index 00000000..a625a4ce --- /dev/null +++ b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/stash/ui/UpdateChangesConstants.java @@ -0,0 +1,14 @@ +package jetbrains.buildServer.commitPublisher.stash.ui; + +import jetbrains.buildServer.commitPublisher.Constants; +import jetbrains.buildServer.commitPublisher.stash.StashAuthenticationType; + +public class UpdateChangesConstants { + public String getStashBaseUrl() { return Constants.STASH_BASE_URL; } + public String getStashUsername() { return Constants.STASH_USERNAME; } + public String getStashPassword() { return Constants.STASH_PASSWORD; } + public String getStashToken() { return Constants.STASH_TOKEN; } + public String getAuthenticationTypeKey() { return Constants.STASH_AUTH_TYPE;} + public String getAuthenticationTypePasswordValue() { return StashAuthenticationType.PASSWORD_AUTH.getValue();} + public String getAuthenticationTypeTokenValue() { return StashAuthenticationType.TOKEN_AUTH.getValue();} +} diff --git a/commit-status-publisher-server/src/main/resources/buildServerResources/stash/stashSettings.jsp b/commit-status-publisher-server/src/main/resources/buildServerResources/stash/stashSettings.jsp index fa7110c5..f2139609 100644 --- a/commit-status-publisher-server/src/main/resources/buildServerResources/stash/stashSettings.jsp +++ b/commit-status-publisher-server/src/main/resources/buildServerResources/stash/stashSettings.jsp @@ -4,7 +4,8 @@ <%@ taglib prefix="forms" tagdir="/WEB-INF/tags/forms" %> <%@ taglib prefix="bs" tagdir="/WEB-INF/tags" %> <%@ taglib prefix="util" uri="/WEB-INF/functions/util" %> - + + Bitbucket Server Base URL: @@ -14,24 +15,41 @@ - - Username: - - - - + + + + + Token: + + + + + + + + + Username: + + + + + + + Password: + + + + + + + + + + + - - Password: - - - - - - - diff --git a/commit-status-publisher-server/src/test/java/jetbrains/buildServer/commitPublisher/stash/StashPublisherTest.java b/commit-status-publisher-server/src/test/java/jetbrains/buildServer/commitPublisher/stash/StashPublisherTest.java index b6adebe4..8b3c5752 100644 --- a/commit-status-publisher-server/src/test/java/jetbrains/buildServer/commitPublisher/stash/StashPublisherTest.java +++ b/commit-status-publisher-server/src/test/java/jetbrains/buildServer/commitPublisher/stash/StashPublisherTest.java @@ -82,6 +82,7 @@ public void test_buildFinishedSuccessfully_server_url_with_slash() throws Except @Override protected Map getPublisherParams() { return new HashMap() {{ + put(Constants.STASH_TOKEN, "token"); put(Constants.STASH_USERNAME, "user"); put(Constants.STASH_PASSWORD, "pwd"); put(Constants.STASH_BASE_URL, getServerUrl());