From 43ac0cdb9c4eea9d3c5eceb2c11b9e5b98b87b00 Mon Sep 17 00:00:00 2001 From: kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com> Date: Mon, 30 May 2022 13:41:24 +0100 Subject: [chore] Global server configuration overhaul (#575) * move config flag names and usage to config package, rewrite config package to use global Configuration{} struct Signed-off-by: kim * improved code comment Signed-off-by: kim * linter Signed-off-by: kim * fix unmarshaling Signed-off-by: kim * remove kim's custom go compiler changes Signed-off-by: kim * generate setter and flag-name functions, implement these in codebase Signed-off-by: kim * update deps Signed-off-by: kim * small change Signed-off-by: kim * appease the linter... Signed-off-by: kim * move configuration into ConfigState structure, ensure reloading to/from viper settings to keep in sync Signed-off-by: kim * lint Signed-off-by: kim * update code comments Signed-off-by: kim * fix merge issue Signed-off-by: kim * fix merge issue Signed-off-by: kim * improved version string (removes time + go version) Signed-off-by: kim * fix version string build to pass test script + consolidate logic in func Signed-off-by: kim * add license text, update config.Defaults comment Signed-off-by: kim * add license text to generated config helpers file Signed-off-by: kim * defer unlock on config.Set___(), to ensure unlocked on panic Signed-off-by: kim * make it more obvious which cmd flags are being attached Signed-off-by: kim --- internal/router/router.go | 35 ++++++++++++++--------------------- internal/router/session.go | 15 +++++++-------- internal/router/session_test.go | 27 +++++++++++++-------------- internal/router/template.go | 5 ++--- 4 files changed, 36 insertions(+), 46 deletions(-) (limited to 'internal/router') diff --git a/internal/router/router.go b/internal/router/router.go index 939624cb7..ee7024cd1 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -27,7 +27,6 @@ import ( "codeberg.org/gruf/go-debug" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "github.com/spf13/viper" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" "golang.org/x/crypto/acme/autocert" @@ -70,16 +69,12 @@ func (r *router) AttachStaticFS(relativePath string, fs http.FileSystem) { // Start starts the router nicely. It will serve two handlers if letsencrypt is enabled, and only the web/API handler if letsencrypt is not enabled. func (r *router) Start() { - var ( - keys = config.Keys + // listen is the server start function, by + // default pointing to regular HTTP listener, + // but updated to TLS if LetsEncrypt is enabled. + listen := r.srv.ListenAndServe - // listen is the server start function, by - // default pointing to regular HTTP listener, - // but updated to TLS if LetsEncrypt is enabled. - listen = r.srv.ListenAndServe - ) - - if viper.GetBool(keys.LetsEncryptEnabled) { + if config.GetLetsEncryptEnabled() { // LetsEncrypt support is enabled // Prepare an HTTPS-redirect handler for LetsEncrypt fallback @@ -97,8 +92,8 @@ func (r *router) Start() { srv := (*r.srv) //nolint srv.Handler = r.certManager.HTTPHandler(redirect) srv.Addr = fmt.Sprintf("%s:%d", - viper.GetString(keys.BindAddress), - viper.GetInt(keys.LetsEncryptPort), + config.GetBindAddress(), + config.GetLetsEncryptPort(), ) // Start the LetsEncrypt autocert manager HTTP server. @@ -144,8 +139,6 @@ func (r *router) Stop(ctx context.Context) error { // The given DB is only used in the New function for parsing config values, and is not otherwise // pinned to the router. func New(ctx context.Context, db db.DB) (Router, error) { - keys := config.Keys - gin.SetMode(gin.ReleaseMode) // create the actual engine here -- this is the core request routing handler for gts @@ -158,7 +151,7 @@ func New(ctx context.Context, db db.DB) (Router, error) { engine.MaxMultipartMemory = 8 << 20 // set up IP forwarding via x-forward-* headers. - trustedProxies := viper.GetStringSlice(keys.TrustedProxies) + trustedProxies := config.GetTrustedProxies() if err := engine.SetTrustedProxies(trustedProxies); err != nil { return nil, err } @@ -187,8 +180,8 @@ func New(ctx context.Context, db db.DB) (Router, error) { } // create the http server here, passing the gin engine as handler - bindAddress := viper.GetString(keys.BindAddress) - port := viper.GetInt(keys.Port) + bindAddress := config.GetBindAddress() + port := config.GetPort() listen := fmt.Sprintf("%s:%d", bindAddress, port) s := &http.Server{ Addr: listen, @@ -201,14 +194,14 @@ func New(ctx context.Context, db db.DB) (Router, error) { // We need to spawn the underlying server slightly differently depending on whether lets encrypt is enabled or not. // In either case, the gin engine will still be used for routing requests. - leEnabled := viper.GetBool(keys.LetsEncryptEnabled) + leEnabled := config.GetLetsEncryptEnabled() var m *autocert.Manager if leEnabled { // le IS enabled, so roll up an autocert manager for handling letsencrypt requests - host := viper.GetString(keys.Host) - leCertDir := viper.GetString(keys.LetsEncryptCertDir) - leEmailAddress := viper.GetString(keys.LetsEncryptEmailAddress) + host := config.GetHost() + leCertDir := config.GetLetsEncryptCertDir() + leEmailAddress := config.GetLetsEncryptEmailAddress() m = &autocert.Manager{ Prompt: autocert.AcceptTOS, HostPolicy: autocert.HostWhitelist(host), diff --git a/internal/router/session.go b/internal/router/session.go index a2cbff7d1..f94b0a22a 100644 --- a/internal/router/session.go +++ b/internal/router/session.go @@ -28,7 +28,6 @@ import ( "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/memstore" "github.com/gin-gonic/gin" - "github.com/spf13/viper" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" "golang.org/x/net/idna" @@ -38,19 +37,19 @@ import ( func SessionOptions() sessions.Options { return sessions.Options{ Path: "/", - Domain: viper.GetString(config.Keys.Host), - MaxAge: 120, // 2 minutes - Secure: viper.GetString(config.Keys.Protocol) == "https", // only use cookie over https - HttpOnly: true, // exclude javascript from inspecting cookie - SameSite: http.SameSiteStrictMode, // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1 + Domain: config.GetHost(), + MaxAge: 120, // 2 minutes + Secure: config.GetProtocol() == "https", // only use cookie over https + HttpOnly: true, // exclude javascript from inspecting cookie + SameSite: http.SameSiteStrictMode, // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1 } } // SessionName is a utility function that derives an appropriate session name from the hostname. func SessionName() (string, error) { // parse the protocol + host - protocol := viper.GetString(config.Keys.Protocol) - host := viper.GetString(config.Keys.Host) + protocol := config.GetProtocol() + host := config.GetHost() u, err := url.Parse(fmt.Sprintf("%s://%s", protocol, host)) if err != nil { return "", err diff --git a/internal/router/session_test.go b/internal/router/session_test.go index d36da9596..5f4777a48 100644 --- a/internal/router/session_test.go +++ b/internal/router/session_test.go @@ -21,7 +21,6 @@ package router_test import ( "testing" - "github.com/spf13/viper" "github.com/stretchr/testify/suite" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/router" @@ -37,8 +36,8 @@ func (suite *SessionTestSuite) SetupTest() { } func (suite *SessionTestSuite) TestDeriveSessionNameLocalhostWithPort() { - viper.Set(config.Keys.Protocol, "http") - viper.Set(config.Keys.Host, "localhost:8080") + config.SetProtocol("http") + config.SetHost("localhost:8080") sessionName, err := router.SessionName() suite.NoError(err) @@ -46,8 +45,8 @@ func (suite *SessionTestSuite) TestDeriveSessionNameLocalhostWithPort() { } func (suite *SessionTestSuite) TestDeriveSessionNameLocalhost() { - viper.Set(config.Keys.Protocol, "http") - viper.Set(config.Keys.Host, "localhost") + config.SetProtocol("http") + config.SetHost("localhost") sessionName, err := router.SessionName() suite.NoError(err) @@ -55,8 +54,8 @@ func (suite *SessionTestSuite) TestDeriveSessionNameLocalhost() { } func (suite *SessionTestSuite) TestDeriveSessionNoProtocol() { - viper.Set(config.Keys.Protocol, "") - viper.Set(config.Keys.Host, "localhost") + config.SetProtocol("") + config.SetHost("localhost") sessionName, err := router.SessionName() suite.EqualError(err, "parse \"://localhost\": missing protocol scheme") @@ -64,9 +63,9 @@ func (suite *SessionTestSuite) TestDeriveSessionNoProtocol() { } func (suite *SessionTestSuite) TestDeriveSessionNoHost() { - viper.Set(config.Keys.Protocol, "https") - viper.Set(config.Keys.Host, "") - viper.Set(config.Keys.Port, 0) + config.SetProtocol("https") + config.SetHost("") + config.SetPort(0) sessionName, err := router.SessionName() suite.EqualError(err, "could not derive hostname without port from https://") @@ -74,8 +73,8 @@ func (suite *SessionTestSuite) TestDeriveSessionNoHost() { } func (suite *SessionTestSuite) TestDeriveSessionOK() { - viper.Set(config.Keys.Protocol, "https") - viper.Set(config.Keys.Host, "example.org") + config.SetProtocol("https") + config.SetHost("example.org") sessionName, err := router.SessionName() suite.NoError(err) @@ -83,8 +82,8 @@ func (suite *SessionTestSuite) TestDeriveSessionOK() { } func (suite *SessionTestSuite) TestDeriveSessionIDNOK() { - viper.Set(config.Keys.Protocol, "https") - viper.Set(config.Keys.Host, "fóid.org") + config.SetProtocol("https") + config.SetHost("fóid.org") sessionName, err := router.SessionName() suite.NoError(err) diff --git a/internal/router/template.go b/internal/router/template.go index 315f44a56..c033c8f07 100644 --- a/internal/router/template.go +++ b/internal/router/template.go @@ -26,16 +26,15 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/spf13/viper" "github.com/superseriousbusiness/gotosocial/internal/api/model" "github.com/superseriousbusiness/gotosocial/internal/config" ) // LoadTemplates loads html templates for use by the given engine func loadTemplates(engine *gin.Engine) error { - templateBaseDir := viper.GetString(config.Keys.WebTemplateBaseDir) + templateBaseDir := config.GetWebTemplateBaseDir() if templateBaseDir == "" { - return fmt.Errorf("%s cannot be empty and must be a relative or absolute path", config.Keys.WebTemplateBaseDir) + return fmt.Errorf("%s cannot be empty and must be a relative or absolute path", config.WebTemplateBaseDirFlag()) } templateBaseDir, err := filepath.Abs(templateBaseDir) -- cgit v1.2.3