diff --git a/web/router.go b/web/router.go index 57edf5a..4a23a33 100644 --- a/web/router.go +++ b/web/router.go @@ -147,9 +147,10 @@ func (s *HttpRouter) setupStatusRoutes(reporter status.Reporter, l log.Logger) { } type endpoint struct { - handler http.HandlerFunc - method string - path string + handler http.HandlerFunc + method string + path string + sdkKeyHeaderBased bool } func (s *HttpRouter) setupAPIRoutes(conf *config.ApiConfig, sdkRegistrar sdk.Registrar, l log.Logger) { @@ -159,10 +160,10 @@ func (s *HttpRouter) setupAPIRoutes(conf *config.ApiConfig, sdkRegistrar sdk.Reg {path: "/api/{sdkId}/eval-all", handler: mware.GZip(s.apiServer.EvalAll), method: http.MethodPost}, {path: "/api/{sdkId}/keys", handler: mware.GZip(s.apiServer.Keys), method: http.MethodGet}, {path: "/api/{sdkId}/refresh", handler: http.HandlerFunc(s.apiServer.Refresh), method: http.MethodPost}, - {path: "/api/eval", handler: mware.GZip(s.apiServer.Eval), method: http.MethodPost}, - {path: "/api/eval-all", handler: mware.GZip(s.apiServer.EvalAll), method: http.MethodPost}, - {path: "/api/keys", handler: mware.GZip(s.apiServer.Keys), method: http.MethodGet}, - {path: "/api/refresh", handler: http.HandlerFunc(s.apiServer.Refresh), method: http.MethodPost}, + {path: "/api/eval", handler: mware.GZip(s.apiServer.Eval), method: http.MethodPost, sdkKeyHeaderBased: true}, + {path: "/api/eval-all", handler: mware.GZip(s.apiServer.EvalAll), method: http.MethodPost, sdkKeyHeaderBased: true}, + {path: "/api/keys", handler: mware.GZip(s.apiServer.Keys), method: http.MethodGet, sdkKeyHeaderBased: true}, + {path: "/api/refresh", handler: http.HandlerFunc(s.apiServer.Refresh), method: http.MethodPost, sdkKeyHeaderBased: true}, {path: "/api/icanhascoffee", handler: http.HandlerFunc(s.apiServer.ICanHasCoffee), method: http.MethodGet}, } for _, endpoint := range endpoints { @@ -174,8 +175,12 @@ func (s *HttpRouter) setupAPIRoutes(conf *config.ApiConfig, sdkRegistrar sdk.Reg endpoint.handler = mware.ExtraHeaders(conf.Headers, endpoint.handler) } if conf.CORS.Enabled { + allowedHeaders := utils.KeysOfMap(conf.AuthHeaders) + if endpoint.sdkKeyHeaderBased { + allowedHeaders = append(allowedHeaders, api.SdkKeyHeader) + } endpoint.handler = mware.CORS([]string{endpoint.method, http.MethodOptions}, conf.CORS.AllowedOrigins, - utils.KeysOfMap(conf.Headers), utils.KeysOfMap(conf.AuthHeaders), &conf.CORS.AllowedOriginsRegex, endpoint.handler) + utils.KeysOfMap(conf.Headers), allowedHeaders, &conf.CORS.AllowedOriginsRegex, endpoint.handler) } if l.Level() == log.Debug { endpoint.handler = mware.DebugLog(l, endpoint.handler) @@ -201,7 +206,7 @@ func (s *HttpRouter) setupOFREPRoutes(conf *config.OFREPConfig, sdkRegistrar sdk endpoint.handler = mware.ExtraHeaders(conf.Headers, endpoint.handler) } if conf.CORS.Enabled { - allowedHeaders := append(utils.KeysOfMap(conf.AuthHeaders), ofrep.SdkIdHeader) + allowedHeaders := append(utils.KeysOfMap(conf.AuthHeaders), ofrep.SdkIdHeader, api.SdkKeyHeader) endpoint.handler = mware.CORS([]string{endpoint.method, http.MethodOptions}, conf.CORS.AllowedOrigins, utils.KeysOfMap(conf.Headers), allowedHeaders, &conf.CORS.AllowedOriginsRegex, endpoint.handler) } diff --git a/web/router_api_test.go b/web/router_api_test.go index 2a5fda5..11cfd94 100644 --- a/web/router_api_test.go +++ b/web/router_api_test.go @@ -84,6 +84,19 @@ func TestAPI_Eval(t *testing.T) { assert.Equal(t, "Content-Length,ETag,Date,Content-Encoding,h1", resp.Header.Get("Access-Control-Expose-Headers")) assert.Equal(t, "v1", resp.Header.Get("h1")) }) + t.Run("options cors sdk key", func(t *testing.T) { + req, _ := http.NewRequest(http.MethodOptions, fmt.Sprintf("%s/api/eval", srv.URL), http.NoBody) + resp, _ := http.DefaultClient.Do(req) + assert.Equal(t, http.StatusNoContent, resp.StatusCode) + + assert.Equal(t, "POST,OPTIONS", resp.Header.Get("Access-Control-Allow-Methods")) + assert.Equal(t, "false", resp.Header.Get("Access-Control-Allow-Credentials")) + assert.Equal(t, "Cache-Control,Content-Type,Content-Length,Accept-Encoding,If-None-Match,X-AUTH,"+api.SdkKeyHeader, resp.Header.Get("Access-Control-Allow-Headers")) + assert.Equal(t, "600", resp.Header.Get("Access-Control-Max-Age")) + assert.Equal(t, "*", resp.Header.Get("Access-Control-Allow-Origin")) + assert.Equal(t, "Content-Length,ETag,Date,Content-Encoding,h1", resp.Header.Get("Access-Control-Expose-Headers")) + assert.Equal(t, "v1", resp.Header.Get("h1")) + }) t.Run("get not allowed", func(t *testing.T) { req, _ := http.NewRequest(http.MethodGet, path, http.NoBody) resp, _ := http.DefaultClient.Do(req) diff --git a/web/router_ofrep_test.go b/web/router_ofrep_test.go index f2ae9cd..bbe6699 100644 --- a/web/router_ofrep_test.go +++ b/web/router_ofrep_test.go @@ -127,7 +127,7 @@ func TestOFREP_Eval(t *testing.T) { assert.Equal(t, "POST,OPTIONS", resp.Header.Get("Access-Control-Allow-Methods")) assert.Equal(t, "false", resp.Header.Get("Access-Control-Allow-Credentials")) - assert.Equal(t, "Cache-Control,Content-Type,Content-Length,Accept-Encoding,If-None-Match,X-AUTH,"+ofrep.SdkIdHeader, resp.Header.Get("Access-Control-Allow-Headers")) + assert.Equal(t, "Cache-Control,Content-Type,Content-Length,Accept-Encoding,If-None-Match,X-AUTH,"+ofrep.SdkIdHeader+","+api.SdkKeyHeader, resp.Header.Get("Access-Control-Allow-Headers")) assert.Equal(t, "600", resp.Header.Get("Access-Control-Max-Age")) assert.Equal(t, "*", resp.Header.Get("Access-Control-Allow-Origin")) assert.Equal(t, "Content-Length,ETag,Date,Content-Encoding,h1", resp.Header.Get("Access-Control-Expose-Headers")) @@ -252,7 +252,7 @@ func TestOFREP_EvalAll(t *testing.T) { assert.Equal(t, "POST,OPTIONS", resp.Header.Get("Access-Control-Allow-Methods")) assert.Equal(t, "false", resp.Header.Get("Access-Control-Allow-Credentials")) - assert.Equal(t, "Cache-Control,Content-Type,Content-Length,Accept-Encoding,If-None-Match,X-AUTH,"+ofrep.SdkIdHeader, resp.Header.Get("Access-Control-Allow-Headers")) + assert.Equal(t, "Cache-Control,Content-Type,Content-Length,Accept-Encoding,If-None-Match,X-AUTH,"+ofrep.SdkIdHeader+","+api.SdkKeyHeader, resp.Header.Get("Access-Control-Allow-Headers")) assert.Equal(t, "600", resp.Header.Get("Access-Control-Max-Age")) assert.Equal(t, "*", resp.Header.Get("Access-Control-Allow-Origin")) assert.Equal(t, "Content-Length,ETag,Date,Content-Encoding,h1", resp.Header.Get("Access-Control-Expose-Headers"))