Repository: supabase/gotrue
Pull request #298 (2021-12-03 21:15:37)

Adds support for Azure tenant configuration
## What kind of change does this PR introduce?

Another possible solution for Azure tenant configuration.

## What is the current behavior?

Unsupported via #179 

## What is the new behavior?

Similar to #270 but attempts to preserve the supported External Authentication Providers configuration by using the EXTERNAL_X_URL value for the auth host prefix.

`EXTERNAL_AZURE_URL=https://login.microsoftonline.com/{tenant_id}`

## Additional context

Removes the use of configuration value from the api path as it is the same in both use cases.


kangmingtay: hey @jimkytola, would this be introducing a breaking change for existing users using azure as an oauth provider? 
jimkytola: The default values in the PR continue to use the `common` configuration, so I expect no breaking changes.

Patch:
diff --git a/api/provider/azure.go b/api/provider/azure.go
index fe78cf92..760660df 100644
--- a/api/provider/azure.go
+++ b/api/provider/azure.go
@@ -10,7 +10,7 @@ import (
 )
 
 const (
-	defaultAzureAuthBase = "login.microsoftonline.com"
+	defaultAzureAuthBase = "login.microsoftonline.com/common"
 	defaultAzureAPIBase  = "graph.microsoft.com"
 )
 
@@ -38,7 +38,7 @@ func NewAzureProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuth
 	}
 
 	authHost := chooseHost(ext.URL, defaultAzureAuthBase)
-	apiPath := chooseHost(ext.URL, defaultAzureAPIBase)
+	apiPath := chooseHost(ext.ApiURL, defaultAzureAPIBase)
 
 	oauthScopes := []string{"openid"}
 
@@ -51,8 +51,8 @@ func NewAzureProvider(ext conf.OAuthProviderConfiguration, scopes string) (OAuth
 			ClientID:     ext.ClientID,
 			ClientSecret: ext.Secret,
 			Endpoint: oauth2.Endpoint{
-				AuthURL:  authHost + "/common/oauth2/v2.0/authorize",
-				TokenURL: authHost + "/common/oauth2/v2.0/token",
+				AuthURL:  authHost + "/oauth2/v2.0/authorize",
+				TokenURL: authHost + "/oauth2/v2.0/token",
 			},
 			RedirectURL: ext.RedirectURI,
 			Scopes:      oauthScopes,
diff --git a/api/token.go b/api/token.go
index b99e6b66..a315d5f4 100644
--- a/api/token.go
+++ b/api/token.go
@@ -77,7 +77,11 @@ func (p *IdTokenGrantParams) getVerifier(ctx context.Context) (*oidc.IDTokenVeri
 	case "azure":
 		oAuthProvider = config.External.Azure
 		oAuthProviderClientId = oAuthProvider.ClientID
-		provider, err = oidc.NewProvider(ctx, "https://login.microsoftonline.com/common/v2.0")
+		url := oAuthProvider.URL
+		if url == "" {
+			url = "https://login.microsoftonline.com/common"
+		}
+		provider, err = oidc.NewProvider(ctx, url + "/v2.0")
 	case "facebook":
 		oAuthProvider = config.External.Facebook
 		oAuthProviderClientId = oAuthProvider.ClientID
diff --git a/conf/configuration.go b/conf/configuration.go
index b4796747..ee9bc0a5 100644
--- a/conf/configuration.go
+++ b/conf/configuration.go
@@ -17,6 +17,7 @@ type OAuthProviderConfiguration struct {
 	Secret      string `json:"secret"`
 	RedirectURI string `json:"redirect_uri" split_words:"true"`
 	URL         string `json:"url"`
+	ApiURL      string `json:"api_url"`
 	Enabled     bool   `json:"enabled"`
 }
 


Test patch:
diff --git a/api/external_azure_test.go b/api/external_azure_test.go
index 0626e9a7..b0599c45 100644
--- a/api/external_azure_test.go
+++ b/api/external_azure_test.go
@@ -41,7 +41,7 @@ func (ts *ExternalTestSuite) TestSignupExternalAzure() {
 func AzureTestSignupSetup(ts *ExternalTestSuite, tokenCount *int, userCount *int, code string, user string) *httptest.Server {
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		switch r.URL.Path {
-		case "/common/oauth2/v2.0/token":
+		case "/oauth2/v2.0/token":
 			*tokenCount++
 			ts.Equal(code, r.FormValue("code"))
 			ts.Equal("authorization_code", r.FormValue("grant_type"))
@@ -60,6 +60,7 @@ func AzureTestSignupSetup(ts *ExternalTestSuite, tokenCount *int, userCount *int
 	}))
 
 	ts.Config.External.Azure.URL = server.URL
+	ts.Config.External.Azure.ApiURL = server.URL
 
 	return server
 }