gitea-github-proxy/config/config.go

159 lines
3.6 KiB
Go

package config
import (
"encoding"
"encoding/base64"
"fmt"
"github.com/fatih/structs"
"github.com/iancoleman/strcase"
"github.com/spf13/viper"
"go.uber.org/fx"
"go.uber.org/zap"
"reflect"
)
import (
"crypto/ed25519"
)
type PrivateKey ed25519.PrivateKey
var (
_ encoding.TextUnmarshaler = (*PrivateKey)(nil)
_ encoding.TextMarshaler = (*PrivateKey)(nil)
)
func (p *PrivateKey) UnmarshalText(text []byte) error {
dec, err := base64.StdEncoding.DecodeString(string(text))
if err != nil {
return err
}
*p = dec
return nil
}
func (p *PrivateKey) MarshalText() ([]byte, error) {
return []byte(base64.StdEncoding.EncodeToString(*p)), nil
}
type Config struct {
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" structs:"domain"`
GiteaWebHookSecret string `mapstructure:"gitea_webhook_secret" structs:"gitea_webhook_secret"`
}
type OauthConfig struct {
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",
fx.Options(
fx.Provide(NewConfig),
),
)
func NewConfig(logger *zap.Logger) *Config {
c := &Config{}
_, sk, err := ed25519.GenerateKey(nil)
if err != nil {
logger.Fatal("Error generating private key", zap.Error(err))
}
// Set the default values
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", "")
viper.AddConfigPath(".")
viper.AddConfigPath("/etc/gitea-github-proxy")
viper.SetConfigName("config")
viper.SetConfigType("yaml")
err = viper.ReadInConfig()
if err != nil {
err = viper.SafeWriteConfig()
if err != nil {
logger.Fatal("Error writing config file", zap.Error(err))
}
}
err = viper.Unmarshal(c)
if err != nil {
logger.Fatal("Error unmarshalling config", 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")
}
return c
}
func SaveConfig(cfg *Config) error {
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())
}