Compare commits

...
2 Commits
3 changed files with 74 additions and 9 deletions
@@ -918,6 +918,7 @@ func TestProxyController(t *testing.T) {
aclsService := service.NewAccessControlsService(service.AccessControlServiceInput{
Log: log,
Config: &cfg,
Runtime: &runtime,
LabelProvider: nil,
})
+8 -1
View File
@@ -19,6 +19,7 @@ type LabelProvider interface {
type AccessControlsService struct {
log *logger.Logger
config *model.Config
runtime *model.RuntimeConfig
labelProvider LabelProvider
}
@@ -27,6 +28,7 @@ type AccessControlServiceInput struct {
Log *logger.Logger
Config *model.Config
Runtime *model.RuntimeConfig
LabelProvider LabelProvider `optional:"true"`
}
@@ -35,6 +37,7 @@ func NewAccessControlsService(i AccessControlServiceInput) *AccessControlsServic
return &AccessControlsService{
log: i.Log,
config: i.Config,
runtime: i.Runtime,
labelProvider: i.LabelProvider,
}
}
@@ -63,6 +66,10 @@ func (service *AccessControlsService) getACLs(domain string, lookup func(locator
normalizedDomain := service.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)
}
var domainMatch *model.App
var nameMatch *model.App
var nameMatchedApps []string
@@ -104,7 +111,7 @@ func (service *AccessControlsService) getACLs(domain string, lookup func(locator
}
if len(nameMatchedApps) > 1 {
return nil, fmt.Errorf("multiple apps matched domain by name, app names must be unique")
return nil, fmt.Errorf("domain matched multiple apps by name prefix, use explicit domain config")
}
service.log.App.Debug().Str("domain", domain).Msg("Found matching app by app name")
@@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tinyauthapp/tinyauth/internal/model"
"github.com/tinyauthapp/tinyauth/internal/test"
"github.com/tinyauthapp/tinyauth/internal/utils/logger"
)
@@ -35,6 +36,8 @@ func TestAccessControlsService(t *testing.T) {
log := logger.NewLogger().WithTestConfig()
log.Init()
_, runtime := test.CreateTestConfigs(t)
tests := []struct {
name string
domain string
@@ -44,6 +47,14 @@ func TestAccessControlsService(t *testing.T) {
}{
{
name: "returns ACLs for domain",
domain: "app.example.com",
acls: map[string]model.App{
"foo": {Config: model.AppConfig{Domain: "app.example.com"}},
},
want: &model.App{Config: model.AppConfig{Domain: "app.example.com"}},
},
{
name: "returns ACLs for root domain",
domain: "example.com",
acls: map[string]model.App{
"foo": {Config: model.AppConfig{Domain: "example.com"}},
@@ -103,6 +114,33 @@ func TestAccessControlsService(t *testing.T) {
acls: map[string]model.App{},
want: nil,
},
{
name: "App in domain not matching with the cookie domain should return nothing with name matching",
domain: "foo.bad_example.com",
acls: map[string]model.App{
"foo": {
Path: model.AppPath{Allow: "/foo"},
},
},
want: nil,
errorFunc: func(t *testing.T, e error) {
assert.ErrorContains(t, e, "domain does not match cookie domain")
},
},
{
name: "App in domain not matching with the cookie domain should return nothing with domain matching",
domain: "foo.bad_example.com",
acls: map[string]model.App{
"foo": {
Path: model.AppPath{Allow: "/foo"},
Config: model.AppConfig{Domain: "foo.bad_example.com"},
},
},
want: nil,
errorFunc: func(t *testing.T, e error) {
assert.ErrorContains(t, e, "domain does not match cookie domain")
},
},
}
// run once for a mock provider
@@ -111,6 +149,7 @@ func TestAccessControlsService(t *testing.T) {
mock := newMockProvider(test.acls, false)
acls := NewAccessControlsService(AccessControlServiceInput{
Log: log,
Runtime: &runtime,
Config: &model.Config{},
LabelProvider: mock,
})
@@ -128,7 +167,8 @@ func TestAccessControlsService(t *testing.T) {
for _, test := range tests {
t.Run(test.name+"(staticACLs)", func(t *testing.T) {
acls := NewAccessControlsService(AccessControlServiceInput{
Log: log,
Log: log,
Runtime: &runtime,
Config: &model.Config{
Apps: test.acls,
},
@@ -146,16 +186,32 @@ 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,
Config: &model.Config{},
Log: log,
Runtime: &runtime,
Config: &model.Config{},
})
_, err := acls.getACLs("example.com", mock.Lookup)
require.Error(t, err)
assert.Error(t, err)
// get acls should return an error when multiple apps with the same domain exist
acls = NewAccessControlsService(AccessControlServiceInput{
Log: log,
Runtime: &runtime,
Config: &model.Config{
Apps: map[string]model.App{
"foo": {Path: model.AppPath{Allow: "/foo"}},
"foo.bar": {Path: model.AppPath{Allow: "/bar"}},
},
},
})
_, err = acls.GetAccessControls("foo.bar.example.com")
assert.ErrorContains(t, err, "domain matched multiple apps by name prefix, use explicit domain config")
// get access controls should get acls from
// static when static acls are configured
acls = NewAccessControlsService(AccessControlServiceInput{
Log: log,
Log: log,
Runtime: &runtime,
Config: &model.Config{
Apps: map[string]model.App{
"foo": {Config: model.AppConfig{Domain: "foo.example.com"}},
@@ -164,12 +220,12 @@ func TestAccessControlsService(t *testing.T) {
})
app, err := acls.GetAccessControls("foo.example.com")
require.NoError(t, err)
require.Equal(t, &model.App{Config: model.AppConfig{Domain: "foo.example.com"}}, app)
assert.Equal(t, &model.App{Config: model.AppConfig{Domain: "foo.example.com"}}, app)
// should return nil for no apps
app, err = acls.GetAccessControls("bar.example.com")
require.NoError(t, err)
require.Nil(t, app)
assert.Nil(t, app)
// Should use label provider if available
mock = newMockProvider(map[string]model.App{
@@ -179,10 +235,11 @@ func TestAccessControlsService(t *testing.T) {
}, false)
acls = NewAccessControlsService(AccessControlServiceInput{
Log: log,
Runtime: &runtime,
Config: &model.Config{},
LabelProvider: mock,
})
app, err = acls.GetAccessControls("bar.example.com")
require.NoError(t, err)
require.Equal(t, &model.App{Config: model.AppConfig{Domain: "bar.example.com"}}, app)
assert.Equal(t, &model.App{Config: model.AppConfig{Domain: "bar.example.com"}}, app)
}