Implement Cobra CLI tooling, Viper config tooling (#336)

* start pulling out + replacing urfave and config

* replace many many instances of config

* move more stuff => viper

* properly remove urfave

* move some flags to root command

* add testrig commands to root

* alias config file keys

* start adding cli parsing tests

* reorder viper init

* remove config path alias

* fmt

* change config file keys to non-nested

* we're more or less in business now

* tidy up the common func

* go fmt

* get tests passing again

* add note about the cliparsing tests

* reorganize

* update docs with changes

* structure cmd dir better

* rename + move some files around

* fix dangling comma
This commit is contained in:
tobi 2021-12-07 13:31:39 +01:00 committed by GitHub
commit 0884f89431
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
487 changed files with 46667 additions and 8831 deletions

View file

@ -1,622 +0,0 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
import (
"errors"
"fmt"
"os"
"gopkg.in/yaml.v2"
)
// Flags and usage strings for configuration.
const (
UsernameFlag = "username"
UsernameUsage = "the username to create/delete/etc"
EmailFlag = "email"
EmailUsage = "the email address of this account"
PasswordFlag = "password"
PasswordUsage = "the password to set for this account"
TransPathFlag = "path"
TransPathUsage = "the path of the file to import from/export to"
)
// Config pulls together all the configuration needed to run gotosocial
type Config struct {
/*
Parseable from .yaml configuration file.
For long-running commands (server start etc).
*/
LogLevel string `yaml:"logLevel"`
ApplicationName string `yaml:"applicationName"`
Host string `yaml:"host"`
AccountDomain string `yaml:"accountDomain"`
Protocol string `yaml:"protocol"`
BindAddress string `yaml:"bindAddress"`
Port int `yaml:"port"`
TrustedProxies []string `yaml:"trustedProxies"`
DBConfig *DBConfig `yaml:"db"`
TemplateConfig *TemplateConfig `yaml:"template"`
AccountsConfig *AccountsConfig `yaml:"accounts"`
MediaConfig *MediaConfig `yaml:"media"`
StorageConfig *StorageConfig `yaml:"storage"`
StatusesConfig *StatusesConfig `yaml:"statuses"`
LetsEncryptConfig *LetsEncryptConfig `yaml:"letsEncrypt"`
OIDCConfig *OIDCConfig `yaml:"oidc"`
SMTPConfig *SMTPConfig `yaml:"smtp"`
/*
Not parsed from .yaml configuration file.
*/
AccountCLIFlags map[string]string
ExportCLIFlags map[string]string
SoftwareVersion string
}
// FromFile returns a new config from a file, or an error if something goes amiss.
func FromFile(path string) (*Config, error) {
if path != "" {
c, err := loadFromFile(path)
if err != nil {
return nil, fmt.Errorf("error creating config: %s", err)
}
return c, nil
}
return Default(), nil
}
// loadFromFile takes a path to a yaml file and attempts to load a Config object from it
func loadFromFile(path string) (*Config, error) {
bytes, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("could not read file at path %s: %s", path, err)
}
config := Default()
if err := yaml.Unmarshal(bytes, config); err != nil {
return nil, fmt.Errorf("could not unmarshal file at path %s: %s", path, err)
}
return config, nil
}
// ParseCLIFlags sets flags on the config using the provided Flags object
func (c *Config) ParseCLIFlags(f KeyedFlags, version string) error {
fn := GetFlagNames()
// For all of these flags, we only want to set them on the config if:
//
// a) They haven't been set at all in the config file we already parsed,
// and so we take the default from the flags object.
//
// b) They may have been set in the config, but they've *also* been set explicitly
// as a command-line argument or an env variable, which takes priority.
// general flags
if f.IsSet(fn.LogLevel) {
c.LogLevel = f.String(fn.LogLevel)
}
if f.IsSet(fn.ApplicationName) {
c.ApplicationName = f.String(fn.ApplicationName)
}
if f.IsSet(fn.Host) {
c.Host = f.String(fn.Host)
}
if c.Host == "" {
return errors.New("host was not set")
}
if f.IsSet(fn.AccountDomain) {
c.AccountDomain = f.String(fn.AccountDomain)
}
if c.AccountDomain == "" {
c.AccountDomain = c.Host // default to whatever the host is, if this is empty
}
if f.IsSet(fn.Protocol) {
c.Protocol = f.String(fn.Protocol)
}
if c.Protocol == "" {
return errors.New("protocol was not set")
}
if f.IsSet(fn.BindAddress) {
c.BindAddress = f.String(fn.BindAddress)
}
if f.IsSet(fn.Port) {
c.Port = f.Int(fn.Port)
}
if f.IsSet(fn.TrustedProxies) {
c.TrustedProxies = f.StringSlice(fn.TrustedProxies)
}
// db flags
if f.IsSet(fn.DbType) {
c.DBConfig.Type = f.String(fn.DbType)
}
if f.IsSet(fn.DbAddress) {
c.DBConfig.Address = f.String(fn.DbAddress)
}
if f.IsSet(fn.DbPort) {
c.DBConfig.Port = f.Int(fn.DbPort)
}
if f.IsSet(fn.DbUser) {
c.DBConfig.User = f.String(fn.DbUser)
}
if f.IsSet(fn.DbPassword) {
c.DBConfig.Password = f.String(fn.DbPassword)
}
if f.IsSet(fn.DbDatabase) {
c.DBConfig.Database = f.String(fn.DbDatabase)
}
if f.IsSet(fn.DbTLSMode) {
c.DBConfig.TLSMode = DBTLSMode(f.String(fn.DbTLSMode))
}
if f.IsSet(fn.DbTLSCACert) {
c.DBConfig.TLSCACert = f.String(fn.DbTLSCACert)
}
// template flags
if f.IsSet(fn.TemplateBaseDir) {
c.TemplateConfig.BaseDir = f.String(fn.TemplateBaseDir)
}
// template flags
if f.IsSet(fn.AssetBaseDir) {
c.TemplateConfig.AssetBaseDir = f.String(fn.AssetBaseDir)
}
// accounts flags
if f.IsSet(fn.AccountsOpenRegistration) {
c.AccountsConfig.OpenRegistration = f.Bool(fn.AccountsOpenRegistration)
}
if f.IsSet(fn.AccountsApprovalRequired) {
c.AccountsConfig.RequireApproval = f.Bool(fn.AccountsApprovalRequired)
}
// media flags
if f.IsSet(fn.MediaMaxImageSize) {
c.MediaConfig.MaxImageSize = f.Int(fn.MediaMaxImageSize)
}
if f.IsSet(fn.MediaMaxVideoSize) {
c.MediaConfig.MaxVideoSize = f.Int(fn.MediaMaxVideoSize)
}
if f.IsSet(fn.MediaMinDescriptionChars) {
c.MediaConfig.MinDescriptionChars = f.Int(fn.MediaMinDescriptionChars)
}
if f.IsSet(fn.MediaMaxDescriptionChars) {
c.MediaConfig.MaxDescriptionChars = f.Int(fn.MediaMaxDescriptionChars)
}
// storage flags
if f.IsSet(fn.StorageBackend) {
c.StorageConfig.Backend = f.String(fn.StorageBackend)
}
if f.IsSet(fn.StorageBasePath) {
c.StorageConfig.BasePath = f.String(fn.StorageBasePath)
}
if f.IsSet(fn.StorageServeProtocol) {
c.StorageConfig.ServeProtocol = f.String(fn.StorageServeProtocol)
}
if f.IsSet(fn.StorageServeHost) {
c.StorageConfig.ServeHost = f.String(fn.StorageServeHost)
}
if f.IsSet(fn.StorageServeBasePath) {
c.StorageConfig.ServeBasePath = f.String(fn.StorageServeBasePath)
}
// statuses flags
if f.IsSet(fn.StatusesMaxChars) {
c.StatusesConfig.MaxChars = f.Int(fn.StatusesMaxChars)
}
if f.IsSet(fn.StatusesCWMaxChars) {
c.StatusesConfig.CWMaxChars = f.Int(fn.StatusesCWMaxChars)
}
if f.IsSet(fn.StatusesPollMaxOptions) {
c.StatusesConfig.PollMaxOptions = f.Int(fn.StatusesPollMaxOptions)
}
if f.IsSet(fn.StatusesPollOptionMaxChars) {
c.StatusesConfig.PollOptionMaxChars = f.Int(fn.StatusesPollOptionMaxChars)
}
if f.IsSet(fn.StatusesMaxMediaFiles) {
c.StatusesConfig.MaxMediaFiles = f.Int(fn.StatusesMaxMediaFiles)
}
// letsencrypt flags
if f.IsSet(fn.LetsEncryptEnabled) {
c.LetsEncryptConfig.Enabled = f.Bool(fn.LetsEncryptEnabled)
}
if f.IsSet(fn.LetsEncryptPort) {
c.LetsEncryptConfig.Port = f.Int(fn.LetsEncryptPort)
}
if f.IsSet(fn.LetsEncryptCertDir) {
c.LetsEncryptConfig.CertDir = f.String(fn.LetsEncryptCertDir)
}
if f.IsSet(fn.LetsEncryptEmailAddress) {
c.LetsEncryptConfig.EmailAddress = f.String(fn.LetsEncryptEmailAddress)
}
// OIDC flags
if f.IsSet(fn.OIDCEnabled) {
c.OIDCConfig.Enabled = f.Bool(fn.OIDCEnabled)
}
if f.IsSet(fn.OIDCIdpName) {
c.OIDCConfig.IDPName = f.String(fn.OIDCIdpName)
}
if f.IsSet(fn.OIDCSkipVerification) {
c.OIDCConfig.SkipVerification = f.Bool(fn.OIDCSkipVerification)
}
if f.IsSet(fn.OIDCIssuer) {
c.OIDCConfig.Issuer = f.String(fn.OIDCIssuer)
}
if f.IsSet(fn.OIDCClientID) {
c.OIDCConfig.ClientID = f.String(fn.OIDCClientID)
}
if f.IsSet(fn.OIDCClientSecret) {
c.OIDCConfig.ClientSecret = f.String(fn.OIDCClientSecret)
}
if f.IsSet(fn.OIDCScopes) {
c.OIDCConfig.Scopes = f.StringSlice(fn.OIDCScopes)
}
// smtp flags
if f.IsSet(fn.SMTPHost) {
c.SMTPConfig.Host = f.String(fn.SMTPHost)
}
if f.IsSet(fn.SMTPPort) {
c.SMTPConfig.Port = f.Int(fn.SMTPPort)
}
if f.IsSet(fn.SMTPUsername) {
c.SMTPConfig.Username = f.String(fn.SMTPUsername)
}
if f.IsSet(fn.SMTPPassword) {
c.SMTPConfig.Password = f.String(fn.SMTPPassword)
}
if f.IsSet(fn.SMTPFrom) {
c.SMTPConfig.From = f.String(fn.SMTPFrom)
}
// command-specific flags
// admin account CLI flags
c.AccountCLIFlags[UsernameFlag] = f.String(UsernameFlag)
c.AccountCLIFlags[EmailFlag] = f.String(EmailFlag)
c.AccountCLIFlags[PasswordFlag] = f.String(PasswordFlag)
// export CLI flags
c.ExportCLIFlags[TransPathFlag] = f.String(TransPathFlag)
c.SoftwareVersion = version
return nil
}
// KeyedFlags is a wrapper for any type that can store keyed flags and give them back.
// HINT: This works with a urfave cli context struct ;)
type KeyedFlags interface {
Bool(k string) bool
String(k string) string
StringSlice(k string) []string
Int(k string) int
IsSet(k string) bool
}
// Flags is used for storing the names of the various flags used for
// initializing and storing urfavecli flag variables.
type Flags struct {
LogLevel string
ApplicationName string
ConfigPath string
Host string
AccountDomain string
Protocol string
BindAddress string
Port string
TrustedProxies string
DbType string
DbAddress string
DbPort string
DbUser string
DbPassword string
DbDatabase string
DbTLSMode string
DbTLSCACert string
TemplateBaseDir string
AssetBaseDir string
AccountsOpenRegistration string
AccountsApprovalRequired string
AccountsReasonRequired string
MediaMaxImageSize string
MediaMaxVideoSize string
MediaMinDescriptionChars string
MediaMaxDescriptionChars string
StorageBackend string
StorageBasePath string
StorageServeProtocol string
StorageServeHost string
StorageServeBasePath string
StatusesMaxChars string
StatusesCWMaxChars string
StatusesPollMaxOptions string
StatusesPollOptionMaxChars string
StatusesMaxMediaFiles string
LetsEncryptEnabled string
LetsEncryptCertDir string
LetsEncryptEmailAddress string
LetsEncryptPort string
OIDCEnabled string
OIDCIdpName string
OIDCSkipVerification string
OIDCIssuer string
OIDCClientID string
OIDCClientSecret string
OIDCScopes string
SMTPHost string
SMTPPort string
SMTPUsername string
SMTPPassword string
SMTPFrom string
}
// Defaults contains all the default values for a gotosocial config
type Defaults struct {
LogLevel string
ApplicationName string
ConfigPath string
Host string
AccountDomain string
Protocol string
BindAddress string
Port int
TrustedProxies []string
SoftwareVersion string
DbType string
DbAddress string
DbPort int
DbUser string
DbPassword string
DbDatabase string
DBTlsMode string
DBTlsCACert string
TemplateBaseDir string
AssetBaseDir string
AccountsOpenRegistration bool
AccountsRequireApproval bool
AccountsReasonRequired bool
MediaMaxImageSize int
MediaMaxVideoSize int
MediaMinDescriptionChars int
MediaMaxDescriptionChars int
StorageBackend string
StorageBasePath string
StorageServeProtocol string
StorageServeHost string
StorageServeBasePath string
StatusesMaxChars int
StatusesCWMaxChars int
StatusesPollMaxOptions int
StatusesPollOptionMaxChars int
StatusesMaxMediaFiles int
LetsEncryptEnabled bool
LetsEncryptCertDir string
LetsEncryptEmailAddress string
LetsEncryptPort int
OIDCEnabled bool
OIDCIdpName string
OIDCSkipVerification bool
OIDCIssuer string
OIDCClientID string
OIDCClientSecret string
OIDCScopes []string
SMTPHost string
SMTPPort int
SMTPUsername string
SMTPPassword string
SMTPFrom string
}
// GetFlagNames returns a struct containing the names of the various flags used for
// initializing and storing urfavecli flag variables.
func GetFlagNames() Flags {
return Flags{
LogLevel: "log-level",
ApplicationName: "application-name",
ConfigPath: "config-path",
Host: "host",
AccountDomain: "account-domain",
Protocol: "protocol",
BindAddress: "bind-address",
Port: "port",
TrustedProxies: "trusted-proxies",
DbType: "db-type",
DbAddress: "db-address",
DbPort: "db-port",
DbUser: "db-user",
DbPassword: "db-password",
DbDatabase: "db-database",
DbTLSMode: "db-tls-mode",
DbTLSCACert: "db-tls-ca-cert",
TemplateBaseDir: "template-basedir",
AssetBaseDir: "asset-basedir",
AccountsOpenRegistration: "accounts-open-registration",
AccountsApprovalRequired: "accounts-approval-required",
AccountsReasonRequired: "accounts-reason-required",
MediaMaxImageSize: "media-max-image-size",
MediaMaxVideoSize: "media-max-video-size",
MediaMinDescriptionChars: "media-min-description-chars",
MediaMaxDescriptionChars: "media-max-description-chars",
StorageBackend: "storage-backend",
StorageBasePath: "storage-base-path",
StorageServeProtocol: "storage-serve-protocol",
StorageServeHost: "storage-serve-host",
StorageServeBasePath: "storage-serve-base-path",
StatusesMaxChars: "statuses-max-chars",
StatusesCWMaxChars: "statuses-cw-max-chars",
StatusesPollMaxOptions: "statuses-poll-max-options",
StatusesPollOptionMaxChars: "statuses-poll-option-max-chars",
StatusesMaxMediaFiles: "statuses-max-media-files",
LetsEncryptEnabled: "letsencrypt-enabled",
LetsEncryptPort: "letsencrypt-port",
LetsEncryptCertDir: "letsencrypt-cert-dir",
LetsEncryptEmailAddress: "letsencrypt-email",
OIDCEnabled: "oidc-enabled",
OIDCIdpName: "oidc-idp-name",
OIDCSkipVerification: "oidc-skip-verification",
OIDCIssuer: "oidc-issuer",
OIDCClientID: "oidc-client-id",
OIDCClientSecret: "oidc-client-secret",
OIDCScopes: "oidc-scopes",
SMTPHost: "smtp-host",
SMTPPort: "smtp-port",
SMTPUsername: "smtp-username",
SMTPPassword: "smtp-password",
SMTPFrom: "smtp-from",
}
}
// GetEnvNames returns a struct containing the names of the environment variable keys used for
// initializing and storing urfavecli flag variables.
func GetEnvNames() Flags {
return Flags{
LogLevel: "GTS_LOG_LEVEL",
ApplicationName: "GTS_APPLICATION_NAME",
ConfigPath: "GTS_CONFIG_PATH",
Host: "GTS_HOST",
AccountDomain: "GTS_ACCOUNT_DOMAIN",
Protocol: "GTS_PROTOCOL",
BindAddress: "GTS_BIND_ADDRESS",
Port: "GTS_PORT",
TrustedProxies: "GTS_TRUSTED_PROXIES",
DbType: "GTS_DB_TYPE",
DbAddress: "GTS_DB_ADDRESS",
DbPort: "GTS_DB_PORT",
DbUser: "GTS_DB_USER",
DbPassword: "GTS_DB_PASSWORD",
DbDatabase: "GTS_DB_DATABASE",
DbTLSMode: "GTS_DB_TLS_MODE",
DbTLSCACert: "GTS_DB_CA_CERT",
TemplateBaseDir: "GTS_TEMPLATE_BASEDIR",
AssetBaseDir: "GTS_ASSET_BASEDIR",
AccountsOpenRegistration: "GTS_ACCOUNTS_OPEN_REGISTRATION",
AccountsApprovalRequired: "GTS_ACCOUNTS_APPROVAL_REQUIRED",
AccountsReasonRequired: "GTS_ACCOUNTS_REASON_REQUIRED",
MediaMaxImageSize: "GTS_MEDIA_MAX_IMAGE_SIZE",
MediaMaxVideoSize: "GTS_MEDIA_MAX_VIDEO_SIZE",
MediaMinDescriptionChars: "GTS_MEDIA_MIN_DESCRIPTION_CHARS",
MediaMaxDescriptionChars: "GTS_MEDIA_MAX_DESCRIPTION_CHARS",
StorageBackend: "GTS_STORAGE_BACKEND",
StorageBasePath: "GTS_STORAGE_BASE_PATH",
StorageServeProtocol: "GTS_STORAGE_SERVE_PROTOCOL",
StorageServeHost: "GTS_STORAGE_SERVE_HOST",
StorageServeBasePath: "GTS_STORAGE_SERVE_BASE_PATH",
StatusesMaxChars: "GTS_STATUSES_MAX_CHARS",
StatusesCWMaxChars: "GTS_STATUSES_CW_MAX_CHARS",
StatusesPollMaxOptions: "GTS_STATUSES_POLL_MAX_OPTIONS",
StatusesPollOptionMaxChars: "GTS_STATUSES_POLL_OPTION_MAX_CHARS",
StatusesMaxMediaFiles: "GTS_STATUSES_MAX_MEDIA_FILES",
LetsEncryptEnabled: "GTS_LETSENCRYPT_ENABLED",
LetsEncryptPort: "GTS_LETSENCRYPT_PORT",
LetsEncryptCertDir: "GTS_LETSENCRYPT_CERT_DIR",
LetsEncryptEmailAddress: "GTS_LETSENCRYPT_EMAIL",
OIDCEnabled: "GTS_OIDC_ENABLED",
OIDCIdpName: "GTS_OIDC_IDP_NAME",
OIDCSkipVerification: "GTS_OIDC_SKIP_VERIFICATION",
OIDCIssuer: "GTS_OIDC_ISSUER",
OIDCClientID: "GTS_OIDC_CLIENT_ID",
OIDCClientSecret: "GTS_OIDC_CLIENT_SECRET",
OIDCScopes: "GTS_OIDC_SCOPES",
SMTPHost: "SMTP_HOST",
SMTPPort: "SMTP_PORT",
SMTPUsername: "SMTP_USERNAME",
SMTPPassword: "SMTP_PASSWORD",
SMTPFrom: "SMTP_FROM",
}
}

View file

@ -1,49 +0,0 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
// DBConfig provides configuration options for the database connection
type DBConfig struct {
Type string `yaml:"type"`
Address string `yaml:"address"`
Port int `yaml:"port"`
User string `yaml:"user"`
Password string `yaml:"password"`
Database string `yaml:"database"`
ApplicationName string `yaml:"applicationName"`
TLSMode DBTLSMode `yaml:"tlsMode"`
TLSCACert string `yaml:"tlsCACert"`
}
// DBTLSMode describes a mode of connecting to a database with or without TLS.
type DBTLSMode string
// DBTLSModeDisable does not attempt to make a TLS connection to the database.
var DBTLSModeDisable DBTLSMode = "disable"
// DBTLSModeEnable attempts to make a TLS connection to the database, but doesn't fail if
// the certificate passed by the database isn't verified.
var DBTLSModeEnable DBTLSMode = "enable"
// DBTLSModeRequire attempts to make a TLS connection to the database, and requires
// that the certificate presented by the database is valid.
var DBTLSModeRequire DBTLSMode = "require"
// DBTLSModeUnset means that the TLS mode has not been set.
var DBTLSModeUnset DBTLSMode

View file

@ -1,289 +0,0 @@
package config
import "github.com/coreos/go-oidc/v3/oidc"
// TestDefault returns a default config for testing
func TestDefault() *Config {
defaults := GetTestDefaults()
return &Config{
LogLevel: defaults.LogLevel,
ApplicationName: defaults.ApplicationName,
Host: defaults.Host,
AccountDomain: defaults.AccountDomain,
Protocol: defaults.Protocol,
BindAddress: defaults.BindAddress,
Port: defaults.Port,
TrustedProxies: defaults.TrustedProxies,
SoftwareVersion: defaults.SoftwareVersion,
DBConfig: &DBConfig{
Type: defaults.DbType,
Address: defaults.DbAddress,
Port: defaults.DbPort,
User: defaults.DbUser,
Password: defaults.DbPassword,
Database: defaults.DbDatabase,
ApplicationName: defaults.ApplicationName,
},
TemplateConfig: &TemplateConfig{
BaseDir: defaults.TemplateBaseDir,
AssetBaseDir: defaults.AssetBaseDir,
},
AccountsConfig: &AccountsConfig{
OpenRegistration: defaults.AccountsOpenRegistration,
RequireApproval: defaults.AccountsRequireApproval,
ReasonRequired: defaults.AccountsReasonRequired,
},
MediaConfig: &MediaConfig{
MaxImageSize: defaults.MediaMaxImageSize,
MaxVideoSize: defaults.MediaMaxVideoSize,
MinDescriptionChars: defaults.MediaMinDescriptionChars,
MaxDescriptionChars: defaults.MediaMaxDescriptionChars,
},
StorageConfig: &StorageConfig{
Backend: defaults.StorageBackend,
BasePath: defaults.StorageBasePath,
ServeProtocol: defaults.StorageServeProtocol,
ServeHost: defaults.StorageServeHost,
ServeBasePath: defaults.StorageServeBasePath,
},
StatusesConfig: &StatusesConfig{
MaxChars: defaults.StatusesMaxChars,
CWMaxChars: defaults.StatusesCWMaxChars,
PollMaxOptions: defaults.StatusesPollMaxOptions,
PollOptionMaxChars: defaults.StatusesPollOptionMaxChars,
MaxMediaFiles: defaults.StatusesMaxMediaFiles,
},
LetsEncryptConfig: &LetsEncryptConfig{
Enabled: defaults.LetsEncryptEnabled,
Port: defaults.LetsEncryptPort,
CertDir: defaults.LetsEncryptCertDir,
EmailAddress: defaults.LetsEncryptEmailAddress,
},
OIDCConfig: &OIDCConfig{
Enabled: defaults.OIDCEnabled,
IDPName: defaults.OIDCIdpName,
SkipVerification: defaults.OIDCSkipVerification,
Issuer: defaults.OIDCIssuer,
ClientID: defaults.OIDCClientID,
ClientSecret: defaults.OIDCClientSecret,
Scopes: defaults.OIDCScopes,
},
SMTPConfig: &SMTPConfig{
Host: defaults.SMTPHost,
Port: defaults.SMTPPort,
Username: defaults.SMTPUsername,
Password: defaults.SMTPPassword,
From: defaults.SMTPFrom,
},
}
}
// Default returns a config with all default values set
func Default() *Config {
defaults := GetDefaults()
return &Config{
LogLevel: defaults.LogLevel,
ApplicationName: defaults.ApplicationName,
Host: defaults.Host,
Protocol: defaults.Protocol,
BindAddress: defaults.BindAddress,
Port: defaults.Port,
TrustedProxies: defaults.TrustedProxies,
SoftwareVersion: defaults.SoftwareVersion,
DBConfig: &DBConfig{
Type: defaults.DbType,
Address: defaults.DbAddress,
Port: defaults.DbPort,
User: defaults.DbUser,
Password: defaults.DbPassword,
Database: defaults.DbDatabase,
ApplicationName: defaults.ApplicationName,
},
TemplateConfig: &TemplateConfig{
BaseDir: defaults.TemplateBaseDir,
AssetBaseDir: defaults.AssetBaseDir,
},
AccountsConfig: &AccountsConfig{
OpenRegistration: defaults.AccountsOpenRegistration,
RequireApproval: defaults.AccountsRequireApproval,
ReasonRequired: defaults.AccountsReasonRequired,
},
MediaConfig: &MediaConfig{
MaxImageSize: defaults.MediaMaxImageSize,
MaxVideoSize: defaults.MediaMaxVideoSize,
MinDescriptionChars: defaults.MediaMinDescriptionChars,
MaxDescriptionChars: defaults.MediaMaxDescriptionChars,
},
StorageConfig: &StorageConfig{
Backend: defaults.StorageBackend,
BasePath: defaults.StorageBasePath,
ServeProtocol: defaults.StorageServeProtocol,
ServeHost: defaults.StorageServeHost,
ServeBasePath: defaults.StorageServeBasePath,
},
StatusesConfig: &StatusesConfig{
MaxChars: defaults.StatusesMaxChars,
CWMaxChars: defaults.StatusesCWMaxChars,
PollMaxOptions: defaults.StatusesPollMaxOptions,
PollOptionMaxChars: defaults.StatusesPollOptionMaxChars,
MaxMediaFiles: defaults.StatusesMaxMediaFiles,
},
LetsEncryptConfig: &LetsEncryptConfig{
Enabled: defaults.LetsEncryptEnabled,
Port: defaults.LetsEncryptPort,
CertDir: defaults.LetsEncryptCertDir,
EmailAddress: defaults.LetsEncryptEmailAddress,
},
OIDCConfig: &OIDCConfig{
Enabled: defaults.OIDCEnabled,
IDPName: defaults.OIDCIdpName,
SkipVerification: defaults.OIDCSkipVerification,
Issuer: defaults.OIDCIssuer,
ClientID: defaults.OIDCClientID,
ClientSecret: defaults.OIDCClientSecret,
Scopes: defaults.OIDCScopes,
},
SMTPConfig: &SMTPConfig{
Host: defaults.SMTPHost,
Port: defaults.SMTPPort,
Username: defaults.SMTPUsername,
Password: defaults.SMTPPassword,
From: defaults.SMTPFrom,
},
AccountCLIFlags: make(map[string]string),
ExportCLIFlags: make(map[string]string),
}
}
// GetDefaults returns a populated Defaults struct with most of the values set to reasonable defaults.
// Note that if you use this function, you still need to set Host and, if desired, ConfigPath.
func GetDefaults() Defaults {
return Defaults{
LogLevel: "info",
ApplicationName: "gotosocial",
ConfigPath: "",
Host: "",
AccountDomain: "",
Protocol: "https",
BindAddress: "0.0.0.0",
Port: 8080,
TrustedProxies: []string{"127.0.0.1/32"}, // localhost
DbType: "postgres",
DbAddress: "localhost",
DbPort: 5432,
DbUser: "postgres",
DbPassword: "postgres",
DbDatabase: "postgres",
DBTlsMode: "disable",
DBTlsCACert: "",
TemplateBaseDir: "./web/template/",
AssetBaseDir: "./web/assets/",
AccountsOpenRegistration: true,
AccountsRequireApproval: true,
AccountsReasonRequired: true,
MediaMaxImageSize: 2097152, // 2mb
MediaMaxVideoSize: 10485760, // 10mb
MediaMinDescriptionChars: 0,
MediaMaxDescriptionChars: 500,
StorageBackend: "local",
StorageBasePath: "/gotosocial/storage",
StorageServeProtocol: "https",
StorageServeHost: "localhost",
StorageServeBasePath: "/fileserver",
StatusesMaxChars: 5000,
StatusesCWMaxChars: 100,
StatusesPollMaxOptions: 6,
StatusesPollOptionMaxChars: 50,
StatusesMaxMediaFiles: 6,
LetsEncryptEnabled: true,
LetsEncryptPort: 80,
LetsEncryptCertDir: "/gotosocial/storage/certs",
LetsEncryptEmailAddress: "",
OIDCEnabled: false,
OIDCIdpName: "",
OIDCSkipVerification: false,
OIDCIssuer: "",
OIDCClientID: "",
OIDCClientSecret: "",
OIDCScopes: []string{oidc.ScopeOpenID, "profile", "email", "groups"},
SMTPHost: "",
SMTPPort: 0,
SMTPUsername: "",
SMTPPassword: "",
SMTPFrom: "GoToSocial",
}
}
// GetTestDefaults returns a Defaults struct with values set that are suitable for local testing.
func GetTestDefaults() Defaults {
return Defaults{
LogLevel: "trace",
ApplicationName: "gotosocial",
ConfigPath: "",
Host: "localhost:8080",
AccountDomain: "localhost:8080",
Protocol: "http",
BindAddress: "127.0.0.1",
Port: 8080,
TrustedProxies: []string{"127.0.0.1/32"},
DbType: "sqlite",
DbAddress: ":memory:",
DbPort: 5432,
DbUser: "postgres",
DbPassword: "postgres",
DbDatabase: "postgres",
TemplateBaseDir: "./web/template/",
AssetBaseDir: "./web/assets/",
AccountsOpenRegistration: true,
AccountsRequireApproval: true,
AccountsReasonRequired: true,
MediaMaxImageSize: 1048576, // 1mb
MediaMaxVideoSize: 5242880, // 5mb
MediaMinDescriptionChars: 0,
MediaMaxDescriptionChars: 500,
StorageBackend: "local",
StorageBasePath: "/gotosocial/storage",
StorageServeProtocol: "http",
StorageServeHost: "localhost:8080",
StorageServeBasePath: "/fileserver",
StatusesMaxChars: 5000,
StatusesCWMaxChars: 100,
StatusesPollMaxOptions: 6,
StatusesPollOptionMaxChars: 50,
StatusesMaxMediaFiles: 6,
LetsEncryptEnabled: false,
LetsEncryptPort: 0,
LetsEncryptCertDir: "",
LetsEncryptEmailAddress: "",
OIDCEnabled: false,
OIDCIdpName: "",
OIDCSkipVerification: false,
OIDCIssuer: "",
OIDCClientID: "",
OIDCClientSecret: "",
OIDCScopes: []string{oidc.ScopeOpenID, "profile", "email", "groups"},
SMTPHost: "",
SMTPPort: 0,
SMTPUsername: "",
SMTPPassword: "",
SMTPFrom: "GoToSocial",
}
}

View file

@ -0,0 +1,87 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
import "github.com/coreos/go-oidc/v3/oidc"
// Defaults returns a populated Values struct with most of the values set to reasonable defaults.
// Note that if you use this, you still need to set Host and, if desired, ConfigPath.
var Defaults = Values{
LogLevel: "info",
ApplicationName: "gotosocial",
ConfigPath: "",
Host: "",
AccountDomain: "",
Protocol: "https",
BindAddress: "0.0.0.0",
Port: 8080,
TrustedProxies: []string{"127.0.0.1/32"}, // localhost
DbType: "postgres",
DbAddress: "localhost",
DbPort: 5432,
DbUser: "postgres",
DbPassword: "postgres",
DbDatabase: "postgres",
DbTLSMode: "disable",
DbTLSCACert: "",
WebTemplateBaseDir: "./web/template/",
WebAssetBaseDir: "./web/assets/",
AccountsRegistrationOpen: true,
AccountsApprovalRequired: true,
AccountsReasonRequired: true,
MediaImageMaxSize: 2097152, // 2mb
MediaVideoMaxSize: 10485760, // 10mb
MediaDescriptionMinChars: 0,
MediaDescriptionMaxChars: 500,
StorageBackend: "local",
StorageBasePath: "/gotosocial/storage",
StorageServeProtocol: "https",
StorageServeHost: "localhost",
StorageServeBasePath: "/fileserver",
StatusesMaxChars: 5000,
StatusesCWMaxChars: 100,
StatusesPollMaxOptions: 6,
StatusesPollOptionMaxChars: 50,
StatusesMediaMaxFiles: 6,
LetsEncryptEnabled: true,
LetsEncryptPort: 80,
LetsEncryptCertDir: "/gotosocial/storage/certs",
LetsEncryptEmailAddress: "",
OIDCEnabled: false,
OIDCIdpName: "",
OIDCSkipVerification: false,
OIDCIssuer: "",
OIDCClientID: "",
OIDCClientSecret: "",
OIDCScopes: []string{oidc.ScopeOpenID, "profile", "email", "groups"},
SMTPHost: "",
SMTPPort: 0,
SMTPUsername: "",
SMTPPassword: "",
SMTPFrom: "GoToSocial",
}

View file

@ -18,10 +18,21 @@
package config
// TemplateConfig pertains to templating of web pages/email notifications and the like
type TemplateConfig struct {
// Directory from which gotosocial will attempt to load html templates (.tmpl files).
BaseDir string `yaml:"baseDir"`
// Directory from which static files are served
AssetBaseDir string `yaml:"assetDir"`
import (
"github.com/spf13/viper"
)
// ReadFromFile checks if there's already a path to the config file set in viper.
// If there is, it will attempt to read the config file into viper.
func ReadFromFile() error {
// config file stuff
// check if we have a config path set (either by cli arg or env var)
if configPath := viper.GetString(Keys.ConfigPath); configPath != "" {
viper.SetConfigFile(configPath)
if err := viper.ReadInConfig(); err != nil {
return err
}
}
return nil
}

175
internal/config/keys.go Normal file
View file

@ -0,0 +1,175 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
// KeyNames is a struct that just contains the names of configuration keys.
type KeyNames struct {
// root
LogLevel string
ConfigPath string
// general
ApplicationName string
Host string
AccountDomain string
Protocol string
BindAddress string
Port string
TrustedProxies string
SoftwareVersion string
// database
DbType string
DbAddress string
DbPort string
DbUser string
DbPassword string
DbDatabase string
DbTLSMode string
DbTLSCACert string
// template
WebTemplateBaseDir string
WebAssetBaseDir string
// accounts
AccountsRegistrationOpen string
AccountsApprovalRequired string
AccountsReasonRequired string
// media
MediaImageMaxSize string
MediaVideoMaxSize string
MediaDescriptionMinChars string
MediaDescriptionMaxChars string
// storage
StorageBackend string
StorageBasePath string
StorageServeProtocol string
StorageServeHost string
StorageServeBasePath string
// statuses
StatusesMaxChars string
StatusesCWMaxChars string
StatusesPollMaxOptions string
StatusesPollOptionMaxChars string
StatusesMediaMaxFiles string
// letsencrypt
LetsEncryptEnabled string
LetsEncryptCertDir string
LetsEncryptEmailAddress string
LetsEncryptPort string
// oidc
OIDCEnabled string
OIDCIdpName string
OIDCSkipVerification string
OIDCIssuer string
OIDCClientID string
OIDCClientSecret string
OIDCScopes string
// smtp
SMTPHost string
SMTPPort string
SMTPUsername string
SMTPPassword string
SMTPFrom string
// admin
AdminAccountUsername string
AdminAccountEmail string
AdminAccountPassword string
AdminTransPath string
}
// Keys contains the names of the various keys used for initializing and storing flag variables,
// and retrieving values from the viper config store.
var Keys = KeyNames{
LogLevel: "log-level",
ApplicationName: "application-name",
ConfigPath: "config-path",
Host: "host",
AccountDomain: "account-domain",
Protocol: "protocol",
BindAddress: "bind-address",
Port: "port",
TrustedProxies: "trusted-proxies",
SoftwareVersion: "software-version",
DbType: "db-type",
DbAddress: "db-address",
DbPort: "db-port",
DbUser: "db-user",
DbPassword: "db-password",
DbDatabase: "db-database",
DbTLSMode: "db-tls-mode",
DbTLSCACert: "db-tls-ca-cert",
WebTemplateBaseDir: "web-template-base-dir",
WebAssetBaseDir: "web-asset-base-dir",
AccountsRegistrationOpen: "accounts-registration-open",
AccountsApprovalRequired: "accounts-approval-required",
AccountsReasonRequired: "accounts-reason-required",
MediaImageMaxSize: "media-image-max-size",
MediaVideoMaxSize: "media-video-max-size",
MediaDescriptionMinChars: "media-description-min-chars",
MediaDescriptionMaxChars: "media-description-max-chars",
StorageBackend: "storage-backend",
StorageBasePath: "storage-base-path",
StorageServeProtocol: "storage-serve-protocol",
StorageServeHost: "storage-serve-host",
StorageServeBasePath: "storage-serve-base-path",
StatusesMaxChars: "statuses-max-chars",
StatusesCWMaxChars: "statuses-cw-max-chars",
StatusesPollMaxOptions: "statuses-poll-max-options",
StatusesPollOptionMaxChars: "statuses-poll-option-max-chars",
StatusesMediaMaxFiles: "statuses-media-max-files",
LetsEncryptEnabled: "letsencrypt-enabled",
LetsEncryptPort: "letsencrypt-port",
LetsEncryptCertDir: "letsencrypt-cert-dir",
LetsEncryptEmailAddress: "letsencrypt-email-address",
OIDCEnabled: "oidc-enabled",
OIDCIdpName: "oidc-idp-name",
OIDCSkipVerification: "oidc-skip-verification",
OIDCIssuer: "oidc-issuer",
OIDCClientID: "oidc-client-id",
OIDCClientSecret: "oidc-client-secret",
OIDCScopes: "oidc-scopes",
SMTPHost: "smtp-host",
SMTPPort: "smtp-port",
SMTPUsername: "smtp-username",
SMTPPassword: "smtp-password",
SMTPFrom: "smtp-from",
AdminAccountUsername: "username",
AdminAccountEmail: "email",
AdminAccountPassword: "password",
AdminTransPath: "path",
}

View file

@ -1,13 +0,0 @@
package config
// LetsEncryptConfig wraps everything needed to manage letsencrypt certificates from within gotosocial.
type LetsEncryptConfig struct {
// Should letsencrypt certificate fetching be enabled?
Enabled bool `yaml:"enabled"`
// What port should the server listen for letsencrypt challenges on?
Port int `yaml:"port"`
// Where should certificates be stored?
CertDir string `yaml:"certDir"`
// Email address to pass to letsencrypt for notifications about certificate expiry etc.
EmailAddress string `yaml:"emailAddress"`
}

View file

@ -1,31 +0,0 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
// MediaConfig contains configuration for receiving and parsing media files and attachments
type MediaConfig struct {
// Max size of uploaded images in bytes
MaxImageSize int `yaml:"maxImageSize"`
// Max size of uploaded video in bytes
MaxVideoSize int `yaml:"maxVideoSize"`
// Minimum amount of chars required in an image description
MinDescriptionChars int `yaml:"minDescriptionChars"`
// Max amount of chars allowed in an image description
MaxDescriptionChars int `yaml:"maxDescriptionChars"`
}

View file

@ -1,30 +0,0 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
// OIDCConfig contains configuration values for openID connect (oauth) authorization by an external service such as Dex.
type OIDCConfig struct {
Enabled bool `yaml:"enabled"`
IDPName string `yaml:"idpName"`
SkipVerification bool `yaml:"skipVerification"`
Issuer string `yaml:"issuer"`
ClientID string `yaml:"clientID"`
ClientSecret string `yaml:"clientSecret"`
Scopes []string `yaml:"scopes"`
}

View file

@ -1,33 +0,0 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
// SMTPConfig holds configuration for sending emails using the smtp protocol.
type SMTPConfig struct {
// Host of the smtp server.
Host string `yaml:"host"`
// Port of the smtp server.
Port int `yaml:"port"`
// Username to use when authenticating with the smtp server.
Username string `yaml:"username"`
// Password to use when authenticating with the smtp server.
Password string `yaml:"password"`
// From address to use when sending emails.
From string `yaml:"from"`
}

View file

@ -1,33 +0,0 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
// StatusesConfig pertains to posting/deleting/interacting with statuses
type StatusesConfig struct {
// Maximum amount of characters allowed in a status, excluding CW
MaxChars int `yaml:"max_chars"`
// Maximum amount of characters allowed in a content-warning/spoiler field
CWMaxChars int `yaml:"cw_max_chars"`
// Maximum number of options allowed in a poll
PollMaxOptions int `yaml:"poll_max_options"`
// Maximum characters allowed per poll option
PollOptionMaxChars int `yaml:"poll_option_max_chars"`
// Maximum amount of media files allowed to be attached to one status
MaxMediaFiles int `yaml:"max_media_files"`
}

View file

@ -1,36 +0,0 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
// StorageConfig contains configuration for storage and serving of media files and attachments
type StorageConfig struct {
// Type of storage backend to use: currently only 'local' is supported.
// TODO: add S3 support here.
Backend string `yaml:"backend"`
// The base path for storing things. Should be an already-existing directory.
BasePath string `yaml:"basePath"`
// Protocol to use when *serving* media files from storage
ServeProtocol string `yaml:"serveProtocol"`
// Host to use when *serving* media files from storage
ServeHost string `yaml:"serveHost"`
// Base path to use when *serving* media files from storage
ServeBasePath string `yaml:"serveBasePath"`
}

90
internal/config/values.go Normal file
View file

@ -0,0 +1,90 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
// Values contains contains the type of each configuration value.
type Values struct {
LogLevel string
ApplicationName string
ConfigPath string
Host string
AccountDomain string
Protocol string
BindAddress string
Port int
TrustedProxies []string
SoftwareVersion string
DbType string
DbAddress string
DbPort int
DbUser string
DbPassword string
DbDatabase string
DbTLSMode string
DbTLSCACert string
WebTemplateBaseDir string
WebAssetBaseDir string
AccountsRegistrationOpen bool
AccountsApprovalRequired bool
AccountsReasonRequired bool
MediaImageMaxSize int
MediaVideoMaxSize int
MediaDescriptionMinChars int
MediaDescriptionMaxChars int
StorageBackend string
StorageBasePath string
StorageServeProtocol string
StorageServeHost string
StorageServeBasePath string
StatusesMaxChars int
StatusesCWMaxChars int
StatusesPollMaxOptions int
StatusesPollOptionMaxChars int
StatusesMediaMaxFiles int
LetsEncryptEnabled bool
LetsEncryptCertDir string
LetsEncryptEmailAddress string
LetsEncryptPort int
OIDCEnabled bool
OIDCIdpName string
OIDCSkipVerification bool
OIDCIssuer string
OIDCClientID string
OIDCClientSecret string
OIDCScopes []string
SMTPHost string
SMTPPort int
SMTPUsername string
SMTPPassword string
SMTPFrom string
AdminAccountUsername string
AdminAccountEmail string
AdminAccountPassword string
AdminTransPath string
}

View file

@ -18,12 +18,25 @@
package config
// AccountsConfig contains configuration to do with creating accounts, new registrations, and defaults.
type AccountsConfig struct {
// Do we want people to be able to just submit sign up requests, or do we want invite only?
OpenRegistration bool `yaml:"openRegistration"`
// Do sign up requests require approval from an admin/moderator?
RequireApproval bool `yaml:"requireApproval"`
// Do we require a reason for a sign up or is an empty string OK?
ReasonRequired bool `yaml:"reasonRequired"`
import (
"strings"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
func InitViper(f *pflag.FlagSet) error {
// environment variable stuff
// flag 'some-flag-name' becomes env var 'GTS_SOME_FLAG_NAME'
viper.SetEnvPrefix("gts")
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
viper.AutomaticEnv()
// flag stuff
// bind all of the flags in flagset to viper so that we can retrieve their values from the viper store
if err := viper.BindPFlags(f); err != nil {
return err
}
return nil
}