Skip to content

Commit ef25872

Browse files
feat: add support for Envoy proxy (#538)
* feat: add support for 'envoy' proxy in proxyHandler validation * refactor: simplify proxy route setup by consolidating envoy handling * feat(proxy): add method validation for proxy authentication * fix(proxy): reorder method validation for proxy authentication * refactor: use a slice to check for supported proxies --------- Co-authored-by: pushpinderbal <me@s1ngh.ca> Co-authored-by: Pushpinder Singh <53684951+pushpinderbal@users.noreply.github.com> Co-authored-by: Pushpinder Singh <pushpinder.singh@arcticwolf.com>
1 parent 03ed183 commit ef25872

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

internal/controller/proxy_controller.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package controller
33
import (
44
"fmt"
55
"net/http"
6+
"slices"
67
"strings"
78
"tinyauth/internal/config"
89
"tinyauth/internal/service"
@@ -13,6 +14,8 @@ import (
1314
"github.com/rs/zerolog/log"
1415
)
1516

17+
var SupportedProxies = []string{"nginx", "traefik", "caddy", "envoy"}
18+
1619
type Proxy struct {
1720
Proxy string `uri:"proxy" binding:"required"`
1821
}
@@ -39,7 +42,7 @@ func NewProxyController(config ProxyControllerConfig, router *gin.RouterGroup, a
3942

4043
func (controller *ProxyController) SetupRoutes() {
4144
proxyGroup := controller.router.Group("/auth")
42-
proxyGroup.GET("/:proxy", controller.proxyHandler)
45+
proxyGroup.Any("/:proxy", controller.proxyHandler)
4346
}
4447

4548
func (controller *ProxyController) proxyHandler(c *gin.Context) {
@@ -55,7 +58,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
5558
return
5659
}
5760

58-
if req.Proxy != "nginx" && req.Proxy != "traefik" && req.Proxy != "caddy" {
61+
if !slices.Contains(SupportedProxies, req.Proxy) {
5962
log.Warn().Str("proxy", req.Proxy).Msg("Invalid proxy")
6063
c.JSON(400, gin.H{
6164
"status": 400,
@@ -64,6 +67,15 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
6467
return
6568
}
6669

70+
if req.Proxy != "envoy" && c.Request.Method != http.MethodGet {
71+
log.Warn().Str("method", c.Request.Method).Msg("Invalid method for proxy")
72+
c.JSON(405, gin.H{
73+
"status": 405,
74+
"message": "Method Not Allowed",
75+
})
76+
return
77+
}
78+
6779
isBrowser := strings.Contains(c.Request.Header.Get("Accept"), "text/html")
6880

6981
if isBrowser {

internal/controller/proxy_controller_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ func TestProxyHandler(t *testing.T) {
8080

8181
assert.Equal(t, 400, recorder.Code)
8282

83+
// Test invalid method
84+
recorder = httptest.NewRecorder()
85+
req = httptest.NewRequest("POST", "/api/auth/traefik", nil)
86+
router.ServeHTTP(recorder, req)
87+
88+
assert.Equal(t, 405, recorder.Code)
89+
8390
// Test logged out user (traefik/caddy)
8491
recorder = httptest.NewRecorder()
8592
req = httptest.NewRequest("GET", "/api/auth/traefik", nil)
@@ -92,6 +99,18 @@ func TestProxyHandler(t *testing.T) {
9299
assert.Equal(t, 307, recorder.Code)
93100
assert.Equal(t, "http://localhost:8080/login?redirect_uri=https%3A%2F%2Fexample.com%2Fsomepath", recorder.Header().Get("Location"))
94101

102+
// Test logged out user (envoy)
103+
recorder = httptest.NewRecorder()
104+
req = httptest.NewRequest("POST", "/api/auth/envoy", nil)
105+
req.Header.Set("X-Forwarded-Proto", "https")
106+
req.Header.Set("X-Forwarded-Host", "example.com")
107+
req.Header.Set("X-Forwarded-Uri", "/somepath")
108+
req.Header.Set("Accept", "text/html")
109+
router.ServeHTTP(recorder, req)
110+
111+
assert.Equal(t, 307, recorder.Code)
112+
assert.Equal(t, "http://localhost:8080/login?redirect_uri=https%3A%2F%2Fexample.com%2Fsomepath", recorder.Header().Get("Location"))
113+
95114
// Test logged out user (nginx)
96115
recorder = httptest.NewRecorder()
97116
req = httptest.NewRequest("GET", "/api/auth/nginx", nil)

0 commit comments

Comments
 (0)