refactor: unify labels (#329)

* refactor: unify labels

* feat: implement path block and user block

Fixes #313

* fix: fix oauth group check logic

* chore: fix typo
This commit is contained in:
Stavros
2025-08-29 17:04:34 +03:00
committed by GitHub
parent 03d06cb0a7
commit c7c3de4f78
6 changed files with 164 additions and 114 deletions

View File

@@ -283,18 +283,25 @@ func (auth *AuthService) UserAuthConfigured() bool {
return len(auth.Config.Users) > 0 || auth.LDAP != nil
}
func (auth *AuthService) IsResourceAllowed(c *gin.Context, context config.UserContext, labels config.Labels) bool {
func (auth *AuthService) IsResourceAllowed(c *gin.Context, context config.UserContext, labels config.AppLabels) bool {
if context.OAuth {
log.Debug().Msg("Checking OAuth whitelist")
return utils.CheckFilter(labels.OAuth.Whitelist, context.Email)
}
if labels.Users.Block != "" {
log.Debug().Msg("Checking blocked users")
if utils.CheckFilter(labels.Users.Block, context.Username) {
return false
}
}
log.Debug().Msg("Checking users")
return utils.CheckFilter(labels.Users, context.Username)
return utils.CheckFilter(labels.Users.Allow, context.Username)
}
func (auth *AuthService) IsInOAuthGroup(c *gin.Context, context config.UserContext, labels config.Labels) bool {
if labels.OAuth.Groups == "" {
func (auth *AuthService) IsInOAuthGroup(c *gin.Context, context config.UserContext, requiredGroups string) bool {
if requiredGroups == "" {
return true
}
@@ -303,11 +310,8 @@ func (auth *AuthService) IsInOAuthGroup(c *gin.Context, context config.UserConte
return true
}
// No need to parse since they are from the API response
oauthGroups := strings.Split(context.OAuthGroups, ",")
for _, group := range oauthGroups {
if utils.CheckFilter(labels.OAuth.Groups, group) {
for _, userGroup := range strings.Split(context.OAuthGroups, ",") {
if utils.CheckFilter(requiredGroups, strings.TrimSpace(userGroup)) {
return true
}
}
@@ -316,19 +320,31 @@ func (auth *AuthService) IsInOAuthGroup(c *gin.Context, context config.UserConte
return false
}
func (auth *AuthService) IsAuthEnabled(uri string, labels config.Labels) (bool, error) {
if labels.Allowed == "" {
return true, nil
func (auth *AuthService) IsAuthEnabled(uri string, path config.PathLabels) (bool, error) {
// Check for block list
if path.Block != "" {
regex, err := regexp.Compile(path.Block)
if err != nil {
return true, err
}
if !regex.MatchString(uri) {
return false, nil
}
}
regex, err := regexp.Compile(labels.Allowed)
// Check for allow list
if path.Allow != "" {
regex, err := regexp.Compile(path.Allow)
if err != nil {
return true, err
}
if err != nil {
return true, err
}
if regex.MatchString(uri) {
return false, nil
if regex.MatchString(uri) {
return false, nil
}
}
return true, nil
@@ -346,8 +362,8 @@ func (auth *AuthService) GetBasicAuth(c *gin.Context) *config.User {
}
}
func (auth *AuthService) CheckIP(labels config.Labels, ip string) bool {
for _, blocked := range labels.IP.Block {
func (auth *AuthService) CheckIP(labels config.IPLabels, ip string) bool {
for _, blocked := range labels.Block {
res, err := utils.FilterIP(blocked, ip)
if err != nil {
log.Warn().Err(err).Str("item", blocked).Msg("Invalid IP/CIDR in block list")
@@ -359,7 +375,7 @@ func (auth *AuthService) CheckIP(labels config.Labels, ip string) bool {
}
}
for _, allowed := range labels.IP.Allow {
for _, allowed := range labels.Allow {
res, err := utils.FilterIP(allowed, ip)
if err != nil {
log.Warn().Err(err).Str("item", allowed).Msg("Invalid IP/CIDR in allow list")
@@ -371,7 +387,7 @@ func (auth *AuthService) CheckIP(labels config.Labels, ip string) bool {
}
}
if len(labels.IP.Allow) > 0 {
if len(labels.Allow) > 0 {
log.Debug().Str("ip", ip).Msg("IP not in allow list, denying access")
return false
}
@@ -380,8 +396,8 @@ func (auth *AuthService) CheckIP(labels config.Labels, ip string) bool {
return true
}
func (auth *AuthService) IsBypassedIP(labels config.Labels, ip string) bool {
for _, bypassed := range labels.IP.Bypass {
func (auth *AuthService) IsBypassedIP(labels config.IPLabels, ip string) bool {
for _, bypassed := range labels.Bypass {
res, err := utils.FilterIP(bypassed, ip)
if err != nil {
log.Warn().Err(err).Str("item", bypassed).Msg("Invalid IP/CIDR in bypass list")

View File

@@ -6,8 +6,6 @@ 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"
@@ -57,17 +55,17 @@ func (docker *DockerService) DockerConnected() bool {
return err == nil
}
func (docker *DockerService) GetLabels(app string, domain string) (config.Labels, error) {
func (docker *DockerService) GetLabels(app string, domain string) (config.AppLabels, error) {
isConnected := docker.DockerConnected()
if !isConnected {
log.Debug().Msg("Docker not connected, returning empty labels")
return config.Labels{}, nil
return config.AppLabels{}, nil
}
containers, err := docker.GetContainers()
if err != nil {
return config.Labels{}, err
return config.AppLabels{}, err
}
for _, container := range containers {
@@ -83,18 +81,19 @@ func (docker *DockerService) GetLabels(app string, domain string) (config.Labels
continue
}
// Check if the container matches the ID or domain
if slices.Contains(labels.Domain, domain) {
log.Debug().Str("id", inspect.ID).Msg("Found matching container by domain")
return labels, nil
}
for appName, appLabels := range labels.Apps {
if appLabels.Config.Domain == domain {
log.Debug().Str("id", inspect.ID).Msg("Found matching container by domain")
return appLabels, nil
}
if strings.TrimPrefix(inspect.Name, "/") == app {
log.Debug().Str("id", inspect.ID).Msg("Found matching container by name")
return labels, nil
if strings.TrimPrefix(inspect.Name, "/") == appName {
log.Debug().Str("id", inspect.ID).Msg("Found matching container by app name")
return appLabels, nil
}
}
}
log.Debug().Msg("No matching container found, returning empty labels")
return config.Labels{}, nil
return config.AppLabels{}, nil
}