package provider import ( "context" "github.com/supabase/auth/internal/conf" "golang.org/x/oauth2" ) const ( defaultBitbucketAuthBase = "bitbucket.org" defaultBitbucketAPIBase = "api.bitbucket.org" ) type bitbucketProvider struct { *oauth2.Config APIPath string } type bitbucketUser struct { Name string `json:"display_name"` ID string `json:"uuid"` Avatar struct { Href string `json:"href"` } `json:"avatar"` } type bitbucketEmail struct { Email string `json:"email"` Primary bool `json:"is_primary"` Verified bool `json:"is_confirmed"` } type bitbucketEmails struct { Values []bitbucketEmail `json:"values"` } // NewBitbucketProvider creates a Bitbucket account provider. func NewBitbucketProvider(ext conf.OAuthProviderConfiguration) (OAuthProvider, error) { if err := ext.ValidateOAuth(); err != nil { return nil, err } authHost := chooseHost(ext.URL, defaultBitbucketAuthBase) apiPath := chooseHost(ext.URL, defaultBitbucketAPIBase) + "/2.0" return &bitbucketProvider{ Config: &oauth2.Config{ ClientID: ext.ClientID[0], ClientSecret: ext.Secret, Endpoint: oauth2.Endpoint{ AuthURL: authHost + "/site/oauth2/authorize", TokenURL: authHost + "/site/oauth2/access_token", }, RedirectURL: ext.RedirectURI, Scopes: []string{"account", "email"}, }, APIPath: apiPath, }, nil } func (g bitbucketProvider) GetOAuthToken(code string) (*oauth2.Token, error) { return g.Exchange(context.Background(), code) } func (g bitbucketProvider) GetUserData(ctx context.Context, tok *oauth2.Token) (*UserProvidedData, error) { var u bitbucketUser if err := makeRequest(ctx, tok, g.Config, g.APIPath+"/user", &u); err != nil { return nil, err } data := &UserProvidedData{} var emails bitbucketEmails if err := makeRequest(ctx, tok, g.Config, g.APIPath+"/user/emails", &emails); err != nil { return nil, err } if len(emails.Values) > 0 { for _, e := range emails.Values { if e.Email != "" { data.Emails = append(data.Emails, Email{ Email: e.Email, Verified: e.Verified, Primary: e.Primary, }) } } } data.Metadata = &Claims{ Issuer: g.APIPath, Subject: u.ID, Name: u.Name, Picture: u.Avatar.Href, // To be deprecated AvatarURL: u.Avatar.Href, FullName: u.Name, ProviderId: u.ID, } return data, nil }