446 lines
11 KiB
Go
446 lines
11 KiB
Go
// Copyright 2023 wanderer <a_mirre at utb dot cz>
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
package settings
|
|
|
|
import (
|
|
"os"
|
|
"time"
|
|
|
|
"git.dotya.ml/mirre-mt/pcmt/config"
|
|
"git.dotya.ml/mirre-mt/pcmt/slogging"
|
|
"golang.org/x/exp/slog"
|
|
)
|
|
|
|
type Settings struct {
|
|
host string
|
|
port int
|
|
appPath string
|
|
httpDomain string
|
|
httpSecure bool
|
|
httpGzipEnabled bool
|
|
httpGzipLevel int
|
|
httpRateLimitEnabled bool
|
|
httpRateLimit int
|
|
isLive bool
|
|
isDevel bool
|
|
initCreateAdmin bool
|
|
initAdminPassword string
|
|
loggerJSON bool
|
|
sessionCookieName string
|
|
sessionCookieAuthSecret string
|
|
sessionCookieEncrSecret string
|
|
sessionAuthIsHex bool
|
|
sessionEncrIsHex bool
|
|
sessionMaxAge int
|
|
assetsPath string
|
|
templatesPath string
|
|
version string
|
|
dbConnstring string
|
|
dbType string
|
|
dbIsSetUp bool
|
|
RegistrationAllowed bool
|
|
}
|
|
|
|
const (
|
|
appName = "pcmt"
|
|
defaultPort = 3000
|
|
defaultSessionMaxAge = 86400 // seconds.
|
|
defaultHTTPDomain = "localhost"
|
|
defaultServerWriteTimeout = 30 * time.Second
|
|
defaultServerReadHeaderTimeout = 30 * time.Second
|
|
)
|
|
|
|
// cleantgt is a list of ENV vars pertaining to pcmt.
|
|
var cleantgt = []string{
|
|
"PCMT_LIVE",
|
|
"PCMT_DEVEL",
|
|
"PCMT_CONNSTRING",
|
|
"PCMT_DBTYPE",
|
|
"PCMT_SESSION_AUTH_SECRET",
|
|
"PCMT_SESSION_ENCR_SECRET",
|
|
"PCMT_INIT_ADMIN_PASSWORD",
|
|
}
|
|
|
|
// New returns a new instance of the settings struct.
|
|
func New() *Settings {
|
|
return &Settings{}
|
|
}
|
|
|
|
// DefaultServerWriteTimeout returns the server default write timeout.
|
|
func (s *Settings) DefaultServerWriteTimeout() time.Duration {
|
|
return defaultServerWriteTimeout
|
|
}
|
|
|
|
// DefaultServerReadHeaderTimeout returns the server default read header timeout.
|
|
func (s *Settings) DefaultServerReadHeaderTimeout() time.Duration {
|
|
return defaultServerReadHeaderTimeout
|
|
}
|
|
|
|
// Consolidate reconciles whatever values are set in config and via flags and
|
|
// sets it to one place that should be regarded as a single source of truth -
|
|
// the settings struct. Order of preference for values is (from higher to
|
|
// lower) as follows: flag -> Env var -> configuration file.
|
|
func (s *Settings) Consolidate(conf *config.Config, host *string, port *int, devel *bool, version string) {
|
|
log := *slogging.Logger() // have a local copy.
|
|
log.Logger = log.Logger.With(
|
|
slog.Group("pcmt extra", slog.String("module", "app/settings")),
|
|
)
|
|
|
|
log.Debug("starting to consolidate settings")
|
|
log.Debug("parsing config values")
|
|
|
|
if p := conf.Port; p > 0 && p < 65536 {
|
|
log.Warnf("port '%d', outside of bounds, setting a default of %d/tcp", p, defaultPort)
|
|
s.SetPort(defaultPort)
|
|
}
|
|
|
|
s.SetHost(conf.Host)
|
|
s.SetAppPath(conf.AppPath)
|
|
s.SetIsLive(conf.LiveMode)
|
|
s.SetIsDevel(conf.DevelMode)
|
|
s.SetLoggerIsJSON(conf.Logger.JSON)
|
|
s.SetSessionCookieName(conf.Session.CookieName)
|
|
s.SetSessionCookieAuthSecret(conf.Session.CookieAuthSecret)
|
|
s.SetSessionCookieEncrSecret(conf.Session.CookieEncrSecret)
|
|
|
|
authHex, encrHex := conf.SessionSecretsAreHex()
|
|
|
|
if authHex {
|
|
s.sessionAuthIsHex = true
|
|
}
|
|
|
|
if encrHex {
|
|
s.sessionEncrIsHex = true
|
|
}
|
|
|
|
if conf.HTTP.Gzip > 0 {
|
|
s.SetHTTPGzipEnabled(true)
|
|
s.SetHTTPGzipLevel(conf.HTTP.Gzip)
|
|
}
|
|
|
|
if conf.HTTP.RateLimit > 0 {
|
|
s.SetHTTPRateLimitEnabled(true)
|
|
s.SetHTTPRateLimit(conf.HTTP.RateLimit)
|
|
}
|
|
|
|
if conf.Init.CreateAdmin {
|
|
s.SetInitCreateAdmin(true)
|
|
s.SetInitAdminPassword(conf.Init.AdminPassword)
|
|
}
|
|
|
|
s.SetHTTPDomain(conf.HTTP.Domain)
|
|
s.SetHTTPSecure(conf.HTTP.Secure)
|
|
|
|
log.Debug("checking flag overrides")
|
|
|
|
overrideMsg := "overriding '%s' based on a flag: %+v"
|
|
|
|
if isFlagPassed("host") {
|
|
if h := *host; h != "unset" && h != conf.Host {
|
|
log.Debugf(overrideMsg, "host", h)
|
|
s.SetHost(h)
|
|
}
|
|
}
|
|
|
|
if isFlagPassed("port") {
|
|
if p := *port; p > 0 && p < 65536 {
|
|
if p != conf.Port {
|
|
log.Debugf(overrideMsg, "port", p)
|
|
s.SetPort(p)
|
|
}
|
|
} else {
|
|
log.Warnf("flag-supplied port '%d' outside of bounds, ignoring", p)
|
|
}
|
|
}
|
|
|
|
if isFlagPassed("devel") {
|
|
if d := *devel; d != conf.DevelMode {
|
|
log.Debugf(overrideMsg, "develMode", d)
|
|
s.SetIsDevel(d)
|
|
}
|
|
}
|
|
|
|
if conf.Registration.Allowed {
|
|
s.RegistrationAllowed = true
|
|
}
|
|
|
|
s.SetVersion(version)
|
|
}
|
|
|
|
// Host returns the host.
|
|
func (s *Settings) Host() string {
|
|
return s.host
|
|
}
|
|
|
|
// Port returns the port.
|
|
func (s *Settings) Port() int {
|
|
return s.port
|
|
}
|
|
|
|
// AppName returns the appName.
|
|
func (s *Settings) AppName() string {
|
|
return appName
|
|
}
|
|
|
|
// AppPath returns the appPath.
|
|
func (s *Settings) AppPath() string {
|
|
return s.appPath
|
|
}
|
|
|
|
// IsLive returns the value of isLive of the receiver.
|
|
func (s *Settings) IsLive() bool {
|
|
return s.isLive
|
|
}
|
|
|
|
// IsDevel returns the value of isDevel of the receiver.
|
|
func (s *Settings) IsDevel() bool {
|
|
return s.isDevel
|
|
}
|
|
|
|
// InitCreateAdmin returns the value of initCreateAdmin of the receiver.
|
|
func (s *Settings) InitCreateAdmin() bool {
|
|
return s.initCreateAdmin
|
|
}
|
|
|
|
// InitAdminPassword returns the value of initAdminPassword of the receiver.
|
|
func (s *Settings) InitAdminPassword() string {
|
|
return s.initAdminPassword
|
|
}
|
|
|
|
// LoggerIsJSON returns whether the logger should use the JSON handler.
|
|
func (s *Settings) LoggerIsJSON() bool {
|
|
return s.loggerJSON
|
|
}
|
|
|
|
// SessionCookieName returns the name of the session cookie.
|
|
func (s *Settings) SessionCookieName() string {
|
|
return s.sessionCookieName
|
|
}
|
|
|
|
// SessionCookieAuthSecret returns the session cookie authentication secret.
|
|
func (s *Settings) SessionCookieAuthSecret() string {
|
|
return s.sessionCookieAuthSecret
|
|
}
|
|
|
|
// SessionCookieEncrSecret returns the session cookie encryption secret.
|
|
func (s *Settings) SessionCookieEncrSecret() string {
|
|
return s.sessionCookieEncrSecret
|
|
}
|
|
|
|
// SessionAuthIsHex returns whether the session cookie authentication secret is hex.
|
|
func (s *Settings) SessionAuthIsHex() bool {
|
|
return s.sessionAuthIsHex
|
|
}
|
|
|
|
// SessionEncrIsHex returns whether the session cookie encryption secret is hex.
|
|
func (s *Settings) SessionEncrIsHex() bool {
|
|
return s.sessionEncrIsHex
|
|
}
|
|
|
|
// SessionMaxAge returns the session cookie MaxAge value.
|
|
func (s *Settings) SessionMaxAge() int {
|
|
return s.sessionMaxAge
|
|
}
|
|
|
|
// HTTPDomain returns the httpDomain.
|
|
func (s *Settings) HTTPDomain() string {
|
|
return s.httpDomain
|
|
}
|
|
|
|
// HTTPSecure returns the httpSecure.
|
|
func (s *Settings) HTTPSecure() bool {
|
|
return s.httpSecure
|
|
}
|
|
|
|
// HTTPGzipEnabled returns the httpGzipEnabled variable.
|
|
func (s *Settings) HTTPGzipEnabled() bool {
|
|
return s.httpGzipEnabled
|
|
}
|
|
|
|
// HTTPGzipLevel returns the httpGzipLevel.
|
|
func (s *Settings) HTTPGzipLevel() int {
|
|
return s.httpGzipLevel
|
|
}
|
|
|
|
// HTTPRateLimitEnabled returns the httpRateLimitEnabled variable.
|
|
func (s *Settings) HTTPRateLimitEnabled() bool {
|
|
return s.httpRateLimitEnabled
|
|
}
|
|
|
|
// HTTPRateLimit returns the httpRateLimit.
|
|
func (s *Settings) HTTPRateLimit() int {
|
|
return s.httpRateLimit
|
|
}
|
|
|
|
// AssetsPath returns the assetsPath.
|
|
func (s *Settings) AssetsPath() string {
|
|
return s.assetsPath
|
|
}
|
|
|
|
// TemplatesPath returns the templatesPath.
|
|
func (s *Settings) TemplatesPath() string {
|
|
return s.templatesPath
|
|
}
|
|
|
|
// Version returns the version.
|
|
func (s *Settings) Version() string {
|
|
return s.version
|
|
}
|
|
|
|
// DbIsSetUp returns the dbIsSetUp.
|
|
func (s *Settings) DbIsSetUp() bool {
|
|
return s.dbIsSetUp
|
|
}
|
|
|
|
// DbConnstring returns the dbConnString.
|
|
func (s *Settings) DbConnstring() string {
|
|
return s.dbConnstring
|
|
}
|
|
|
|
// DbType returns the dbType.
|
|
func (s *Settings) DbType() string {
|
|
return s.dbType
|
|
}
|
|
|
|
// SetHost sets the host.
|
|
func (s *Settings) SetHost(host string) {
|
|
s.host = host
|
|
}
|
|
|
|
// SetPort sets the port.
|
|
func (s *Settings) SetPort(port int) {
|
|
s.port = port
|
|
}
|
|
|
|
// SetAppPath sets the appPath.
|
|
func (s *Settings) SetAppPath(appPath string) {
|
|
s.appPath = appPath
|
|
}
|
|
|
|
// SetIsLive sets the value of isLive of the receiver.
|
|
func (s *Settings) SetIsLive(live bool) {
|
|
s.isLive = live
|
|
}
|
|
|
|
// SetIsDevel sets the value of isDevel of the receiver.
|
|
func (s *Settings) SetIsDevel(devel bool) {
|
|
s.isDevel = devel
|
|
}
|
|
|
|
// SetInitCreateAdmin sets the value of initCreateAdmin of the receiver.
|
|
func (s *Settings) SetInitCreateAdmin(create bool) {
|
|
s.initCreateAdmin = create
|
|
}
|
|
|
|
// SetInitAdminPassword sets the value of initAdminPassword of the receiver.
|
|
func (s *Settings) SetInitAdminPassword(password string) {
|
|
s.initAdminPassword = password
|
|
}
|
|
|
|
// SetLoggerIsJSON sets the setting value of loggerIsJSON.
|
|
func (s *Settings) SetLoggerIsJSON(isJSON bool) {
|
|
s.loggerJSON = isJSON
|
|
}
|
|
|
|
// SetSessionCookieName sets session cookie name.
|
|
func (s *Settings) SetSessionCookieName(sessionCookieName string) {
|
|
s.sessionCookieName = sessionCookieName
|
|
}
|
|
|
|
// SetSessionCookieAuthSecret sets the session cookie authentication secret.
|
|
func (s *Settings) SetSessionCookieAuthSecret(sessionCookieAuthSecret string) {
|
|
s.sessionCookieAuthSecret = sessionCookieAuthSecret
|
|
}
|
|
|
|
// SetSessionCookieEncrSecret sets the session cookie encryption secret.
|
|
func (s *Settings) SetSessionCookieEncrSecret(sessionCookieEncrSecret string) {
|
|
s.sessionCookieEncrSecret = sessionCookieEncrSecret
|
|
}
|
|
|
|
// SetSessionMaxAge sets sessionMaxAge.
|
|
func (s *Settings) SetSessionMaxAge(sessionMaxAge int) {
|
|
if sessionMaxAge < 1 {
|
|
s.sessionMaxAge = defaultSessionMaxAge
|
|
} else {
|
|
s.sessionMaxAge = sessionMaxAge
|
|
}
|
|
}
|
|
|
|
// SetHTTPDomain sets the httpDomain.
|
|
func (s *Settings) SetHTTPDomain(domain string) {
|
|
switch domain {
|
|
case "":
|
|
s.httpDomain = defaultHTTPDomain
|
|
default:
|
|
s.httpDomain = domain
|
|
}
|
|
}
|
|
|
|
// SetHTTPSecure sets the httpSecure.
|
|
func (s *Settings) SetHTTPSecure(secure bool) {
|
|
s.httpSecure = secure
|
|
}
|
|
|
|
// SetHTTPGzipEnabled sets the httpGzipEnabled variable.
|
|
func (s *Settings) SetHTTPGzipEnabled(enabled bool) {
|
|
s.httpGzipEnabled = enabled
|
|
}
|
|
|
|
// SetHTTPGzipLevel sets the httpGzipLevel.
|
|
func (s *Settings) SetHTTPGzipLevel(level int) {
|
|
s.httpGzipLevel = level
|
|
}
|
|
|
|
// SetHTTPRateLimitEnabled sets the httpRateLimitEnabled variable.
|
|
func (s *Settings) SetHTTPRateLimitEnabled(enabled bool) {
|
|
s.httpRateLimitEnabled = enabled
|
|
}
|
|
|
|
// SetHTTPRateLimit sets the httpRateLimit.
|
|
func (s *Settings) SetHTTPRateLimit(rateLimit int) {
|
|
s.httpRateLimit = rateLimit
|
|
}
|
|
|
|
// SetAssetsPath sets the assetsPath.
|
|
func (s *Settings) SetAssetsPath(assetsPath string) {
|
|
s.assetsPath = assetsPath
|
|
}
|
|
|
|
// SetTemplatesPath sets the templatesPath.
|
|
func (s *Settings) SetTemplatesPath(templatesPath string) {
|
|
s.templatesPath = templatesPath
|
|
}
|
|
|
|
// SetVersion sets the version.
|
|
func (s *Settings) SetVersion(version string) {
|
|
s.version = version
|
|
}
|
|
|
|
// SetDbConnstring sets the dbConnString.
|
|
func (s *Settings) SetDbConnstring(connstring string) {
|
|
s.dbConnstring = connstring
|
|
}
|
|
|
|
// SetDbType sets the dbType.
|
|
func (s *Settings) SetDbType(dbType string) {
|
|
s.dbType = dbType
|
|
}
|
|
|
|
// SetDbIsSetUp sets the dbIsSetUp.
|
|
func (s *Settings) SetDbIsSetUp(is bool) {
|
|
s.dbIsSetUp = is
|
|
}
|
|
|
|
// EraseENVs attempts to clear environment vars pertaining to pcmt.
|
|
func (s *Settings) EraseENVs() error {
|
|
for _, v := range cleantgt {
|
|
err := os.Unsetenv(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|