outposts/proxy: add more test cases for domain-level auth
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
07b09df3fe
commit
ef335ec083
2
Makefile
2
Makefile
|
@ -16,7 +16,7 @@ test-e2e-rest:
|
||||||
coverage run manage.py test tests/e2e/test_flows* tests/e2e/test_source*
|
coverage run manage.py test tests/e2e/test_flows* tests/e2e/test_source*
|
||||||
|
|
||||||
test-go:
|
test-go:
|
||||||
go test -timeout 0 -v -race ./...
|
go test -timeout 0 -v -race -cover ./...
|
||||||
|
|
||||||
test:
|
test:
|
||||||
coverage run manage.py test authentik
|
coverage run manage.py test authentik
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -28,6 +28,7 @@ require (
|
||||||
github.com/prometheus/client_golang v1.12.0
|
github.com/prometheus/client_golang v1.12.0
|
||||||
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect
|
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
|
github.com/stretchr/testify v1.7.0 // indirect
|
||||||
goauthentik.io/api v0.2021125.1
|
goauthentik.io/api v0.2021125.1
|
||||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
|
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
|
|
1
go.sum
1
go.sum
|
@ -517,6 +517,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
||||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
|
|
@ -46,9 +46,13 @@ func (a *Application) forwardHandleTraefik(rw http.ResponseWriter, r *http.Reque
|
||||||
if *a.proxyConfig.Mode == api.PROXYMODE_FORWARD_SINGLE {
|
if *a.proxyConfig.Mode == api.PROXYMODE_FORWARD_SINGLE {
|
||||||
host = web.GetHost(r)
|
host = web.GetHost(r)
|
||||||
} else if *a.proxyConfig.Mode == api.PROXYMODE_FORWARD_DOMAIN {
|
} else if *a.proxyConfig.Mode == api.PROXYMODE_FORWARD_DOMAIN {
|
||||||
eh, _ := url.Parse(a.proxyConfig.ExternalHost)
|
eh, err := url.Parse(a.proxyConfig.ExternalHost)
|
||||||
|
if err != nil {
|
||||||
|
a.log.WithField("host", a.proxyConfig.ExternalHost).WithError(err).Warning("invalid external_host")
|
||||||
|
} else {
|
||||||
host = eh.Host
|
host = eh.Host
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// set the redirect flag to the current URL we have, since we redirect
|
// set the redirect flag to the current URL we have, since we redirect
|
||||||
// to a (possibly) different domain, but we want to be redirected back
|
// to a (possibly) different domain, but we want to be redirected back
|
||||||
// to the application
|
// to the application
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
package application
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"goauthentik.io/api"
|
||||||
|
"goauthentik.io/internal/outpost/proxyv2/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestForwardHandleNginx_Single_Blank(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleNginx(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestForwardHandleNginx_Single_Skip(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil)
|
||||||
|
req.Header.Set("X-Original-URI", "http://test.goauthentik.io/skip")
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleNginx(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusOK, rr.Code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestForwardHandleNginx_Single_Headers(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil)
|
||||||
|
req.Header.Set("X-Original-URI", "http://test.goauthentik.io/app")
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleNginx(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(t, rr.Code, http.StatusUnauthorized)
|
||||||
|
|
||||||
|
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||||
|
assert.Equal(t, "http://test.goauthentik.io/app", s.Values[constants.SessionRedirect])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestForwardHandleNginx_Single_Claims(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleNginx(rr, req)
|
||||||
|
|
||||||
|
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||||
|
s.Values[constants.SessionClaims] = Claims{
|
||||||
|
Sub: "foo",
|
||||||
|
Proxy: ProxyClaims{
|
||||||
|
UserAttributes: map[string]interface{}{
|
||||||
|
"username": "foo",
|
||||||
|
"password": "bar",
|
||||||
|
"additionalHeaders": map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := a.sessions.Save(req, rr, s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rr = httptest.NewRecorder()
|
||||||
|
a.forwardHandleTraefik(rr, req)
|
||||||
|
|
||||||
|
h := rr.Result().Header
|
||||||
|
|
||||||
|
assert.Equal(t, []string{"Basic Zm9vOmJhcg=="}, h["Authorization"])
|
||||||
|
assert.Equal(t, []string{"bar"}, h["Foo"])
|
||||||
|
assert.Equal(t, []string{""}, h["User-Agent"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Email"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Groups"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Jwt"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Meta-App"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Meta-Jwks"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Meta-Outpost"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Name"])
|
||||||
|
assert.Equal(t, []string{"foo"}, h["X-Authentik-Uid"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Username"])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestForwardHandleNginx_Domain_Blank(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr()
|
||||||
|
a.proxyConfig.CookieDomain = api.PtrString("foo")
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleNginx(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
||||||
|
|
||||||
|
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||||
|
assert.Equal(t, "/akprox/auth/nginx", s.Values[constants.SessionRedirect])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestForwardHandleNginx_Domain_Header(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr()
|
||||||
|
a.proxyConfig.CookieDomain = api.PtrString("foo")
|
||||||
|
a.proxyConfig.ExternalHost = "http://auth.test.goauthentik.io"
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil)
|
||||||
|
req.Header.Set("X-Original-URI", "http://test.goauthentik.io/app")
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleNginx(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
||||||
|
|
||||||
|
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||||
|
assert.Equal(t, "http://test.goauthentik.io/app", s.Values[constants.SessionRedirect])
|
||||||
|
}
|
|
@ -1,216 +0,0 @@
|
||||||
package application
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/quasoft/memstore"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"goauthentik.io/api"
|
|
||||||
"goauthentik.io/internal/outpost/ak"
|
|
||||||
"goauthentik.io/internal/outpost/proxyv2/constants"
|
|
||||||
)
|
|
||||||
|
|
||||||
func newTestApplication() *Application {
|
|
||||||
a, _ := NewApplication(
|
|
||||||
api.ProxyOutpostConfig{
|
|
||||||
Name: ak.TestSecret(),
|
|
||||||
ClientId: api.PtrString(ak.TestSecret()),
|
|
||||||
ClientSecret: api.PtrString(ak.TestSecret()),
|
|
||||||
CookieSecret: api.PtrString(ak.TestSecret()),
|
|
||||||
CookieDomain: api.PtrString(""),
|
|
||||||
Mode: api.PROXYMODE_FORWARD_SINGLE.Ptr(),
|
|
||||||
SkipPathRegex: api.PtrString("/skip.*"),
|
|
||||||
BasicAuthEnabled: api.PtrBool(true),
|
|
||||||
BasicAuthUserAttribute: api.PtrString("username"),
|
|
||||||
BasicAuthPasswordAttribute: api.PtrString("password"),
|
|
||||||
},
|
|
||||||
http.DefaultClient,
|
|
||||||
nil,
|
|
||||||
ak.MockAK(
|
|
||||||
api.Outpost{
|
|
||||||
Config: map[string]interface{}{
|
|
||||||
"authentik_host": ak.TestSecret(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ak.MockConfig(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
a.sessions = memstore.NewMemStore(
|
|
||||||
[]byte(ak.TestSecret()),
|
|
||||||
)
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForwardHandleTraefik_Blank(t *testing.T) {
|
|
||||||
a := newTestApplication()
|
|
||||||
req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil)
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
a.forwardHandleTraefik(rr, req)
|
|
||||||
|
|
||||||
assert.Equal(t, http.StatusTemporaryRedirect, rr.Code)
|
|
||||||
loc, _ := rr.Result().Location()
|
|
||||||
assert.Equal(t, "/akprox/start", loc.String())
|
|
||||||
|
|
||||||
s, _ := a.sessions.Get(req, constants.SeesionName)
|
|
||||||
// Since we're not setting the traefik specific headers, expect it to redirect to the auth URL
|
|
||||||
assert.Equal(t, "/akprox/auth/traefik", s.Values[constants.SessionRedirect])
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForwardHandleTraefik_Skip(t *testing.T) {
|
|
||||||
logrus.SetLevel(logrus.TraceLevel)
|
|
||||||
a := newTestApplication()
|
|
||||||
req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil)
|
|
||||||
req.Header.Set("X-Forwarded-Proto", "http")
|
|
||||||
req.Header.Set("X-Forwarded-Host", "test.goauthentik.io")
|
|
||||||
req.Header.Set("X-Forwarded-Uri", "/skip")
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
a.forwardHandleTraefik(rr, req)
|
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, rr.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForwardHandleTraefik_Headers(t *testing.T) {
|
|
||||||
a := newTestApplication()
|
|
||||||
req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil)
|
|
||||||
req.Header.Set("X-Forwarded-Proto", "http")
|
|
||||||
req.Header.Set("X-Forwarded-Host", "test.goauthentik.io")
|
|
||||||
req.Header.Set("X-Forwarded-Uri", "/")
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
a.forwardHandleTraefik(rr, req)
|
|
||||||
|
|
||||||
assert.Equal(t, rr.Code, http.StatusTemporaryRedirect)
|
|
||||||
loc, _ := rr.Result().Location()
|
|
||||||
assert.Equal(t, loc.String(), "http://test.goauthentik.io/akprox/start")
|
|
||||||
|
|
||||||
s, _ := a.sessions.Get(req, constants.SeesionName)
|
|
||||||
assert.Equal(t, "http://test.goauthentik.io/", s.Values[constants.SessionRedirect])
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForwardHandleTraefik_Claims(t *testing.T) {
|
|
||||||
a := newTestApplication()
|
|
||||||
req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil)
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
a.forwardHandleTraefik(rr, req)
|
|
||||||
|
|
||||||
s, _ := a.sessions.Get(req, constants.SeesionName)
|
|
||||||
s.Values[constants.SessionClaims] = Claims{
|
|
||||||
Sub: "foo",
|
|
||||||
Proxy: ProxyClaims{
|
|
||||||
UserAttributes: map[string]interface{}{
|
|
||||||
"username": "foo",
|
|
||||||
"password": "bar",
|
|
||||||
"additionalHeaders": map[string]interface{}{
|
|
||||||
"foo": "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := a.sessions.Save(req, rr, s)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rr = httptest.NewRecorder()
|
|
||||||
a.forwardHandleTraefik(rr, req)
|
|
||||||
|
|
||||||
h := rr.Result().Header
|
|
||||||
|
|
||||||
assert.Equal(t, []string{"Basic Zm9vOmJhcg=="}, h["Authorization"])
|
|
||||||
assert.Equal(t, []string{"bar"}, h["Foo"])
|
|
||||||
assert.Equal(t, []string{""}, h["User-Agent"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Email"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Groups"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Jwt"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Meta-App"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Meta-Jwks"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Meta-Outpost"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Name"])
|
|
||||||
assert.Equal(t, []string{"foo"}, h["X-Authentik-Uid"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Username"])
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForwardHandleNginx_Blank(t *testing.T) {
|
|
||||||
a := newTestApplication()
|
|
||||||
req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil)
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
a.forwardHandleNginx(rr, req)
|
|
||||||
|
|
||||||
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForwardHandleNginx_Skip(t *testing.T) {
|
|
||||||
a := newTestApplication()
|
|
||||||
req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil)
|
|
||||||
req.Header.Set("X-Original-URI", "http://test.goauthentik.io/skip")
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
a.forwardHandleNginx(rr, req)
|
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, rr.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForwardHandleNginx_Headers(t *testing.T) {
|
|
||||||
a := newTestApplication()
|
|
||||||
req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil)
|
|
||||||
req.Header.Set("X-Original-URI", "http://test.goauthentik.io")
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
a.forwardHandleNginx(rr, req)
|
|
||||||
|
|
||||||
assert.Equal(t, rr.Code, http.StatusUnauthorized)
|
|
||||||
|
|
||||||
s, _ := a.sessions.Get(req, constants.SeesionName)
|
|
||||||
assert.Equal(t, "http://test.goauthentik.io", s.Values[constants.SessionRedirect])
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForwardHandleNginx_Claims(t *testing.T) {
|
|
||||||
a := newTestApplication()
|
|
||||||
req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil)
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
a.forwardHandleNginx(rr, req)
|
|
||||||
|
|
||||||
s, _ := a.sessions.Get(req, constants.SeesionName)
|
|
||||||
s.Values[constants.SessionClaims] = Claims{
|
|
||||||
Sub: "foo",
|
|
||||||
Proxy: ProxyClaims{
|
|
||||||
UserAttributes: map[string]interface{}{
|
|
||||||
"username": "foo",
|
|
||||||
"password": "bar",
|
|
||||||
"additionalHeaders": map[string]interface{}{
|
|
||||||
"foo": "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := a.sessions.Save(req, rr, s)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rr = httptest.NewRecorder()
|
|
||||||
a.forwardHandleTraefik(rr, req)
|
|
||||||
|
|
||||||
h := rr.Result().Header
|
|
||||||
|
|
||||||
assert.Equal(t, []string{"Basic Zm9vOmJhcg=="}, h["Authorization"])
|
|
||||||
assert.Equal(t, []string{"bar"}, h["Foo"])
|
|
||||||
assert.Equal(t, []string{""}, h["User-Agent"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Email"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Groups"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Jwt"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Meta-App"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Meta-Jwks"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Meta-Outpost"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Name"])
|
|
||||||
assert.Equal(t, []string{"foo"}, h["X-Authentik-Uid"])
|
|
||||||
assert.Equal(t, []string{""}, h["X-Authentik-Username"])
|
|
||||||
}
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
package application
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"goauthentik.io/api"
|
||||||
|
"goauthentik.io/internal/outpost/proxyv2/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestForwardHandleTraefik_Single_Blank(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleTraefik(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusTemporaryRedirect, rr.Code)
|
||||||
|
loc, _ := rr.Result().Location()
|
||||||
|
assert.Equal(t, "/akprox/start", loc.String())
|
||||||
|
|
||||||
|
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||||
|
// Since we're not setting the traefik specific headers, expect it to redirect to the auth URL
|
||||||
|
assert.Equal(t, "/akprox/auth/traefik", s.Values[constants.SessionRedirect])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestForwardHandleTraefik_Single_Skip(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil)
|
||||||
|
req.Header.Set("X-Forwarded-Proto", "http")
|
||||||
|
req.Header.Set("X-Forwarded-Host", "test.goauthentik.io")
|
||||||
|
req.Header.Set("X-Forwarded-Uri", "/skip")
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleTraefik(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusOK, rr.Code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestForwardHandleTraefik_Single_Headers(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil)
|
||||||
|
req.Header.Set("X-Forwarded-Proto", "http")
|
||||||
|
req.Header.Set("X-Forwarded-Host", "test.goauthentik.io")
|
||||||
|
req.Header.Set("X-Forwarded-Uri", "/app")
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleTraefik(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(t, rr.Code, http.StatusTemporaryRedirect)
|
||||||
|
loc, _ := rr.Result().Location()
|
||||||
|
assert.Equal(t, loc.String(), "http://test.goauthentik.io/akprox/start")
|
||||||
|
|
||||||
|
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||||
|
assert.Equal(t, "http://test.goauthentik.io/app", s.Values[constants.SessionRedirect])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestForwardHandleTraefik_Single_Claims(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleTraefik(rr, req)
|
||||||
|
|
||||||
|
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||||
|
s.Values[constants.SessionClaims] = Claims{
|
||||||
|
Sub: "foo",
|
||||||
|
Proxy: ProxyClaims{
|
||||||
|
UserAttributes: map[string]interface{}{
|
||||||
|
"username": "foo",
|
||||||
|
"password": "bar",
|
||||||
|
"additionalHeaders": map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := a.sessions.Save(req, rr, s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rr = httptest.NewRecorder()
|
||||||
|
a.forwardHandleTraefik(rr, req)
|
||||||
|
|
||||||
|
h := rr.Result().Header
|
||||||
|
|
||||||
|
assert.Equal(t, []string{"Basic Zm9vOmJhcg=="}, h["Authorization"])
|
||||||
|
assert.Equal(t, []string{"bar"}, h["Foo"])
|
||||||
|
assert.Equal(t, []string{""}, h["User-Agent"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Email"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Groups"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Jwt"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Meta-App"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Meta-Jwks"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Meta-Outpost"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Name"])
|
||||||
|
assert.Equal(t, []string{"foo"}, h["X-Authentik-Uid"])
|
||||||
|
assert.Equal(t, []string{""}, h["X-Authentik-Username"])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestForwardHandleTraefik_Domain_Blank(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr()
|
||||||
|
a.proxyConfig.CookieDomain = api.PtrString("foo")
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleTraefik(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusTemporaryRedirect, rr.Code)
|
||||||
|
loc, _ := rr.Result().Location()
|
||||||
|
assert.Equal(t, "/akprox/start", loc.String())
|
||||||
|
|
||||||
|
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||||
|
// Since we're not setting the traefik specific headers, expect it to redirect to the auth URL
|
||||||
|
assert.Equal(t, "/akprox/auth/traefik", s.Values[constants.SessionRedirect])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestForwardHandleTraefik_Domain_Header(t *testing.T) {
|
||||||
|
a := newTestApplication()
|
||||||
|
a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr()
|
||||||
|
a.proxyConfig.CookieDomain = api.PtrString("foo")
|
||||||
|
a.proxyConfig.ExternalHost = "http://auth.test.goauthentik.io"
|
||||||
|
req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil)
|
||||||
|
req.Header.Set("X-Forwarded-Proto", "http")
|
||||||
|
req.Header.Set("X-Forwarded-Host", "test.goauthentik.io")
|
||||||
|
req.Header.Set("X-Forwarded-Uri", "/app")
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
a.forwardHandleTraefik(rr, req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusTemporaryRedirect, rr.Code)
|
||||||
|
loc, _ := rr.Result().Location()
|
||||||
|
assert.Equal(t, "http://auth.test.goauthentik.io/akprox/start", loc.String())
|
||||||
|
|
||||||
|
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||||
|
assert.Equal(t, "http://test.goauthentik.io/app", s.Values[constants.SessionRedirect])
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package application
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/quasoft/memstore"
|
||||||
|
"goauthentik.io/api"
|
||||||
|
"goauthentik.io/internal/outpost/ak"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newTestApplication() *Application {
|
||||||
|
a, _ := NewApplication(
|
||||||
|
api.ProxyOutpostConfig{
|
||||||
|
Name: ak.TestSecret(),
|
||||||
|
ClientId: api.PtrString(ak.TestSecret()),
|
||||||
|
ClientSecret: api.PtrString(ak.TestSecret()),
|
||||||
|
CookieSecret: api.PtrString(ak.TestSecret()),
|
||||||
|
CookieDomain: api.PtrString(""),
|
||||||
|
Mode: api.PROXYMODE_FORWARD_SINGLE.Ptr(),
|
||||||
|
SkipPathRegex: api.PtrString("/skip.*"),
|
||||||
|
BasicAuthEnabled: api.PtrBool(true),
|
||||||
|
BasicAuthUserAttribute: api.PtrString("username"),
|
||||||
|
BasicAuthPasswordAttribute: api.PtrString("password"),
|
||||||
|
},
|
||||||
|
http.DefaultClient,
|
||||||
|
nil,
|
||||||
|
ak.MockAK(
|
||||||
|
api.Outpost{
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"authentik_host": ak.TestSecret(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ak.MockConfig(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
a.sessions = memstore.NewMemStore(
|
||||||
|
[]byte(ak.TestSecret()),
|
||||||
|
)
|
||||||
|
return a
|
||||||
|
}
|
Reference in New Issue