mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2026-10-06 14:41:22 +02:00
fix(bitbucket): auth failure due to Bitbucket API changes (#3477)
* fix: #3428 bybitbucket auth failure by changing token n validation flow to use Authentication header instead of query param Co-authored-by: aviralgarg05 <gargaviral99@gmail.com> Signed-off-by: Mohammad Hassan <m8fouad@gmail.com> Signed-off-by: Jan Larwig <jan.larwig@digits.schwarz> * fix: added changelog entry and added tests to verify bitbucket auth header fix Signed-off-by: Mohammad Hassan <m8fouad@gmail.com> * fix(bitbucket): aded support for limiting login for workspace members and handled deprecated team api and added test cases Signed-off-by: Mohammad Hassan <m8fouad@gmail.com> * docs(bitbucket): applied missing docs changes Signed-off-by: Jan Larwig <jan.larwig@digits.schwarz> --------- Signed-off-by: Mohammad Hassan <m8fouad@gmail.com> Signed-off-by: Jan Larwig <jan.larwig@digits.schwarz> Co-authored-by: aviralgarg05 <gargaviral99@gmail.com> Co-authored-by: Jan Larwig <jan.larwig@digits.schwarz>
This commit is contained in:
co-authored by
aviralgarg05
Jan Larwig
parent
b0d87093a8
commit
bde7f9eee1
@@ -3,6 +3,9 @@
|
||||
## Release Highlights
|
||||
|
||||
## Important Notes
|
||||
The Bitbucket provider `--bitbucket-team` flag got deprecated and we added `--bitbucket-workspace` flag to restrict logins to members of a specific workspace instead of a team. The `--bitbucket-team` flag is still supported and will act like workspace but will be removed in a future release. Please update your configuration to use the new `--bitbucket-workspace` flag. For more information, refer to [Bitbucket teams API deprecation](https://developer.atlassian.com/cloud/bitbucket/bitbucket-api-teams-deprecation/).
|
||||
|
||||
Additionally refer to OAuth client configuration for Bitbucket provider in the [documentation](https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/bitbucket/). for changes in the scopes (Account>Read) is now required if you restrict by workspace.
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
@@ -10,6 +13,7 @@
|
||||
|
||||
- [#3546](https://github.com/oauth2-proxy/oauth2-proxy/pull/3546) fix: strip the port from the request host when matching cookie domains @kirilju
|
||||
- [#3547](https://github.com/oauth2-proxy/oauth2-proxy/pull/3547) fix: refresh additional claims for OIDC and MS Entra ID providers and properly populate additional claims during login (@Apollo3zehn)
|
||||
- [#3477](https://github.com/oauth2-proxy/oauth2-proxy/pull/3477) fix(bitbucket): auth failure due to Bitbucket OAuth 2.0 [changes on May 4th 2026](https://developer.atlassian.com/cloud/bitbucket/changelog/#CHANGE-3052) @mfouad
|
||||
|
||||
# V7.15.4
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ _oauth2_proxy() {
|
||||
COMPREPLY=( $(compgen -W 'X-Real-IP X-Forwarded-For X-ProxyUser-IP' -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
--@(http-address|https-address|redirect-url|upstream|basic-auth-password|skip-auth-regex|flush-interval|extra-jwt-issuers|email-domain|whitelist-domain|trusted-ip|keycloak-group|azure-tenant|bitbucket-team|bitbucket-repository|github-org|github-team|github-repo|github-token|gitlab-group|github-user|google-group|google-admin-email|google-service-account-json|client-id|client_secret|banner|footer|proxy-prefix|ping-path|ready-path|cookie-name|cookie-secret|cookie-domain|cookie-path|cookie-expire|cookie-refresh|cookie-samesite|redist-sentinel-master-name|redist-sentinel-connection-urls|redist-cluster-connection-urls|logging-max-size|logging-max-age|logging-max-backups|standard-logging-format|request-logging-format|exclude-logging-paths|auth-logging-format|oidc-issuer-url|oidc-jwks-url|login-url|redeem-url|profile-url|resource|validate-url|scope|approval-prompt|signature-key|acr-values|jwt-key|pubjwk-url|force-json-errors))
|
||||
--@(http-address|https-address|redirect-url|upstream|basic-auth-password|skip-auth-regex|flush-interval|extra-jwt-issuers|email-domain|whitelist-domain|trusted-ip|keycloak-group|azure-tenant|bitbucket-workspace|bitbucket-repository|github-org|github-team|github-repo|github-token|gitlab-group|github-user|google-group|google-admin-email|google-service-account-json|client-id|client_secret|banner|footer|proxy-prefix|ping-path|ready-path|cookie-name|cookie-secret|cookie-domain|cookie-path|cookie-expire|cookie-refresh|cookie-samesite|redist-sentinel-master-name|redist-sentinel-connection-urls|redist-cluster-connection-urls|logging-max-size|logging-max-age|logging-max-backups|standard-logging-format|request-logging-format|exclude-logging-paths|auth-logging-format|oidc-issuer-url|oidc-jwks-url|login-url|redeem-url|profile-url|resource|validate-url|scope|approval-prompt|signature-key|acr-values|jwt-key|pubjwk-url|force-json-errors))
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -342,7 +342,8 @@ They may change between releases without notice.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `team` | _string_ | Team sets restrict logins to members of this team |
|
||||
| `team` | _string_ | Team sets restrict logins to members of this team - Bitbucket has deprecated teams, it will act as workspace instead |
|
||||
| `workspace` | _string_ | Workspace sets restrict logins to members of this workspace, use workspace slug |
|
||||
| `repository` | _string_ | Repository sets restrict logins to user with access to this repository |
|
||||
|
||||
### ClaimSource
|
||||
|
||||
@@ -8,7 +8,7 @@ title: BitBucket
|
||||
hostname that oauth2-proxy is running on.
|
||||
* In Permissions section select:
|
||||
* Account -> Email
|
||||
* Team membership -> Read
|
||||
* Account -> Read [Required for workspace membership check]
|
||||
* Repositories -> Read
|
||||
2. Note the Client ID and Client Secret.
|
||||
|
||||
@@ -20,6 +20,11 @@ To use the provider, pass the following options:
|
||||
--client-secret=<Client Secret>
|
||||
```
|
||||
|
||||
The default configuration allows everyone with Bitbucket account to authenticate. To restrict the access to the team
|
||||
members use additional configuration option: `--bitbucket-team=<Team name>`. To restrict the access to only these users
|
||||
who have access to one selected repository use `--bitbucket-repository=<Repository name>`.
|
||||
The default configuration allows everyone with Bitbucket account to authenticate.
|
||||
|
||||
To restrict the access to members of a specific workspace, use the additional configuration option: `--bitbucket-workspace=<Workspace name>`.
|
||||
|
||||
To restrict the access to users who have write access to one selected repository (contributors) use `--bitbucket-repository=<Repository name>`. Note that repository full name format `owner/repo` is required, for example `--bitbucket-repository=myworkspace/myrepo`.
|
||||
|
||||
**Deprecated**: To restrict the access to members of a specific team, use the additional configuration option: `--bitbucket-team=<Team name>`. Note that this option is deprecated and will be removed in a future release. Please use `--bitbucket-workspace` instead. For more info, see [Bitbucket teams API deprecation](https://developer.atlassian.com/cloud/bitbucket/bitbucket-api-teams-deprecation/).
|
||||
|
||||
|
||||
@@ -331,7 +331,8 @@ They may change between releases without notice.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `team` | _string_ | Team sets restrict logins to members of this team |
|
||||
| `team` | _string_ | Team sets restrict logins to members of this team - Bitbucket has deprecated the teams, it will act as workspace instead |
|
||||
| `workspace` | _string_ | Workspace sets restrict logins to members of this workspace, use workspace slug |
|
||||
| `repository` | _string_ | Repository sets restrict logins to user with access to this repository |
|
||||
|
||||
### ClaimSource
|
||||
|
||||
@@ -8,7 +8,7 @@ title: BitBucket
|
||||
hostname that oauth2-proxy is running on.
|
||||
* In Permissions section select:
|
||||
* Account -> Email
|
||||
* Team membership -> Read
|
||||
* Account -> Read [Required for workspace membership check]
|
||||
* Repositories -> Read
|
||||
2. Note the Client ID and Client Secret.
|
||||
|
||||
@@ -20,6 +20,11 @@ To use the provider, pass the following options:
|
||||
--client-secret=<Client Secret>
|
||||
```
|
||||
|
||||
The default configuration allows everyone with Bitbucket account to authenticate. To restrict the access to the team
|
||||
members use additional configuration option: `--bitbucket-team=<Team name>`. To restrict the access to only these users
|
||||
who have access to one selected repository use `--bitbucket-repository=<Repository name>`.
|
||||
The default configuration allows everyone with Bitbucket account to authenticate.
|
||||
|
||||
To restrict the access to members of a specific workspace, use the additional configuration option: `--bitbucket-workspace=<Workspace name>`.
|
||||
|
||||
To restrict the access to users who have write access to one selected repository (contributors) use `--bitbucket-repository=<Repository name>`. Note that repository full name format `owner/repo` is required, for example `--bitbucket-repository=myworkspace/myrepo`.
|
||||
|
||||
**Deprecated**: To restrict the access to members of a specific team, use the additional configuration option: `--bitbucket-team=<Team name>`. Note that this option is deprecated and will be removed in a future release. Please use `--bitbucket-workspace` instead. For more info, see [Bitbucket teams API deprecation](https://developer.atlassian.com/cloud/bitbucket/bitbucket-api-teams-deprecation/).
|
||||
|
||||
|
||||
@@ -512,6 +512,7 @@ type LegacyProvider struct {
|
||||
EntraIDAllowedTenants []string `flag:"entra-id-allowed-tenant" cfg:"entra_id_allowed_tenants"`
|
||||
EntraIDFederatedTokenAuth bool `flag:"entra-id-federated-token-auth" cfg:"entra_id_federated_token_auth"`
|
||||
BitbucketTeam string `flag:"bitbucket-team" cfg:"bitbucket_team"`
|
||||
BitbucketWorkspace string `flag:"bitbucket-workspace" cfg:"bitbucket_workspace"`
|
||||
BitbucketRepository string `flag:"bitbucket-repository" cfg:"bitbucket_repository"`
|
||||
GitHubOrg string `flag:"github-org" cfg:"github_org"`
|
||||
GitHubTeam string `flag:"github-team" cfg:"github_team"`
|
||||
@@ -580,7 +581,8 @@ func legacyProviderFlagSet() *pflag.FlagSet {
|
||||
flagSet.String("azure-graph-group-field", "", "configures the group field to be used when building the groups list(`id` or `displayName`. Default is `id`) from Microsoft Graph(available only for v2.0 oidc url). Based on this value, the `allowed-group` config values should be adjusted accordingly. If using `id` as group field, `allowed-group` should contains groups IDs, if using `displayName` as group field, `allowed-group` should contains groups name")
|
||||
flagSet.StringSlice("entra-id-allowed-tenant", []string{}, "list of tenants allowed for MS Entra ID multi-tenant application")
|
||||
flagSet.Bool("entra-id-federated-token-auth", false, "enable oAuth client authentication with federated token projected by Azure Workload Identity plugin, instead of client secret.")
|
||||
flagSet.String("bitbucket-team", "", "restrict logins to members of this team")
|
||||
flagSet.String("bitbucket-team", "", "[deprecated, use bitbucket-workspace instead] restrict logins to members of this team")
|
||||
flagSet.String("bitbucket-workspace", "", "restrict logins to members of this workspace, use workspace slug (eg. `myworkspace`) instead of workspace name (eg. `My Workspace`)")
|
||||
flagSet.String("bitbucket-repository", "", "restrict logins to user with access to this repository")
|
||||
flagSet.String("github-org", "", "restrict logins to members of this organisation")
|
||||
flagSet.String("github-team", "", "restrict logins to members of this team")
|
||||
@@ -777,6 +779,7 @@ func (l *LegacyProvider) convert() (Providers, error) {
|
||||
case "bitbucket":
|
||||
provider.BitbucketConfig = BitbucketOptions{
|
||||
Team: l.BitbucketTeam,
|
||||
Workspace: l.BitbucketWorkspace,
|
||||
Repository: l.BitbucketRepository,
|
||||
}
|
||||
case "google":
|
||||
|
||||
@@ -236,8 +236,10 @@ type ADFSOptions struct {
|
||||
}
|
||||
|
||||
type BitbucketOptions struct {
|
||||
// Team sets restrict logins to members of this team
|
||||
// Team sets restrict logins to members of this team - Bitbucket has deprecated teams, it will act as workspace instead
|
||||
Team string `yaml:"team,omitempty"`
|
||||
// Workspace sets restrict logins to members of this workspace, use workspace slug
|
||||
Workspace string `yaml:"workspace,omitempty"`
|
||||
// Repository sets restrict logins to user with access to this repository
|
||||
Repository string `yaml:"repository,omitempty"`
|
||||
}
|
||||
|
||||
+37
-19
@@ -14,7 +14,7 @@ import (
|
||||
// BitbucketProvider represents an Bitbucket based Identity Provider
|
||||
type BitbucketProvider struct {
|
||||
*ProviderData
|
||||
Team string
|
||||
Workspace string
|
||||
Repository string
|
||||
}
|
||||
|
||||
@@ -67,7 +67,10 @@ func NewBitbucketProvider(p *ProviderData, opts options.BitbucketOptions) *Bitbu
|
||||
provider := &BitbucketProvider{ProviderData: p}
|
||||
|
||||
if opts.Team != "" {
|
||||
provider.setTeam(opts.Team)
|
||||
provider.setWorkspace(opts.Team)
|
||||
}
|
||||
if opts.Workspace != "" {
|
||||
provider.setWorkspace(opts.Workspace)
|
||||
}
|
||||
if opts.Repository != "" {
|
||||
provider.setRepository(opts.Repository)
|
||||
@@ -75,11 +78,11 @@ func NewBitbucketProvider(p *ProviderData, opts options.BitbucketOptions) *Bitbu
|
||||
return provider
|
||||
}
|
||||
|
||||
// setTeam defines the Bitbucket team the user must be part of
|
||||
func (p *BitbucketProvider) setTeam(team string) {
|
||||
p.Team = team
|
||||
if !strings.Contains(p.Scope, "team") {
|
||||
p.Scope += " team"
|
||||
// setWorkspace defines the Bitbucket workspace the user must be part of
|
||||
func (p *BitbucketProvider) setWorkspace(workspace string) {
|
||||
p.Workspace = workspace
|
||||
if !strings.Contains(p.Scope, "account") {
|
||||
p.Scope += " account"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +94,11 @@ func (p *BitbucketProvider) setRepository(repository string) {
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateSession validates the AccessToken using a Bearer token header
|
||||
func (p *BitbucketProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool {
|
||||
return validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken))
|
||||
}
|
||||
|
||||
// GetEmailAddress returns the email of the authenticated user
|
||||
func (p *BitbucketProvider) GetEmailAddress(ctx context.Context, s *sessions.SessionState) (string, error) {
|
||||
|
||||
@@ -100,9 +108,11 @@ func (p *BitbucketProvider) GetEmailAddress(ctx context.Context, s *sessions.Ses
|
||||
Primary bool `json:"is_primary"`
|
||||
}
|
||||
}
|
||||
var teams struct {
|
||||
var workspaces struct {
|
||||
Values []struct {
|
||||
Name string `json:"username"`
|
||||
Workspace struct {
|
||||
Slug string `json:"slug"`
|
||||
} `json:"workspace"`
|
||||
}
|
||||
}
|
||||
var repositories struct {
|
||||
@@ -111,9 +121,10 @@ func (p *BitbucketProvider) GetEmailAddress(ctx context.Context, s *sessions.Ses
|
||||
}
|
||||
}
|
||||
|
||||
requestURL := p.ValidateURL.String() + "?access_token=" + s.AccessToken
|
||||
requestURL := p.ValidateURL.String()
|
||||
err := requests.New(requestURL).
|
||||
WithContext(ctx).
|
||||
WithHeaders(makeOIDCHeader(s.AccessToken)).
|
||||
Do().
|
||||
UnmarshalInto(&emails)
|
||||
if err != nil {
|
||||
@@ -121,24 +132,29 @@ func (p *BitbucketProvider) GetEmailAddress(ctx context.Context, s *sessions.Ses
|
||||
return "", err
|
||||
}
|
||||
|
||||
if p.Team != "" {
|
||||
if p.Workspace != "" {
|
||||
teamURL := &url.URL{}
|
||||
*teamURL = *p.ValidateURL
|
||||
teamURL.Path = "/2.0/teams"
|
||||
// /teams api was deprecated in Oct 20, use workspaces instead
|
||||
// https://developer.atlassian.com/cloud/bitbucket/bitbucket-api-teams-deprecation/
|
||||
// https://developer.atlassian.com/cloud/bitbucket/rest/api-group-workspaces/#api-workspaces-get
|
||||
teamURL.Path = "2.0/user/workspaces"
|
||||
|
||||
requestURL := teamURL.String() + "?role=member&access_token=" + s.AccessToken
|
||||
requestURL := teamURL.String()
|
||||
|
||||
err := requests.New(requestURL).
|
||||
WithContext(ctx).
|
||||
WithHeaders(makeOIDCHeader(s.AccessToken)).
|
||||
Do().
|
||||
UnmarshalInto(&teams)
|
||||
UnmarshalInto(&workspaces)
|
||||
logger.Printf("workspaces: %+v", workspaces)
|
||||
if err != nil {
|
||||
logger.Errorf("failed requesting teams membership: %v", err)
|
||||
return "", err
|
||||
}
|
||||
var found = false
|
||||
for _, team := range teams.Values {
|
||||
if p.Team == team.Name {
|
||||
for _, workspace := range workspaces.Values {
|
||||
if p.Workspace == workspace.Workspace.Slug {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
@@ -152,14 +168,16 @@ func (p *BitbucketProvider) GetEmailAddress(ctx context.Context, s *sessions.Ses
|
||||
if p.Repository != "" {
|
||||
repositoriesURL := &url.URL{}
|
||||
*repositoriesURL = *p.ValidateURL
|
||||
repositoriesURL.Path = "/2.0/repositories/" + strings.Split(p.Repository, "/")[0]
|
||||
// split the repository name to get the workspace name, which is the first part of the repository name
|
||||
var repoWorkspace = strings.Split(p.Repository, "/")[0]
|
||||
repositoriesURL.Path = "/2.0/repositories/" + repoWorkspace
|
||||
|
||||
requestURL := repositoriesURL.String() + "?role=contributor" +
|
||||
"&q=full_name=" + url.QueryEscape("\""+p.Repository+"\"") +
|
||||
"&access_token=" + s.AccessToken
|
||||
"&q=full_name=" + url.QueryEscape("\""+p.Repository+"\"")
|
||||
|
||||
err := requests.New(requestURL).
|
||||
WithContext(ctx).
|
||||
WithHeaders(makeOIDCHeader(s.AccessToken)).
|
||||
Do().
|
||||
UnmarshalInto(&repositories)
|
||||
if err != nil {
|
||||
|
||||
+126
-4
@@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
||||
@@ -25,6 +26,7 @@ func testBitbucketProvider(hostname, team string, repository string) *BitbucketP
|
||||
Scope: ""},
|
||||
options.BitbucketOptions{
|
||||
Team: team,
|
||||
Workspace: team,
|
||||
Repository: repository,
|
||||
},
|
||||
)
|
||||
@@ -41,7 +43,6 @@ func testBitbucketProvider(hostname, team string, repository string) *BitbucketP
|
||||
func testBitbucketBackend(payload string) *httptest.Server {
|
||||
paths := map[string]bool{
|
||||
"/2.0/user/emails": true,
|
||||
"/2.0/teams": true,
|
||||
}
|
||||
|
||||
return httptest.NewServer(http.HandlerFunc(
|
||||
@@ -50,7 +51,7 @@ func testBitbucketBackend(payload string) *httptest.Server {
|
||||
if !paths[url.Path] {
|
||||
log.Printf("%s not in %+v\n", url.Path, paths)
|
||||
w.WriteHeader(404)
|
||||
} else if !IsAuthorizedInURL(r.URL) {
|
||||
} else if !IsAuthorizedInHeader(r.Header) {
|
||||
w.WriteHeader(403)
|
||||
} else {
|
||||
w.WriteHeader(200)
|
||||
@@ -59,6 +60,34 @@ func testBitbucketBackend(payload string) *httptest.Server {
|
||||
}))
|
||||
}
|
||||
|
||||
func testBitbucketBackendWithWorkspace(emailPayload, workspacePayload string) *httptest.Server {
|
||||
return testBitbucketBackendFull(emailPayload, workspacePayload, "")
|
||||
}
|
||||
|
||||
func testBitbucketBackendFull(emailPayload, workspacePayload, repoPayload string) *httptest.Server {
|
||||
return httptest.NewServer(http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsAuthorizedInHeader(r.Header) {
|
||||
w.WriteHeader(403)
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case r.URL.Path == "/2.0/user/emails":
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(emailPayload))
|
||||
case r.URL.Path == "/2.0/user/workspaces":
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(workspacePayload))
|
||||
case strings.HasPrefix(r.URL.Path, "/2.0/repositories/"):
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(repoPayload))
|
||||
default:
|
||||
log.Printf("%s not handled\n", r.URL.Path)
|
||||
w.WriteHeader(404)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
func TestNewBitbucketProvider(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
@@ -75,7 +104,7 @@ func TestNewBitbucketProvider(t *testing.T) {
|
||||
func TestBitbucketProviderScopeAdjustForTeam(t *testing.T) {
|
||||
p := testBitbucketProvider("", "test-team", "")
|
||||
assert.NotEqual(t, nil, p)
|
||||
assert.Equal(t, "email team", p.Data().Scope)
|
||||
assert.Equal(t, "email account", p.Data().Scope)
|
||||
}
|
||||
|
||||
func TestBitbucketProviderScopeAdjustForRepository(t *testing.T) {
|
||||
@@ -126,7 +155,9 @@ func TestBitbucketProviderGetEmailAddress(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBitbucketProviderGetEmailAddressAndGroup(t *testing.T) {
|
||||
b := testBitbucketBackend("{\"values\": [ { \"email\": \"michael.bland@gsa.gov\", \"is_primary\": true, \"username\": \"bioinformatics\" } ] }")
|
||||
emailPayload := `{"values": [ { "email": "michael.bland@gsa.gov", "is_primary": true } ] }`
|
||||
workspacePayload := `{"values": [ { "type": "workspace_access", "workspace": { "slug": "bioinformatics" } } ] }`
|
||||
b := testBitbucketBackendWithWorkspace(emailPayload, workspacePayload)
|
||||
defer b.Close()
|
||||
|
||||
bURL, _ := url.Parse(b.URL)
|
||||
@@ -138,6 +169,97 @@ func TestBitbucketProviderGetEmailAddressAndGroup(t *testing.T) {
|
||||
assert.Equal(t, "michael.bland@gsa.gov", email)
|
||||
}
|
||||
|
||||
func TestBitbucketProviderGetEmailAddressMultipleWorkspaces(t *testing.T) {
|
||||
emailPayload := `{"values": [ { "email": "michael.bland@gsa.gov", "is_primary": true } ] }`
|
||||
// target workspace is the last entry to exercise the full loop
|
||||
workspacePayload := `{"values": [
|
||||
{ "type": "workspace_access", "workspace": { "slug": "other-team-1" } },
|
||||
{ "type": "workspace_access", "workspace": { "slug": "other-team-2" } },
|
||||
{ "type": "workspace_access", "workspace": { "slug": "bioinformatics" } }
|
||||
]}`
|
||||
b := testBitbucketBackendWithWorkspace(emailPayload, workspacePayload)
|
||||
defer b.Close()
|
||||
|
||||
bURL, _ := url.Parse(b.URL)
|
||||
p := testBitbucketProvider(bURL.Host, "bioinformatics", "")
|
||||
|
||||
session := CreateAuthorizedSession()
|
||||
email, err := p.GetEmailAddress(context.Background(), session)
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Equal(t, "michael.bland@gsa.gov", email)
|
||||
}
|
||||
|
||||
func TestBitbucketProviderWorkspaceNotInList(t *testing.T) {
|
||||
emailPayload := `{"values": [ { "email": "michael.bland@gsa.gov", "is_primary": true } ] }`
|
||||
workspacePayload := `{"values": [
|
||||
{ "type": "workspace_access", "workspace": { "slug": "other-team-1" } },
|
||||
{ "type": "workspace_access", "workspace": { "slug": "other-team-2" } }
|
||||
]}`
|
||||
b := testBitbucketBackendWithWorkspace(emailPayload, workspacePayload)
|
||||
defer b.Close()
|
||||
|
||||
bURL, _ := url.Parse(b.URL)
|
||||
p := testBitbucketProvider(bURL.Host, "bioinformatics", "")
|
||||
|
||||
session := CreateAuthorizedSession()
|
||||
email, err := p.GetEmailAddress(context.Background(), session)
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Equal(t, "", email)
|
||||
}
|
||||
|
||||
func TestBitbucketProviderGetEmailAddressAndRepository(t *testing.T) {
|
||||
emailPayload := `{"values": [ { "email": "michael.bland@gsa.gov", "is_primary": true } ] }`
|
||||
repoPayload := `{"values": [ { "full_name": "bioinformatics/myrepo" } ] }`
|
||||
b := testBitbucketBackendFull(emailPayload, "", repoPayload)
|
||||
defer b.Close()
|
||||
|
||||
bURL, _ := url.Parse(b.URL)
|
||||
p := testBitbucketProvider(bURL.Host, "", "bioinformatics/myrepo")
|
||||
|
||||
session := CreateAuthorizedSession()
|
||||
email, err := p.GetEmailAddress(context.Background(), session)
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Equal(t, "michael.bland@gsa.gov", email)
|
||||
}
|
||||
|
||||
func TestBitbucketProviderGetEmailAddressMultipleRepositories(t *testing.T) {
|
||||
emailPayload := `{"values": [ { "email": "michael.bland@gsa.gov", "is_primary": true } ] }`
|
||||
// target repo is the last entry to exercise the full loop
|
||||
repoPayload := `{"values": [
|
||||
{ "full_name": "bioinformatics/other-repo-1" },
|
||||
{ "full_name": "bioinformatics/other-repo-2" },
|
||||
{ "full_name": "bioinformatics/myrepo" }
|
||||
]}`
|
||||
b := testBitbucketBackendFull(emailPayload, "", repoPayload)
|
||||
defer b.Close()
|
||||
|
||||
bURL, _ := url.Parse(b.URL)
|
||||
p := testBitbucketProvider(bURL.Host, "", "bioinformatics/myrepo")
|
||||
|
||||
session := CreateAuthorizedSession()
|
||||
email, err := p.GetEmailAddress(context.Background(), session)
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Equal(t, "michael.bland@gsa.gov", email)
|
||||
}
|
||||
|
||||
func TestBitbucketProviderRepositoryNotInList(t *testing.T) {
|
||||
emailPayload := `{"values": [ { "email": "michael.bland@gsa.gov", "is_primary": true } ] }`
|
||||
repoPayload := `{"values": [
|
||||
{ "full_name": "bioinformatics/other-repo-1" },
|
||||
{ "full_name": "bioinformatics/other-repo-2" }
|
||||
]}`
|
||||
b := testBitbucketBackendFull(emailPayload, "", repoPayload)
|
||||
defer b.Close()
|
||||
|
||||
bURL, _ := url.Parse(b.URL)
|
||||
p := testBitbucketProvider(bURL.Host, "", "bioinformatics/myrepo")
|
||||
|
||||
session := CreateAuthorizedSession()
|
||||
email, err := p.GetEmailAddress(context.Background(), session)
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Equal(t, "", email)
|
||||
}
|
||||
|
||||
// Note that trying to trigger the "failed building request" case is not
|
||||
// practical, since the only way it can fail is if the URL fails to parse.
|
||||
func TestBitbucketProviderGetEmailAddressFailedRequest(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user