2024-02-11 04:50:46 +00:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding"
|
|
|
|
"encoding/base64"
|
2024-02-11 21:27:24 +00:00
|
|
|
"fmt"
|
|
|
|
"github.com/fatih/structs"
|
|
|
|
"github.com/iancoleman/strcase"
|
2024-02-11 04:50:46 +00:00
|
|
|
"github.com/spf13/viper"
|
|
|
|
"go.uber.org/fx"
|
|
|
|
"go.uber.org/zap"
|
2024-02-11 21:27:24 +00:00
|
|
|
"reflect"
|
2024-02-11 04:50:46 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ed25519"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PrivateKey ed25519.PrivateKey
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ encoding.TextUnmarshaler = (*PrivateKey)(nil)
|
2024-02-11 21:27:24 +00:00
|
|
|
_ encoding.TextMarshaler = (*PrivateKey)(nil)
|
2024-02-11 04:50:46 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func (p *PrivateKey) UnmarshalText(text []byte) error {
|
|
|
|
dec, err := base64.StdEncoding.DecodeString(string(text))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = dec
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-02-11 21:27:24 +00:00
|
|
|
func (p *PrivateKey) MarshalText() ([]byte, error) {
|
|
|
|
return []byte(base64.StdEncoding.EncodeToString(*p)), nil
|
|
|
|
}
|
|
|
|
|
2024-02-11 04:50:46 +00:00
|
|
|
type Config struct {
|
2024-02-11 21:27:24 +00:00
|
|
|
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"`
|
2024-02-11 05:23:46 +00:00
|
|
|
Oauth OauthConfig
|
|
|
|
JwtPrivateKey PrivateKey
|
2024-02-11 21:27:24 +00:00
|
|
|
Domain string `mapstructure:"domain" structs:"domain"`
|
|
|
|
GiteaWebHookSecret string `mapstructure:"gitea_webhook_secret" structs:"gitea_webhook_secret"`
|
2024-02-11 04:50:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type OauthConfig struct {
|
2024-02-11 21:27:24 +00:00
|
|
|
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"`
|
2024-02-11 04:50:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2024-02-11 21:27:24 +00:00
|
|
|
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()
|
2024-02-11 04:50:46 +00:00
|
|
|
if err != nil {
|
2024-02-11 21:27:24 +00:00
|
|
|
err = viper.SafeWriteConfig()
|
2024-02-11 04:50:46 +00:00
|
|
|
if err != nil {
|
|
|
|
logger.Fatal("Error writing config file", zap.Error(err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-11 21:27:24 +00:00
|
|
|
err = viper.Unmarshal(c)
|
2024-02-11 04:50:46 +00:00
|
|
|
if err != nil {
|
|
|
|
logger.Fatal("Error unmarshalling config", zap.Error(err))
|
|
|
|
}
|
|
|
|
|
2024-02-11 21:27:24 +00:00
|
|
|
/* err = viper.UnmarshalKey("jwt_private_key", &c.JwtPrivateKey, viper.DecodeHook(mapstructure.TextUnmarshallerHookFunc()))
|
|
|
|
if err != nil {
|
|
|
|
logger.Fatal("Error unmarshalling jwtPrivateKey", zap.Error(err))
|
|
|
|
}*/
|
2024-02-11 04:50:46 +00:00
|
|
|
|
|
|
|
if len(c.GiteaUrl) == 0 {
|
|
|
|
logger.Fatal("Gitea URL is required")
|
|
|
|
}
|
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
2024-02-11 19:50:53 +00:00
|
|
|
|
|
|
|
func SaveConfig(cfg *Config) error {
|
2024-02-11 21:27:24 +00:00
|
|
|
data := structs.New(cfg)
|
|
|
|
|
|
|
|
for _, field := range data.Fields() {
|
|
|
|
processFields(field, nil)
|
2024-02-11 19:50:53 +00:00
|
|
|
}
|
|
|
|
|
2024-02-11 21:27:24 +00:00
|
|
|
/* 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))
|
|
|
|
}
|
|
|
|
*/
|
2024-02-11 19:50:53 +00:00
|
|
|
return viper.WriteConfig()
|
|
|
|
}
|
2024-02-11 21:27:24 +00:00
|
|
|
|
|
|
|
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())
|
|
|
|
}
|