178 lines
4.4 KiB
Go
178 lines
4.4 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/spf13/viper"
|
|
"zeevdiukman.com/zprox/pkg/helper"
|
|
)
|
|
|
|
const Viper_File_Name string = "config"
|
|
const Viper_File_Type string = "yaml"
|
|
const Viper_File_Path string = "."
|
|
|
|
var c *Config
|
|
|
|
func init() {
|
|
helper.New().Screen.Clear()
|
|
c = createConfig()
|
|
|
|
}
|
|
func Wrapper(fn func(c *Config)) {
|
|
fn(c)
|
|
}
|
|
func Get() *Config {
|
|
return c
|
|
}
|
|
func createConfig() *Config {
|
|
c := &Config{}
|
|
c.initViper()
|
|
c.setViperOptions(Viper_File_Name, Viper_File_Type, Viper_File_Path)
|
|
c.viperReadYaml()
|
|
c.viperUnmarshalYaml()
|
|
c.initDomainToProxyNameMap()
|
|
c.initDomainToProxyAuthName()
|
|
c.initDomainToCertName()
|
|
c.initOpenIDEndPoints()
|
|
return c
|
|
}
|
|
|
|
func (c *Config) initViper() {
|
|
c.Viper = viper.New()
|
|
}
|
|
|
|
func (c *Config) setViperOptions(fileName string, fileExtention string, filePath string) {
|
|
c.Viper.SetConfigName(fileName)
|
|
c.Viper.SetConfigType(fileExtention)
|
|
c.Viper.AddConfigPath(filePath)
|
|
}
|
|
|
|
func (c *Config) viperReadYaml() {
|
|
err := c.Viper.ReadInConfig()
|
|
if err != nil {
|
|
log.Fatalf("Error reading config file, %s", err)
|
|
}
|
|
}
|
|
func (c *Config) viperUnmarshalYaml() {
|
|
err := c.Viper.Unmarshal(&c)
|
|
if err != nil {
|
|
log.Fatalf("Unable to decode into struct, %v", err)
|
|
}
|
|
}
|
|
|
|
func (eps *EntryPoints) ForEach(fn func(epName string, epConfig *EntryPoint)) {
|
|
for epName, epConfig := range *eps {
|
|
fn(epName, &epConfig)
|
|
}
|
|
}
|
|
|
|
func (rp *ReverseProxies) ForEach(fn func(rpName string, rpConfig *ReverseProxy)) {
|
|
for rpName, rpData := range *rp {
|
|
fn(rpName, &rpData)
|
|
}
|
|
}
|
|
|
|
func (c *Config) fetchEndPointsByAuthName(authName string) map[string]any {
|
|
configURL := c.KeycloakWellknownURL(authName)
|
|
resp := helper.IsFetchOK[EndPoints](configURL, "", http.Get)
|
|
respByes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
log.Println(err.Error())
|
|
}
|
|
data := map[string]any{}
|
|
json.Unmarshal(respByes, &data)
|
|
return data
|
|
}
|
|
|
|
func (c *Config) initOpenIDEndPoints() {
|
|
for authName := range c.Auth {
|
|
data := c.fetchEndPointsByAuthName(authName)
|
|
|
|
c.Auth[authName].OpenID.EndPoints = &EndPoints{
|
|
Issuer: data["issuer"].(string),
|
|
Auth: data["authorization_endpoint"].(string),
|
|
Introspection: data["introspection_endpoint"].(string),
|
|
Token: data["token_endpoint"].(string),
|
|
UserInfo: data["userinfo_endpoint"].(string),
|
|
Logout: data["end_session_endpoint"].(string),
|
|
JwksUri: data["jwks_uri"].(string),
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
func (c *Config) KeycloakWellknownURL(authName string) string {
|
|
|
|
if _, ok := c.Auth[authName]; !ok {
|
|
return ""
|
|
}
|
|
hostUrl := c.Auth[authName].OpenID.Host
|
|
realm := c.Auth[authName].OpenID.Realm
|
|
configPath := c.Auth[authName].OpenID.ConfigPath
|
|
u := hostUrl
|
|
u += strings.ReplaceAll(configPath, "{{realm}}", realm)
|
|
return u
|
|
}
|
|
|
|
func (c *Config) initDomainToProxyNameMap() {
|
|
mp := make(map[string]string)
|
|
c.ReverseProxies.ForEach(func(rpName string, rpConfig *ReverseProxy) {
|
|
mp[rpConfig.Domain] = rpName
|
|
})
|
|
c.DataMaps.DomainToProxy = mp
|
|
}
|
|
func (c *Config) initDomainToProxyAuthName() {
|
|
authMap := map[string]int{}
|
|
for authName := range c.Auth {
|
|
authMap[authName] = 1
|
|
}
|
|
mp := make(map[string]string)
|
|
c.ReverseProxies.ForEach(func(rpName string, rpConfig *ReverseProxy) {
|
|
if v, ok := authMap[rpConfig.Auth]; ok && v == 1 {
|
|
mp[rpConfig.Domain] = rpConfig.Auth
|
|
}
|
|
})
|
|
c.DataMaps.DomainToAuth = mp
|
|
}
|
|
func (c *Config) initDomainToCertName() {
|
|
crtMap := map[string]int{}
|
|
for crtName := range c.TLS.Certs {
|
|
crtMap[crtName] = 1
|
|
}
|
|
mp := make(map[string]string)
|
|
c.ReverseProxies.ForEach(func(rpName string, rpConfig *ReverseProxy) {
|
|
if v, ok := crtMap[rpConfig.TLS.Certs]; ok && v == 1 {
|
|
mp[rpConfig.Domain] = rpConfig.TLS.Certs
|
|
}
|
|
mp[rpConfig.Domain] = rpConfig.TLS.Certs
|
|
})
|
|
c.DataMaps.DomainToCert = mp
|
|
}
|
|
func (c *Config) GetAuthNameByDomain(domain string) string {
|
|
return c.DataMaps.DomainToAuth[domain]
|
|
}
|
|
func (c *Config) GetProxyNameByDomain(domain string) string {
|
|
return c.DataMaps.DomainToProxy[domain]
|
|
}
|
|
func (c *Config) GetCertNameByDomain(domain string) string {
|
|
return c.DataMaps.DomainToCert[domain]
|
|
}
|
|
func (c *Config) GetCertsPairByDomain(domain string) (string, string) {
|
|
var crt string
|
|
var key string
|
|
certName := c.DataMaps.DomainToCert[domain]
|
|
crt = c.TLS.Certs[certName].Cert
|
|
key = c.TLS.Certs[certName].Key
|
|
if !(certName != "" && crt == "" && key != "") {
|
|
certName = "default"
|
|
crt = c.TLS.Certs[certName].Cert
|
|
key = c.TLS.Certs[certName].Key
|
|
}
|
|
|
|
return crt, key
|
|
|
|
}
|