Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions config/sample_webconfig.conf
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ webconfig {
server_api_token_auth {
enabled = true
}

// Protect /config with API token authentication.
// Defaults to false to preserve existing endpoint access.
config_api_token_auth {
enabled = false
}

device_api_token_auth {
enabled = true
}
Expand Down
3 changes: 3 additions & 0 deletions http/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ func (s *WebconfigServer) AddBaseRoutes(testOnly bool, router *mux.Router) {
r2.HandleFunc("", s.VersionHandler).Methods("GET")

r3 := router.Path("/config").Subrouter()
if s.ConfigApiTokenAuthEnabled() {
r3.Use(s.ApiMiddleware)
}
r3.HandleFunc("", s.ServerConfigHandler).Methods("GET")

if s.TokenApiEnabled() {
Expand Down
12 changes: 12 additions & 0 deletions http/webconfig_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const (
MetricsEnabledDefault = true
FactoryResetEnabledDefault = false
serverApiTokenAuthEnabledDefault = true
configApiTokenAuthEnabledDefault = false
deviceApiTokenAuthEnabledDefault = true
tokenApiEnabledDefault = false
activeDriverDefault = "cassandra"
Expand Down Expand Up @@ -109,6 +110,7 @@ type WebconfigServer struct {
metricsEnabled bool
factoryResetEnabled bool
serverApiTokenAuthEnabled bool
configApiTokenAuthEnabled bool
deviceApiTokenAuthEnabled bool
tokenApiEnabled bool
kafkaEnabled bool
Expand Down Expand Up @@ -270,6 +272,7 @@ func NewWebconfigServer(sc *common.ServerConfig, testOnly bool) *WebconfigServer
tlsConfig, _ := NewTlsConfig(conf)

serverApiTokenAuthEnabled := conf.GetBoolean("webconfig.jwt.server_api_token_auth.enabled", serverApiTokenAuthEnabledDefault)
configApiTokenAuthEnabled := conf.GetBoolean("webconfig.jwt.config_api_token_auth.enabled", configApiTokenAuthEnabledDefault)
if conf.GetNode("webconfig.jwt.server_api_token_auth.enabled") == nil {
log.Warn("webconfig.jwt.server_api_token_auth.enabled is not set in config; defaulting to true (server API token auth enforced). See MIGRATION.md.")
}
Expand Down Expand Up @@ -399,6 +402,7 @@ func NewWebconfigServer(sc *common.ServerConfig, testOnly bool) *WebconfigServer
metricsEnabled: metricsEnabled,
factoryResetEnabled: factoryResetEnabled,
serverApiTokenAuthEnabled: serverApiTokenAuthEnabled,
configApiTokenAuthEnabled: configApiTokenAuthEnabled,
deviceApiTokenAuthEnabled: deviceApiTokenAuthEnabled,
tokenApiEnabled: tokenApiEnabled,
kafkaEnabled: kafkaEnabled,
Expand Down Expand Up @@ -642,6 +646,14 @@ func (s *WebconfigServer) SetServerApiTokenAuthEnabled(enabled bool) {
s.serverApiTokenAuthEnabled = enabled
}

func (s *WebconfigServer) ConfigApiTokenAuthEnabled() bool {
return s.configApiTokenAuthEnabled
}

func (s *WebconfigServer) SetConfigApiTokenAuthEnabled(enabled bool) {
s.configApiTokenAuthEnabled = enabled
}

func (s *WebconfigServer) DeviceApiTokenAuthEnabled() bool {
return s.deviceApiTokenAuthEnabled
}
Expand Down
33 changes: 33 additions & 0 deletions http/webconfig_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package http

import (
"net/http"
"testing"

"gotest.tools/assert"
Expand All @@ -27,9 +28,33 @@ func TestApiTokenAuthSecureDefaults(t *testing.T) {
// Admin write endpoints (document, rootdocument, poke, reference) MUST
// be guarded by ApiMiddleware out of the box. Regression guard for f003.
assert.Assert(t, serverApiTokenAuthEnabledDefault, "server API token auth must default to enabled")
assert.Assert(t, !configApiTokenAuthEnabledDefault, "config API token auth must default to disabled")
assert.Assert(t, deviceApiTokenAuthEnabledDefault, "device API token auth must default to enabled")
}

func TestConfigEndpointRemainsUnauthenticatedByDefault(t *testing.T) {
server := NewWebconfigServer(sc, true)
assert.Assert(t, !server.ConfigApiTokenAuthEnabled())
router := server.GetRouter(false)

req, err := http.NewRequest("GET", "/config", nil)
assert.NilError(t, err)
res := ExecuteRequest(req, router).Result()
assert.Equal(t, res.StatusCode, http.StatusOK)
}

func TestConfigEndpointRequiresApiTokenWhenEnabled(t *testing.T) {
server := NewWebconfigServer(sc, true)
server.SetConfigApiTokenAuthEnabled(true)
assert.Assert(t, server.ConfigApiTokenAuthEnabled())
router := server.GetRouter(false)

req, err := http.NewRequest("GET", "/config", nil)
assert.NilError(t, err)
res := ExecuteRequest(req, router).Result()
assert.Equal(t, res.StatusCode, http.StatusForbidden)
}

func TestWebconfigServerSetterGetter(t *testing.T) {
server := NewWebconfigServer(sc, true)

Expand All @@ -49,6 +74,14 @@ func TestWebconfigServerSetterGetter(t *testing.T) {
server.SetServerApiTokenAuthEnabled(enabled)
assert.Equal(t, server.ServerApiTokenAuthEnabled(), enabled)

// config api token auth
enabled = true
server.SetConfigApiTokenAuthEnabled(enabled)
assert.Equal(t, server.ConfigApiTokenAuthEnabled(), enabled)
enabled = false
server.SetConfigApiTokenAuthEnabled(enabled)
assert.Equal(t, server.ConfigApiTokenAuthEnabled(), enabled)

// device api token auth
enabled = true
server.SetDeviceApiTokenAuthEnabled(enabled)
Expand Down
Loading