feat: unified config (#533)

* chore: add yaml config ref

* feat: add initial implementation of a traefik like cli

* refactor: remove dependency on traefik

* chore: update example env

* refactor: update build

* chore: remove unused code

* fix: fix translations not loading

* feat: add experimental config file support

* chore: mod tidy

* fix: review comments

* refactor: move tinyauth to separate package

* chore: add quotes to all env variables

* chore: resolve go mod and sum conflicts

* chore: go mod tidy

* fix: review comments
This commit is contained in:
Stavros
2025-12-22 22:13:40 +02:00
committed by GitHub
parent f3d2e14535
commit 03ed18343e
46 changed files with 1074 additions and 1259 deletions

View File

@@ -43,7 +43,7 @@ func NewBootstrapApp(config config.Config) *BootstrapApp {
func (app *BootstrapApp) Setup() error {
// Parse users
users, err := utils.GetUsers(app.config.Users, app.config.UsersFile)
users, err := utils.GetUsers(app.config.Auth.Users, app.config.Auth.UsersFile)
if err != nil {
return err
@@ -51,14 +51,35 @@ func (app *BootstrapApp) Setup() error {
app.context.users = users
// Get OAuth configs
oauthProviders, err := utils.GetOAuthProvidersConfig(os.Environ(), os.Args, app.config.AppURL)
// Setup OAuth providers
app.context.oauthProviders = app.config.OAuth.Providers
if err != nil {
return err
for name, provider := range app.context.oauthProviders {
secret := utils.GetSecret(provider.ClientSecret, provider.ClientSecretFile)
provider.ClientSecret = secret
provider.ClientSecretFile = ""
app.context.oauthProviders[name] = provider
}
app.context.oauthProviders = oauthProviders
for id := range config.OverrideProviders {
if provider, exists := app.context.oauthProviders[id]; exists {
if provider.RedirectURL == "" {
provider.RedirectURL = app.config.AppURL + "/api/oauth/callback/" + id
app.context.oauthProviders[id] = provider
}
}
}
for id, provider := range app.context.oauthProviders {
if provider.Name == "" {
if name, ok := config.OverrideProviders[id]; ok {
provider.Name = name
} else {
provider.Name = utils.Capitalize(id)
}
}
app.context.oauthProviders[id] = provider
}
// Get cookie domain
cookieDomain, err := utils.GetCookieDomain(app.config.AppURL)
@@ -98,7 +119,7 @@ func (app *BootstrapApp) Setup() error {
// Configured providers
configuredProviders := make([]controller.Provider, 0)
for id, provider := range oauthProviders {
for id, provider := range app.context.oauthProviders {
configuredProviders = append(configuredProviders, controller.Provider{
Name: provider.Name,
ID: id,
@@ -144,17 +165,17 @@ func (app *BootstrapApp) Setup() error {
}
// If we have an socket path, bind to it
if app.config.SocketPath != "" {
if _, err := os.Stat(app.config.SocketPath); err == nil {
log.Info().Msgf("Removing existing socket file %s", app.config.SocketPath)
err := os.Remove(app.config.SocketPath)
if app.config.Server.SocketPath != "" {
if _, err := os.Stat(app.config.Server.SocketPath); err == nil {
log.Info().Msgf("Removing existing socket file %s", app.config.Server.SocketPath)
err := os.Remove(app.config.Server.SocketPath)
if err != nil {
return fmt.Errorf("failed to remove existing socket file: %w", err)
}
}
log.Info().Msgf("Starting server on unix socket %s", app.config.SocketPath)
if err := router.RunUnix(app.config.SocketPath); err != nil {
log.Info().Msgf("Starting server on unix socket %s", app.config.Server.SocketPath)
if err := router.RunUnix(app.config.Server.SocketPath); err != nil {
log.Fatal().Err(err).Msg("Failed to start server")
}
@@ -162,7 +183,7 @@ func (app *BootstrapApp) Setup() error {
}
// Start server
address := fmt.Sprintf("%s:%d", app.config.Address, app.config.Port)
address := fmt.Sprintf("%s:%d", app.config.Server.Address, app.config.Server.Port)
log.Info().Msgf("Starting server on %s", address)
if err := router.Run(address); err != nil {
log.Fatal().Err(err).Msg("Failed to start server")
@@ -193,7 +214,7 @@ func (app *BootstrapApp) heartbeat() {
}
client := &http.Client{
Timeout: time.Duration(10) * time.Second, // The server should never take more than 10 seconds to respond
Timeout: 30 * time.Second, // The server should never take more than 30 seconds to respond
}
heartbeatURL := config.ApiServer + "/v1/instances/heartbeat"

View File

@@ -13,8 +13,8 @@ func (app *BootstrapApp) setupRouter() (*gin.Engine, error) {
engine := gin.New()
engine.Use(gin.Recovery())
if len(app.config.TrustedProxies) > 0 {
err := engine.SetTrustedProxies(strings.Split(app.config.TrustedProxies, ","))
if len(app.config.Server.TrustedProxies) > 0 {
err := engine.SetTrustedProxies(strings.Split(app.config.Server.TrustedProxies, ","))
if err != nil {
return nil, fmt.Errorf("failed to set trusted proxies: %w", err)
@@ -57,12 +57,12 @@ func (app *BootstrapApp) setupRouter() (*gin.Engine, error) {
contextController := controller.NewContextController(controller.ContextControllerConfig{
Providers: app.context.configuredProviders,
Title: app.config.Title,
Title: app.config.UI.Title,
AppURL: app.config.AppURL,
CookieDomain: app.context.cookieDomain,
ForgotPasswordMessage: app.config.ForgotPasswordMessage,
BackgroundImage: app.config.BackgroundImage,
OAuthAutoRedirect: app.config.OAuthAutoRedirect,
ForgotPasswordMessage: app.config.UI.ForgotPasswordMessage,
BackgroundImage: app.config.UI.BackgroundImage,
OAuthAutoRedirect: app.config.OAuth.AutoRedirect,
DisableUIWarnings: app.config.DisableUIWarnings,
}, apiRouter)
@@ -70,7 +70,7 @@ func (app *BootstrapApp) setupRouter() (*gin.Engine, error) {
oauthController := controller.NewOAuthController(controller.OAuthControllerConfig{
AppURL: app.config.AppURL,
SecureCookie: app.config.SecureCookie,
SecureCookie: app.config.Auth.SecureCookie,
CSRFCookieName: app.context.csrfCookieName,
RedirectCookieName: app.context.redirectCookieName,
CookieDomain: app.context.cookieDomain,

View File

@@ -31,12 +31,12 @@ func (app *BootstrapApp) initServices() (Services, error) {
services.databaseService = databaseService
ldapService := service.NewLdapService(service.LdapServiceConfig{
Address: app.config.LdapAddress,
BindDN: app.config.LdapBindDN,
BindPassword: app.config.LdapBindPassword,
BaseDN: app.config.LdapBaseDN,
Insecure: app.config.LdapInsecure,
SearchFilter: app.config.LdapSearchFilter,
Address: app.config.Ldap.Address,
BindDN: app.config.Ldap.BindDN,
BindPassword: app.config.Ldap.BindPassword,
BaseDN: app.config.Ldap.BaseDN,
Insecure: app.config.Ldap.Insecure,
SearchFilter: app.config.Ldap.SearchFilter,
})
err = ldapService.Init()
@@ -69,12 +69,12 @@ func (app *BootstrapApp) initServices() (Services, error) {
authService := service.NewAuthService(service.AuthServiceConfig{
Users: app.context.users,
OauthWhitelist: app.config.OAuthWhitelist,
SessionExpiry: app.config.SessionExpiry,
SecureCookie: app.config.SecureCookie,
OauthWhitelist: app.config.OAuth.Whitelist,
SessionExpiry: app.config.Auth.SessionExpiry,
SecureCookie: app.config.Auth.SecureCookie,
CookieDomain: app.context.cookieDomain,
LoginTimeout: app.config.LoginTimeout,
LoginMaxRetries: app.config.LoginMaxRetries,
LoginTimeout: app.config.Auth.LoginTimeout,
LoginMaxRetries: app.config.Auth.LoginMaxRetries,
SessionCookieName: app.context.sessionCookieName,
}, dockerService, ldapService, databaseService.GetDatabase())