From e4c0388f0d872054061c5adfc7fd2c699388e431 Mon Sep 17 00:00:00 2001 From: Aleksei Sizov Date: Fri, 19 Nov 2021 16:45:36 +0300 Subject: [PATCH] initial version of atlassian-cloud provider --- providers/atlassian-cloud.go | 94 ++++++++++++++++++++++++++++++++++++ providers/providers.go | 2 + 2 files changed, 96 insertions(+) create mode 100644 providers/atlassian-cloud.go diff --git a/providers/atlassian-cloud.go b/providers/atlassian-cloud.go new file mode 100644 index 0000000..6f003c6 --- /dev/null +++ b/providers/atlassian-cloud.go @@ -0,0 +1,94 @@ +package providers + +import ( + "context" + "net/url" + "errors" + + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests" +) + +// AtlassianProvider represents an Atlassian based Identity Provider +type AtlassianProvider struct { + *ProviderData +} + +var _ Provider = (*AtlassianProvider)(nil) + +const ( + atlassianProviderName = "Atlassian" + atlassianDefaultScope = "read:me" + atlassianPrompt = "consent" + atlassianAudience = "api.atlassian.com" +) + +var ( + // Default Login URL for Atlassian. + // Pre-parsed URL of https://atlassian.org/site/oauth2/authorize. + atlassianDefaultLoginURL = &url.URL{ + Scheme: "https", + Host: "auth.atlassian.com", + Path: "/authorize", + } + + // Default Redeem URL for Atlassian. + // Pre-parsed URL of https://atlassian.org/site/oauth2/access_token. + atlassianDefaultRedeemURL = &url.URL{ + Scheme: "https", + Host: "auth.atlassian.com", + Path: "/oauth/token", + } + + // Default Validation URL for Atlassian. + // This simply returns the email of the authenticated user. + // Atlassian does not have a Profile URL to use. + // Pre-parsed URL of https://api.atlassian.org/2.0/user/emails. + atlassianDefaultValidateURL = &url.URL{ + Scheme: "https", + Host: "api.atlassian.com", + Path: "/me", + } +) + +// NewAtlassianProvider initiates a new AtlassianProvider +func NewAtlassianProvider(p *ProviderData) *AtlassianProvider { + p.setProviderDefaults(providerDefaults{ + name: atlassianProviderName, + loginURL: atlassianDefaultLoginURL, + redeemURL: atlassianDefaultRedeemURL, + profileURL: nil, + validateURL: atlassianDefaultValidateURL, + scope: atlassianDefaultScope, + }) + p.Prompt = atlassianPrompt + return &AtlassianProvider{ProviderData: p} +} +func (p *AtlassianProvider) GetLoginURL(redirectURI, state, _ string) string { + extraParams := url.Values{} + extraParams.Add("audience", atlassianAudience) + loginURL := makeLoginURL(p.ProviderData, redirectURI, state, extraParams) + return loginURL.String() +} +func (p *AtlassianProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { + return validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken)) +} +func (p *AtlassianProvider) GetEmailAddress(ctx context.Context, s *sessions.SessionState) (string, error) { + type me_email struct { + Email string `json:"email"` + } + var email me_email + err := requests.New(atlassianDefaultValidateURL.String()). + WithContext(ctx). + WithHeaders(makeOIDCHeader(s.AccessToken)). + Do(). + UnmarshalInto(&email) + + if err != nil { + return "", err + } + if email.Email == "" { + return "", errors.New("No email in respose") + } + return email.Email, nil +} diff --git a/providers/providers.go b/providers/providers.go index a192f22..0c41c69 100644 --- a/providers/providers.go +++ b/providers/providers.go @@ -51,6 +51,8 @@ func New(provider string, p *ProviderData) Provider { return NewDigitalOceanProvider(p) case "google": return NewGoogleProvider(p) + case "atlassian": + return NewAtlassianProvider(p) default: return nil }