mirror of
				https://github.com/steveiliop56/tinyauth.git
				synced 2025-11-03 23:55:44 +00:00 
			
		
		
		
	* feat: add LabelService to retrieve application labels from environment variables * feat: allow usage of labels from docker and env variables simultaneously Prioritize labels from environment variables over labels from docker labels * fix: handle error returned by label_serive.go/LoadLabels see https://github.com/steveiliop56/tinyauth/pull/422#discussion_r2443443032 * refactor(label_service): use simple loop instead of slices.ContainsFunc to avoid experimental slices package see https://github.com/steveiliop56/tinyauth/pull/422#pullrequestreview-3354632045 * refactor: merge acl logic into one service --------- Co-authored-by: Stavros <steveiliop56@gmail.com>
		
			
				
	
	
		
			104 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package service
 | 
						|
 | 
						|
import (
 | 
						|
	"os"
 | 
						|
	"strings"
 | 
						|
	"tinyauth/internal/config"
 | 
						|
	"tinyauth/internal/utils/decoders"
 | 
						|
 | 
						|
	"github.com/rs/zerolog/log"
 | 
						|
)
 | 
						|
 | 
						|
type AccessControlsService struct {
 | 
						|
	docker  *DockerService
 | 
						|
	envACLs config.Apps
 | 
						|
}
 | 
						|
 | 
						|
func NewAccessControlsService(docker *DockerService) *AccessControlsService {
 | 
						|
	return &AccessControlsService{
 | 
						|
		docker: docker,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (acls *AccessControlsService) Init() error {
 | 
						|
	acls.envACLs = config.Apps{}
 | 
						|
	env := os.Environ()
 | 
						|
	appEnvVars := []string{}
 | 
						|
 | 
						|
	for _, e := range env {
 | 
						|
		if strings.HasPrefix(e, "TINYAUTH_APPS_") {
 | 
						|
			appEnvVars = append(appEnvVars, e)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	err := acls.loadEnvACLs(appEnvVars)
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (acls *AccessControlsService) loadEnvACLs(appEnvVars []string) error {
 | 
						|
	if len(appEnvVars) == 0 {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	envAcls := map[string]string{}
 | 
						|
 | 
						|
	for _, e := range appEnvVars {
 | 
						|
		parts := strings.SplitN(e, "=", 2)
 | 
						|
		if len(parts) != 2 {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		// Normalize key, this should use the same normalization logic as in utils/decoders/decoders.go
 | 
						|
		key := parts[0]
 | 
						|
		key = strings.ToLower(key)
 | 
						|
		key = strings.ReplaceAll(key, "_", ".")
 | 
						|
		value := parts[1]
 | 
						|
		envAcls[key] = value
 | 
						|
	}
 | 
						|
 | 
						|
	apps, err := decoders.DecodeLabels(envAcls)
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	acls.envACLs = apps
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (acls *AccessControlsService) lookupEnvACLs(appDomain string) *config.App {
 | 
						|
	if len(acls.envACLs.Apps) == 0 {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	for appName, appACLs := range acls.envACLs.Apps {
 | 
						|
		if appACLs.Config.Domain == appDomain {
 | 
						|
			return &appACLs
 | 
						|
		}
 | 
						|
 | 
						|
		if strings.SplitN(appDomain, ".", 2)[0] == appName {
 | 
						|
			return &appACLs
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (acls *AccessControlsService) GetAccessControls(appDomain string) (config.App, error) {
 | 
						|
	// First check environment variables
 | 
						|
	envACLs := acls.lookupEnvACLs(appDomain)
 | 
						|
 | 
						|
	if envACLs != nil {
 | 
						|
		log.Debug().Str("domain", appDomain).Msg("Found matching access controls in environment variables")
 | 
						|
		return *envACLs, nil
 | 
						|
	}
 | 
						|
 | 
						|
	// Fallback to Docker labels
 | 
						|
	return acls.docker.GetLabels(appDomain)
 | 
						|
}
 |