diff --git a/accounts/pkg/command/server.go b/accounts/pkg/command/server.go
index a64c23080e..0378c39cd9 100644
--- a/accounts/pkg/command/server.go
+++ b/accounts/pkg/command/server.go
@@ -35,6 +35,15 @@ func Server(cfg *config.Config) *cli.Command {
if !cfg.Supervised {
return ParseConfig(ctx, cfg)
}
+ if origins := ctx.StringSlice("cors-allowed-origins"); len(origins) != 0 {
+ cfg.HTTP.CORS.AllowedOrigins = origins
+ }
+ if methods := ctx.StringSlice("cors-allowed-methods"); len(methods) != 0 {
+ cfg.HTTP.CORS.AllowedMethods = methods
+ }
+ if headers := ctx.StringSlice("cors-allowed-headers"); len(headers) != 0 {
+ cfg.HTTP.CORS.AllowedOrigins = headers
+ }
logger.Debug().Str("service", "accounts").Msg("ignoring config file parsing when running supervised")
return nil
},
diff --git a/accounts/pkg/config/config.go b/accounts/pkg/config/config.go
index 0afc8e094c..a98554f0e2 100644
--- a/accounts/pkg/config/config.go
+++ b/accounts/pkg/config/config.go
@@ -26,12 +26,21 @@ type LDAPSchema struct {
Groups string
}
+// CORS defines the available cors configuration.
+type CORS struct {
+ AllowedOrigins []string
+ AllowedMethods []string
+ AllowedHeaders []string
+ AllowCredentials bool
+}
+
// HTTP defines the available http configuration.
type HTTP struct {
Addr string
Namespace string
Root string
CacheTTL int
+ CORS CORS
}
// GRPC defines the available grpc configuration.
diff --git a/accounts/pkg/flagset/flagset.go b/accounts/pkg/flagset/flagset.go
index 4c6224a975..fc29ca6d1c 100644
--- a/accounts/pkg/flagset/flagset.go
+++ b/accounts/pkg/flagset/flagset.go
@@ -109,6 +109,30 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
EnvVars: []string{"ACCOUNTS_CACHE_TTL"},
Destination: &cfg.HTTP.CacheTTL,
},
+ &cli.StringSliceFlag{
+ Name: "cors-allowed-origins",
+ Value: cli.NewStringSlice("*"),
+ Usage: "Set the allowed CORS origins",
+ EnvVars: []string{"ACCOUNTS_CORS_ALLOW_ORIGINS", "OCIS_CORS_ALLOW_ORIGINS"},
+ },
+ &cli.StringSliceFlag{
+ Name: "cors-allowed-methods",
+ Value: cli.NewStringSlice("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"),
+ Usage: "Set the allowed CORS origins",
+ EnvVars: []string{"ACCOUNTS_CORS_ALLOW_METHODS", "OCIS_CORS_ALLOW_METHODS"},
+ },
+ &cli.StringSliceFlag{
+ Name: "cors-allowed-headers",
+ Value: cli.NewStringSlice("Authorization", "Origin", "Content-Type", "Accept", "X-Requested-With"),
+ Usage: "Set the allowed CORS origins",
+ EnvVars: []string{"ACCOUNTS_CORS_ALLOW_HEADERS", "OCIS_CORS_ALLOW_HEADERS"},
+ },
+ &cli.BoolFlag{
+ Name: "cors-allow-credentials",
+ Value: flags.OverrideDefaultBool(cfg.HTTP.CORS.AllowCredentials, true),
+ Usage: "Allow credentials for CORS",
+ EnvVars: []string{"ACCOUNTS_CORS_ALLOW_CREDENTIALS", "OCIS_CORS_ALLOW_CREDENTIALS"},
+ },
&cli.StringFlag{
Name: "grpc-namespace",
Value: flags.OverrideDefaultString(cfg.GRPC.Namespace, "com.owncloud.api"),
diff --git a/accounts/pkg/server/http/server.go b/accounts/pkg/server/http/server.go
index dc2f5e8cf1..21487a2d61 100644
--- a/accounts/pkg/server/http/server.go
+++ b/accounts/pkg/server/http/server.go
@@ -6,6 +6,7 @@ import (
"github.com/owncloud/ocis/accounts/pkg/assets"
"github.com/owncloud/ocis/accounts/pkg/proto/v0"
"github.com/owncloud/ocis/ocis-pkg/account"
+ "github.com/owncloud/ocis/ocis-pkg/cors"
"github.com/owncloud/ocis/ocis-pkg/middleware"
"github.com/owncloud/ocis/ocis-pkg/service/http"
"github.com/owncloud/ocis/ocis-pkg/version"
@@ -33,7 +34,13 @@ func Server(opts ...Option) http.Service {
mux.Use(chimiddleware.RequestID)
mux.Use(middleware.TraceContext)
mux.Use(middleware.NoCache)
- mux.Use(middleware.Cors)
+ mux.Use(middleware.Cors(
+ cors.Logger(options.Logger),
+ cors.AllowedOrigins(options.Config.HTTP.CORS.AllowedOrigins),
+ cors.AllowedMethods(options.Config.HTTP.CORS.AllowedMethods),
+ cors.AllowedHeaders(options.Config.HTTP.CORS.AllowedHeaders),
+ cors.AllowCredentials(options.Config.HTTP.CORS.AllowCredentials),
+ ))
mux.Use(middleware.Secure)
mux.Use(middleware.ExtractAccountUUID(
account.Logger(options.Logger),
diff --git a/changelog/unreleased/http-header.md b/changelog/unreleased/http-header.md
new file mode 100644
index 0000000000..83fb60debe
--- /dev/null
+++ b/changelog/unreleased/http-header.md
@@ -0,0 +1,6 @@
+Enhancement: Review and correct http header
+
+Reviewed and corrected the necessary http headers.
+Made CORS configurable.
+
+https://github.com/owncloud/ocis/pull/2666
diff --git a/go.mod b/go.mod
index 010383f3cb..6688a5d3d8 100644
--- a/go.mod
+++ b/go.mod
@@ -23,6 +23,7 @@ require (
github.com/disintegration/imaging v1.6.2
github.com/glauth/glauth/v2 v2.0.0-20211021011345-ef3151c28733
github.com/go-chi/chi/v5 v5.0.4
+ github.com/go-chi/cors v1.2.0
github.com/go-chi/render v1.0.1
github.com/go-logr/logr v0.4.0
github.com/go-ozzo/ozzo-validation/v4 v4.3.0
@@ -84,7 +85,6 @@ require (
github.com/RoaringBitmap/roaring v0.9.4 // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
- github.com/asim/go-micro/v3 v3.7.0 // indirect
github.com/aws/aws-sdk-go v1.41.6 // indirect
github.com/beevik/etree v1.1.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
diff --git a/go.sum b/go.sum
index 2371db35da..bec946fae0 100644
--- a/go.sum
+++ b/go.sum
@@ -164,9 +164,8 @@ github.com/asim/go-micro/plugins/wrapper/monitoring/prometheus/v3 v3.0.0-2021101
github.com/asim/go-micro/plugins/wrapper/trace/opencensus/v3 v3.0.0-20211012122208-f63e46a7d1e9 h1:EAewDo27l8kidfQQo3yTrJ64pFy8sCOaJ6I5ZRHKFOg=
github.com/asim/go-micro/plugins/wrapper/trace/opencensus/v3 v3.0.0-20211012122208-f63e46a7d1e9/go.mod h1:5mB3LtO4EUAWFz5PZaRxnC48OCSI005ySscXtRu37+M=
github.com/asim/go-micro/v3 v3.5.1/go.mod h1:OJ5DnUQmoEVQTNbKRstR7/krtYJI+QaBe/XeN5MZkqE=
+github.com/asim/go-micro/v3 v3.5.2-0.20210629124054-4929a7c16ecc h1:ikUleoYb/ZJDhh0sckGHxSplZfJILvfBzGM9KnGxp6o=
github.com/asim/go-micro/v3 v3.5.2-0.20210629124054-4929a7c16ecc/go.mod h1:cNGIIYQcp0qy+taNYmrBdaIHeqMWHV5ZH/FfQzfOyE8=
-github.com/asim/go-micro/v3 v3.7.0 h1:iPpKAkcftVyg8zcXWV4dTyrDkpJ5wst6g3ad7gEczqQ=
-github.com/asim/go-micro/v3 v3.7.0/go.mod h1:GP48EHjG/7dw16ZL+lflu2S2SXSPKEVE2mPc45URs1E=
github.com/aws/aws-sdk-go v1.20.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.23.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
@@ -393,6 +392,8 @@ github.com/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAU
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-chi/chi/v5 v5.0.4 h1:5e494iHzsYBiyXQAHHuI4tyJS9M3V84OuX3ufIIGHFo=
github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-chi/cors v1.2.0 h1:tV1g1XENQ8ku4Bq3K9ub2AtgG+p16SmzeMSGTwrOKdE=
+github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/render v1.0.1 h1:4/5tis2cKaNdnv9zFLfXzcquC9HbeZgCnxGnKrltBS8=
github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
@@ -816,6 +817,7 @@ github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 h1:Z/i1e+gTZrmcGeZy
github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103/go.mod h1:o9YPB5aGP8ob35Vy6+vyq3P3bWe7NQWzf+JLiXCiMaE=
github.com/mennanov/fieldmask-utils v0.5.0 h1:8em4akN0NM3hmmrg8VbvOPfdS4SSBdbFd53m9VtfOg0=
github.com/mennanov/fieldmask-utils v0.5.0/go.mod h1:lah2lHczE2ff+7SqnNKpB+YzaO7M3h5iNO4LgPTJheM=
+github.com/micro/cli/v2 v2.1.2 h1:43J1lChg/rZCC1rvdqZNFSQDrGT7qfMrtp6/ztpIkEM=
github.com/micro/cli/v2 v2.1.2/go.mod h1:EguNh6DAoWKm9nmk+k/Rg0H3lQnDxqzu5x5srOtGtYg=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
diff --git a/graph-explorer/pkg/server/http/server.go b/graph-explorer/pkg/server/http/server.go
index f8025d93a8..33c85458e1 100644
--- a/graph-explorer/pkg/server/http/server.go
+++ b/graph-explorer/pkg/server/http/server.go
@@ -30,7 +30,6 @@ func Server(opts ...Option) (http.Service, error) {
chimiddleware.RealIP,
chimiddleware.RequestID,
middleware.NoCache,
- middleware.Cors,
middleware.Secure,
middleware.Version(
"graph-explorer",
diff --git a/idp/pkg/server/http/server.go b/idp/pkg/server/http/server.go
index dae7b49be1..cab4554b3d 100644
--- a/idp/pkg/server/http/server.go
+++ b/idp/pkg/server/http/server.go
@@ -57,7 +57,6 @@ func Server(opts ...Option) (http.Service, error) {
chimiddleware.RequestID,
middleware.TraceContext,
middleware.NoCache,
- middleware.Cors,
middleware.Secure,
middleware.Version(
options.Config.Service.Name,
diff --git a/ocis-pkg/cors/option.go b/ocis-pkg/cors/option.go
new file mode 100644
index 0000000000..e53454191d
--- /dev/null
+++ b/ocis-pkg/cors/option.go
@@ -0,0 +1,68 @@
+package cors
+
+import (
+ "github.com/owncloud/ocis/ocis-pkg/log"
+)
+
+// Option defines a single option function.
+type Option func(o *Options)
+
+// Options defines the available options for this package.
+type Options struct {
+ // Logger to use for logging, must be set
+ Logger log.Logger
+ // AllowedOrigins represents the allowed CORS origins
+ AllowedOrigins []string
+ // AllowedMethods represents the allowed CORS methods
+ AllowedMethods []string
+ // AllowedHeaders represents the allowed CORS headers
+ AllowedHeaders []string
+ // AllowCredentials represents the AllowCredentials CORS option
+ AllowCredentials bool
+}
+
+// newAccountOptions initializes the available default options.
+func NewOptions(opts ...Option) Options {
+ opt := Options{}
+
+ for _, o := range opts {
+ o(&opt)
+ }
+
+ return opt
+}
+
+// Logger provides a function to set the logger option.
+func Logger(l log.Logger) Option {
+ return func(o *Options) {
+ o.Logger = l
+ }
+}
+
+// AllowedOrigins provides a function to set the AllowedOrigins option.
+func AllowedOrigins(origins []string) Option {
+ return func(o *Options) {
+ o.AllowedOrigins = origins
+ }
+}
+
+// AllowedMethods provides a function to set the AllowedMethods option.
+func AllowedMethods(methods []string) Option {
+ return func(o *Options) {
+ o.AllowedMethods = methods
+ }
+}
+
+// AllowedHeaders provides a function to set the AllowedHeaders option.
+func AllowedHeaders(headers []string) Option {
+ return func(o *Options) {
+ o.AllowedHeaders = headers
+ }
+}
+
+// AlloweCredentials provides a function to set the AllowCredentials option.
+func AllowCredentials(allow bool) Option {
+ return func(o *Options) {
+ o.AllowCredentials = allow
+ }
+}
diff --git a/ocis-pkg/middleware/header.go b/ocis-pkg/middleware/header.go
index 0087d84f5d..9c94e6a2e0 100644
--- a/ocis-pkg/middleware/header.go
+++ b/ocis-pkg/middleware/header.go
@@ -2,7 +2,12 @@ package middleware
import (
"net/http"
+ "strings"
"time"
+
+ "github.com/owncloud/ocis/ocis-pkg/cors"
+
+ chicors "github.com/go-chi/cors"
)
// NoCache writes required cache headers to all requests.
@@ -17,30 +22,35 @@ func NoCache(next http.Handler) http.Handler {
}
// Cors writes required cors headers to all requests.
-func Cors(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Method != "OPTIONS" {
- next.ServeHTTP(w, r)
- } else {
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
- w.Header().Set("Access-Control-Allow-Headers", "authorization, origin, content-type, accept, x-requested-with")
- w.Header().Set("Allow", "HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS")
-
- w.WriteHeader(http.StatusOK)
- }
+func Cors(opts ...cors.Option) func(http.Handler) http.Handler {
+ options := cors.NewOptions(opts...)
+ logger := options.Logger
+ logger.Debug().
+ Str("allowed_origins", strings.Join(options.AllowedOrigins, ", ")).
+ Str("allowed_methods", strings.Join(options.AllowedMethods, ", ")).
+ Str("allowed_headers", strings.Join(options.AllowedHeaders, ", ")).
+ Bool("allow_credentials", options.AllowCredentials).
+ Msg("setup cors middleware")
+ return chicors.Handler(chicors.Options{
+ AllowedOrigins: options.AllowedOrigins,
+ AllowedMethods: options.AllowedMethods,
+ AllowedHeaders: options.AllowedHeaders,
+ AllowCredentials: options.AllowCredentials,
})
}
// Secure writes required access headers to all requests.
func Secure(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Access-Control-Allow-Origin", "*")
+ // Indicates whether the browser is allowed to render this page in a ,