Repository: kubesphere/ks-devops
Pull request #581 (2022-05-07 03:31:01)

Support list organizations and repositories of bitbuckets

<!-- Thanks for sending a pull request! Here are some tips for you:

1. If you want **faster** PR reviews, read how: https://github.com/kubesphere/community/blob/master/developer-guide/development/the-pr-author-guide-to-getting-through-code-review.md
2. In case you want to know how your PR got reviewed, read: https://github.com/kubesphere/community/blob/master/developer-guide/development/code-review-guide.md
3. Here are some coding conventions followed by the KubeSphere community: https://github.com/kubesphere/community/blob/master/developer-guide/development/coding-conventions.md
4. Additional open-source best practice: https://github.com/LinuxSuRen/open-source-best-practice
-->

### What type of PR is this?
<!-- 
Add one of the following kinds:
/kind bug
/kind cleanup
/kind documentation
/kind feature
/kind design
/kind chore

Optionally add one or more of the following kinds if applicable:
/kind api-change
/kind deprecation
/kind failing-test
/kind flake
/kind regression
-->

### What this PR does / why we need it:

### Which issue(s) this PR fixes:
<!--
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
Please leave it or change # to be None if there is no corresponding issue that exists
-->
Fixes #

### Special notes for reviewers:
<!--
You can use the following command to let the DevOps SIG members help you to review your PR.
/cc @kubesphere/sig-devops 
And please avoid cc any individual.
-->
Please check the following list before waiting reviewers:

- [ ] Already committed the CRD files to [the Helm Chart](https://github.com/kubesphere-sigs/ks-devops-helm-chart/) if you created some new CRDs
- [ ] Already [added the permission](https://github.com/kubesphere/ks-installer/blob/9e063b085a0e43fdb3d0d9e3e7f4149146f14b9c/roles/ks-core/prepare/files/ks-init/role-templates.yaml) for the new API
- [ ] Already added the RBAC markers for the new controllers

### Does this PR introduce a user-facing change??
<!--
If no, just write "None" in the release-note block below.
If yes, a release note is required:
Enter your extended-release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".

Please keep the note be same as your PR title if you believe it should be in the release notes.
-->
```release-note
None
```


ks-ci-bot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please ask for approval from **linuxsuren** after the PR has been reviewed.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubesphere%2Fks-devops).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubesphere/ks-devops/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["linuxsuren"]} -->
codecov[bot]: # [Codecov](https://codecov.io/gh/kubesphere/ks-devops/pull/581?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere) Report
> Merging [#581](https://codecov.io/gh/kubesphere/ks-devops/pull/581?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere) (4421467) into [master](https://codecov.io/gh/kubesphere/ks-devops/commit/07cd1208c18440a95d4855a342e3ac4d6cad9e2d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere) (07cd120) will **decrease** coverage by `0.04%`.
> The diff coverage is `76.00%`.

```diff
@@            Coverage Diff             @@
##           master     #581      +/-   ##
==========================================
- Coverage   77.33%   77.29%   -0.05%     
==========================================
  Files         147      147              
  Lines       23299    23304       +5     
==========================================
- Hits        18019    18013       -6     
- Misses       5067     5077      +10     
- Partials      213      214       +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `77.29% <76.00%> (-0.05%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/kubesphere/ks-devops/pull/581?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere) | Coverage Δ | |
|---|---|---|
| [pkg/client/git/client.go](https://codecov.io/gh/kubesphere/ks-devops/pull/581/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-cGtnL2NsaWVudC9naXQvY2xpZW50Lmdv) | `84.61% <53.84%> (-15.39%)` | :arrow_down: |
| [pkg/kapis/devops/v1alpha3/scm/route.go](https://codecov.io/gh/kubesphere/ks-devops/pull/581/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-cGtnL2thcGlzL2Rldm9wcy92MWFscGhhMy9zY20vcm91dGUuZ28=) | `100.00% <100.00%> (ø)` | |
| [pkg/kapis/devops/v1alpha3/scm/scmhandler.go](https://codecov.io/gh/kubesphere/ks-devops/pull/581/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-cGtnL2thcGlzL2Rldm9wcy92MWFscGhhMy9zY20vc2NtaGFuZGxlci5nbw==) | `83.50% <100.00%> (+0.89%)` | :arrow_up: |
| [...ns/devopscredential/devopscredential\_controller.go](https://codecov.io/gh/kubesphere/ks-devops/pull/581/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-Y29udHJvbGxlcnMvamVua2lucy9kZXZvcHNjcmVkZW50aWFsL2Rldm9wc2NyZWRlbnRpYWxfY29udHJvbGxlci5nbw==) | `33.33% <0.00%> (-3.41%)` | :arrow_down: |
| [.../jenkins/devopsproject/devopsproject\_controller.go](https://codecov.io/gh/kubesphere/ks-devops/pull/581/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-Y29udHJvbGxlcnMvamVua2lucy9kZXZvcHNwcm9qZWN0L2Rldm9wc3Byb2plY3RfY29udHJvbGxlci5nbw==) | `40.62% <0.00%> (-2.61%)` | :arrow_down: |
| [...ontrollers/jenkins/pipeline/pipeline\_controller.go](https://codecov.io/gh/kubesphere/ks-devops/pull/581/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-Y29udHJvbGxlcnMvamVua2lucy9waXBlbGluZS9waXBlbGluZV9jb250cm9sbGVyLmdv) | `43.18% <0.00%> (+3.78%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/kubesphere/ks-devops/pull/581?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/kubesphere/ks-devops/pull/581?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere). Last update [07cd120...4421467](https://codecov.io/gh/kubesphere/ks-devops/pull/581?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere).


Patch:
diff --git a/go.mod b/go.mod
index 014b92a..e206279 100644
--- a/go.mod
+++ b/go.mod
@@ -67,3 +67,5 @@ replace (
 	k8s.io/component-base => k8s.io/component-base v0.18.6
 	k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6
 )
+
+replace github.com/jenkins-x/go-scm v1.11.4 => github.com/kubesphere-sigs/go-scm v1.5.1-0.20220507031329-56e7d91dd4e5
diff --git a/go.sum b/go.sum
index 9cc03b7..579b33d 100644
--- a/go.sum
+++ b/go.sum
@@ -12,6 +12,7 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 code.cloudfoundry.org/bytefmt v0.0.0-20210524144015-27119551aaea h1:sgtgFDWrhV2cML3UbS2EZu+AfHLP96N0DJ1IHqI1rXA=
 code.cloudfoundry.org/bytefmt v0.0.0-20210524144015-27119551aaea/go.mod h1:yABoJ2k296jrOM76JpOlcsbJuC/4d+WtP+MEAQuuQOk=
+code.gitea.io/sdk/gitea v0.14.0 h1:m4J352I3p9+bmJUfS+g0odeQzBY/5OXP91Gv6D4fnJ0=
 code.gitea.io/sdk/gitea v0.14.0/go.mod h1:89WiyOX1KEcvjP66sRHdu0RafojGo60bT9UqW17VbWs=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/AlecAivazis/survey/v2 v2.2.2/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
@@ -72,6 +73,7 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
 github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
 github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
 github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/bluekeyes/go-gitdiff v0.4.0 h1:Q3qUnQ5cv27vG6ywUTiSQUobRYRcQIBs8KVGKojLg9I=
 github.com/bluekeyes/go-gitdiff v0.4.0/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
@@ -305,6 +307,7 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv
 github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
 github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -326,8 +329,6 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH
 github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
-github.com/jenkins-x/go-scm v1.11.4 h1:uYEFE4Ty9nmlo8paG4ysSxmO5ii6uj7nCQIsSh+ppXU=
-github.com/jenkins-x/go-scm v1.11.4/go.mod h1:8zDNVAps5UCZ7nDVBCzkIrPaSGN4vHq+1bDrHLk6JJc=
 github.com/jenkins-zh/jenkins-cli v0.0.32/go.mod h1:uE1mH9PNITrg0sugv6HXuM/CSddg0zxXoYu3w57I3JY=
 github.com/jenkins-zh/jenkins-client v0.0.9 h1:yqWtjLifYWbVxR+wFdExh/cHSQ54i/Cdco2MYkc/5vI=
 github.com/jenkins-zh/jenkins-client v0.0.9/go.mod h1:ICBk7OOoTafVP//f/VfKZ34c0ff8vJwVnOsF9btiMYU=
@@ -368,6 +369,8 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kubesphere-sigs/go-scm v1.5.1-0.20220507031329-56e7d91dd4e5 h1:yXIEJMzT7V6JaoRJVxV3QWHJDTCLvurXkIBFsgoXuvQ=
+github.com/kubesphere-sigs/go-scm v1.5.1-0.20220507031329-56e7d91dd4e5/go.mod h1:GB6XjszezsDOxKTsPoyk4MT/cKw30qkPdJ4tml+MImg=
 github.com/kubesphere/sonargo v0.0.2 h1:hsSRE3sv3mkPcUAeSABdp7rtfcNW2zzeHXzFa01CTkU=
 github.com/kubesphere/sonargo v0.0.2/go.mod h1:ww8n9ANlDXhX5PBZ18iaRnCgEkXN0GMml3/KZXOZ11w=
 github.com/linuxsuren/cobra-extension v0.0.6/go.mod h1:qcEJv7BbL0UpK6MbrTESP/nKf1+z1wQdMAnE1NBl3QQ=
diff --git a/pkg/client/git/client.go b/pkg/client/git/client.go
index 202612d..3927110 100644
--- a/pkg/client/git/client.go
+++ b/pkg/client/git/client.go
@@ -18,17 +18,13 @@ package git
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	goscm "github.com/jenkins-x/go-scm/scm"
-	"github.com/jenkins-x/go-scm/scm/driver/github"
-	"github.com/jenkins-x/go-scm/scm/driver/gitlab"
-	"github.com/jenkins-x/go-scm/scm/transport/oauth2"
+	"github.com/jenkins-x/go-scm/scm/factory"
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
 	"kubesphere.io/devops/pkg/api/devops/v1alpha3"
-	"net/http"
 )
 
 // ClientFactory responsible for creating a git client
@@ -36,6 +32,8 @@ type ClientFactory struct {
 	provider  string
 	secretRef *v1.SecretReference
 	k8sClient ResourceGetter
+
+	Server string
 }
 
 // NewClientFactory creates an instance of the ClientFactory
@@ -49,36 +47,32 @@ func NewClientFactory(provider string, secretRef *v1.SecretReference, k8sClient
 
 // GetClient returns the git client with auth
 func (c *ClientFactory) GetClient() (client *goscm.Client, err error) {
+	provider := c.provider
 	switch c.provider {
-	case "github":
-		client = github.NewDefault()
-	case "gitlab":
-		client = gitlab.NewDefault()
-	default:
-		err = errors.New("not support git provider: " + c.provider)
-		return
+	case "bitbucket_cloud":
+		provider = "bitbucketcloud"
+	case "bitbucket-server":
+		provider = "bitbucketserver"
+	}
+
+	if c.Server == "https://api.bitbucket.org" || c.Server == "https://bitbucket.org" {
+		provider = "bitbucketcloud"
 	}
 
+	var token string
+	username := ""
 	if c.secretRef != nil {
-		var gitToken string
-		if gitToken, err = c.getTokenFromSecret(c.secretRef); err != nil {
+		if token, username, err = c.getTokenFromSecret(c.secretRef); err != nil {
 			return
 		}
-
-		client.Client = &http.Client{
-			Transport: &oauth2.Transport{
-				Source: oauth2.StaticTokenSource(
-					&goscm.Token{
-						Token: gitToken,
-					},
-				),
-			},
-		}
 	}
+	client, err = factory.NewClient(provider, c.Server, token, func(scmClient *goscm.Client) {
+		scmClient.Username = username
+	})
 	return
 }
 
-func (c *ClientFactory) getTokenFromSecret(secretRef *v1.SecretReference) (token string, err error) {
+func (c *ClientFactory) getTokenFromSecret(secretRef *v1.SecretReference) (token, username string, err error) {
 	var gitSecret *v1.Secret
 	if gitSecret, err = c.getSecret(secretRef); err != nil {
 		return
@@ -87,6 +81,7 @@ func (c *ClientFactory) getTokenFromSecret(secretRef *v1.SecretReference) (token
 	switch gitSecret.Type {
 	case v1.SecretTypeBasicAuth, v1alpha3.SecretTypeBasicAuth:
 		token = string(gitSecret.Data[v1.BasicAuthPasswordKey])
+		username = string(gitSecret.Data[v1.BasicAuthUsernameKey])
 	case v1.SecretTypeOpaque:
 		token = string(gitSecret.Data[v1.ServiceAccountTokenKey])
 	case v1alpha3.SecretTypeSecretText:
diff --git a/pkg/kapis/devops/v1alpha3/scm/route.go b/pkg/kapis/devops/v1alpha3/scm/route.go
index b5b4688..9e5a8d1 100644
--- a/pkg/kapis/devops/v1alpha3/scm/route.go
+++ b/pkg/kapis/devops/v1alpha3/scm/route.go
@@ -32,6 +32,7 @@ var (
 	pathParameterSCM          = restful.PathParameter("scm", "the SCM type")
 	pathParameterOrganization = restful.PathParameter("organization",
 		"The git provider organization. For a GitHub repository address: https://github.com/kubesphere/ks-devops. kubesphere is the organization name")
+	queryParameterServer          = restful.PathParameter("server", "The address of a self-hosted scm provider")
 	pathParameterGitRepository    = restful.PathParameter("gitrepository", "The GitRepository customs resource")
 	queryParameterSecret          = restful.QueryParameter("secret", "the secret name")
 	queryParameterSecretNamespace = restful.QueryParameter("secretNamespace", "the namespace of target secret")
@@ -49,6 +50,7 @@ func registerSCMAPIs(ws *restful.WebService, h *handler) {
 	ws.Route(ws.POST("/scms/{scm}/verify").
 		To(h.verify).
 		Param(pathParameterSCM).
+		Param(queryParameterServer).
 		Param(queryParameterSecret).
 		Param(queryParameterSecretNamespace).
 		Doc("verify the token of different git providers").
@@ -57,6 +59,7 @@ func registerSCMAPIs(ws *restful.WebService, h *handler) {
 	ws.Route(ws.GET("/scms/{scm}/organizations").
 		To(h.listOrganizations).
 		Param(pathParameterSCM).
+		Param(queryParameterServer).
 		Param(queryParameterSecret).
 		Param(queryParameterSecretNamespace).
 		Param(queryParameterIncludeUser.DataType("boolean").DefaultValue("true")).
@@ -66,6 +69,7 @@ func registerSCMAPIs(ws *restful.WebService, h *handler) {
 	ws.Route(ws.GET("/scms/{scm}/organizations/{organization}/repositories").
 		To(h.listRepositories).
 		Param(pathParameterSCM).
+		Param(queryParameterServer).
 		Param(pathParameterOrganization).
 		Param(queryParameterSecret.Required(true)).
 		Param(queryParameterSecretNamespace.Required(true)).
diff --git a/pkg/kapis/devops/v1alpha3/scm/scmhandler.go b/pkg/kapis/devops/v1alpha3/scm/scmhandler.go
index 197d5cf..9c70b00 100644
--- a/pkg/kapis/devops/v1alpha3/scm/scmhandler.go
+++ b/pkg/kapis/devops/v1alpha3/scm/scmhandler.go
@@ -26,6 +26,7 @@ import (
 	"kubesphere.io/devops/pkg/kapis"
 	"kubesphere.io/devops/pkg/kapis/common"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+	"strings"
 )
 
 // handler holds all the API handlers of SCM
@@ -45,8 +46,9 @@ func (h *handler) verify(request *restful.Request, response *restful.Response) {
 	scm := request.PathParameter("scm")
 	secretName := request.QueryParameter("secret")
 	secretNamespace := request.QueryParameter("secretNamespace")
+	server := common.GetQueryParameter(request, queryParameterServer)
 
-	_, code, err := h.getOrganizations(scm, secretName, secretNamespace, 1, 1, false)
+	_, code, err := h.getOrganizations(scm, server, secretName, secretNamespace, 1, 1, false)
 
 	response.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
 	verifyResult := git.VerifyResult(err, code)
@@ -54,10 +56,11 @@ func (h *handler) verify(request *restful.Request, response *restful.Response) {
 	_ = response.WriteAsJson(verifyResult)
 }
 
-func (h *handler) getOrganizations(scm, secret, namespace string, page, size int, includeUser bool) (orgs []*goscm.Organization, code int, err error) {
+func (h *handler) getOrganizations(scm, server, secret, namespace string, page, size int, includeUser bool) (orgs []*goscm.Organization, code int, err error) {
 	factory := git.NewClientFactory(scm, &v1.SecretReference{
 		Namespace: namespace, Name: secret,
 	}, h.Client)
+	factory.Server = server
 
 	ctx := context.Background()
 	var c *goscm.Client
@@ -85,18 +88,19 @@ func (h *handler) getOrganizations(scm, secret, namespace string, page, size int
 	return
 }
 
-func (h *handler) getRepositories(scm, org, secret, namespace string, page, size int) (repos []*goscm.Repository, code int, err error) {
+func (h *handler) getRepositories(scm, server, org, secret, namespace string, page, size int) (repos []*goscm.Repository, code int, err error) {
 	factory := git.NewClientFactory(scm, &v1.SecretReference{
 		Namespace: namespace, Name: secret,
 	}, h.Client)
+	factory.Server = server
 
 	var c *goscm.Client
 	if c, err = factory.GetClient(); err == nil {
-		// check if the org name is an user account name
+		// check if the org name is a user account name
 		var user string
 		var listRepositoryFunc listRepository
 		if user, err = h.getCurrentUsername(c); err == nil {
-			if user == org {
+			if user == org && !strings.HasPrefix(scm, "bitbucket") {
 				listRepositoryFunc = c.Repositories.ListUser
 			} else {
 				listRepositoryFunc = c.Repositories.ListOrganisation
@@ -124,10 +128,11 @@ func (h *handler) listOrganizations(req *restful.Request, rsp *restful.Response)
 	scm := req.PathParameter("scm")
 	secretName := req.QueryParameter("secret")
 	secretNamespace := req.QueryParameter("secretNamespace")
+	server := common.GetQueryParameter(req, queryParameterServer)
 	includeUser := common.GetQueryParameter(req, queryParameterIncludeUser) == "true"
 	pageNumber, pageSize := common.GetPageParameters(req)
 
-	orgs, _, err := h.getOrganizations(scm, secretName, secretNamespace, pageNumber, pageSize, includeUser)
+	orgs, _, err := h.getOrganizations(scm, server, secretName, secretNamespace, pageNumber, pageSize, includeUser)
 	if err != nil {
 		kapis.HandleError(req, rsp, err)
 	} else {
@@ -137,12 +142,13 @@ func (h *handler) listOrganizations(req *restful.Request, rsp *restful.Response)
 
 func (h *handler) listRepositories(req *restful.Request, rsp *restful.Response) {
 	scm := req.PathParameter("scm")
+	server := common.GetQueryParameter(req, queryParameterServer)
 	organization := req.PathParameter("organization")
 	secretName := req.QueryParameter("secret")
 	secretNamespace := req.QueryParameter("secretNamespace")
 	pageNumber, pageSize := common.GetPageParameters(req)
 
-	repos, _, err := h.getRepositories(scm, organization, secretName, secretNamespace, pageNumber, pageSize)
+	repos, _, err := h.getRepositories(scm, server, organization, secretName, secretNamespace, pageNumber, pageSize)
 	if err != nil {
 		kapis.HandleError(req, rsp, err)
 	} else {


Test patch:
diff --git a/controllers/gitrepository/gitrepository_webhook_controller_test.go b/controllers/gitrepository/gitrepository_webhook_controller_test.go
index 207d004..35d8506 100644
--- a/controllers/gitrepository/gitrepository_webhook_controller_test.go
+++ b/controllers/gitrepository/gitrepository_webhook_controller_test.go
@@ -22,7 +22,6 @@ import (
 	"github.com/go-logr/logr"
 	testing2 "github.com/go-logr/logr/testing"
 	"github.com/jenkins-x/go-scm/scm"
-	"github.com/jenkins-x/go-scm/scm/driver/github"
 	"github.com/stretchr/testify/assert"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -569,7 +568,7 @@ func TestReconciler_getGitClient(t *testing.T) {
 		},
 		wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
 			assert.NotNil(t, err, i)
-			assert.Equal(t, strings.HasPrefix(err.Error(), "not support git provider: "), true, i)
+			assert.Equal(t, strings.HasPrefix(err.Error(), "Unsupported"), true, i)
 			return true
 		},
 	}, {
@@ -592,7 +591,6 @@ func TestReconciler_getGitClient(t *testing.T) {
 			assert.NotNil(t, err, i)
 			return true
 		},
-		wantClient: github.NewDefault(),
 	}, {
 		name: "github provider",
 		fields: fields{
diff --git a/pkg/client/git/client_test.go b/pkg/client/git/client_test.go
index fc427ff..a1a2eca 100644
--- a/pkg/client/git/client_test.go
+++ b/pkg/client/git/client_test.go
@@ -19,7 +19,6 @@ package git
 import (
 	"fmt"
 	"github.com/jenkins-x/go-scm/scm"
-	"github.com/jenkins-x/go-scm/scm/driver/github"
 	"github.com/stretchr/testify/assert"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -93,6 +92,9 @@ func TestGetClient(t *testing.T) {
 		wantErr    assert.ErrorAssertionFunc
 	}{{
 		name: "not support git provider",
+		fields: fields{
+			provider: "not-support",
+		},
 		args: args{
 			repo: &v1alpha3.GitRepository{
 				Spec: v1alpha3.GitRepositorySpec{
@@ -102,7 +104,7 @@ func TestGetClient(t *testing.T) {
 		},
 		wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
 			assert.NotNil(t, err, i)
-			assert.Equal(t, strings.HasPrefix(err.Error(), "not support git provider: "), true, i)
+			assert.Equal(t, strings.HasPrefix(err.Error(), "Unsupported"), true, i)
 			return true
 		},
 	}, {
@@ -116,7 +118,6 @@ func TestGetClient(t *testing.T) {
 			assert.NotNil(t, err, i)
 			return true
 		},
-		wantClient: github.NewDefault(),
 	}, {
 		name: "github provider",
 		fields: fields{
diff --git a/pkg/kapis/devops/v1alpha3/scm/scmhandler_test.go b/pkg/kapis/devops/v1alpha3/scm/scmhandler_test.go
index 0d78aa6..4611d3d 100644
--- a/pkg/kapis/devops/v1alpha3/scm/scmhandler_test.go
+++ b/pkg/kapis/devops/v1alpha3/scm/scmhandler_test.go
@@ -101,7 +101,7 @@ func TestSCMAPI(t *testing.T) {
 		name: "verify against a fake scm type",
 		args: args{
 			method: http.MethodPost,
-			uri:    "/scms/fake/verify?secret=token&secretNamespace=default",
+			uri:    "/scms/fake-scm/verify?secret=token&secretNamespace=default",
 		},
 		prepare: func() {},
 		verify: func(code int, response []byte, t *testing.T) {