feat: add support for nginx/nginx proxy manager (breaking)

This commit is contained in:
Stavros
2025-02-07 16:36:47 +02:00
parent 87393d3c64
commit ce567ae3de
3 changed files with 88 additions and 22 deletions

2
.gitignore vendored
View File

@@ -5,7 +5,7 @@ internal/assets/dist
tinyauth tinyauth
# test docker compose # test docker compose
docker-compose.test.yml docker-compose.test*
# users file # users file
users.txt users.txt

View File

@@ -95,8 +95,17 @@ func (api *API) Init() {
} }
func (api *API) SetupRoutes() { func (api *API) SetupRoutes() {
api.Router.GET("/api/auth", func(c *gin.Context) { api.Router.GET("/api/auth/:proxy", func(c *gin.Context) {
log.Debug().Msg("Checking auth") var proxy types.Proxy
bindErr := c.BindUri(&proxy)
if api.handleError(c, "Failed to bind URI", bindErr) {
return
}
log.Debug().Interface("proxy", proxy.Proxy).Msg("Got proxy")
userContext := api.Hooks.UseUserContext(c) userContext := api.Hooks.UseUserContext(c)
uri := c.Request.Header.Get("X-Forwarded-Uri") uri := c.Request.Header.Get("X-Forwarded-Uri")
@@ -108,22 +117,59 @@ func (api *API) SetupRoutes() {
appAllowed, appAllowedErr := api.Auth.ResourceAllowed(userContext, host) appAllowed, appAllowedErr := api.Auth.ResourceAllowed(userContext, host)
log.Debug().Bool("appAllowed", appAllowed).Msg("Checking if user is allowed") if appAllowedErr != nil {
switch proxy.Proxy {
case "nginx":
log.Error().Err(appAllowedErr).Msg("Failed to check if resource is allowed")
c.JSON(501, gin.H{
"status": 501,
"message": "Internal Server Error",
})
return
default:
if api.handleError(c, "Failed to check if resource is allowed", appAllowedErr) { if api.handleError(c, "Failed to check if resource is allowed", appAllowedErr) {
return return
} }
}
}
log.Debug().Bool("appAllowed", appAllowed).Msg("Checking if app is allowed")
if !appAllowed { if !appAllowed {
log.Warn().Str("username", userContext.Username).Str("host", host).Msg("User not allowed") log.Warn().Str("username", userContext.Username).Str("host", host).Msg("User not allowed")
queries, queryErr := query.Values(types.UnauthorizedQuery{ queries, queryErr := query.Values(types.UnauthorizedQuery{
Username: userContext.Username, Username: userContext.Username,
Resource: strings.Split(host, ".")[0], Resource: strings.Split(host, ".")[0],
}) })
if queryErr != nil {
switch proxy.Proxy {
case "nginx":
log.Error().Err(queryErr).Msg("Failed to build query")
c.JSON(501, gin.H{
"status": 501,
"message": "Internal Server Error",
})
return
default:
if api.handleError(c, "Failed to build query", queryErr) { if api.handleError(c, "Failed to build query", queryErr) {
return return
} }
}
}
switch proxy.Proxy {
case "nginx":
c.JSON(401, gin.H{
"status": 401,
"message": "Unauthorized",
})
return
default:
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/unauthorized?%s", api.Config.AppURL, queries.Encode())) c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/unauthorized?%s", api.Config.AppURL, queries.Encode()))
return
}
} }
c.JSON(200, gin.H{ c.JSON(200, gin.H{
@@ -133,6 +179,14 @@ func (api *API) SetupRoutes() {
return return
} }
switch proxy.Proxy {
case "nginx":
c.JSON(401, gin.H{
"status": 401,
"message": "Unauthorized",
})
return
default:
queries, queryErr := query.Values(types.LoginQuery{ queries, queryErr := query.Values(types.LoginQuery{
RedirectURI: fmt.Sprintf("%s://%s%s", proto, host, uri), RedirectURI: fmt.Sprintf("%s://%s%s", proto, host, uri),
}) })
@@ -140,15 +194,23 @@ func (api *API) SetupRoutes() {
log.Debug().Interface("redirect_uri", fmt.Sprintf("%s://%s%s", proto, host, uri)).Msg("Redirecting to login") log.Debug().Interface("redirect_uri", fmt.Sprintf("%s://%s%s", proto, host, uri)).Msg("Redirecting to login")
if queryErr != nil { if queryErr != nil {
switch proxy.Proxy {
case "nginx":
log.Error().Err(queryErr).Msg("Failed to build query") log.Error().Err(queryErr).Msg("Failed to build query")
c.JSON(501, gin.H{ c.JSON(501, gin.H{
"status": 501, "status": 501,
"message": "Internal Server Error", "message": "Internal Server Error",
}) })
return return
default:
if api.handleError(c, "Failed to build query", queryErr) {
return
}
}
} }
c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/?%s", api.Config.AppURL, queries.Encode())) c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/?%s", api.Config.AppURL, queries.Encode()))
}
}) })
api.Router.POST("/api/login", func(c *gin.Context) { api.Router.POST("/api/login", func(c *gin.Context) {

View File

@@ -110,3 +110,7 @@ type TinyauthLabels struct {
type TailscaleQuery struct { type TailscaleQuery struct {
Code int `url:"code"` Code int `url:"code"`
} }
type Proxy struct {
Proxy string `uri:"proxy" binding:"required"`
}