diff --git a/coderd/oauth2_metadata_test.go b/coderd/oauth2_metadata_test.go index 62eb63d1e1..a3e8ec1f50 100644 --- a/coderd/oauth2_metadata_test.go +++ b/coderd/oauth2_metadata_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/testutil" ) @@ -46,6 +47,8 @@ func TestOAuth2AuthorizationServerMetadata(t *testing.T) { require.Contains(t, metadata.GrantTypesSupported, "authorization_code") require.Contains(t, metadata.GrantTypesSupported, "refresh_token") require.Contains(t, metadata.CodeChallengeMethodsSupported, "S256") + // Supported scopes are published from the curated catalog + require.Equal(t, rbac.ExternalScopeNames(), metadata.ScopesSupported) } func TestOAuth2ProtectedResourceMetadata(t *testing.T) { @@ -80,7 +83,6 @@ func TestOAuth2ProtectedResourceMetadata(t *testing.T) { // RFC 6750 bearer tokens are now supported as fallback methods require.Contains(t, metadata.BearerMethodsSupported, "header") require.Contains(t, metadata.BearerMethodsSupported, "query") - // ScopesSupported can be empty until scope system is implemented - // Empty slice is marshaled as empty array, but can be nil when unmarshaled - require.True(t, len(metadata.ScopesSupported) == 0) + // Supported scopes are published from the curated catalog + require.Equal(t, rbac.ExternalScopeNames(), metadata.ScopesSupported) } diff --git a/coderd/oauth2provider/metadata.go b/coderd/oauth2provider/metadata.go index 9ce10f8993..a6edc4006b 100644 --- a/coderd/oauth2provider/metadata.go +++ b/coderd/oauth2provider/metadata.go @@ -5,6 +5,7 @@ import ( "net/url" "github.com/coder/coder/v2/coderd/httpapi" + "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/codersdk" ) @@ -13,15 +14,14 @@ func GetAuthorizationServerMetadata(accessURL *url.URL) http.HandlerFunc { return func(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() metadata := codersdk.OAuth2AuthorizationServerMetadata{ - Issuer: accessURL.String(), - AuthorizationEndpoint: accessURL.JoinPath("/oauth2/authorize").String(), - TokenEndpoint: accessURL.JoinPath("/oauth2/tokens").String(), - RegistrationEndpoint: accessURL.JoinPath("/oauth2/register").String(), // RFC 7591 - ResponseTypesSupported: []string{"code"}, - GrantTypesSupported: []string{"authorization_code", "refresh_token"}, - CodeChallengeMethodsSupported: []string{"S256"}, - // TODO: Implement scope system - ScopesSupported: []string{}, + Issuer: accessURL.String(), + AuthorizationEndpoint: accessURL.JoinPath("/oauth2/authorize").String(), + TokenEndpoint: accessURL.JoinPath("/oauth2/tokens").String(), + RegistrationEndpoint: accessURL.JoinPath("/oauth2/register").String(), // RFC 7591 + ResponseTypesSupported: []string{"code"}, + GrantTypesSupported: []string{"authorization_code", "refresh_token"}, + CodeChallengeMethodsSupported: []string{"S256"}, + ScopesSupported: rbac.ExternalScopeNames(), TokenEndpointAuthMethodsSupported: []string{"client_secret_post"}, } httpapi.Write(ctx, rw, http.StatusOK, metadata) @@ -35,8 +35,7 @@ func GetProtectedResourceMetadata(accessURL *url.URL) http.HandlerFunc { metadata := codersdk.OAuth2ProtectedResourceMetadata{ Resource: accessURL.String(), AuthorizationServers: []string{accessURL.String()}, - // TODO: Implement scope system based on RBAC permissions - ScopesSupported: []string{}, + ScopesSupported: rbac.ExternalScopeNames(), // RFC 6750 Bearer Token methods supported as fallback methods in api key middleware BearerMethodsSupported: []string{"header", "query"}, } diff --git a/coderd/oauth2provider/metadata_test.go b/coderd/oauth2provider/metadata_test.go index c51bb80984..006c341f75 100644 --- a/coderd/oauth2provider/metadata_test.go +++ b/coderd/oauth2provider/metadata_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/testutil" ) @@ -35,6 +36,8 @@ func TestOAuth2AuthorizationServerMetadata(t *testing.T) { require.Contains(t, metadata.GrantTypesSupported, "authorization_code") require.Contains(t, metadata.GrantTypesSupported, "refresh_token") require.Contains(t, metadata.CodeChallengeMethodsSupported, "S256") + // Supported scopes are published from the curated catalog + require.Equal(t, rbac.ExternalScopeNames(), metadata.ScopesSupported) } func TestOAuth2ProtectedResourceMetadata(t *testing.T) { @@ -60,7 +63,6 @@ func TestOAuth2ProtectedResourceMetadata(t *testing.T) { // RFC 6750 bearer tokens are now supported as fallback methods require.Contains(t, metadata.BearerMethodsSupported, "header") require.Contains(t, metadata.BearerMethodsSupported, "query") - // ScopesSupported can be empty until scope system is implemented - // Empty slice is marshaled as empty array, but can be nil when unmarshaled - require.True(t, len(metadata.ScopesSupported) == 0) + // Supported scopes are published from the curated catalog + require.Equal(t, rbac.ExternalScopeNames(), metadata.ScopesSupported) }