mirror of
				https://github.com/steveiliop56/tinyauth.git
				synced 2025-10-28 04:35:40 +00:00 
			
		
		
		
	refactor: mode label decoder to separate package
This commit is contained in:
		| @@ -126,51 +126,51 @@ type RedirectQuery struct { | ||||
|  | ||||
| // Labels | ||||
|  | ||||
| type Labels struct { | ||||
| 	Apps map[string]AppLabels | ||||
| type Apps struct { | ||||
| 	Apps map[string]App | ||||
| } | ||||
|  | ||||
| type AppLabels struct { | ||||
| 	Config   ConfigLabels | ||||
| 	Users    UsersLabels | ||||
| 	OAuth    OAuthLabels | ||||
| 	IP       IPLabels | ||||
| 	Response ResponseLabels | ||||
| 	Path     PathLabels | ||||
| type App struct { | ||||
| 	Config   AppConfig | ||||
| 	Users    AppUsers | ||||
| 	OAuth    AppOAuth | ||||
| 	IP       AppIP | ||||
| 	Response AppResponse | ||||
| 	Path     AppPath | ||||
| } | ||||
|  | ||||
| type ConfigLabels struct { | ||||
| type AppConfig struct { | ||||
| 	Domain string | ||||
| } | ||||
|  | ||||
| type UsersLabels struct { | ||||
| type AppUsers struct { | ||||
| 	Allow string | ||||
| 	Block string | ||||
| } | ||||
|  | ||||
| type OAuthLabels struct { | ||||
| type AppOAuth struct { | ||||
| 	Whitelist string | ||||
| 	Groups    string | ||||
| } | ||||
|  | ||||
| type IPLabels struct { | ||||
| type AppIP struct { | ||||
| 	Allow  []string | ||||
| 	Block  []string | ||||
| 	Bypass []string | ||||
| } | ||||
|  | ||||
| type ResponseLabels struct { | ||||
| type AppResponse struct { | ||||
| 	Headers   []string | ||||
| 	BasicAuth BasicAuthLabels | ||||
| 	BasicAuth AppBasicAuth | ||||
| } | ||||
|  | ||||
| type BasicAuthLabels struct { | ||||
| type AppBasicAuth struct { | ||||
| 	Username     string | ||||
| 	Password     string | ||||
| 	PasswordFile string | ||||
| } | ||||
|  | ||||
| type PathLabels struct { | ||||
| type AppPath struct { | ||||
| 	Allow string | ||||
| 	Block string | ||||
| } | ||||
|   | ||||
| @@ -251,7 +251,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) { | ||||
| 	c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/login?%s", controller.config.AppURL, queries.Encode())) | ||||
| } | ||||
|  | ||||
| func (controller *ProxyController) setHeaders(c *gin.Context, labels config.AppLabels) { | ||||
| func (controller *ProxyController) setHeaders(c *gin.Context, labels config.App) { | ||||
| 	c.Header("Authorization", c.Request.Header.Get("Authorization")) | ||||
|  | ||||
| 	headers := utils.ParseHeaders(labels.Response.Headers) | ||||
|   | ||||
| @@ -285,7 +285,7 @@ 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.AppLabels) bool { | ||||
| func (auth *AuthService) IsResourceAllowed(c *gin.Context, context config.UserContext, labels config.App) bool { | ||||
| 	if context.OAuth { | ||||
| 		log.Debug().Msg("Checking OAuth whitelist") | ||||
| 		return utils.CheckFilter(labels.OAuth.Whitelist, context.Email) | ||||
| @@ -322,7 +322,7 @@ func (auth *AuthService) IsInOAuthGroup(c *gin.Context, context config.UserConte | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (auth *AuthService) IsAuthEnabled(uri string, path config.PathLabels) (bool, error) { | ||||
| func (auth *AuthService) IsAuthEnabled(uri string, path config.AppPath) (bool, error) { | ||||
| 	// Check for block list | ||||
| 	if path.Block != "" { | ||||
| 		regex, err := regexp.Compile(path.Block) | ||||
| @@ -364,7 +364,7 @@ func (auth *AuthService) GetBasicAuth(c *gin.Context) *config.User { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (auth *AuthService) CheckIP(labels config.IPLabels, ip string) bool { | ||||
| func (auth *AuthService) CheckIP(labels config.AppIP, ip string) bool { | ||||
| 	for _, blocked := range labels.Block { | ||||
| 		res, err := utils.FilterIP(blocked, ip) | ||||
| 		if err != nil { | ||||
| @@ -398,7 +398,7 @@ func (auth *AuthService) CheckIP(labels config.IPLabels, ip string) bool { | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func (auth *AuthService) IsBypassedIP(labels config.IPLabels, ip string) bool { | ||||
| func (auth *AuthService) IsBypassedIP(labels config.AppIP, ip string) bool { | ||||
| 	for _, bypassed := range labels.Bypass { | ||||
| 		res, err := utils.FilterIP(bypassed, ip) | ||||
| 		if err != nil { | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import ( | ||||
| 	"context" | ||||
| 	"strings" | ||||
| 	"tinyauth/internal/config" | ||||
| 	"tinyauth/internal/utils" | ||||
| 	"tinyauth/internal/utils/decoders" | ||||
|  | ||||
| 	container "github.com/docker/docker/api/types/container" | ||||
| 	"github.com/docker/docker/client" | ||||
| @@ -55,17 +55,17 @@ func (docker *DockerService) DockerConnected() bool { | ||||
| 	return err == nil | ||||
| } | ||||
|  | ||||
| func (docker *DockerService) GetLabels(appDomain string) (config.AppLabels, error) { | ||||
| func (docker *DockerService) GetLabels(appDomain string) (config.App, error) { | ||||
| 	isConnected := docker.DockerConnected() | ||||
|  | ||||
| 	if !isConnected { | ||||
| 		log.Debug().Msg("Docker not connected, returning empty labels") | ||||
| 		return config.AppLabels{}, nil | ||||
| 		return config.App{}, nil | ||||
| 	} | ||||
|  | ||||
| 	containers, err := docker.GetContainers() | ||||
| 	if err != nil { | ||||
| 		return config.AppLabels{}, err | ||||
| 		return config.App{}, err | ||||
| 	} | ||||
|  | ||||
| 	for _, ctr := range containers { | ||||
| @@ -75,7 +75,7 @@ func (docker *DockerService) GetLabels(appDomain string) (config.AppLabels, erro | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		labels, err := utils.GetLabels(inspect.Config.Labels) | ||||
| 		labels, err := decoders.DecodeLabels(inspect.Config.Labels) | ||||
| 		if err != nil { | ||||
| 			log.Warn().Str("id", ctr.ID).Err(err).Msg("Error getting container labels, skipping") | ||||
| 			continue | ||||
| @@ -95,5 +95,5 @@ func (docker *DockerService) GetLabels(appDomain string) (config.AppLabels, erro | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msg("No matching container found, returning empty labels") | ||||
| 	return config.AppLabels{}, nil | ||||
| 	return config.App{}, nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										19
									
								
								internal/utils/decoders/label_decoder.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								internal/utils/decoders/label_decoder.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| package decoders | ||||
|  | ||||
| import ( | ||||
| 	"tinyauth/internal/config" | ||||
|  | ||||
| 	"github.com/traefik/paerser/parser" | ||||
| ) | ||||
|  | ||||
| func DecodeLabels(labels map[string]string) (config.Apps, error) { | ||||
| 	var appLabels config.Apps | ||||
|  | ||||
| 	err := parser.Decode(labels, &appLabels, "tinyauth", "tinyauth.apps") | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return config.Apps{}, err | ||||
| 	} | ||||
|  | ||||
| 	return appLabels, nil | ||||
| } | ||||
							
								
								
									
										73
									
								
								internal/utils/decoders/label_decoder_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								internal/utils/decoders/label_decoder_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| package decoders_test | ||||
|  | ||||
| import ( | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| 	"tinyauth/internal/config" | ||||
| 	"tinyauth/internal/utils/decoders" | ||||
| ) | ||||
|  | ||||
| func TestDecodeLabels(t *testing.T) { | ||||
| 	// Variables | ||||
| 	expected := config.Apps{ | ||||
| 		Apps: map[string]config.App{ | ||||
| 			"foo": { | ||||
| 				Config: config.AppConfig{ | ||||
| 					Domain: "example.com", | ||||
| 				}, | ||||
| 				Users: config.AppUsers{ | ||||
| 					Allow: "user1,user2", | ||||
| 					Block: "user3", | ||||
| 				}, | ||||
| 				OAuth: config.AppOAuth{ | ||||
| 					Whitelist: "somebody@example.com", | ||||
| 					Groups:    "group3", | ||||
| 				}, | ||||
| 				IP: config.AppIP{ | ||||
| 					Allow:  []string{"10.71.0.1/24", "10.71.0.2"}, | ||||
| 					Block:  []string{"10.10.10.10", "10.0.0.0/24"}, | ||||
| 					Bypass: []string{"192.168.1.1"}, | ||||
| 				}, | ||||
| 				Response: config.AppResponse{ | ||||
| 					Headers: []string{"X-Foo=Bar", "X-Baz=Qux"}, | ||||
| 					BasicAuth: config.AppBasicAuth{ | ||||
| 						Username:     "admin", | ||||
| 						Password:     "password", | ||||
| 						PasswordFile: "/path/to/passwordfile", | ||||
| 					}, | ||||
| 				}, | ||||
| 				Path: config.AppPath{ | ||||
| 					Allow: "/public", | ||||
| 					Block: "/private", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	test := map[string]string{ | ||||
| 		"tinyauth.apps.foo.config.domain":                   "example.com", | ||||
| 		"tinyauth.apps.foo.users.allow":                     "user1,user2", | ||||
| 		"tinyauth.apps.foo.users.block":                     "user3", | ||||
| 		"tinyauth.apps.foo.oauth.whitelist":                 "somebody@example.com", | ||||
| 		"tinyauth.apps.foo.oauth.groups":                    "group3", | ||||
| 		"tinyauth.apps.foo.ip.allow":                        "10.71.0.1/24,10.71.0.2", | ||||
| 		"tinyauth.apps.foo.ip.block":                        "10.10.10.10,10.0.0.0/24", | ||||
| 		"tinyauth.apps.foo.ip.bypass":                       "192.168.1.1", | ||||
| 		"tinyauth.apps.foo.response.headers":                "X-Foo=Bar,X-Baz=Qux", | ||||
| 		"tinyauth.apps.foo.response.basicauth.username":     "admin", | ||||
| 		"tinyauth.apps.foo.response.basicauth.password":     "password", | ||||
| 		"tinyauth.apps.foo.response.basicauth.passwordfile": "/path/to/passwordfile", | ||||
| 		"tinyauth.apps.foo.path.allow":                      "/public", | ||||
| 		"tinyauth.apps.foo.path.block":                      "/private", | ||||
| 	} | ||||
|  | ||||
| 	// Test | ||||
| 	result, err := decoders.DecodeLabels(test) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Unexpected error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if reflect.DeepEqual(expected, result) == false { | ||||
| 		t.Fatalf("Expected %v but got %v", expected, result) | ||||
| 	} | ||||
| } | ||||
| @@ -3,22 +3,8 @@ package utils | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"strings" | ||||
| 	"tinyauth/internal/config" | ||||
|  | ||||
| 	"github.com/traefik/paerser/parser" | ||||
| ) | ||||
|  | ||||
| func GetLabels(labels map[string]string) (config.Labels, error) { | ||||
| 	var labelsParsed config.Labels | ||||
|  | ||||
| 	err := parser.Decode(labels, &labelsParsed, "tinyauth", "tinyauth.apps") | ||||
| 	if err != nil { | ||||
| 		return config.Labels{}, err | ||||
| 	} | ||||
|  | ||||
| 	return labelsParsed, nil | ||||
| } | ||||
|  | ||||
| func ParseHeaders(headers []string) map[string]string { | ||||
| 	headerMap := make(map[string]string) | ||||
| 	for _, header := range headers { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Stavros
					Stavros