From e55f29ccf967b3827fe928abbfbf7243a22cd027 Mon Sep 17 00:00:00 2001 From: Stavros Date: Sat, 5 Jul 2025 02:53:16 +0300 Subject: [PATCH] feat: add insecure option for self-signed certificates --- cmd/root.go | 18 +++++++++++------- internal/auth/auth.go | 17 +++++++++-------- internal/handlers/handlers.go | 4 ++-- internal/hooks/hooks.go | 8 ++++---- internal/ldap/ldap.go | 12 +++++------- internal/types/config.go | 6 ++++-- 6 files changed, 35 insertions(+), 30 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 3d79aa4..37b8454 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -59,10 +59,6 @@ var rootCmd = &cobra.Command{ users, err := utils.GetUsers(config.Users, config.UsersFile) HandleError(err, "Failed to parse users") - if len(users) == 0 && !utils.OAuthConfigured(config) { - HandleError(errors.New("no users or OAuth configured"), "No users or OAuth configured") - } - // Get domain log.Debug().Msg("Getting domain") domain, err := utils.GetUpperDomain(config.AppURL) @@ -152,9 +148,10 @@ var rootCmd = &cobra.Command{ ldapConfig := types.LdapConfig{ Address: config.LdapAddress, - BindUser: config.LdapBindUser, + BindDN: config.LdapBindDN, BindPassword: config.LdapBindPassword, BaseDN: config.LdapBaseDN, + Insecure: config.LdapInsecure, } // Create LDAP service @@ -164,6 +161,11 @@ var rootCmd = &cobra.Command{ log.Info().Msg("LDAP not configured, using local users or OAuth") } + // Check if we have any users configured + if len(users) == 0 && !utils.OAuthConfigured(config) && ldapService == nil { + HandleError(errors.New("err no users"), "Unable to find a source of users") + } + // Create auth service auth := auth.NewAuth(authConfig, docker, ldapService) @@ -243,9 +245,10 @@ func init() { rootCmd.Flags().String("forgot-password-message", "You can reset your password by changing the `USERS` environment variable.", "Message to show on the forgot password page.") rootCmd.Flags().String("background-image", "/background.jpg", "Background image URL for the login page.") rootCmd.Flags().String("ldap-address", "", "LDAP server address (e.g. ldap://localhost:389).") - rootCmd.Flags().String("ldap-bind-user", "", "LDAP bind user.") + rootCmd.Flags().String("ldap-bind-dn", "", "LDAP bind DN (e.g. uid=user,dc=example,dc=com).") rootCmd.Flags().String("ldap-bind-password", "", "LDAP bind password.") rootCmd.Flags().String("ldap-base-dn", "", "LDAP base DN (e.g. dc=example,dc=com).") + rootCmd.Flags().Bool("ldap-insecure", false, "Skip certificate verification for the LDAP server.") // Bind flags to environment viper.BindEnv("port", "PORT") @@ -282,9 +285,10 @@ func init() { viper.BindEnv("forgot-password-message", "FORGOT_PASSWORD_MESSAGE") viper.BindEnv("background-image", "BACKGROUND_IMAGE") viper.BindEnv("ldap-address", "LDAP_ADDRESS") - viper.BindEnv("ldap-bind-user", "LDAP_BIND_USER") + viper.BindEnv("ldap-bind-dn", "LDAP_BIND_DN") viper.BindEnv("ldap-bind-password", "LDAP_BIND_PASSWORD") viper.BindEnv("ldap-base-dn", "LDAP_BASE_DN") + viper.BindEnv("ldap-insecure", "LDAP_INSECURE") // Bind flags to viper viper.BindPFlags(rootCmd.Flags()) diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 8f0fccf..73312b2 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -71,16 +71,17 @@ func (auth *Auth) GetSession(c *gin.Context) (*sessions.Session, error) { return session, nil } -func (auth *Auth) GetUser(username string) types.UserSearch { +func (auth *Auth) SearchUser(username string) types.UserSearch { // Loop through users and return the user if the username matches log.Debug().Str("username", username).Msg("Searching for user") - for _, user := range auth.Config.Users { - if user.Username == username { - return types.UserSearch{ - Username: user.Username, - Type: "local", - } + if auth.GetLocalUser(username).Username != "" { + log.Debug().Str("username", username).Msg("Found local user") + + // If user found, return a user with the username and type "local" + return types.UserSearch{ + Username: username, + Type: "local", } } @@ -126,7 +127,7 @@ func (auth *Auth) VerifyUser(search types.UserSearch, password string) bool { } // If bind is successful, rebind with the LDAP bind user - auth.LDAP.Bind(auth.LDAP.Config.BindUser, auth.LDAP.Config.BindPassword) + auth.LDAP.Bind(auth.LDAP.Config.BindDN, auth.LDAP.Config.BindPassword) log.Debug().Str("username", search.Username).Msg("LDAP authentication successful") // Return true if the bind was successful diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index d2228de..6b23c42 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -362,8 +362,8 @@ func (h *Handlers) LoginHandler(c *gin.Context) { return } - // Get user based on username - userSearch := h.Auth.GetUser(login.Username) + // Search for a user based on username + userSearch := h.Auth.SearchUser(login.Username) log.Debug().Interface("userSearch", userSearch).Msg("Searching for user") diff --git a/internal/hooks/hooks.go b/internal/hooks/hooks.go index a264fe2..e5341a3 100644 --- a/internal/hooks/hooks.go +++ b/internal/hooks/hooks.go @@ -35,8 +35,8 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) types.UserContext { if basic != nil { log.Debug().Msg("Got basic auth") - // Get user - userSearch := hooks.Auth.GetUser(basic.Username) + // Search for a user based on username + userSearch := hooks.Auth.SearchUser(basic.Username) if userSearch.Type == "" { log.Error().Str("username", basic.Username).Msg("User does not exist") @@ -104,8 +104,8 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) types.UserContext { if cookie.Provider == "username" { log.Debug().Msg("Provider is username") - // Get user - userSearch := hooks.Auth.GetUser(cookie.Username) + // Search for the user with the username + userSearch := hooks.Auth.SearchUser(cookie.Username) if userSearch.Type == "" { log.Error().Str("username", cookie.Username).Msg("User does not exist") diff --git a/internal/ldap/ldap.go b/internal/ldap/ldap.go index 7a83390..4bb1538 100644 --- a/internal/ldap/ldap.go +++ b/internal/ldap/ldap.go @@ -1,6 +1,7 @@ package ldap import ( + "crypto/tls" "fmt" "tinyauth/internal/types" @@ -15,18 +16,15 @@ type LDAP struct { func NewLDAP(config types.LdapConfig) (*LDAP, error) { // Connect to the LDAP server - conn, err := ldapgo.DialURL(config.Address) + conn, err := ldapgo.DialURL(config.Address, ldapgo.DialWithTLSConfig(&tls.Config{ + InsecureSkipVerify: config.Insecure, + })) if err != nil { return nil, err } - // Try to connect using TLS - // conn.StartTLS(&tls.Config{ - // InsecureSkipVerify: true, - // }) - // Bind to the LDAP server with the provided credentials - err = conn.Bind(config.BindUser, config.BindPassword) + err = conn.Bind(config.BindDN, config.BindPassword) if err != nil { return nil, err } diff --git a/internal/types/config.go b/internal/types/config.go index 7186e36..188a7c5 100644 --- a/internal/types/config.go +++ b/internal/types/config.go @@ -37,9 +37,10 @@ type Config struct { FogotPasswordMessage string `mapstructure:"forgot-password-message" validate:"required"` BackgroundImage string `mapstructure:"background-image" validate:"required"` LdapAddress string `mapstructure:"ldap-address"` - LdapBindUser string `mapstructure:"ldap-bind-user"` + LdapBindDN string `mapstructure:"ldap-bind-dn"` LdapBindPassword string `mapstructure:"ldap-bind-password"` LdapBaseDN string `mapstructure:"ldap-base-dn"` + LdapInsecure bool `mapstructure:"ldap-insecure"` } // Server configuration @@ -130,7 +131,8 @@ type Labels struct { // Ldap config is a struct that contains the configuration for the LDAP service type LdapConfig struct { Address string - BindUser string + BindDN string BindPassword string BaseDN string + Insecure bool }