135 lines
4.1 KiB
Go
135 lines
4.1 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
)
|
|
|
|
type ConfigSSL struct {
|
|
HandleSSL bool `toml:"handle_ssl"` // Whether Linstrom should handle SSL encryption itself
|
|
// If Linstrom is to handle SSL, whether it should use LetsEncrypt for certificates
|
|
UseLetsEncrypt *bool `toml:"use_lets_encrypt"`
|
|
// Path to the certificate if Linstrom is to handle SSL while not using LetsEncrypt
|
|
CertificateFile *string `toml:"certificate_file"`
|
|
// Mail adress to use in case of using LetsEncrypt
|
|
AdminMail *string `toml:"admin_mail"`
|
|
}
|
|
|
|
type ConfigGeneral struct {
|
|
Domain string `toml:"domain"` // The domain this server operates under
|
|
FullDomain string `toml:"full_domain"` // The full url the server operates under (without port), eg "http://localhost", the public port will be appended as needed
|
|
PublicPort int `toml:"public_port"` // The public facing port, usually either 80 or 443
|
|
PrivatePort int `toml:"private_port"` // The port the server should launch at
|
|
// Explanation:
|
|
// The public port is the port to connect to from outside the server to access it.
|
|
// The private port is where the server will open for itself on launch
|
|
// Important for reverse proxies like nginx or traeffik
|
|
// Where you the public port would be either 80 (http) or 443 (https), but the private one could be 3000 for example
|
|
}
|
|
|
|
type ConfigAdmin struct {
|
|
Username string `toml:"username"`
|
|
PasswordHash string `toml:"password_hash"`
|
|
}
|
|
|
|
type ConfigStorage struct {
|
|
IsPostgres bool `toml:"is_postgres"`
|
|
Uri string `toml:"uri"`
|
|
}
|
|
|
|
type ConfigMail struct {
|
|
Host string `toml:"host"`
|
|
Port int `toml:"port"`
|
|
Username string `toml:"username"`
|
|
Password string `toml:"password"`
|
|
EncryptionOverwrite *string `toml:"encryption_overwrite,omitempty"`
|
|
KeepAliveOverwrite *bool `toml:"keep_alive_overwrite,omitempty"`
|
|
ConnectTimeoutSecondsOverwrite *int `toml:"connect_timeout_seconds_overwrite,omitempty"`
|
|
SendTimeoutSecondsOverwrite *int `toml:"send_timeout_seconds_overwrite,omitempty"`
|
|
TemplateOverwriteDirectory *string `toml:"template_overwrite_directory,omitempty"`
|
|
}
|
|
|
|
type Config struct {
|
|
General ConfigGeneral `toml:"general"`
|
|
SSL ConfigSSL `toml:"ssl"`
|
|
Admin ConfigAdmin `toml:"admin"`
|
|
Storage ConfigStorage `toml:"storage"`
|
|
Mail ConfigMail `toml:"mail"`
|
|
}
|
|
|
|
const DEFAULT_CONFIG_FILE_PATH = "config.toml"
|
|
|
|
// "Global" variable for accessing the config
|
|
// If nil, no config has been loaded yet
|
|
var Global *Config
|
|
|
|
var ErrGlobalConfigNotSet = errors.New("global config not set")
|
|
|
|
// The default config is for a local debug environment
|
|
var defaultConfig = Config{
|
|
General: ConfigGeneral{
|
|
Domain: "localhost",
|
|
PublicPort: 8080,
|
|
PrivatePort: 8080,
|
|
},
|
|
SSL: ConfigSSL{
|
|
HandleSSL: false,
|
|
UseLetsEncrypt: nil,
|
|
CertificateFile: nil,
|
|
AdminMail: nil,
|
|
},
|
|
Admin: ConfigAdmin{
|
|
Username: "admin",
|
|
PasswordHash: "", // No password
|
|
},
|
|
Storage: ConfigStorage{
|
|
IsPostgres: false,
|
|
Uri: "db.sqlite",
|
|
},
|
|
}
|
|
|
|
func LoadConfigFromFile(file string, tryDefaultPath, saveIntoGlobal bool) (*Config, error) {
|
|
conf := &Config{}
|
|
data, err := os.ReadFile(file)
|
|
if err != nil && !tryDefaultPath {
|
|
return nil, fmt.Errorf("failed to read config %s: %w", file, err)
|
|
}
|
|
if err != nil && tryDefaultPath {
|
|
conf, err = loadFromDefaultPath()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read custom and default config: %w", err)
|
|
}
|
|
}
|
|
err = toml.Unmarshal(data, &conf)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to convert from toml: %w", err)
|
|
}
|
|
if saveIntoGlobal {
|
|
Global = conf
|
|
}
|
|
return conf, nil
|
|
}
|
|
|
|
func loadFromDefaultPath() (*Config, error) {
|
|
data, err := os.ReadFile(DEFAULT_CONFIG_FILE_PATH)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(
|
|
"failed to load default config path %s: %w",
|
|
DEFAULT_CONFIG_FILE_PATH,
|
|
err,
|
|
)
|
|
}
|
|
conf := Config{}
|
|
err = toml.Unmarshal(data, &conf)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(
|
|
"failed to parse file content of %s as toml: %w",
|
|
DEFAULT_CONFIG_FILE_PATH,
|
|
err,
|
|
)
|
|
}
|
|
return &conf, nil
|
|
}
|