feat: add some logging

This commit is contained in:
Stavros
2025-08-26 12:45:24 +03:00
parent 645c555cf0
commit 77296daef3
8 changed files with 98 additions and 61 deletions

View File

@@ -4,6 +4,7 @@ import (
"tinyauth/internal/utils"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
)
type UserContextResponse struct {
@@ -76,6 +77,7 @@ func (controller *ContextController) userContextHandler(c *gin.Context) {
}
if err != nil {
log.Debug().Err(err).Msg("No user context found in request")
userContext.Status = 401
userContext.Message = "Unauthorized"
userContext.IsLoggedIn = false

View File

@@ -11,6 +11,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/go-querystring/query"
"github.com/rs/zerolog/log"
)
type OAuthRequest struct {
@@ -51,6 +52,7 @@ func (controller *OAuthController) oauthURLHandler(c *gin.Context) {
err := c.BindUri(&req)
if err != nil {
log.Error().Err(err).Msg("Failed to bind URI")
c.JSON(400, gin.H{
"status": 400,
"message": "Bad Request",
@@ -61,6 +63,7 @@ func (controller *OAuthController) oauthURLHandler(c *gin.Context) {
service, exists := controller.Broker.GetService(req.Provider)
if !exists {
log.Warn().Msgf("OAuth provider not found: %s", req.Provider)
c.JSON(404, gin.H{
"status": 404,
"message": "Not Found",
@@ -75,6 +78,7 @@ func (controller *OAuthController) oauthURLHandler(c *gin.Context) {
redirectURI := c.Query("redirect_uri")
if redirectURI != "" {
log.Debug().Msg("Setting redirect URI cookie")
c.SetCookie(controller.Config.RedirectCookieName, redirectURI, int(time.Hour.Seconds()), "/", "", controller.Config.SecureCookie, true)
}
@@ -90,6 +94,7 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
err := c.BindUri(&req)
if err != nil {
log.Error().Err(err).Msg("Failed to bind URI")
c.JSON(400, gin.H{
"status": 400,
"message": "Bad Request",
@@ -101,6 +106,7 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
csrfCookie, err := c.Cookie(controller.Config.CSRFCookieName)
if err != nil || state != csrfCookie {
log.Warn().Err(err).Msg("CSRF token mismatch or cookie missing")
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
return
}
@@ -111,12 +117,14 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
service, exists := controller.Broker.GetService(req.Provider)
if !exists {
log.Warn().Msgf("OAuth provider not found: %s", req.Provider)
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
return
}
err = service.VerifyCode(code)
if err != nil {
log.Error().Err(err).Msg("Failed to verify OAuth code")
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
return
}
@@ -124,11 +132,13 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
user, err := controller.Broker.GetUser(req.Provider)
if err != nil {
log.Error().Err(err).Msg("Failed to get user from OAuth provider")
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
return
}
if user.Email == "" {
log.Error().Msg("OAuth provider did not return an email")
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
return
}
@@ -139,6 +149,7 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
})
if err != nil {
log.Error().Err(err).Msg("Failed to encode unauthorized query")
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
return
}
@@ -150,8 +161,10 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
var name string
if user.Name != "" {
log.Debug().Msg("Using name from OAuth provider")
name = user.Name
} else {
log.Debug().Msg("No name from OAuth provider, using pseudo name")
name = fmt.Sprintf("%s (%s)", utils.Capitalize(strings.Split(user.Email, "@")[0]), strings.Split(user.Email, "@")[1])
}
@@ -166,6 +179,7 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
redirectURI, err := c.Cookie(controller.Config.RedirectCookieName)
if err != nil {
log.Debug().Msg("No redirect URI cookie found, redirecting to app root")
c.Redirect(http.StatusTemporaryRedirect, controller.Config.AppURL)
return
}
@@ -175,6 +189,7 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
})
if err != nil {
log.Error().Err(err).Msg("Failed to encode redirect URI query")
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
return
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/go-querystring/query"
"github.com/rs/zerolog/log"
)
type Proxy struct {
@@ -46,6 +47,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
err := c.BindUri(&req)
if err != nil {
log.Error().Err(err).Msg("Failed to bind URI")
c.JSON(400, gin.H{
"status": 400,
"message": "Bad Request",
@@ -55,6 +57,12 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
isBrowser := strings.Contains(c.Request.Header.Get("Accept"), "text/html")
if isBrowser {
log.Debug().Msg("Request identified as (most likely) coming from a browser")
} else {
log.Debug().Msg("Request identified as (most likely) coming from a non-browser client")
}
uri := c.Request.Header.Get("X-Forwarded-Uri")
proto := c.Request.Header.Get("X-Forwarded-Proto")
host := c.Request.Header.Get("X-Forwarded-Host")
@@ -65,6 +73,8 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
labels, err := controller.Docker.GetLabels(id, hostWithoutPort)
if err != nil {
log.Error().Err(err).Msg("Failed to get labels from Docker")
if req.Proxy == "nginx" || !isBrowser {
c.JSON(500, gin.H{
"status": 500,
@@ -85,10 +95,12 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
headers := utils.ParseHeaders(labels.Headers)
for key, value := range headers {
log.Debug().Str("header", key).Msg("Setting header")
c.Header(key, value)
}
if labels.Basic.Username != "" && utils.GetSecret(labels.Basic.Password.Plain, labels.Basic.Password.File) != "" {
log.Debug().Str("username", labels.Basic.Username).Msg("Setting basic auth header")
c.Header("Authorization", fmt.Sprintf("Basic %s", utils.GetBasicAuth(labels.Basic.Username, utils.GetSecret(labels.Basic.Password.Plain, labels.Basic.Password.File))))
}
@@ -114,6 +126,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
})
if err != nil {
log.Error().Err(err).Msg("Failed to encode unauthorized query")
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
}
@@ -124,6 +137,8 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
authEnabled, err := controller.Auth.AuthEnabled(uri, labels)
if err != nil {
log.Error().Err(err).Msg("Failed to check if auth is enabled for resource")
if req.Proxy == "nginx" || !isBrowser {
c.JSON(500, gin.H{
"status": 500,
@@ -137,15 +152,19 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
}
if !authEnabled {
log.Debug().Msg("Authentication disabled for resource, allowing access")
c.Header("Authorization", c.Request.Header.Get("Authorization"))
headers := utils.ParseHeaders(labels.Headers)
for key, value := range headers {
log.Debug().Str("header", key).Msg("Setting header")
c.Header(key, value)
}
if labels.Basic.Username != "" && utils.GetSecret(labels.Basic.Password.Plain, labels.Basic.Password.File) != "" {
log.Debug().Str("username", labels.Basic.Username).Msg("Setting basic auth header")
c.Header("Authorization", fmt.Sprintf("Basic %s", utils.GetBasicAuth(labels.Basic.Username, utils.GetSecret(labels.Basic.Password.Plain, labels.Basic.Password.File))))
}
@@ -161,6 +180,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
context, err := utils.GetContext(c)
if err != nil {
log.Debug().Msg("No user context found in request, treating as not logged in")
userContext = config.UserContext{
IsLoggedIn: false,
}
@@ -169,6 +189,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
}
if userContext.Provider == "basic" && userContext.TotpEnabled {
log.Debug().Msg("User has TOTP enabled, denying basic auth access")
userContext.IsLoggedIn = false
}
@@ -176,6 +197,8 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
appAllowed := controller.Auth.ResourceAllowed(c, userContext, labels)
if !appAllowed {
log.Warn().Str("user", userContext.Username).Str("resource", strings.Split(host, ".")[0]).Msg("User not allowed to access resource")
if req.Proxy == "nginx" || !isBrowser {
c.JSON(403, gin.H{
"status": 403,
@@ -195,6 +218,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
}
if err != nil {
log.Error().Err(err).Msg("Failed to encode unauthorized query")
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
return
}
@@ -207,6 +231,8 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
groupOK := controller.Auth.OAuthGroup(c, userContext, labels)
if !groupOK {
log.Warn().Str("user", userContext.Username).Str("resource", strings.Split(host, ".")[0]).Msg("User OAuth groups do not match resource requirements")
if req.Proxy == "nginx" || !isBrowser {
c.JSON(403, gin.H{
"status": 403,
@@ -227,6 +253,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
}
if err != nil {
log.Error().Err(err).Msg("Failed to encode unauthorized query")
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
return
}
@@ -245,10 +272,12 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
headers := utils.ParseHeaders(labels.Headers)
for key, value := range headers {
log.Debug().Str("header", key).Msg("Setting header")
c.Header(key, value)
}
if labels.Basic.Username != "" && utils.GetSecret(labels.Basic.Password.Plain, labels.Basic.Password.File) != "" {
log.Debug().Str("username", labels.Basic.Username).Msg("Setting basic auth header")
c.Header("Authorization", fmt.Sprintf("Basic %s", utils.GetBasicAuth(labels.Basic.Username, utils.GetSecret(labels.Basic.Password.Plain, labels.Basic.Password.File))))
}
@@ -272,6 +301,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
})
if err != nil {
log.Error().Err(err).Msg("Failed to encode redirect URI query")
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/error", controller.Config.AppURL))
return
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/pquerna/otp/totp"
"github.com/rs/zerolog/log"
)
type LoginRequest struct {
@@ -50,6 +51,7 @@ func (controller *UserController) loginHandler(c *gin.Context) {
err := c.BindJSON(&req)
if err != nil {
log.Error().Err(err).Msg("Failed to bind JSON")
c.JSON(400, gin.H{
"status": 400,
"message": "Bad Request",
@@ -65,9 +67,12 @@ func (controller *UserController) loginHandler(c *gin.Context) {
rateIdentifier = clientIP
}
log.Debug().Str("username", req.Username).Str("ip", clientIP).Msg("Login attempt")
isLocked, remainingTime := controller.Auth.IsAccountLocked(rateIdentifier)
if isLocked {
log.Warn().Str("username", req.Username).Str("ip", clientIP).Msg("Account is locked due to too many failed login attempts")
c.JSON(429, gin.H{
"status": 429,
"message": fmt.Sprintf("Too many failed login attempts. Try again in %d seconds", remainingTime),
@@ -78,6 +83,7 @@ func (controller *UserController) loginHandler(c *gin.Context) {
userSearch := controller.Auth.SearchUser(req.Username)
if userSearch.Type == "" {
log.Warn().Str("username", req.Username).Str("ip", clientIP).Msg("User not found")
controller.Auth.RecordLoginAttempt(rateIdentifier, false)
c.JSON(401, gin.H{
"status": 401,
@@ -87,6 +93,7 @@ func (controller *UserController) loginHandler(c *gin.Context) {
}
if !controller.Auth.VerifyUser(userSearch, req.Password) {
log.Warn().Str("username", req.Username).Str("ip", clientIP).Msg("Invalid password")
controller.Auth.RecordLoginAttempt(rateIdentifier, false)
c.JSON(401, gin.H{
"status": 401,
@@ -95,12 +102,16 @@ func (controller *UserController) loginHandler(c *gin.Context) {
return
}
log.Info().Str("username", req.Username).Str("ip", clientIP).Msg("Login successful")
controller.Auth.RecordLoginAttempt(rateIdentifier, true)
if userSearch.Type == "local" {
user := controller.Auth.GetLocalUser(userSearch.Username)
if user.TotpSecret != "" {
log.Debug().Str("username", req.Username).Msg("User has TOTP enabled, requiring TOTP verification")
controller.Auth.CreateSessionCookie(c, &config.SessionCookie{
Username: user.Username,
Name: utils.Capitalize(req.Username),
@@ -132,6 +143,7 @@ func (controller *UserController) loginHandler(c *gin.Context) {
}
func (controller *UserController) logoutHandler(c *gin.Context) {
log.Debug().Msg("Logout request received")
controller.Auth.DeleteSessionCookie(c)
c.JSON(200, gin.H{
"status": 200,
@@ -144,6 +156,7 @@ func (controller *UserController) totpHandler(c *gin.Context) {
err := c.BindJSON(&req)
if err != nil {
log.Error().Err(err).Msg("Failed to bind JSON")
c.JSON(400, gin.H{
"status": 400,
"message": "Bad Request",
@@ -154,6 +167,7 @@ func (controller *UserController) totpHandler(c *gin.Context) {
context, err := utils.GetContext(c)
if err != nil {
log.Error().Err(err).Msg("Failed to get user context")
c.JSON(500, gin.H{
"status": 500,
"message": "Internal Server Error",
@@ -162,6 +176,7 @@ func (controller *UserController) totpHandler(c *gin.Context) {
}
if !context.IsLoggedIn {
log.Warn().Msg("TOTP attempt without being logged in")
c.JSON(401, gin.H{
"status": 401,
"message": "Unauthorized",
@@ -177,9 +192,12 @@ func (controller *UserController) totpHandler(c *gin.Context) {
rateIdentifier = clientIP
}
log.Debug().Str("username", context.Username).Str("ip", clientIP).Msg("TOTP verification attempt")
isLocked, remainingTime := controller.Auth.IsAccountLocked(rateIdentifier)
if isLocked {
log.Warn().Str("username", context.Username).Str("ip", clientIP).Msg("Account is locked due to too many failed TOTP attempts")
c.JSON(429, gin.H{
"status": 429,
"message": fmt.Sprintf("Too many failed login attempts. Try again in %d seconds", remainingTime),
@@ -192,6 +210,7 @@ func (controller *UserController) totpHandler(c *gin.Context) {
ok := totp.Validate(req.Code, user.TotpSecret)
if !ok {
log.Warn().Str("username", context.Username).Str("ip", clientIP).Msg("Invalid TOTP code")
controller.Auth.RecordLoginAttempt(rateIdentifier, false)
c.JSON(401, gin.H{
"status": 401,
@@ -200,6 +219,8 @@ func (controller *UserController) totpHandler(c *gin.Context) {
return
}
log.Info().Str("username", context.Username).Str("ip", clientIP).Msg("TOTP verification successful")
controller.Auth.RecordLoginAttempt(rateIdentifier, true)
controller.Auth.CreateSessionCookie(c, &config.SessionCookie{

View File

@@ -8,6 +8,7 @@ import (
"tinyauth/internal/utils"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
)
type ContextMiddlewareConfig struct {
@@ -37,6 +38,7 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc {
cookie, err := m.Auth.GetSessionCookie(c)
if err != nil {
log.Debug().Err(err).Msg("No valid session cookie found")
goto basic
}
@@ -58,6 +60,8 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc {
userSearch := m.Auth.SearchUser(cookie.Username)
if userSearch.Type == "unknown" {
log.Debug().Msg("User from session cookie not found")
m.Auth.DeleteSessionCookie(c)
goto basic
}
@@ -74,10 +78,12 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc {
_, exists := m.Broker.GetService(cookie.Provider)
if !exists {
log.Debug().Msg("OAuth provider from session cookie not found")
goto basic
}
if !m.Auth.EmailWhitelisted(cookie.Email) {
log.Debug().Msg("Email from session cookie not whitelisted")
m.Auth.DeleteSessionCookie(c)
goto basic
}
@@ -99,6 +105,7 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc {
basic := m.Auth.GetBasicAuth(c)
if basic == nil {
log.Debug().Msg("No basic auth provided")
c.Next()
return
}
@@ -106,17 +113,21 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc {
userSearch := m.Auth.SearchUser(basic.Username)
if userSearch.Type == "unknown" {
log.Debug().Msg("User from basic auth not found")
c.Next()
return
}
if !m.Auth.VerifyUser(userSearch, basic.Password) {
log.Debug().Msg("Invalid password for basic auth user")
c.Next()
return
}
switch userSearch.Type {
case "local":
log.Debug().Msg("Basic auth user is local")
user := m.Auth.GetLocalUser(basic.Username)
c.Set("context", &config.UserContext{
@@ -130,6 +141,7 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc {
c.Next()
return
case "ldap":
log.Debug().Msg("Basic auth user is LDAP")
c.Set("context", &config.UserContext{
Username: basic.Username,
Name: utils.Capitalize(basic.Username),

View File

@@ -61,6 +61,7 @@ func (auth *AuthService) Init() error {
HttpOnly: true,
Domain: fmt.Sprintf(".%s", auth.Config.Domain),
}
auth.Store = store
return nil
}
@@ -70,11 +71,10 @@ func (auth *AuthService) GetSession(c *gin.Context) (*sessions.Session, error) {
// If there was an error getting the session, it might be invalid so let's clear it and retry
if err != nil {
log.Error().Err(err).Msg("Invalid session, clearing cookie and retrying")
log.Debug().Err(err).Msg("Error getting session, clearing cookie and retrying")
c.SetCookie(auth.Config.SessionCookieName, "", -1, "/", fmt.Sprintf(".%s", auth.Config.Domain), auth.Config.SecureCookie, true)
session, err = auth.Store.Get(c.Request, auth.Config.SessionCookieName)
if err != nil {
log.Error().Err(err).Msg("Failed to get session")
return nil, err
}
}
@@ -83,25 +83,21 @@ func (auth *AuthService) GetSession(c *gin.Context) (*sessions.Session, error) {
}
func (auth *AuthService) SearchUser(username string) config.UserSearch {
log.Debug().Str("username", username).Msg("Searching for user")
// Check local users first
if auth.GetLocalUser(username).Username != "" {
log.Debug().Str("username", username).Msg("Found local user")
return config.UserSearch{
Username: username,
Type: "local",
}
}
// If no user found, check LDAP
if auth.LDAP != nil {
log.Debug().Str("username", username).Msg("Checking LDAP for user")
userDN, err := auth.LDAP.Search(username)
if err != nil {
log.Warn().Err(err).Str("username", username).Msg("Failed to find user in LDAP")
log.Warn().Err(err).Str("username", username).Msg("Failed to search for user in LDAP")
return config.UserSearch{}
}
return config.UserSearch{
Username: userDN,
Type: "ldap",
@@ -114,54 +110,42 @@ func (auth *AuthService) SearchUser(username string) config.UserSearch {
}
func (auth *AuthService) VerifyUser(search config.UserSearch, password string) bool {
// Authenticate the user based on the type
switch search.Type {
case "local":
// If local user, get the user and check the password
user := auth.GetLocalUser(search.Username)
return auth.CheckPassword(user, password)
case "ldap":
// If LDAP is configured, bind to the LDAP server with the user DN and password
if auth.LDAP != nil {
log.Debug().Str("username", search.Username).Msg("Binding to LDAP for user authentication")
err := auth.LDAP.Bind(search.Username, password)
if err != nil {
log.Warn().Err(err).Str("username", search.Username).Msg("Failed to bind to LDAP")
return false
}
// Rebind with the service account to reset the connection
err = auth.LDAP.Bind(auth.LDAP.Config.BindDN, auth.LDAP.Config.BindPassword)
if err != nil {
log.Error().Err(err).Msg("Failed to rebind with service account after user authentication")
return false
}
log.Debug().Str("username", search.Username).Msg("LDAP authentication successful")
return true
}
default:
log.Warn().Str("type", search.Type).Msg("Unknown user type for authentication")
log.Debug().Str("type", search.Type).Msg("Unknown user type for authentication")
return false
}
// If no user found or authentication failed, return false
log.Warn().Str("username", search.Username).Msg("User authentication failed")
return false
}
func (auth *AuthService) GetLocalUser(username string) config.User {
// Loop through users and return the user if the username matches
log.Debug().Str("username", username).Msg("Searching for local user")
for _, user := range auth.Config.Users {
if user.Username == username {
return user
}
}
// If no user found, return an empty user
log.Warn().Str("username", username).Msg("Local user not found")
return config.User{}
}
@@ -237,16 +221,11 @@ func (auth *AuthService) EmailWhitelisted(email string) bool {
}
func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.SessionCookie) error {
log.Debug().Msg("Creating session cookie")
session, err := auth.GetSession(c)
if err != nil {
log.Error().Err(err).Msg("Failed to get session")
return err
}
log.Debug().Msg("Setting session cookie")
var sessionExpiry int
if data.TotpPending {
@@ -265,7 +244,6 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio
err = session.Save(c.Request, c.Writer)
if err != nil {
log.Error().Err(err).Msg("Failed to save session")
return err
}
@@ -273,11 +251,8 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio
}
func (auth *AuthService) DeleteSessionCookie(c *gin.Context) error {
log.Debug().Msg("Deleting session cookie")
session, err := auth.GetSession(c)
if err != nil {
log.Error().Err(err).Msg("Failed to get session")
return err
}
@@ -288,7 +263,6 @@ func (auth *AuthService) DeleteSessionCookie(c *gin.Context) error {
err = session.Save(c.Request, c.Writer)
if err != nil {
log.Error().Err(err).Msg("Failed to save session")
return err
}
@@ -296,16 +270,11 @@ func (auth *AuthService) DeleteSessionCookie(c *gin.Context) error {
}
func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie, error) {
log.Debug().Msg("Getting session cookie")
session, err := auth.GetSession(c)
if err != nil {
log.Error().Err(err).Msg("Failed to get session")
return config.SessionCookie{}, err
}
log.Debug().Msg("Got session")
username, usernameOk := session.Values["username"].(string)
email, emailOk := session.Values["email"].(string)
name, nameOk := session.Values["name"].(string)
@@ -328,7 +297,6 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie,
return config.SessionCookie{}, nil
}
log.Debug().Str("username", username).Str("provider", provider).Int64("expiry", expiry).Bool("totpPending", totpPending).Str("name", name).Str("email", email).Str("oauthGroups", oauthGroups).Msg("Parsed cookie")
return config.SessionCookie{
Username: username,
Name: name,
@@ -359,7 +327,6 @@ func (auth *AuthService) OAuthGroup(c *gin.Context, context config.UserContext,
return true
}
// Check if we are using the generic oauth provider
if context.Provider != "generic" {
log.Debug().Msg("Not using generic provider, skipping group check")
return true
@@ -371,7 +338,6 @@ func (auth *AuthService) OAuthGroup(c *gin.Context, context config.UserContext,
// For every group check if it is in the required groups
for _, group := range oauthGroups {
if utils.CheckFilter(labels.OAuth.Groups, group) {
log.Debug().Str("group", group).Msg("Group is in required groups")
return true
}
}
@@ -387,12 +353,9 @@ func (auth *AuthService) AuthEnabled(uri string, labels config.Labels) (bool, er
return true, nil
}
// Compile regex
regex, err := regexp.Compile(labels.Allowed)
// If there is an error, invalid regex, auth enabled
if err != nil {
log.Error().Err(err).Msg("Invalid regex")
return true, err
}
@@ -408,6 +371,7 @@ func (auth *AuthService) AuthEnabled(uri string, labels config.Labels) (bool, er
func (auth *AuthService) GetBasicAuth(c *gin.Context) *config.User {
username, password, ok := c.Request.BasicAuth()
if !ok {
log.Debug().Msg("No basic auth provided")
return nil
}
return &config.User{
@@ -421,11 +385,11 @@ func (auth *AuthService) CheckIP(labels config.Labels, ip string) bool {
for _, blocked := range labels.IP.Block {
res, err := utils.FilterIP(blocked, ip)
if err != nil {
log.Error().Err(err).Str("item", blocked).Msg("Invalid IP/CIDR in block list")
log.Warn().Err(err).Str("item", blocked).Msg("Invalid IP/CIDR in block list")
continue
}
if res {
log.Warn().Str("ip", ip).Str("item", blocked).Msg("IP is in blocked list, denying access")
log.Debug().Str("ip", ip).Str("item", blocked).Msg("IP is in blocked list, denying access")
return false
}
}
@@ -434,7 +398,7 @@ func (auth *AuthService) CheckIP(labels config.Labels, ip string) bool {
for _, allowed := range labels.IP.Allow {
res, err := utils.FilterIP(allowed, ip)
if err != nil {
log.Error().Err(err).Str("item", allowed).Msg("Invalid IP/CIDR in allow list")
log.Warn().Err(err).Str("item", allowed).Msg("Invalid IP/CIDR in allow list")
continue
}
if res {
@@ -445,7 +409,7 @@ func (auth *AuthService) CheckIP(labels config.Labels, ip string) bool {
// If not in allowed range and allowed range is not empty, deny access
if len(labels.IP.Allow) > 0 {
log.Warn().Str("ip", ip).Msg("IP not in allow list, denying access")
log.Debug().Str("ip", ip).Msg("IP not in allow list, denying access")
return false
}
@@ -458,7 +422,7 @@ func (auth *AuthService) BypassedIP(labels config.Labels, ip string) bool {
for _, bypassed := range labels.IP.Bypass {
res, err := utils.FilterIP(bypassed, ip)
if err != nil {
log.Error().Err(err).Str("item", bypassed).Msg("Invalid IP/CIDR in bypass list")
log.Warn().Err(err).Str("item", bypassed).Msg("Invalid IP/CIDR in bypass list")
continue
}
if res {

View File

@@ -6,6 +6,8 @@ import (
"tinyauth/internal/config"
"tinyauth/internal/utils"
"slices"
container "github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/rs/zerolog/log"
@@ -60,11 +62,8 @@ func (docker *DockerService) GetLabels(app string, domain string) (config.Labels
return config.Labels{}, nil
}
log.Debug().Msg("Getting containers")
containers, err := docker.GetContainers()
if err != nil {
log.Error().Err(err).Msg("Error getting containers")
return config.Labels{}, err
}
@@ -75,8 +74,6 @@ func (docker *DockerService) GetLabels(app string, domain string) (config.Labels
continue
}
log.Debug().Str("id", inspect.ID).Msg("Getting labels for container")
labels, err := utils.GetLabels(inspect.Config.Labels)
if err != nil {
log.Warn().Str("id", container.ID).Err(err).Msg("Error getting container labels, skipping")
@@ -84,11 +81,9 @@ func (docker *DockerService) GetLabels(app string, domain string) (config.Labels
}
// Check if the container matches the ID or domain
for _, lDomain := range labels.Domain {
if lDomain == domain {
log.Debug().Str("id", inspect.ID).Msg("Found matching container by domain")
return labels, nil
}
if slices.Contains(labels.Domain, domain) {
log.Debug().Str("id", inspect.ID).Msg("Found matching container by domain")
return labels, nil
}
if strings.TrimPrefix(inspect.Name, "/") == app {

View File

@@ -55,7 +55,6 @@ func (ldap *LdapService) Init() error {
}
func (ldap *LdapService) connect() (*ldapgo.Conn, error) {
log.Debug().Msg("Connecting to LDAP server")
conn, err := ldapgo.DialURL(ldap.Config.Address, ldapgo.DialWithTLSConfig(&tls.Config{
InsecureSkipVerify: ldap.Config.Insecure,
MinVersion: tls.VersionTLS12,
@@ -64,7 +63,6 @@ func (ldap *LdapService) connect() (*ldapgo.Conn, error) {
return nil, err
}
log.Debug().Msg("Binding to LDAP server")
err = conn.Bind(ldap.Config.BindDN, ldap.Config.BindPassword)
if err != nil {
return nil, err
@@ -94,7 +92,7 @@ func (ldap *LdapService) Search(username string) (string, error) {
}
if len(searchResult.Entries) != 1 {
return "", fmt.Errorf("err multiple or no entries found for user %s", username)
return "", fmt.Errorf("multiple or no entries found for user %s", username)
}
userDN := searchResult.Entries[0].DN