package config import ( "fmt" "golang.org/x/crypto/bcrypt" "gopkg.in/yaml.v3" "os" ) type ( Configuration struct { Server ServerConfiguration `yaml:"server"` Database DatabaseConfiguration `yaml:"database"` Features FeaturesConfiguration `yaml:"features"` Path PathConfiguration `yaml:"path"` } PathConfiguration struct { Cache string `yaml:"cache"` Storage string `yaml:"storage"` RSAKey string `yaml:"rsa_key"` } ServerConfiguration struct { Port int `yaml:"port"` PingEndPoint bool `yaml:"ping"` Compress bool `yaml:"compress"` } DatabaseConfiguration struct { URL string `yaml:"url"` } FeaturesConfiguration struct { AllowRegister bool `yaml:"allow_register"` PasswordHashCost *int `yaml:"password_hash_cost"` } ) func Load(path string) (Configuration, error) { configYamlContent, err := os.ReadFile(path) if err != nil { return Configuration{}, err } var config Configuration if err := yaml.Unmarshal(configYamlContent, &config); err != nil { return Configuration{}, err } if err := checkConfig(config); err != nil { return Configuration{}, err } return config, nil } func checkConfig(c Configuration) error { if c.Features.PasswordHashCost == nil { c.Features.PasswordHashCost = new(int) *c.Features.PasswordHashCost = bcrypt.DefaultCost } else if *c.Features.PasswordHashCost < bcrypt.MinCost && *c.Features.PasswordHashCost > bcrypt.MaxCost { return fmt.Errorf("password_hash_cost is not on the supported range (%d < x < %d)", bcrypt.MinCost, bcrypt.MaxCost) } if _, err := os.Stat(c.Path.Storage); err != nil { return nil } if _, err := os.Stat(c.Path.Cache); err != nil { return err } return nil }