diff --git a/server/server.go b/server/server.go index a3ebd63857..2052b0d0fc 100644 --- a/server/server.go +++ b/server/server.go @@ -534,12 +534,14 @@ func newServer(ctx context.Context, c Config) (*Server, error) { handleFunc("/auth", s.handleAuthorization) handleFunc("/auth/{connector}", s.handleConnectorLogin) handleFunc("/auth/{connector}/login", s.handlePasswordLogin) - handleFunc("/device", s.handleDeviceExchange) - handleFunc("/device/auth/verify_code", s.verifyUserCode) - handleFunc("/device/code", s.handleDeviceCode) - // TODO(nabokihms): "/device/token" endpoint is deprecated, consider using /token endpoint instead - handleFunc("/device/token", s.handleDeviceTokenDeprecated) - handleFunc(deviceCallbackURI, s.handleDeviceCallback) + if contains(s.supportedGrantTypes, grantTypeDeviceCode) { + handleFunc("/device", s.handleDeviceExchange) + handleFunc("/device/auth/verify_code", s.verifyUserCode) + handleFunc("/device/code", s.handleDeviceCode) + // TODO(nabokihms): "/device/token" endpoint is deprecated, consider using /token endpoint instead + handleFunc("/device/token", s.handleDeviceTokenDeprecated) + handleFunc(deviceCallbackURI, s.handleDeviceCallback) + } handleFunc("/callback", func(w http.ResponseWriter, r *http.Request) { // Strip the X-Remote-* headers to prevent security issues on // misconfigured authproxy connector setups. diff --git a/server/server_test.go b/server/server_test.go index db8f12ce25..e74ce67ac3 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -1826,6 +1826,42 @@ func TestServerSupportedGrants(t *testing.T) { } } +func TestServerDeviceEndpointsGatedByGrant(t *testing.T) { + devicePaths := []string{ + "/device", + "/device/auth/verify_code", + "/device/code", + "/device/token", + "/device/callback", + } + + t.Run("not routed when device_code grant is disallowed", func(t *testing.T) { + httpServer, _ := newTestServer(t, func(c *Config) { + c.AllowedGrantTypes = []string{grantTypeAuthorizationCode, grantTypeRefreshToken} + }) + defer httpServer.Close() + + for _, p := range devicePaths { + resp, err := http.Get(httpServer.URL + p) + require.NoError(t, err) + resp.Body.Close() + require.Equal(t, http.StatusNotFound, resp.StatusCode, "GET %s must be 404", p) + } + }) + + t.Run("routed when device_code grant is allowed", func(t *testing.T) { + httpServer, _ := newTestServer(t, nil) + defer httpServer.Close() + + for _, p := range devicePaths { + resp, err := http.Get(httpServer.URL + p) + require.NoError(t, err) + resp.Body.Close() + require.NotEqual(t, http.StatusNotFound, resp.StatusCode, "GET %s must be routed", p) + } + }) +} + func TestHeaders(t *testing.T) { ctx := t.Context()