From 659ab70f5e6950bdd6248a5d245e0b2b6d8c914c Mon Sep 17 00:00:00 2001 From: Andrey Fomin Date: Thu, 15 Feb 2024 23:10:33 +0300 Subject: [PATCH] Add OAuth token to http clone link (#810) Problem was introduced in #796. Fixes #808. --- .../plugins/bitbucket/BitbucketSCMSource.java | 16 +++++++++--- .../bitbucket/api/BitbucketAuthenticator.java | 11 ++++---- .../BitbucketOAuthAuthenticator.java | 26 +++++++++++++++++-- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java index 0700f3a1e..232292a2b 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java @@ -86,6 +86,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; import jenkins.authentication.tokens.api.AuthenticationTokens; import jenkins.model.Jenkins; import jenkins.plugins.git.AbstractGitSCMSource.SCMRevisionImpl; @@ -536,7 +537,7 @@ public BitbucketRepositoryType getRepositoryType() throws IOException, Interrupt repositoryType = BitbucketRepositoryType.fromString(r.getScm()); Map> links = r.getLinks(); if (links != null && links.containsKey("clone")) { - primaryCloneLinks = links.get("clone"); + setPrimaryCloneLinks(links.get("clone")); } } return repositoryType; @@ -1037,6 +1038,15 @@ public SCM build(SCMHead head, SCMRevision revision) { } } + private void setPrimaryCloneLinks(List links) { + BitbucketAuthenticator authenticator = authenticator(); + if (authenticator == null) { + primaryCloneLinks = links; + } else { + primaryCloneLinks = links.stream().map(authenticator::addAuthToken).collect(Collectors.toList()); + } + } + @NonNull @Override public SCMRevision getTrustedRevision(@NonNull SCMRevision revision, @NonNull TaskListener listener) @@ -1092,7 +1102,7 @@ protected List retrieveActions(@CheckForNull SCMSourceEvent event, BitbucketRepository r = bitbucket.getRepository(); Map> links = r.getLinks(); if (links != null && links.containsKey("clone")) { - primaryCloneLinks = links.get("clone"); + setPrimaryCloneLinks(links.get("clone")); } result.add(new BitbucketRepoMetadataAction(r)); String defaultBranch = bitbucket.getDefaultBranch(); @@ -1288,7 +1298,7 @@ private List getCloneLinksFromMirror( private void initPrimaryCloneLinks(BitbucketApi bitbucket) { try { - primaryCloneLinks = getCloneLinksFromPrimary(bitbucket); + setPrimaryCloneLinks(getCloneLinksFromPrimary(bitbucket)); } catch (Exception e) { throw new IllegalStateException( "Could not determine clone links of " + getRepoOwner() + "/" + getRepository() diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketAuthenticator.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketAuthenticator.java index 9ab774c8c..b8d545242 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketAuthenticator.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketAuthenticator.java @@ -108,14 +108,13 @@ public void configureRequest(HttpRequest request) { } /** - * Return the user to be used in the clone Uri. Override this if your - * authentication method needs to set the user in the repository Uri + * Add authentication token to clone link if + * authentication method requires it * - * @return user name to use in the repository Uri + * @return updated clone link */ - public String getUserUri() { - // override to return a user - return ""; + public BitbucketHref addAuthToken(BitbucketHref bitbucketHref) { + return bitbucketHref; } /** diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/credentials/BitbucketOAuthAuthenticator.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/credentials/BitbucketOAuthAuthenticator.java index 8109305a1..0a8d65059 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/credentials/BitbucketOAuthAuthenticator.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/credentials/BitbucketOAuthAuthenticator.java @@ -1,7 +1,10 @@ package com.cloudbees.jenkins.plugins.bitbucket.api.credentials; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator; +import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketHref; import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import java.net.URI; +import java.net.URISyntaxException; import org.apache.http.HttpRequest; import org.scribe.model.OAuthConfig; import org.scribe.model.OAuthConstants; @@ -35,8 +38,27 @@ public void configureRequest(HttpRequest request) { } @Override - public String getUserUri() { - return "x-token-auth:{" + token.getToken() + "}"; + public BitbucketHref addAuthToken(BitbucketHref bitbucketHref) { + String link = bitbucketHref.getHref(); + if (!link.startsWith("http")) { + return bitbucketHref; + } + try { + URI uri = new URI(link); + String userInfo = "x-token-auth:{" + token.getToken() + "}"; + String newLink = new URI( + uri.getScheme(), + userInfo, + uri.getHost(), + uri.getPort(), + uri.getPath(), + uri.getQuery(), + uri.getFragment() + ).toString(); + return new BitbucketHref(bitbucketHref.getName(), newLink); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } } }