feat(backend): allow configuration of cors allowed origins

This commit is contained in:
Alex Brown
2023-04-15 00:36:31 +01:00
committed by Łukasz Mierzwa
parent 87f54c814b
commit ed575c5cb6
14 changed files with 76 additions and 14 deletions

View File

@@ -89,16 +89,20 @@ func setupRouter(router *chi.Mux, historyPoller *historyPoller) {
router.Use(serverStaticFiles(getViewURL("/"), "build"))
router.Use(serverStaticFiles(getViewURL("/__test__/"), "mock"))
router.Use(cors.Handler(cors.Options{
AllowOriginFunc: func(r *http.Request, origin string) bool {
return true
},
corsOptions := cors.Options{
AllowedOrigins: config.Config.Listen.Cors.AllowedOrigins,
AllowedMethods: []string{"GET", "POST", "DELETE"},
AllowedHeaders: []string{"Origin"},
ExposedHeaders: []string{"Content-Length"},
AllowCredentials: true,
MaxAge: 300,
}))
}
if len(corsOptions.AllowedOrigins) == 0 {
corsOptions.AllowOriginFunc = func(r *http.Request, origin string) bool {
return true
}
}
router.Use(cors.Handler(corsOptions))
router.NotFound(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")

View File

@@ -209,6 +209,8 @@ level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 1234"
level=info msg=" prefix: /prefix/"
level=info msg=" cors:"
level=info msg=" allowedOrigins: []"
level=info msg="log:"
level=info msg=" level: info"
level=info msg=" format: text"

View File

@@ -243,6 +243,8 @@ level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg=" cors:"
level=info msg=" allowedOrigins: []"
level=info msg="log:"
level=info msg=" level: info"
level=info msg=" format: text"

View File

@@ -103,6 +103,8 @@ level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg=" cors:"
level=info msg=" allowedOrigins: []"
level=info msg="log:"
level=info msg=" level: info"
level=info msg=" format: text"

View File

@@ -103,6 +103,8 @@ level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg=" cors:"
level=info msg=" allowedOrigins: []"
level=info msg="log:"
level=info msg=" level: info"
level=info msg=" format: text"

View File

@@ -103,6 +103,8 @@ level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg=" cors:"
level=info msg=" allowedOrigins: []"
level=info msg="log:"
level=info msg=" level: info"
level=info msg=" format: text"

View File

@@ -113,6 +113,8 @@ level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg=" cors:"
level=info msg=" allowedOrigins: []"
level=info msg="log:"
level=info msg=" level: info"
level=info msg=" format: text"

View File

@@ -103,6 +103,8 @@ level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg=" cors:"
level=info msg=" allowedOrigins: []"
level=info msg="log:"
level=info msg=" level: info"
level=info msg=" format: text"

View File

@@ -82,6 +82,8 @@ level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg=" cors:"
level=info msg=" allowedOrigins: []"
level=info msg="log:"
level=info msg=" level: info"
level=info msg=" format: text"

View File

@@ -1068,15 +1068,43 @@ func TestSilences(t *testing.T) {
}
func TestCORS(t *testing.T) {
mockConfig(t.Setenv)
r := testRouter()
setupRouter(r, nil)
req := httptest.NewRequest("OPTIONS", "/alerts.json", nil)
req.Header.Set("Origin", "foo.example.com")
resp := httptest.NewRecorder()
r.ServeHTTP(resp, req)
if resp.Header().Get("Access-Control-Allow-Origin") != "foo.example.com" {
t.Errorf("Invalid Access-Control-Allow-Origin value %q, expected 'foo.example.com'", resp.Header().Get("Access-Control-Allow-Origin"))
type corsTestCase struct {
allowedOrigins []string
requestOrigin string
result string
}
corsTestCases := []corsTestCase{
{
allowedOrigins: []string{},
requestOrigin: "foo.example.com",
result: "foo.example.com",
},
{
allowedOrigins: []string{"bar.example.com"},
requestOrigin: "foo.example.com",
result: "",
},
{
allowedOrigins: []string{"bar.example.com"},
requestOrigin: "bar.example.com",
result: "bar.example.com",
},
}
for _, testCase := range corsTestCases {
mockConfig(t.Setenv)
defer func() {
config.Config.Listen.Cors.AllowedOrigins = nil
}()
config.Config.Listen.Cors.AllowedOrigins = testCase.allowedOrigins
r := testRouter()
setupRouter(r, nil)
req := httptest.NewRequest("OPTIONS", "/alerts.json", nil)
req.Header.Set("Origin", testCase.requestOrigin)
resp := httptest.NewRecorder()
r.ServeHTTP(resp, req)
if resp.Header().Get("Access-Control-Allow-Origin") != testCase.result {
t.Errorf("Invalid Access-Control-Allow-Origin value %q, expected '%q'", resp.Header().Get("Access-Control-Allow-Origin"), testCase.result)
}
}
}

View File

@@ -1052,6 +1052,8 @@ listen:
tls:
cert: string
key: string
cors:
allowedOrigins: list of strings
```
- `address` - Hostname or IP to listen on.
@@ -1063,6 +1065,8 @@ listen:
reverse proxy with other services on the same IP but different URL root.
- `tls:cert` - path to a TLS certificate, enables listening on HTTPS instead of HTTP,
- `tls:key` - path to a TLS key, required when `tls.cert` is set
- `cors:allowedOrigins` - List of origins a cross-domain request can be executed
from. An empty list means all origins are allowed.
Example where karma would listen for HTTP requests on `http://1.2.3.4:80/karma/`
@@ -1094,6 +1098,8 @@ listen:
tls:
cert: ""
key: ""
cors:
allowedOrigins: []
```
### Log

View File

@@ -44,6 +44,9 @@ listen:
address: "0.0.0.0"
port: 8080
prefix: /
cors:
allowedOrigins:
- https://example.com
log:
config: false
level: info

View File

@@ -132,6 +132,8 @@ listen:
key: ""
port: 80
prefix: /
cors:
allowedOrigins: []
log:
level: info
format: text

View File

@@ -182,6 +182,9 @@ type configSchema struct {
}
Port int
Prefix string
Cors struct {
AllowedOrigins []string `yaml:"allowedOrigins" koanf:"allowedOrigins"`
}
}
Log struct {
Level string