2024-05-31 15:21:29 +00:00
package config
2024-08-22 17:57:53 +00:00
import (
"errors"
"fmt"
"os"
"github.com/BurntSushi/toml"
)
2024-05-31 15:21:29 +00:00
type ConfigSSL struct {
2024-08-22 17:57:53 +00:00
HandleSSL bool ` toml:"handle_ssl" ` // Whether Linstrom should handle SSL encryption itself
2024-05-31 15:21:29 +00:00
// If Linstrom is to handle SSL, whether it should use LetsEncrypt for certificates
2024-08-22 17:57:53 +00:00
UseLetsEncrypt * bool ` toml:"use_lets_encrypt" `
2024-05-31 15:21:29 +00:00
// Path to the certificate if Linstrom is to handle SSL while not using LetsEncrypt
2024-08-22 17:57:53 +00:00
CertificateFile * string ` toml:"certificate_file" `
2024-05-31 15:21:29 +00:00
// Mail adress to use in case of using LetsEncrypt
2024-08-22 17:57:53 +00:00
AdminMail * string ` toml:"admin_mail" `
2024-05-31 15:21:29 +00:00
}
type ConfigGeneral struct {
2024-08-22 17:57:53 +00:00
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
2024-05-31 15:21:29 +00:00
}
type ConfigAdmin struct {
2024-08-22 17:57:53 +00:00
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" `
2024-05-31 15:21:29 +00:00
}
type Config struct {
2024-08-22 17:57:53 +00:00
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
2024-05-31 15:21:29 +00:00
}