Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# yaml-language-server: $schema=https://www.coderabbit.ai/integrations/schema.v2.json
issue_enrichment:
auto_enrich:
enabled: false
reviews:
profile: chill
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ require (
golang.org/x/oauth2 v0.36.0
golang.org/x/tools v0.49.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.37.0
k8s.io/apimachinery v0.37.0
k8s.io/client-go v0.37.0
modernc.org/sqlite v1.58.0
Expand Down Expand Up @@ -81,6 +82,7 @@ require (
github.com/go-playground/validator/v10 v10.30.1 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
github.com/google/gnostic-models v0.7.1 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63Y
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA=
github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE=
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=
github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
Expand Down
12 changes: 6 additions & 6 deletions internal/service/access_controls_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func NewAccessControlsService(i AccessControlServiceInput) *AccessControlsServic
}
}

func (service *AccessControlsService) ensureAscii(str string) bool {
func ensureAscii(str string) bool {
for i := 0; i < len(str); i++ {
if str[i] > unicode.MaxASCII {
return false
Expand All @@ -51,7 +51,7 @@ func (service *AccessControlsService) ensureAscii(str string) bool {
return true
}

func (service *AccessControlsService) normalizeDomain(domain string) string {
func normalizeDomain(domain string) string {
if host, _, err := net.SplitHostPort(domain); err == nil {
domain = host
}
Expand All @@ -60,11 +60,11 @@ func (service *AccessControlsService) normalizeDomain(domain string) string {
}

func (service *AccessControlsService) getACLs(domain string, lookup func(locator func(name string, app *model.App) bool) error) (*model.App, error) {
if !service.ensureAscii(domain) {
if !ensureAscii(domain) {
return nil, errors.New("domain contains non-ascii characters")
}

normalizedDomain := service.normalizeDomain(domain)
normalizedDomain := normalizeDomain(domain)

if !strings.HasSuffix(normalizedDomain, "."+service.runtime.CookieDomain) && normalizedDomain != service.runtime.CookieDomain {
return nil, fmt.Errorf("domain does not match cookie domain, expected %s (or a subdomain), got %s", service.runtime.CookieDomain, domain)
Expand All @@ -76,11 +76,11 @@ func (service *AccessControlsService) getACLs(domain string, lookup func(locator

locatorFunc := func(name string, app *model.App) bool {
if app.Config.Domain != "" {
if !service.ensureAscii(app.Config.Domain) {
if !ensureAscii(app.Config.Domain) {
service.log.App.Warn().Str("name", name).Str("domain", app.Config.Domain).Msg("Domain contains non-ascii characters, skipping")
return false
}
if normalizedDomain == service.normalizeDomain(app.Config.Domain) {
if normalizedDomain == normalizeDomain(app.Config.Domain) {
service.log.App.Debug().Str("name", name).Msg("Found matching container by domain")
domainMatch = app
return true
Expand Down
7 changes: 4 additions & 3 deletions internal/service/access_controls_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,10 @@ func TestAccessControlsService(t *testing.T) {
// get acls should return an error when the provider fails
mock := newMockProvider(map[string]model.App{}, true)
acls := NewAccessControlsService(AccessControlServiceInput{
Log: log,
Runtime: &runtime,
Config: &model.Config{},
Log: log,
Runtime: &runtime,
Config: &model.Config{},
LabelProvider: mock,
})
_, err := acls.getACLs("example.com", mock.Lookup)
assert.Error(t, err)
Expand Down
68 changes: 68 additions & 0 deletions internal/service/kubernetes_ingress_extractor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package service

import (
"slices"

"github.com/tinyauthapp/tinyauth/internal/utils/logger"
networking "k8s.io/api/networking/v1"
)

type KubernetesIngressExtractor struct {
log *logger.Logger
}

type KubernetesIngressExtractorInput struct {
Log *logger.Logger
}

func NewKubernetesIngressExtractor(i KubernetesIngressExtractorInput) *KubernetesIngressExtractor {
return &KubernetesIngressExtractor{
log: i.Log,
}
}

func (k *KubernetesIngressExtractor) getPaths(rule networking.IngressRule) []string {
var paths []string

if rule.HTTP == nil {
return paths
}

for _, path := range rule.HTTP.Paths {
paths = append(paths, path.Path)
}

return paths
}

func (k *KubernetesIngressExtractor) getHosts(rules []networking.IngressRule) []string {
var hosts []string

for _, rule := range rules {
hosts = append(hosts, rule.Host)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
paths := k.getPaths(rule)

if len(paths) == 0 {
continue
}

if !slices.Contains(paths, "/") {
k.log.App.Warn().Strs("hosts", hosts).Strs("paths", paths).Msg("Ingress rule does not contain a catch-all path, another ingress may be able to bypass auth checks if it routes the same host with a different path. Consider adding a catch-all path to this rule to ensure auth checks are applied to all paths for this host.")
}
}

return hosts
}

func (k *KubernetesIngressExtractor) Extract(ingress *networking.Ingress) *ExtractionResult {
annotations := ingress.GetAnnotations()
hosts := k.getHosts(ingress.Spec.Rules)

return &ExtractionResult{
typ: ResourceTypeIngress,
name: ingress.GetName(),
namespace: ingress.GetNamespace(),
hosts: hosts,
annotations: annotations,
}
}
Loading
Loading