refactor: viper can't save a struct, got to do it ourselves

This commit is contained in:
Derrick Hammer 2024-02-11 16:27:24 -05:00
parent 0cf1b8827a
commit 6d20106bb5
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
2 changed files with 81 additions and 35 deletions

View File

@ -3,10 +3,13 @@ package config
import (
"encoding"
"encoding/base64"
"github.com/mitchellh/mapstructure"
"fmt"
"github.com/fatih/structs"
"github.com/iancoleman/strcase"
"github.com/spf13/viper"
"go.uber.org/fx"
"go.uber.org/zap"
"reflect"
)
import (
@ -17,6 +20,7 @@ type PrivateKey ed25519.PrivateKey
var (
_ encoding.TextUnmarshaler = (*PrivateKey)(nil)
_ encoding.TextMarshaler = (*PrivateKey)(nil)
)
func (p *PrivateKey) UnmarshalText(text []byte) error {
@ -30,23 +34,27 @@ func (p *PrivateKey) UnmarshalText(text []byte) error {
return nil
}
func (p *PrivateKey) MarshalText() ([]byte, error) {
return []byte(base64.StdEncoding.EncodeToString(*p)), nil
}
type Config struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
GiteaUrl string `mapstructure:"gitea_url"`
DbPath string `mapstructure:"db_path"`
Host string `mapstructure:"host" structs:"host"`
Port int `mapstructure:"port" structs:"port"`
GiteaUrl string `mapstructure:"gitea_url" structs:"gitea_url"`
DbPath string `mapstructure:"db_path" structs:"db_path"`
Oauth OauthConfig
JwtPrivateKey PrivateKey
Domain string `mapstructure:"domain"`
GiteaWebHookSecret string `mapstructure:"gitea_webhook_secret"`
Domain string `mapstructure:"domain" structs:"domain"`
GiteaWebHookSecret string `mapstructure:"gitea_webhook_secret" structs:"gitea_webhook_secret"`
}
type OauthConfig struct {
Authorization string `mapstructure:"authorization"`
Token string `mapstructure:"token"`
ClientId string `mapstructure:"client_id"`
ClientSecret string `mapstructure:"client_secret"`
RefreshToken string `mapstructure:"refresh_token"`
Authorization string `mapstructure:"authorization" structs:"authorization"`
Token string `mapstructure:"token" structs:"token"`
ClientId string `mapstructure:"client_id" structs:"client_id"`
ClientSecret string `mapstructure:"client_secret" structs:"client_secret"`
RefreshToken string `mapstructure:"refresh_token" structs:"refresh_token"`
}
var Module = fx.Module("config",
@ -58,8 +66,6 @@ var Module = fx.Module("config",
func NewConfig(logger *zap.Logger) *Config {
c := &Config{}
cfg := viper.New()
_, sk, err := ed25519.GenerateKey(nil)
if err != nil {
@ -67,35 +73,35 @@ func NewConfig(logger *zap.Logger) *Config {
}
// Set the default values
cfg.SetDefault("host", "localhost")
cfg.SetDefault("port", 8080)
cfg.SetDefault("gitea_url", "")
cfg.SetDefault("db_path", "data.db")
cfg.SetDefault("jwt_private_key", base64.StdEncoding.EncodeToString(sk))
cfg.SetDefault("oauth.client_id", "")
cfg.SetDefault("oauth.client_secret", "")
viper.SetDefault("host", "localhost")
viper.SetDefault("port", 8080)
viper.SetDefault("gitea_url", "")
viper.SetDefault("db_path", "data.db")
viper.SetDefault("jwt_private_key", base64.StdEncoding.EncodeToString(sk))
viper.SetDefault("oauth.client_id", "")
viper.SetDefault("oauth.client_secret", "")
cfg.AddConfigPath(".")
cfg.AddConfigPath("/etc/gitea-github-proxy")
cfg.SetConfigName("config")
cfg.SetConfigType("yaml")
err = cfg.ReadInConfig()
viper.AddConfigPath(".")
viper.AddConfigPath("/etc/gitea-github-proxy")
viper.SetConfigName("config")
viper.SetConfigType("yaml")
err = viper.ReadInConfig()
if err != nil {
err = cfg.SafeWriteConfig()
err = viper.SafeWriteConfig()
if err != nil {
logger.Fatal("Error writing config file", zap.Error(err))
}
}
err = cfg.Unmarshal(c)
err = viper.Unmarshal(c)
if err != nil {
logger.Fatal("Error unmarshalling config", zap.Error(err))
}
err = cfg.UnmarshalKey("jwt_private_key", &c.JwtPrivateKey, viper.DecodeHook(mapstructure.TextUnmarshallerHookFunc()))
if err != nil {
logger.Fatal("Error unmarshalling jwtPrivateKey", zap.Error(err))
}
/* err = viper.UnmarshalKey("jwt_private_key", &c.JwtPrivateKey, viper.DecodeHook(mapstructure.TextUnmarshallerHookFunc()))
if err != nil {
logger.Fatal("Error unmarshalling jwtPrivateKey", zap.Error(err))
}*/
if len(c.GiteaUrl) == 0 {
logger.Fatal("Gitea URL is required")
@ -105,10 +111,48 @@ func NewConfig(logger *zap.Logger) *Config {
}
func SaveConfig(cfg *Config) error {
err := viper.Unmarshal(cfg)
if err != nil {
return err
data := structs.New(cfg)
for _, field := range data.Fields() {
processFields(field, nil)
}
/* if field, ok := interface{}(cfg.JwtPrivateKey).(encoding.TextMarshaler); ok {
text, err := field.MarshalText()
if err != nil {
return err
}
viper.Set("jwt_private_key", string(text))
}
*/
return viper.WriteConfig()
}
func processFields(f *structs.Field, parent *structs.Field) {
if f.IsZero() {
return
}
if f.Kind() == reflect.Struct {
fields := f.Fields()
if len(fields) > 0 {
for _, field := range fields {
processFields(field, f)
}
return
}
}
name := ""
if parent != nil {
name = fmt.Sprintf("%s.%s", parent.Name(), f.Name())
} else {
name = f.Name()
}
name = strcase.ToSnakeWithIgnore(name, ".")
viper.Set(name, f.Value())
}

2
go.mod
View File

@ -5,9 +5,11 @@ go 1.21
require (
code.gitea.io/gitea v1.21.5
code.gitea.io/sdk/gitea v0.17.1
github.com/fatih/structs v1.1.0
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/google/go-github/v59 v59.0.0
github.com/gorilla/mux v1.8.1
github.com/iancoleman/strcase v0.3.0
github.com/mitchellh/mapstructure v1.5.0
github.com/spf13/viper v1.18.2
go.uber.org/fx v1.20.1