Skip to content

Commit 3397e2a

Browse files
authored
refactor: move to traefik paerser for label parsing (#197)
* refactor: move to traefik paerser for label parsing * fix: sanitize headers before adding to map * refactor: use splitn in header parser * refactor: ignore containers that failed to get inspected in docker
1 parent ee83c17 commit 3397e2a

12 files changed

Lines changed: 96 additions & 84 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Site builder
2-
FROM oven/bun:1.2.15-alpine AS frontend-builder
2+
FROM oven/bun:1.2.16-alpine AS frontend-builder
33

44
WORKDIR /frontend
55

frontend/Dockerfile.dev

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM oven/bun:1.1.45-alpine
1+
FROM oven/bun:1.2.16-alpine
22

33
WORKDIR /frontend
44

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ require (
2424
github.com/moby/sys/atomicwriter v0.1.0 // indirect
2525
github.com/moby/term v0.5.2 // indirect
2626
github.com/morikuni/aec v1.0.0 // indirect
27+
github.com/traefik/paerser v0.2.2 // indirect
2728
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
2829
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
2930
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
238238
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
239239
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
240240
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
241+
github.com/traefik/paerser v0.2.2 h1:cpzW/ZrQrBh3mdwD/jnp6aXASiUFKOVr6ldP+keJTcQ=
242+
github.com/traefik/paerser v0.2.2/go.mod h1:7BBDd4FANoVgaTZG+yh26jI6CA2nds7D/4VTEdIsh24=
241243
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
242244
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
243245
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=

internal/auth/auth.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,11 @@ func (auth *Auth) UserAuthConfigured() bool {
264264
return len(auth.Config.Users) > 0
265265
}
266266

267-
func (auth *Auth) ResourceAllowed(c *gin.Context, context types.UserContext, labels types.TinyauthLabels) bool {
267+
func (auth *Auth) ResourceAllowed(c *gin.Context, context types.UserContext, labels types.Labels) bool {
268268
// Check if oauth is allowed
269269
if context.OAuth {
270270
log.Debug().Msg("Checking OAuth whitelist")
271-
return utils.CheckWhitelist(labels.OAuthWhitelist, context.Email)
271+
return utils.CheckWhitelist(labels.OAuth.Whitelist, context.Email)
272272
}
273273

274274
// Check users
@@ -277,9 +277,9 @@ func (auth *Auth) ResourceAllowed(c *gin.Context, context types.UserContext, lab
277277
return utils.CheckWhitelist(labels.Users, context.Username)
278278
}
279279

280-
func (auth *Auth) OAuthGroup(c *gin.Context, context types.UserContext, labels types.TinyauthLabels) bool {
280+
func (auth *Auth) OAuthGroup(c *gin.Context, context types.UserContext, labels types.Labels) bool {
281281
// Check if groups are required
282-
if labels.OAuthGroups == "" {
282+
if labels.OAuth.Groups == "" {
283283
return true
284284
}
285285

@@ -294,7 +294,7 @@ func (auth *Auth) OAuthGroup(c *gin.Context, context types.UserContext, labels t
294294

295295
// For every group check if it is in the required groups
296296
for _, group := range oauthGroups {
297-
if utils.CheckWhitelist(labels.OAuthGroups, group) {
297+
if utils.CheckWhitelist(labels.OAuth.Groups, group) {
298298
log.Debug().Str("group", group).Msg("Group is in required groups")
299299
return true
300300
}
@@ -307,7 +307,7 @@ func (auth *Auth) OAuthGroup(c *gin.Context, context types.UserContext, labels t
307307
return false
308308
}
309309

310-
func (auth *Auth) AuthEnabled(c *gin.Context, labels types.TinyauthLabels) (bool, error) {
310+
func (auth *Auth) AuthEnabled(c *gin.Context, labels types.Labels) (bool, error) {
311311
// Get headers
312312
uri := c.Request.Header.Get("X-Forwarded-Uri")
313313

internal/constants/constants.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
11
package constants
22

3-
// TinyauthLabels is a list of labels that can be used in a tinyauth protected container
4-
var TinyauthLabels = []string{
5-
"tinyauth.oauth.whitelist",
6-
"tinyauth.users",
7-
"tinyauth.allowed",
8-
"tinyauth.headers",
9-
"tinyauth.oauth.groups",
10-
}
11-
123
// Claims are the OIDC supported claims (including preferd username for some reason)
134
type Claims struct {
145
Name string `json:"name"`

internal/docker/docker.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,22 @@ func (docker *Docker) DockerConnected() bool {
7474
return err == nil
7575
}
7676

77-
func (docker *Docker) GetLabels(appId string) (types.TinyauthLabels, error) {
77+
func (docker *Docker) GetLabels(appId string) (types.Labels, error) {
7878
// Check if we have access to the Docker API
7979
isConnected := docker.DockerConnected()
8080

8181
// If we don't have access, return an empty struct
8282
if !isConnected {
8383
log.Debug().Msg("Docker not connected, returning empty labels")
84-
return types.TinyauthLabels{}, nil
84+
return types.Labels{}, nil
8585
}
8686

8787
// Get the containers
8888
containers, err := docker.GetContainers()
8989

9090
// If there is an error, return false
9191
if err != nil {
92-
return types.TinyauthLabels{}, err
92+
return types.Labels{}, err
9393
}
9494

9595
log.Debug().Msg("Got containers")
@@ -99,9 +99,10 @@ func (docker *Docker) GetLabels(appId string) (types.TinyauthLabels, error) {
9999
// Inspect the container
100100
inspect, err := docker.InspectContainer(container.ID)
101101

102-
// If there is an error, return false
102+
// Check if there was an error
103103
if err != nil {
104-
return types.TinyauthLabels{}, err
104+
log.Warn().Str("id", container.ID).Err(err).Msg("Error inspecting container, skipping")
105+
continue
105106
}
106107

107108
// Get the container name (for some reason it is /name)
@@ -112,7 +113,13 @@ func (docker *Docker) GetLabels(appId string) (types.TinyauthLabels, error) {
112113
log.Debug().Str("container", containerName).Msg("Found container")
113114

114115
// Get only the tinyauth labels in a struct
115-
labels := utils.GetTinyauthLabels(inspect.Config.Labels)
116+
labels, err := utils.GetLabels(inspect.Config.Labels)
117+
118+
// Check if there was an error
119+
if err != nil {
120+
log.Error().Err(err).Msg("Error parsing labels")
121+
return types.Labels{}, err
122+
}
116123

117124
log.Debug().Msg("Got labels")
118125

@@ -125,5 +132,5 @@ func (docker *Docker) GetLabels(appId string) (types.TinyauthLabels, error) {
125132
log.Debug().Msg("No matching container found, returning empty labels")
126133

127134
// If no matching container is found, return empty labels
128-
return types.TinyauthLabels{}, nil
135+
return types.Labels{}, nil
129136
}

internal/handlers/handlers.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ func (h *Handlers) AuthHandler(c *gin.Context) {
114114

115115
// If auth is not enabled, return 200
116116
if !authEnabled {
117-
for key, value := range labels.Headers {
117+
headersParsed := utils.ParseHeaders(labels.Headers)
118+
for key, value := range headersParsed {
118119
log.Debug().Str("key", key).Str("value", value).Msg("Setting header")
119120
c.Header(key, utils.SanitizeHeader(value))
120121
}
@@ -236,7 +237,8 @@ func (h *Handlers) AuthHandler(c *gin.Context) {
236237
c.Header("Remote-Groups", utils.SanitizeHeader(userContext.OAuthGroups))
237238

238239
// Set the rest of the headers
239-
for key, value := range labels.Headers {
240+
parsedHeaders := utils.ParseHeaders(labels.Headers)
241+
for key, value := range parsedHeaders {
240242
log.Debug().Str("key", key).Str("value", value).Msg("Setting header")
241243
c.Header(key, utils.SanitizeHeader(value))
242244
}

internal/types/config.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,17 @@ type AuthConfig struct {
9292
type HooksConfig struct {
9393
Domain string
9494
}
95+
96+
// OAuthLabels is a list of labels that can be used in a tinyauth protected container
97+
type OAuthLabels struct {
98+
Whitelist string
99+
Groups string
100+
}
101+
102+
// Labels is a struct that contains the labels for a tinyauth protected container
103+
type Labels struct {
104+
Users string
105+
Allowed string
106+
Headers []string
107+
OAuth OAuthLabels
108+
}

internal/types/types.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,6 @@ type SessionCookie struct {
3232
OAuthGroups string
3333
}
3434

35-
// TinyauthLabels is the labels for the tinyauth container
36-
type TinyauthLabels struct {
37-
OAuthWhitelist string
38-
Users string
39-
Allowed string
40-
Headers map[string]string
41-
OAuthGroups string
42-
}
43-
4435
// UserContext is the context for the user
4536
type UserContext struct {
4637
Username string

0 commit comments

Comments
 (0)