diff --git a/internal/controller/proxy_controller.go b/internal/controller/proxy_controller.go index 891ff59b..ffafaffd 100644 --- a/internal/controller/proxy_controller.go +++ b/internal/controller/proxy_controller.go @@ -158,7 +158,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) { return } - c.Redirect(http.StatusTemporaryRedirect, redirectURL) + c.Redirect(http.StatusFound, redirectURL) return } @@ -207,7 +207,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) { return } - c.Redirect(http.StatusTemporaryRedirect, redirectURL) + c.Redirect(http.StatusFound, redirectURL) return } @@ -251,7 +251,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) { return } - c.Redirect(http.StatusTemporaryRedirect, redirectURL) + c.Redirect(http.StatusFound, redirectURL) return } } @@ -300,7 +300,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) { return } - c.Redirect(http.StatusTemporaryRedirect, redirectURL) + c.Redirect(http.StatusFound, redirectURL) } func (controller *ProxyController) setHeaders(c *gin.Context, acls *model.App) { @@ -336,7 +336,7 @@ func (controller *ProxyController) handleError(c *gin.Context, proxyCtx ProxyCon return } - c.Redirect(http.StatusTemporaryRedirect, redirectURL) + c.Redirect(http.StatusFound, redirectURL) } func (controller *ProxyController) getHeader(c *gin.Context, header string) (string, bool) { diff --git a/internal/controller/proxy_controller_test.go b/internal/controller/proxy_controller_test.go index 1b2eb5c6..faa9934b 100644 --- a/internal/controller/proxy_controller_test.go +++ b/internal/controller/proxy_controller_test.go @@ -2,6 +2,9 @@ package controller import ( "context" + "encoding/base64" + "fmt" + "net/http" "net/http/httptest" "net/url" "testing" @@ -63,6 +66,17 @@ func TestProxyController(t *testing.T) { } tests := []testCase{ + { + description: "Should get bad request on invalid proxy", + middlewares: []gin.HandlerFunc{}, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/invalid", nil) + router.ServeHTTP(recorder, req) + + assert.Equal(t, http.StatusBadRequest, recorder.Code) + assert.Contains(t, recorder.Body.String(), "Bad request") + }, + }, { description: "Default forward auth should be detected and used for traefik", middlewares: []gin.HandlerFunc{}, @@ -74,7 +88,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("user-agent", browserUserAgent) router.ServeHTTP(recorder, req) - assert.Equal(t, 307, recorder.Code) + assert.Equal(t, http.StatusFound, recorder.Code) location := recorder.Header().Get("Location") assert.Contains(t, location, url.QueryEscape("https://test.example.com/")) assert.Contains(t, location, "login_for=app") @@ -89,7 +103,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-original-url", "https://test.example.com/") req.Header.Set("user-agent", browserUserAgent) router.ServeHTTP(recorder, req) - assert.Equal(t, 401, recorder.Code) + assert.Equal(t, http.StatusUnauthorized, recorder.Code) location := recorder.Header().Get("x-tinyauth-location") assert.Contains(t, location, url.QueryEscape("https://test.example.com/")) assert.Contains(t, location, "login_for=app") @@ -105,7 +119,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-proto", "https") req.Header.Set("user-agent", browserUserAgent) router.ServeHTTP(recorder, req) - assert.Equal(t, 307, recorder.Code) + assert.Equal(t, http.StatusFound, recorder.Code) location := recorder.Header().Get("Location") assert.Contains(t, location, url.QueryEscape("https://test.example.com/hello")) assert.Contains(t, location, "login_for=app") @@ -123,7 +137,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("user-agent", browserUserAgent) router.ServeHTTP(recorder, req) - assert.Equal(t, 307, recorder.Code) + assert.Equal(t, http.StatusFound, recorder.Code) location := recorder.Header().Get("Location") assert.Contains(t, location, url.QueryEscape("https://test.example.com/")) assert.Contains(t, location, "login_for=app") @@ -140,7 +154,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-uri", "/") req.Header.Set("user-agent", browserUserAgent) router.ServeHTTP(recorder, req) - assert.Equal(t, 401, recorder.Code) + assert.Equal(t, http.StatusUnauthorized, recorder.Code) location := recorder.Header().Get("x-tinyauth-location") assert.Contains(t, location, url.QueryEscape("https://test.example.com/")) assert.Contains(t, location, "login_for=app") @@ -158,7 +172,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-uri", "/hello") req.Header.Set("user-agent", browserUserAgent) router.ServeHTTP(recorder, req) - assert.Equal(t, 307, recorder.Code) + assert.Equal(t, http.StatusFound, recorder.Code) location := recorder.Header().Get("Location") assert.Contains(t, location, url.QueryEscape("https://test.example.com/")) assert.Contains(t, location, "login_for=app") @@ -175,7 +189,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-uri", "/") router.ServeHTTP(recorder, req) - assert.Equal(t, 401, recorder.Code) + assert.Equal(t, http.StatusUnauthorized, recorder.Code) assert.Contains(t, recorder.Body.String(), `"status":401`) assert.Contains(t, recorder.Body.String(), `"message":"Unauthorized"`) }, @@ -190,7 +204,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-uri", "/") router.ServeHTTP(recorder, req) - assert.Equal(t, 401, recorder.Code) + assert.Equal(t, http.StatusUnauthorized, recorder.Code) assert.Contains(t, recorder.Body.String(), `"status":401`) assert.Contains(t, recorder.Body.String(), `"message":"Unauthorized"`) }, @@ -205,7 +219,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-uri", "/hello") router.ServeHTTP(recorder, req) - assert.Equal(t, 401, recorder.Code) + assert.Equal(t, http.StatusUnauthorized, recorder.Code) assert.Contains(t, recorder.Body.String(), `"status":401`) assert.Contains(t, recorder.Body.String(), `"message":"Unauthorized"`) }, @@ -222,7 +236,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-uri", "/") router.ServeHTTP(recorder, req) - assert.Equal(t, 200, recorder.Code) + assert.Equal(t, http.StatusOK, recorder.Code) assert.Equal(t, "testuser", recorder.Header().Get("remote-user")) assert.Equal(t, "Testuser", recorder.Header().Get("remote-name")) assert.Equal(t, "testuser@example.com", recorder.Header().Get("remote-email")) @@ -238,7 +252,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-original-url", "https://test.example.com/") router.ServeHTTP(recorder, req) - assert.Equal(t, 200, recorder.Code) + assert.Equal(t, http.StatusOK, recorder.Code) assert.Equal(t, "testuser", recorder.Header().Get("remote-user")) assert.Equal(t, "Testuser", recorder.Header().Get("remote-name")) assert.Equal(t, "testuser@example.com", recorder.Header().Get("remote-email")) @@ -255,7 +269,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-proto", "https") router.ServeHTTP(recorder, req) - assert.Equal(t, 200, recorder.Code) + assert.Equal(t, http.StatusOK, recorder.Code) assert.Equal(t, "testuser", recorder.Header().Get("remote-user")) assert.Equal(t, "Testuser", recorder.Header().Get("remote-name")) assert.Equal(t, "testuser@example.com", recorder.Header().Get("remote-email")) @@ -270,7 +284,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-proto", "https") req.Header.Set("x-forwarded-uri", "/allowed") router.ServeHTTP(recorder, req) - assert.Equal(t, 200, recorder.Code) + assert.Equal(t, http.StatusOK, recorder.Code) }, }, { @@ -280,7 +294,7 @@ func TestProxyController(t *testing.T) { req := httptest.NewRequest("GET", "/api/auth/nginx", nil) req.Header.Set("x-original-url", "https://path-allow.example.com/allowed") router.ServeHTTP(recorder, req) - assert.Equal(t, 200, recorder.Code) + assert.Equal(t, http.StatusOK, recorder.Code) }, }, { @@ -291,7 +305,7 @@ func TestProxyController(t *testing.T) { req.Host = "path-allow.example.com" req.Header.Set("x-forwarded-proto", "https") router.ServeHTTP(recorder, req) - assert.Equal(t, 200, recorder.Code) + assert.Equal(t, http.StatusOK, recorder.Code) }, }, { @@ -304,7 +318,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-uri", "/") req.Header.Set("x-forwarded-for", "10.10.10.10") router.ServeHTTP(recorder, req) - assert.Equal(t, 200, recorder.Code) + assert.Equal(t, http.StatusOK, recorder.Code) }, }, { @@ -315,7 +329,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-original-url", "https://ip-bypass.example.com/") req.Header.Set("x-forwarded-for", "10.10.10.10") router.ServeHTTP(recorder, req) - assert.Equal(t, 200, recorder.Code) + assert.Equal(t, http.StatusOK, recorder.Code) }, }, { @@ -327,7 +341,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-proto", "https") req.Header.Set("x-forwarded-for", "10.10.10.10") router.ServeHTTP(recorder, req) - assert.Equal(t, 200, recorder.Code) + assert.Equal(t, http.StatusOK, recorder.Code) }, }, { @@ -341,7 +355,7 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-proto", "https") req.Header.Set("x-forwarded-uri", "/") router.ServeHTTP(recorder, req) - assert.Equal(t, 200, recorder.Code) + assert.Equal(t, http.StatusOK, recorder.Code) }, }, { @@ -355,12 +369,301 @@ func TestProxyController(t *testing.T) { req.Header.Set("x-forwarded-proto", "https") req.Header.Set("x-forwarded-uri", "/") router.ServeHTTP(recorder, req) - assert.Equal(t, 403, recorder.Code) + assert.Equal(t, http.StatusForbidden, recorder.Code) assert.Equal(t, "", recorder.Header().Get("remote-user")) assert.Equal(t, "", recorder.Header().Get("remote-name")) assert.Equal(t, "", recorder.Header().Get("remote-email")) }, }, + { + description: "Test IP block rule, with non browser user agent", + middlewares: []gin.HandlerFunc{}, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "ip-block.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + req.Header.Set("x-forwarded-for", "10.10.10.10") + router.ServeHTTP(recorder, req) + assert.Equal(t, http.StatusForbidden, recorder.Code) + assert.Contains(t, recorder.Header().Get("x-tinyauth-location"), runtime.AppURL) + assert.Contains(t, recorder.Header().Get("x-tinyauth-location"), "ip=10.10.10.10") + assert.Contains(t, recorder.Header().Get("x-tinyauth-location"), "ip-block") + + }, + }, + { + description: "Test IP block rule, with browser user agent", + middlewares: []gin.HandlerFunc{}, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "ip-block.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + req.Header.Set("x-forwarded-for", "10.10.10.10") + req.Header.Set("user-agent", browserUserAgent) + router.ServeHTTP(recorder, req) + assert.Equal(t, http.StatusFound, recorder.Code) + location := recorder.Header().Get("Location") + assert.Contains(t, location, url.QueryEscape("10.10.10.10")) + assert.Contains(t, location, url.QueryEscape("ip-block")) + assert.Contains(t, location, runtime.AppURL) + }, + }, + { + description: "OAuth allowed group", + middlewares: []gin.HandlerFunc{ + func(ctx *gin.Context) { + ctx.Set("context", &model.UserContext{ + Authenticated: true, + Provider: model.ProviderOAuth, + OAuth: &model.OAuthContext{ + BaseContext: model.BaseContext{ + Username: "testuser", + Name: "Testuser", + Email: "testuser@example.com", + }, + Groups: []string{"group1"}, + }, + }) + ctx.Next() + }, + }, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "oauth-group.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + router.ServeHTTP(recorder, req) + assert.Equal(t, http.StatusOK, recorder.Code) + assert.Equal(t, "testuser", recorder.Header().Get("remote-user")) + assert.Equal(t, "Testuser", recorder.Header().Get("remote-name")) + assert.Equal(t, "testuser@example.com", recorder.Header().Get("remote-email")) + assert.Equal(t, "group1", recorder.Header().Get("remote-groups")) + }, + }, + { + description: "OAuth not in required groups and non browser", + middlewares: []gin.HandlerFunc{ + func(ctx *gin.Context) { + ctx.Set("context", &model.UserContext{ + Authenticated: true, + Provider: model.ProviderOAuth, + OAuth: &model.OAuthContext{ + BaseContext: model.BaseContext{ + Username: "testuser", + Name: "Testuser", + Email: "testuser@example.com", + }, + Groups: []string{"group3"}, + }, + }) + ctx.Next() + }, + }, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "oauth-group.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + router.ServeHTTP(recorder, req) + assert.Equal(t, http.StatusForbidden, recorder.Code) + assert.Equal(t, "", recorder.Header().Get("remote-user")) + assert.Equal(t, "", recorder.Header().Get("remote-name")) + assert.Equal(t, "", recorder.Header().Get("remote-email")) + assert.Equal(t, "", recorder.Header().Get("remote-groups")) + assert.Contains(t, recorder.Header().Get("x-tinyauth-location"), runtime.AppURL) + assert.Contains(t, recorder.Header().Get("x-tinyauth-location"), "groupErr=true") + assert.Contains(t, recorder.Header().Get("x-tinyauth-location"), "oauth-group") + }, + }, + { + description: "OAuth not in required groups and browser", + middlewares: []gin.HandlerFunc{ + func(ctx *gin.Context) { + ctx.Set("context", &model.UserContext{ + Authenticated: true, + Provider: model.ProviderOAuth, + OAuth: &model.OAuthContext{ + BaseContext: model.BaseContext{ + Username: "testuser", + Name: "Testuser", + Email: "testuser@example.com", + }, + Groups: []string{"group3"}, + }, + }) + ctx.Next() + }, + }, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "oauth-group.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + req.Header.Set("user-agent", browserUserAgent) + router.ServeHTTP(recorder, req) + assert.Equal(t, http.StatusFound, recorder.Code) + location := recorder.Header().Get("Location") + assert.Contains(t, location, "groupErr=true") + assert.Contains(t, location, "oauth-group") + assert.Contains(t, location, runtime.AppURL) + }, + }, + { + description: "LDAP allowed group", + middlewares: []gin.HandlerFunc{ + func(ctx *gin.Context) { + ctx.Set("context", &model.UserContext{ + Authenticated: true, + Provider: model.ProviderLDAP, + LDAP: &model.LDAPContext{ + BaseContext: model.BaseContext{ + Username: "testuser", + Name: "Testuser", + Email: "testuser@example.com", + }, + Groups: []string{"group1"}, + }, + }) + ctx.Next() + }, + }, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "ldap-group.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + router.ServeHTTP(recorder, req) + assert.Equal(t, http.StatusOK, recorder.Code) + assert.Equal(t, "testuser", recorder.Header().Get("remote-user")) + assert.Equal(t, "Testuser", recorder.Header().Get("remote-name")) + assert.Equal(t, "testuser@example.com", recorder.Header().Get("remote-email")) + assert.Equal(t, "group1", recorder.Header().Get("remote-groups")) + }, + }, + { + description: "LDAP not in required groups and non browser", + middlewares: []gin.HandlerFunc{ + func(ctx *gin.Context) { + ctx.Set("context", &model.UserContext{ + Authenticated: true, + Provider: model.ProviderLDAP, + LDAP: &model.LDAPContext{ + BaseContext: model.BaseContext{ + Username: "testuser", + Name: "Testuser", + Email: "testuser@example.com", + }, + Groups: []string{"group3"}, + }, + }) + ctx.Next() + }, + }, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "ldap-group.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + router.ServeHTTP(recorder, req) + assert.Equal(t, http.StatusForbidden, recorder.Code) + assert.Equal(t, "", recorder.Header().Get("remote-user")) + assert.Equal(t, "", recorder.Header().Get("remote-name")) + assert.Equal(t, "", recorder.Header().Get("remote-email")) + assert.Equal(t, "", recorder.Header().Get("remote-groups")) + assert.Contains(t, recorder.Header().Get("x-tinyauth-location"), runtime.AppURL) + assert.Contains(t, recorder.Header().Get("x-tinyauth-location"), "groupErr=true") + assert.Contains(t, recorder.Header().Get("x-tinyauth-location"), "ldap-group") + }, + }, + { + description: "LDAP not in required groups and browser", + middlewares: []gin.HandlerFunc{ + func(ctx *gin.Context) { + ctx.Set("context", &model.UserContext{ + Authenticated: true, + Provider: model.ProviderLDAP, + LDAP: &model.LDAPContext{ + BaseContext: model.BaseContext{ + Username: "testuser", + Name: "Testuser", + Email: "testuser@example.com", + }, + Groups: []string{"group3"}, + }, + }) + ctx.Next() + }, + }, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "ldap-group.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + req.Header.Set("user-agent", browserUserAgent) + router.ServeHTTP(recorder, req) + assert.Equal(t, http.StatusFound, recorder.Code) + location := recorder.Header().Get("Location") + assert.Contains(t, location, "groupErr=true") + assert.Contains(t, location, "ldap-group") + assert.Contains(t, location, runtime.AppURL) + }, + }, + { + description: "Should add basic auth if it's in ACLs", + middlewares: []gin.HandlerFunc{ + simpleCtx, + }, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "basic-auth.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + req.Header.Set("authorization", "foo") // should be overridden by basic auth + router.ServeHTTP(recorder, req) + + assert.Equal(t, http.StatusOK, recorder.Code) + authorizationHeader := recorder.Header().Get("Authorization") + assert.NotEmpty(t, authorizationHeader) + assert.Equal(t, fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte("test:password"))), authorizationHeader) + }, + }, + { + description: "Authorization header should be preserved when not basic auth acls", + middlewares: []gin.HandlerFunc{ + simpleCtx, + }, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "test.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + req.Header.Set("authorization", "Bearer mytoken") + router.ServeHTTP(recorder, req) + + assert.Equal(t, http.StatusOK, recorder.Code) + authorizationHeader := recorder.Header().Get("Authorization") + assert.NotEmpty(t, authorizationHeader) + assert.Equal(t, "Bearer mytoken", authorizationHeader) + }, + }, + { + description: "Should add response headers if present", + middlewares: []gin.HandlerFunc{ + simpleCtx, + }, + run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { + req := httptest.NewRequest("GET", "/api/auth/traefik", nil) + req.Header.Set("x-forwarded-host", "response-headers.example.com") + req.Header.Set("x-forwarded-proto", "https") + req.Header.Set("x-forwarded-uri", "/") + router.ServeHTTP(recorder, req) + + assert.Equal(t, http.StatusOK, recorder.Code) + assert.Equal(t, "bar", recorder.Header().Get("x-foo")) + }, + }, } store := memory.New() diff --git a/internal/controller/user_controller_test.go b/internal/controller/user_controller_test.go index 4df7efe2..d4cb2c0c 100644 --- a/internal/controller/user_controller_test.go +++ b/internal/controller/user_controller_test.go @@ -41,6 +41,7 @@ func TestUserController(t *testing.T) { TOTPPending: true, }, }) + c.Next() } totpAttrCtx := func(c *gin.Context) { @@ -56,6 +57,7 @@ func TestUserController(t *testing.T) { TOTPPending: true, }, }) + c.Next() } simpleCtx := func(c *gin.Context) { @@ -70,6 +72,7 @@ func TestUserController(t *testing.T) { }, }, }) + c.Next() } store := memory.New() @@ -337,6 +340,7 @@ func TestUserController(t *testing.T) { TOTPPending: true, }, }) + ctx.Next() }, }, run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) { diff --git a/internal/test/test.go b/internal/test/test.go index df10f2b4..676501a4 100644 --- a/internal/test/test.go +++ b/internal/test/test.go @@ -76,6 +76,50 @@ func CreateTestConfigs(t *testing.T) (model.Config, model.RuntimeConfig) { Bypass: []string{"10.10.10.10"}, }, }, + "ip_block": { + Config: model.AppConfig{ + Domain: "ip-block.example.com", + }, + IP: model.AppIP{ + Block: []string{"10.10.10.10"}, + }, + }, + "oauth_group": { + Config: model.AppConfig{ + Domain: "oauth-group.example.com", + }, + OAuth: model.AppOAuth{ + Whitelist: "testuser@example.com", + Groups: "group1,group2", + }, + }, + "ldap_group": { + Config: model.AppConfig{ + Domain: "ldap-group.example.com", + }, + LDAP: model.AppLDAP{ + Groups: "group1,group2", + }, + }, + "basic_auth": { + Config: model.AppConfig{ + Domain: "basic-auth.example.com", + }, + Response: model.AppResponse{ + BasicAuth: model.AppBasicAuth{ + Username: "test", + Password: "password", + }, + }, + }, + "response_headers": { + Config: model.AppConfig{ + Domain: "response-headers.example.com", + }, + Response: model.AppResponse{ + Headers: []string{"x-foo=bar"}, + }, + }, }, }