Skip to content

Commit

Permalink
feat: support multiple client IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
hf committed May 26, 2023
1 parent 962d558 commit 9ec4370
Show file tree
Hide file tree
Showing 35 changed files with 81 additions and 88 deletions.
2 changes: 1 addition & 1 deletion internal/api/external_apple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (ts *ExternalTestSuite) TestSignupExternalApple() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Apple.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Apple.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Apple.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("email name", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_azure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (ts *ExternalTestSuite) TestSignupExternalAzure() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Azure.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Azure.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Azure.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("openid", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_bitbucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (ts *ExternalTestSuite) TestSignupExternalBitbucket() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Bitbucket.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Bitbucket.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Bitbucket.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("account email", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_discord_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (ts *ExternalTestSuite) TestSignupExternalDiscord() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Discord.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Discord.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Discord.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("email identify", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_facebook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (ts *ExternalTestSuite) TestSignupExternalFacebook() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Facebook.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Facebook.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Facebook.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("email", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (ts *ExternalTestSuite) TestSignupExternalGithub() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Github.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Github.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Github.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("user:email", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_gitlab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (ts *ExternalTestSuite) TestSignupExternalGitlab() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Gitlab.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Gitlab.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Gitlab.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("read_user", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_google_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (ts *ExternalTestSuite) TestSignupExternalGoogle() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Google.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Google.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Google.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("email profile", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_kakao_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (ts *ExternalTestSuite) TestSignupExternalKakao() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Kakao.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Kakao.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Kakao.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))

claims := ExternalProviderClaims{}
Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_keycloak_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (ts *ExternalTestSuite) TestSignupExternalKeycloak() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Keycloak.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Keycloak.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Keycloak.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("profile email", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_linkedin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (ts *ExternalTestSuite) TestSignupExternalLinkedin() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Linkedin.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Linkedin.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Linkedin.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("r_emailaddress r_liteprofile", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_notion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (ts *ExternalTestSuite) TestSignupExternalNotion() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Notion.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Notion.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Notion.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))

claims := ExternalProviderClaims{}
Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_twitch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (ts *ExternalTestSuite) TestSignupExternalTwitch() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Twitch.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Twitch.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Twitch.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("user:read:email", q.Get("scope"))

Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_workos_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (ts *ExternalTestSuite) TestSignupExternalWorkOSWithConnection() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.WorkOS.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.WorkOS.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.WorkOS.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))
ts.Equal("", q.Get("scope"))
ts.Equal(connection, q.Get("connection"))
Expand Down
2 changes: 1 addition & 1 deletion internal/api/external_zoom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (ts *ExternalTestSuite) TestSignupExternalZoom() {
ts.Require().NoError(err, "redirect url parse failed")
q := u.Query()
ts.Equal(ts.Config.External.Zoom.RedirectURI, q.Get("redirect_uri"))
ts.Equal(ts.Config.External.Zoom.ClientID, q.Get("client_id"))
ts.Equal(ts.Config.External.Zoom.ClientID, []string{q.Get("client_id")})
ts.Equal("code", q.Get("response_type"))

claims := ExternalProviderClaims{}
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/apple.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type appleUser struct {

// NewAppleProvider creates a Apple account provider.
func NewAppleProvider(ctx context.Context, ext conf.OAuthProviderConfiguration) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -48,7 +48,7 @@ func NewAppleProvider(ctx context.Context, ext conf.OAuthProviderConfiguration)

return &AppleProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oidcProvider.Endpoint(),
Scopes: []string{
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type azureUser struct {

// NewAzureProvider creates a Azure account provider.
func NewAzureProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -44,7 +44,7 @@ func NewAzureProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuth

return &azureProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oauth2.Endpoint{
AuthURL: authHost + "/oauth2/v2.0/authorize",
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type bitbucketEmails struct {

// NewBitbucketProvider creates a Bitbucket account provider.
func NewBitbucketProvider(ext conf.OAuthProviderConfiguration) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -47,7 +47,7 @@ func NewBitbucketProvider(ext conf.OAuthProviderConfiguration) (OAuthProvider, e

return &bitbucketProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oauth2.Endpoint{
AuthURL: authHost + "/site/oauth2/authorize",
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type discordUser struct {

// NewDiscordProvider creates a Discord account provider.
func NewDiscordProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -48,7 +48,7 @@ func NewDiscordProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAu

return &discordProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oauth2.Endpoint{
AuthURL: apiPath + "/oauth2/authorize",
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/facebook.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type facebookUser struct {

// NewFacebookProvider creates a Facebook account provider.
func NewFacebookProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -58,7 +58,7 @@ func NewFacebookProvider(ext conf.OAuthProviderConfiguration, scopes string) (OA

return &facebookProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
RedirectURL: ext.RedirectURI,
Endpoint: oauth2.Endpoint{
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type githubUserEmail struct {

// NewGithubProvider creates a Github account provider.
func NewGithubProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -58,7 +58,7 @@ func NewGithubProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAut

return &githubProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oauth2.Endpoint{
AuthURL: authHost + "/login/oauth/authorize",
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type gitlabUserEmail struct {

// NewGitlabProvider creates a Gitlab account provider.
func NewGitlabProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -49,7 +49,7 @@ func NewGitlabProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAut
host := chooseHost(ext.URL, defaultGitLabAuthBase)
return &gitlabProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oauth2.Endpoint{
AuthURL: host + "/oauth/authorize",
Expand Down
23 changes: 6 additions & 17 deletions internal/api/provider/google.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package provider
import (
"context"
"errors"
"fmt"
"strings"

"github.com/coreos/go-oidc/v3/oidc"
Expand Down Expand Up @@ -40,7 +39,7 @@ type googleProvider struct {

// NewGoogleProvider creates a Google OAuth2 identity provider.
func NewGoogleProvider(ctx context.Context, ext conf.OAuthProviderConfiguration, scopes string) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -64,7 +63,7 @@ func NewGoogleProvider(ctx context.Context, ext conf.OAuthProviderConfiguration,

return &googleProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oidcProvider.Endpoint(),
Scopes: oauthScopes,
Expand All @@ -84,26 +83,16 @@ var internalUserInfoEndpointGoogle = UserInfoEndpointGoogle

func (g googleProvider) GetUserData(ctx context.Context, tok *oauth2.Token) (*UserProvidedData, error) {
if idToken := tok.Extra("id_token"); idToken != nil {
token, data, err := ParseIDToken(ctx, g.oidc, nil, idToken.(string), ParseIDTokenOptions{
_, data, err := ParseIDToken(ctx, g.oidc, &oidc.Config{
ClientID: g.Config.ClientID,
}, idToken.(string), ParseIDTokenOptions{
AccessToken: tok.AccessToken,
})
if err != nil {
return nil, err
}

matchesAudience := false
for _, aud := range token.Audience {
if g.Config.ClientID == aud {
matchesAudience = true
break
}
}

if !matchesAudience {
return nil, fmt.Errorf("provider: Google ID token issued for audience(s) %q but expected %q", strings.Join(token.Audience, ", "), g.Config.ClientID)
}

return data, err
return data, nil
}

// This whole section offers legacy support in case the Google OAuth2
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/kakao.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (p kakaoProvider) GetUserData(ctx context.Context, tok *oauth2.Token) (*Use
}

func NewKakaoProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -90,7 +90,7 @@ func NewKakaoProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuth

return &kakaoProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oauth2.Endpoint{
AuthStyle: oauth2.AuthStyleInParams,
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/keycloak.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type keycloakUser struct {

// NewKeycloakProvider creates a Keycloak account provider.
func NewKeycloakProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -48,7 +48,7 @@ func NewKeycloakProvider(ext conf.OAuthProviderConfiguration, scopes string) (OA

return &keycloakProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oauth2.Endpoint{
AuthURL: ext.URL + "/protocol/openid-connect/auth",
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/linkedin.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ type linkedinElements struct {

// NewLinkedinProvider creates a Linkedin account provider.
func NewLinkedinProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

Expand All @@ -85,7 +85,7 @@ func NewLinkedinProvider(ext conf.OAuthProviderConfiguration, scopes string) (OA

return &linkedinProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oauth2.Endpoint{
AuthURL: apiPath + "/oauth/v2/authorization",
Expand Down
4 changes: 2 additions & 2 deletions internal/api/provider/notion.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ type notionUser struct {

// NewNotionProvider creates a Notion account provider.
func NewNotionProvider(ext conf.OAuthProviderConfiguration) (OAuthProvider, error) {
if err := ext.Validate(); err != nil {
if err := ext.ValidateOAuth(); err != nil {
return nil, err
}

authHost := chooseHost(ext.URL, defaultNotionApiBase)

return &notionProvider{
Config: &oauth2.Config{
ClientID: ext.ClientID,
ClientID: ext.ClientID[0],
ClientSecret: ext.Secret,
Endpoint: oauth2.Endpoint{
AuthURL: authHost + "/v1/oauth/authorize",
Expand Down
Loading

0 comments on commit 9ec4370

Please sign in to comment.