mirror of
				https://github.com/steveiliop56/tinyauth.git
				synced 2025-10-30 21:55:43 +00:00 
			
		
		
		
	 c5bb389258
			
		
	
	c5bb389258
	
	
	
		
			
			* 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)
 | |
| }
 |