feat: add swagger docs for rest of api endpoints

This commit is contained in:
Stavros
2026-07-04 14:56:20 +03:00
parent fb48f1eb2d
commit dcb503b3be
7 changed files with 2516 additions and 136 deletions
+50 -27
View File
@@ -86,15 +86,38 @@ func NewProxyController(i ProxyControllerInput) *ProxyController {
return controller return controller
} }
// Proxy godoc
//
// @Summary Proxy
// @Description Forward-Auth Proxy Endpoint
// @Tags forward-auth
// @Produce json
// @Param proxy path string true "Proxy Name"
// @Success 200 {object} SimpleResponse
// @Failure 302
// @Failure 400 {object} SimpleResponse
// @Failure 401 {object} SimpleResponse
// @Failure 403 {object} SimpleResponse
// @Failure 500 {object} SimpleResponse
// @Router /api/auth/traefik [get]
// @Router /api/auth/caddy [get]
// @Router /api/auth/nginx [get]
// @Router /api/auth/envoy [get]
// @Router /api/auth/envoy [post]
// @Router /api/auth/envoy [head]
// @Router /api/auth/envoy [put]
// @Router /api/auth/envoy [patch]
// @Router /api/auth/envoy [delete]
// @Router /api/auth/envoy [options]
func (controller *ProxyController) proxyHandler(c *gin.Context) { func (controller *ProxyController) proxyHandler(c *gin.Context) {
// Load proxy context based on the request type // Load proxy context based on the request type
proxyCtx, err := controller.getProxyContext(c) proxyCtx, err := controller.getProxyContext(c)
if err != nil { if err != nil {
controller.log.App.Error().Err(err).Msg("Failed to get proxy context from request") controller.log.App.Error().Err(err).Msg("Failed to get proxy context from request")
c.JSON(400, gin.H{ c.JSON(400, SimpleResponse{
"status": 400, Status: 400,
"message": "Bad request", Message: "Bad request",
}) })
return return
} }
@@ -118,9 +141,9 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
if controller.policyEngine.Evaluate(service.RuleIPBypassed, aclsCtx) { if controller.policyEngine.Evaluate(service.RuleIPBypassed, aclsCtx) {
controller.setHeaders(c, acls) controller.setHeaders(c, acls)
c.JSON(200, gin.H{ c.JSON(200, SimpleResponse{
"status": 200, Status: 200,
"message": "Authenticated", Message: "Authenticated",
}) })
return return
} }
@@ -128,9 +151,9 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
if controller.policyEngine.Evaluate(service.RuleAuthEnabled, aclsCtx) { if controller.policyEngine.Evaluate(service.RuleAuthEnabled, aclsCtx) {
controller.log.App.Debug().Msg("Authentication is disabled for this resource, allowing access without authentication") controller.log.App.Debug().Msg("Authentication is disabled for this resource, allowing access without authentication")
controller.setHeaders(c, acls) controller.setHeaders(c, acls)
c.JSON(200, gin.H{ c.JSON(200, SimpleResponse{
"status": 200, Status: 200,
"message": "Authenticated", Message: "Authenticated",
}) })
return return
} }
@@ -151,9 +174,9 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
if !controller.useBrowserResponse(proxyCtx) { if !controller.useBrowserResponse(proxyCtx) {
c.Header("x-tinyauth-location", redirectURL) c.Header("x-tinyauth-location", redirectURL)
c.JSON(403, gin.H{ c.JSON(403, SimpleResponse{
"status": 403, Status: 403,
"message": "Forbidden", Message: "Forbidden",
}) })
return return
} }
@@ -200,9 +223,9 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
if !controller.useBrowserResponse(proxyCtx) { if !controller.useBrowserResponse(proxyCtx) {
c.Header("x-tinyauth-location", redirectURL) c.Header("x-tinyauth-location", redirectURL)
c.JSON(403, gin.H{ c.JSON(403, SimpleResponse{
"status": 403, Status: 403,
"message": "Forbidden", Message: "Forbidden",
}) })
return return
} }
@@ -244,9 +267,9 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
if !controller.useBrowserResponse(proxyCtx) { if !controller.useBrowserResponse(proxyCtx) {
c.Header("x-tinyauth-location", redirectURL) c.Header("x-tinyauth-location", redirectURL)
c.JSON(403, gin.H{ c.JSON(403, SimpleResponse{
"status": 403, Status: 403,
"message": "Forbidden", Message: "Forbidden",
}) })
return return
} }
@@ -271,9 +294,9 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
controller.setHeaders(c, acls) controller.setHeaders(c, acls)
c.JSON(200, gin.H{ c.JSON(200, SimpleResponse{
"status": 200, Status: 200,
"message": "Authenticated", Message: "Authenticated",
}) })
return return
} }
@@ -293,9 +316,9 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
if !controller.useBrowserResponse(proxyCtx) { if !controller.useBrowserResponse(proxyCtx) {
c.Header("x-tinyauth-location", redirectURL) c.Header("x-tinyauth-location", redirectURL)
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
@@ -329,9 +352,9 @@ func (controller *ProxyController) handleError(c *gin.Context, proxyCtx ProxyCon
if !controller.useBrowserResponse(proxyCtx) { if !controller.useBrowserResponse(proxyCtx) {
c.Header("x-tinyauth-location", redirectURL) c.Header("x-tinyauth-location", redirectURL)
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "Internal Server Error", Message: "Internal Server Error",
}) })
return return
} }
+16 -6
View File
@@ -33,18 +33,28 @@ func NewResourcesController(i ResourcesControllerInput) *ResourcesController {
return controller return controller
} }
// Resources godoc
//
// @Summary Resources Endpoint
// @Description Get a resource by file name
// @Tags resources
// @Param resource path string true "Resource Name"
// @Success 200
// @Failure 404 {object} SimpleResponse
// @Failure 403 {object} SimpleResponse
// @Router /resources/{resource} [get]
func (controller *ResourcesController) resourcesHandler(c *gin.Context) { func (controller *ResourcesController) resourcesHandler(c *gin.Context) {
if controller.config.Resources.Path == "" { if controller.config.Resources.Path == "" {
c.JSON(404, gin.H{ c.JSON(404, SimpleResponse{
"status": 404, Status: 404,
"message": "Resource not found", Message: "Resource not found",
}) })
return return
} }
if !controller.config.Resources.Enabled { if !controller.config.Resources.Enabled {
c.JSON(403, gin.H{ c.JSON(403, SimpleResponse{
"status": 403, Status: 403,
"message": "Resources are disabled", Message: "Resources are disabled",
}) })
return return
} }
+139 -85
View File
@@ -32,6 +32,11 @@ type UserController struct {
auth *service.AuthService auth *service.AuthService
} }
type TotpPendingResponse struct {
SimpleResponse
TotpPending bool `json:"totpPending"`
}
type UserControllerInput struct { type UserControllerInput struct {
dig.In dig.In
@@ -57,15 +62,29 @@ func NewUserController(i UserControllerInput) *UserController {
return controller return controller
} }
// Login godoc
//
// @Summary Login
// @Description Login Endpoint
// @Tags accounts
// @Accept json
// @Produce json
// @Success 200 {object} SimpleResponse
// @Success 200 {object} TotpPendingResponse
// @Failure 400 {object} SimpleResponse
// @Failure 401 {object} SimpleResponse
// @Failure 500 {object} SimpleResponse
// @Failure 429 {object} SimpleResponse
// @Router /api/user/login [post]
func (controller *UserController) loginHandler(c *gin.Context) { func (controller *UserController) loginHandler(c *gin.Context) {
var req LoginRequest var req LoginRequest
err := c.ShouldBindJSON(&req) err := c.ShouldBindJSON(&req)
if err != nil { if err != nil {
controller.log.App.Error().Err(err).Msg("Failed to bind JSON") controller.log.App.Error().Err(err).Msg("Failed to bind JSON")
c.JSON(400, gin.H{ c.JSON(400, SimpleResponse{
"status": 400, Status: 400,
"message": "Bad Request", Message: "Bad Request",
}) })
return return
} }
@@ -79,9 +98,9 @@ func (controller *UserController) loginHandler(c *gin.Context) {
controller.log.AuditLoginFailure(req.Username, "local", c.ClientIP(), "account locked") controller.log.AuditLoginFailure(req.Username, "local", c.ClientIP(), "account locked")
c.Writer.Header().Add("x-tinyauth-lock-locked", "true") c.Writer.Header().Add("x-tinyauth-lock-locked", "true")
c.Writer.Header().Add("x-tinyauth-lock-reset", time.Now().Add(time.Duration(remaining)*time.Second).Format(time.RFC3339)) c.Writer.Header().Add("x-tinyauth-lock-reset", time.Now().Add(time.Duration(remaining)*time.Second).Format(time.RFC3339))
c.JSON(429, gin.H{ c.JSON(429, SimpleResponse{
"status": 429, Status: 429,
"message": fmt.Sprintf("Too many failed login attempts. Try again in %d seconds", remaining), Message: fmt.Sprintf("Too many failed login attempts. Try again in %d seconds", remaining),
}) })
return return
} }
@@ -93,16 +112,16 @@ func (controller *UserController) loginHandler(c *gin.Context) {
controller.log.App.Warn().Str("username", req.Username).Msg("User not found during login attempt") controller.log.App.Warn().Str("username", req.Username).Msg("User not found during login attempt")
controller.auth.RecordLoginAttempt(req.Username, false) controller.auth.RecordLoginAttempt(req.Username, false)
controller.log.AuditLoginFailure(req.Username, "unknown", c.ClientIP(), "user not found") controller.log.AuditLoginFailure(req.Username, "unknown", c.ClientIP(), "user not found")
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
controller.log.App.Error().Err(err).Str("username", req.Username).Msg("Error searching for user during login attempt") controller.log.App.Error().Err(err).Str("username", req.Username).Msg("Error searching for user during login attempt")
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "Internal Server Error", Message: "Internal Server Error",
}) })
return return
} }
@@ -115,9 +134,9 @@ func (controller *UserController) loginHandler(c *gin.Context) {
} else { } else {
controller.log.AuditLoginFailure(req.Username, "ldap", c.ClientIP(), "invalid password") controller.log.AuditLoginFailure(req.Username, "ldap", c.ClientIP(), "invalid password")
} }
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
@@ -129,9 +148,9 @@ func (controller *UserController) loginHandler(c *gin.Context) {
if localUser == nil { if localUser == nil {
controller.log.App.Error().Str("username", req.Username).Msg("Local user not found after successful password verification") controller.log.App.Error().Str("username", req.Username).Msg("Local user not found after successful password verification")
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
@@ -159,19 +178,21 @@ func (controller *UserController) loginHandler(c *gin.Context) {
if err != nil { if err != nil {
controller.log.App.Error().Err(err).Str("username", req.Username).Msg("Failed to create pending TOTP session") controller.log.App.Error().Err(err).Str("username", req.Username).Msg("Failed to create pending TOTP session")
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "Internal Server Error", Message: "Internal Server Error",
}) })
return return
} }
http.SetCookie(c.Writer, cookie) http.SetCookie(c.Writer, cookie)
c.JSON(200, gin.H{ c.JSON(200, TotpPendingResponse{
"status": 200, SimpleResponse: SimpleResponse{
"message": "TOTP required", Status: 200,
"totpPending": true, Message: "TOTP required",
},
TotpPending: true,
}) })
return return
} }
@@ -204,9 +225,9 @@ func (controller *UserController) loginHandler(c *gin.Context) {
if err != nil { if err != nil {
controller.log.App.Error().Err(err).Str("username", req.Username).Msg("Failed to create session cookie after successful login") controller.log.App.Error().Err(err).Str("username", req.Username).Msg("Failed to create session cookie after successful login")
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "Internal Server Error", Message: "Internal Server Error",
}) })
return return
} }
@@ -223,12 +244,21 @@ func (controller *UserController) loginHandler(c *gin.Context) {
controller.auth.RecordLoginAttempt(req.Username, true) controller.auth.RecordLoginAttempt(req.Username, true)
c.JSON(200, gin.H{ c.JSON(200, SimpleResponse{
"status": 200, Status: 200,
"message": "Login successful", Message: "Login successful",
}) })
} }
// Logout godoc
//
// @Summary Logout
// @Description Logout Endpoint
// @Tags accounts
// @Produce json
// @Success 200 {object} SimpleResponse
// @Failure 500 {object} SimpleResponse
// @Router /api/user/logout [post]
func (controller *UserController) logoutHandler(c *gin.Context) { func (controller *UserController) logoutHandler(c *gin.Context) {
controller.log.App.Debug().Msg("Logout attempt") controller.log.App.Debug().Msg("Logout attempt")
@@ -237,16 +267,16 @@ func (controller *UserController) logoutHandler(c *gin.Context) {
if err != nil { if err != nil {
if errors.Is(err, http.ErrNoCookie) { if errors.Is(err, http.ErrNoCookie) {
controller.log.App.Warn().Msg("Logout attempt without session cookie, treating as successful logout") controller.log.App.Warn().Msg("Logout attempt without session cookie, treating as successful logout")
c.JSON(200, gin.H{ c.JSON(200, SimpleResponse{
"status": 200, Status: 200,
"message": "Logout successful", Message: "Logout successful",
}) })
return return
} }
controller.log.App.Error().Err(err).Msg("Error retrieving session cookie on logout") controller.log.App.Error().Err(err).Msg("Error retrieving session cookie on logout")
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "Internal Server Error", Message: "Internal Server Error",
}) })
return return
} }
@@ -255,9 +285,9 @@ func (controller *UserController) logoutHandler(c *gin.Context) {
if err != nil { if err != nil {
controller.log.App.Error().Err(err).Msg("Error deleting session on logout") controller.log.App.Error().Err(err).Msg("Error deleting session on logout")
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "Internal Server Error", Message: "Internal Server Error",
}) })
return return
} }
@@ -273,21 +303,34 @@ func (controller *UserController) logoutHandler(c *gin.Context) {
http.SetCookie(c.Writer, cookie) http.SetCookie(c.Writer, cookie)
c.JSON(200, gin.H{ c.JSON(200, SimpleResponse{
"status": 200, Status: 200,
"message": "Logout successful", Message: "Logout successful",
}) })
} }
// TOTP godoc
//
// @Summary TOTP
// @Description TOTP Endpoint
// @Tags accounts
// @Accept json
// @Produce json
// @Success 200 {object} SimpleResponse
// @Failure 400 {object} SimpleResponse
// @Failure 401 {object} SimpleResponse
// @Failure 429 {object} SimpleResponse
// @Failure 500 {object} SimpleResponse
// @Router /api/user/totp [post]
func (controller *UserController) totpHandler(c *gin.Context) { func (controller *UserController) totpHandler(c *gin.Context) {
var req TotpRequest var req TotpRequest
err := c.ShouldBindJSON(&req) err := c.ShouldBindJSON(&req)
if err != nil { if err != nil {
controller.log.App.Error().Err(err).Msg("Failed to bind JSON for TOTP verification") controller.log.App.Error().Err(err).Msg("Failed to bind JSON for TOTP verification")
c.JSON(400, gin.H{ c.JSON(400, SimpleResponse{
"status": 400, Status: 400,
"message": "Bad Request", Message: "Bad Request",
}) })
return return
} }
@@ -297,25 +340,25 @@ func (controller *UserController) totpHandler(c *gin.Context) {
if err != nil { if err != nil {
if errors.Is(err, model.ErrUserContextNotFound) { if errors.Is(err, model.ErrUserContextNotFound) {
controller.log.App.Warn().Msg("TOTP verification attempt without user context") controller.log.App.Warn().Msg("TOTP verification attempt without user context")
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
controller.log.App.Error().Err(err).Msg("Failed to create user context from request for TOTP verification") controller.log.App.Error().Err(err).Msg("Failed to create user context from request for TOTP verification")
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "Internal Server Error", Message: "Internal Server Error",
}) })
return return
} }
if !context.TOTPPending() { if !context.TOTPPending() {
controller.log.App.Warn().Str("username", context.GetUsername()).Msg("TOTP verification attempt without pending TOTP session") controller.log.App.Warn().Str("username", context.GetUsername()).Msg("TOTP verification attempt without pending TOTP session")
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
@@ -329,9 +372,9 @@ func (controller *UserController) totpHandler(c *gin.Context) {
controller.log.AuditLoginFailure(context.GetUsername(), "local", c.ClientIP(), "account locked") controller.log.AuditLoginFailure(context.GetUsername(), "local", c.ClientIP(), "account locked")
c.Writer.Header().Add("x-tinyauth-lock-locked", "true") c.Writer.Header().Add("x-tinyauth-lock-locked", "true")
c.Writer.Header().Add("x-tinyauth-lock-reset", time.Now().Add(time.Duration(remaining)*time.Second).Format(time.RFC3339)) c.Writer.Header().Add("x-tinyauth-lock-reset", time.Now().Add(time.Duration(remaining)*time.Second).Format(time.RFC3339))
c.JSON(429, gin.H{ c.JSON(429, SimpleResponse{
"status": 429, Status: 429,
"message": fmt.Sprintf("Too many failed TOTP attempts. Try again in %d seconds", remaining), Message: fmt.Sprintf("Too many failed TOTP attempts. Try again in %d seconds", remaining),
}) })
return return
} }
@@ -340,9 +383,9 @@ func (controller *UserController) totpHandler(c *gin.Context) {
if user == nil { if user == nil {
controller.log.App.Error().Str("username", context.GetUsername()).Msg("Local user not found during TOTP verification") controller.log.App.Error().Str("username", context.GetUsername()).Msg("Local user not found during TOTP verification")
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
@@ -353,9 +396,9 @@ func (controller *UserController) totpHandler(c *gin.Context) {
controller.log.App.Warn().Str("username", context.GetUsername()).Msg("Invalid TOTP code during verification attempt") controller.log.App.Warn().Str("username", context.GetUsername()).Msg("Invalid TOTP code during verification attempt")
controller.auth.RecordLoginAttempt(context.GetUsername(), false) controller.auth.RecordLoginAttempt(context.GetUsername(), false)
controller.log.AuditLoginFailure(context.GetUsername(), "local", c.ClientIP(), "invalid TOTP code") controller.log.AuditLoginFailure(context.GetUsername(), "local", c.ClientIP(), "invalid TOTP code")
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
@@ -391,9 +434,9 @@ func (controller *UserController) totpHandler(c *gin.Context) {
if err != nil { if err != nil {
controller.log.App.Error().Err(err).Str("username", context.GetUsername()).Msg("Failed to create session cookie after successful TOTP verification") controller.log.App.Error().Err(err).Str("username", context.GetUsername()).Msg("Failed to create session cookie after successful TOTP verification")
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "Internal Server Error", Message: "Internal Server Error",
}) })
return return
} }
@@ -403,37 +446,48 @@ func (controller *UserController) totpHandler(c *gin.Context) {
controller.log.App.Info().Str("username", context.GetUsername()).Msg("TOTP verification successful, login complete") controller.log.App.Info().Str("username", context.GetUsername()).Msg("TOTP verification successful, login complete")
controller.log.AuditLoginSuccess(context.GetUsername(), "local", c.ClientIP()) controller.log.AuditLoginSuccess(context.GetUsername(), "local", c.ClientIP())
c.JSON(200, gin.H{ c.JSON(200, SimpleResponse{
"status": 200, Status: 200,
"message": "Login successful", Message: "Login successful",
}) })
} }
// Tailscale godoc
//
// @Summary Tailscale
// @Description Tailscale Auth Endpoint (Experimental)
// @Tags accounts
// @Accept json
// @Produce json
// @Success 200 {object} SimpleResponse
// @Failure 401 {object} SimpleResponse
// @Failure 500 {object} SimpleResponse
// @Router /api/user/tailscale [post]
func (controller *UserController) tailscaleHandler(c *gin.Context) { func (controller *UserController) tailscaleHandler(c *gin.Context) {
context, err := new(model.UserContext).NewFromGin(c) context, err := new(model.UserContext).NewFromGin(c)
if err != nil { if err != nil {
if errors.Is(err, model.ErrUserContextNotFound) { if errors.Is(err, model.ErrUserContextNotFound) {
controller.log.App.Warn().Msg("Tailscale login attempt without user context") controller.log.App.Warn().Msg("Tailscale login attempt without user context")
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
controller.log.App.Error().Err(err).Msg("Failed to create user context from request") controller.log.App.Error().Err(err).Msg("Failed to create user context from request")
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
if context.Tailscale == nil { if context.Tailscale == nil {
controller.log.App.Warn().Msg("Tailscale login attempt without Tailscale context") controller.log.App.Warn().Msg("Tailscale login attempt without Tailscale context")
c.JSON(401, gin.H{ c.JSON(401, SimpleResponse{
"status": 401, Status: 401,
"message": "Unauthorized", Message: "Unauthorized",
}) })
return return
} }
@@ -449,9 +503,9 @@ func (controller *UserController) tailscaleHandler(c *gin.Context) {
if err != nil { if err != nil {
controller.log.App.Error().Err(err).Str("username", context.GetUsername()).Msg("Failed to create session cookie after successful Tailscale login") controller.log.App.Error().Err(err).Str("username", context.GetUsername()).Msg("Failed to create session cookie after successful Tailscale login")
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "Internal Server Error", Message: "Internal Server Error",
}) })
return return
} }
@@ -461,8 +515,8 @@ func (controller *UserController) tailscaleHandler(c *gin.Context) {
controller.log.App.Info().Str("username", context.GetUsername()).Msg("Tailscale login successful, login complete") controller.log.App.Info().Str("username", context.GetUsername()).Msg("Tailscale login successful, login complete")
controller.log.AuditLoginSuccess(context.GetUsername(), "tailscale", c.ClientIP()) controller.log.AuditLoginSuccess(context.GetUsername(), "tailscale", c.ClientIP())
c.JSON(200, gin.H{ c.JSON(200, SimpleResponse{
"status": 200, Status: 200,
"message": "Login successful", Message: "Login successful",
}) })
} }
+47 -18
View File
@@ -58,18 +58,27 @@ func NewWellKnownController(i WellKnownControllerInput) *WellKnownController {
oidc: i.OIDCService, oidc: i.OIDCService,
} }
i.RouterGroup.GET("/.well-known/openid-configuration", controller.OpenIDConnectConfiguration) i.RouterGroup.GET("/.well-known/openid-configuration", controller.openIDConnectConfiguration)
i.RouterGroup.GET("/.well-known/jwks.json", controller.JWKS) i.RouterGroup.GET("/.well-known/jwks.json", controller.jwks)
i.RouterGroup.GET("/.well-known/webfinger", controller.WebFinger) i.RouterGroup.GET("/.well-known/webfinger", controller.webFinger)
return controller return controller
} }
func (controller *WellKnownController) OpenIDConnectConfiguration(c *gin.Context) { // OpenIDConnectConfiguration godoc
//
// @Summary OpenID Connect Configuration
// @Description OpenID Connect Configuration Discovery Endpoint
// @Tags well-known
// @Produce json
// @Success 200 {object} OpenIDConnectConfiguration
// @Failure 500 {object} SimpleResponse
// @Router /.well-known/openid-configuration [get]
func (controller *WellKnownController) openIDConnectConfiguration(c *gin.Context) {
if controller.oidc == nil { if controller.oidc == nil {
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "OIDC service not configured", Message: "OIDC service not configured",
}) })
return return
} }
@@ -94,11 +103,20 @@ func (controller *WellKnownController) OpenIDConnectConfiguration(c *gin.Context
}) })
} }
func (controller *WellKnownController) JWKS(c *gin.Context) { // JWKS godoc
//
// @Summary JWKS
// @Description JWKS Endpoint
// @Tags well-known
// @Produce json
// @Success 200
// @Failure 500 {object} SimpleResponse
// @Router /.well-known/jwks.json [get]
func (controller *WellKnownController) jwks(c *gin.Context) {
if controller.oidc == nil { if controller.oidc == nil {
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "OIDC service not configured", Message: "OIDC service not configured",
}) })
return return
} }
@@ -106,9 +124,9 @@ func (controller *WellKnownController) JWKS(c *gin.Context) {
jwks, err := controller.oidc.GetJWK() jwks, err := controller.oidc.GetJWK()
if err != nil { if err != nil {
c.JSON(500, gin.H{ c.JSON(500, SimpleResponse{
"status": 500, Status: 500,
"message": "failed to get JWK", Message: "failed to get JWK",
}) })
return return
} }
@@ -122,16 +140,27 @@ func (controller *WellKnownController) JWKS(c *gin.Context) {
c.Status(http.StatusOK) c.Status(http.StatusOK)
} }
func (controller *WellKnownController) WebFinger(c *gin.Context) { // WebFinger godoc
//
// @Summary WebFinger
// @Description WebFinger Endpoint
// @Tags well-known
// @Produce json
// @Param resource query string true "Resource"
// @Param rel query string false "Rel"
// @Success 200 {object} WebfingerResponse
// @Failure 400 {object} SimpleResponse
// @Router /.well-known/webfinger [get]
func (controller *WellKnownController) webFinger(c *gin.Context) {
c.Header("Content-Type", "application/jrd+json") c.Header("Content-Type", "application/jrd+json")
c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Origin", "*")
resource := c.Query("resource") resource := c.Query("resource")
if !controller.validateWebFingerResource(resource) { if !controller.validateWebFingerResource(resource) {
c.JSON(400, gin.H{ c.JSON(400, SimpleResponse{
"status": 400, Status: 400,
"message": "invalid resource", Message: "invalid resource",
}) })
return return
} }
+851
View File
@@ -19,6 +19,554 @@ const docTemplate = `{
"host": "{{.Host}}", "host": "{{.Host}}",
"basePath": "{{.BasePath}}", "basePath": "{{.BasePath}}",
"paths": { "paths": {
"/.well-known/jwks.json": {
"get": {
"description": "JWKS Endpoint",
"produces": [
"application/json"
],
"tags": [
"well-known"
],
"summary": "JWKS",
"responses": {
"200": {
"description": "OK"
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/.well-known/openid-configuration": {
"get": {
"description": "OpenID Connect Configuration Discovery Endpoint",
"produces": [
"application/json"
],
"tags": [
"well-known"
],
"summary": "OpenID Connect Configuration",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.OpenIDConnectConfiguration"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/.well-known/webfinger": {
"get": {
"description": "WebFinger Endpoint",
"produces": [
"application/json"
],
"tags": [
"well-known"
],
"summary": "WebFinger",
"parameters": [
{
"type": "string",
"description": "Resource",
"name": "resource",
"in": "query",
"required": true
},
{
"type": "string",
"description": "Rel",
"name": "rel",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.WebfingerResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/auth/caddy": {
"get": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/auth/envoy": {
"get": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"put": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"post": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"delete": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"options": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"head": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"patch": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/auth/nginx": {
"get": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/auth/traefik": {
"get": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/context/app": { "/api/context/app": {
"get": { "get": {
"description": "Get the app context", "description": "Get the app context",
@@ -231,6 +779,161 @@ const docTemplate = `{
} }
} }
}, },
"/api/user/login": {
"post": {
"description": "Login Endpoint",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"accounts"
],
"summary": "Login",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.TotpPendingResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"429": {
"description": "Too Many Requests",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/user/logout": {
"post": {
"description": "Logout Endpoint",
"produces": [
"application/json"
],
"tags": [
"accounts"
],
"summary": "Logout",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/user/tailscale": {
"post": {
"description": "Tailscale Auth Endpoint (Experimental)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"accounts"
],
"summary": "Tailscale",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/user/totp": {
"post": {
"description": "TOTP Endpoint",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"accounts"
],
"summary": "TOTP",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"429": {
"description": "Too Many Requests",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/authorize": { "/authorize": {
"get": { "get": {
"description": "OpenID Connect Authorize Endpoint", "description": "OpenID Connect Authorize Endpoint",
@@ -724,6 +1427,41 @@ const docTemplate = `{
} }
} }
} }
},
"/resources/{resource}": {
"get": {
"description": "Get a resource by file name",
"tags": [
"resources"
],
"summary": "Resources Endpoint",
"parameters": [
{
"type": "string",
"description": "Resource Name",
"name": "resource",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
} }
}, },
"definitions": { "definitions": {
@@ -836,6 +1574,80 @@ const docTemplate = `{
} }
} }
}, },
"controller.OpenIDConnectConfiguration": {
"type": "object",
"properties": {
"authorization_endpoint": {
"type": "string"
},
"claims_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"grant_types_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"id_token_signing_alg_values_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"issuer": {
"type": "string"
},
"jwks_uri": {
"type": "string"
},
"request_object_signing_alg_values_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"request_parameter_supported": {
"type": "boolean"
},
"response_types_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"scopes_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"service_documentation": {
"type": "string"
},
"subject_types_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"token_endpoint": {
"type": "string"
},
"token_endpoint_auth_methods_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"userinfo_endpoint": {
"type": "string"
}
}
},
"controller.SimpleResponse": { "controller.SimpleResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -847,6 +1659,20 @@ const docTemplate = `{
} }
} }
}, },
"controller.TotpPendingResponse": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"status": {
"type": "integer"
},
"totpPending": {
"type": "boolean"
}
}
},
"controller.UCRAuth": { "controller.UCRAuth": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -917,6 +1743,31 @@ const docTemplate = `{
} }
} }
}, },
"controller.WebfingerResponse": {
"type": "object",
"properties": {
"links": {
"type": "array",
"items": {
"$ref": "#/definitions/controller.WebfingerResponseLink"
}
},
"subject": {
"type": "string"
}
}
},
"controller.WebfingerResponseLink": {
"type": "object",
"properties": {
"href": {
"type": "string"
},
"rel": {
"type": "string"
}
}
},
"model.AddressClaim": { "model.AddressClaim": {
"type": "object", "type": "object",
"properties": { "properties": {
+851
View File
@@ -12,6 +12,554 @@
}, },
"basePath": "/", "basePath": "/",
"paths": { "paths": {
"/.well-known/jwks.json": {
"get": {
"description": "JWKS Endpoint",
"produces": [
"application/json"
],
"tags": [
"well-known"
],
"summary": "JWKS",
"responses": {
"200": {
"description": "OK"
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/.well-known/openid-configuration": {
"get": {
"description": "OpenID Connect Configuration Discovery Endpoint",
"produces": [
"application/json"
],
"tags": [
"well-known"
],
"summary": "OpenID Connect Configuration",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.OpenIDConnectConfiguration"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/.well-known/webfinger": {
"get": {
"description": "WebFinger Endpoint",
"produces": [
"application/json"
],
"tags": [
"well-known"
],
"summary": "WebFinger",
"parameters": [
{
"type": "string",
"description": "Resource",
"name": "resource",
"in": "query",
"required": true
},
{
"type": "string",
"description": "Rel",
"name": "rel",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.WebfingerResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/auth/caddy": {
"get": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/auth/envoy": {
"get": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"put": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"post": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"delete": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"options": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"head": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
},
"patch": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/auth/nginx": {
"get": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/auth/traefik": {
"get": {
"description": "Forward-Auth Proxy Endpoint",
"produces": [
"application/json"
],
"tags": [
"forward-auth"
],
"summary": "Proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"302": {
"description": "Found"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/context/app": { "/api/context/app": {
"get": { "get": {
"description": "Get the app context", "description": "Get the app context",
@@ -224,6 +772,161 @@
} }
} }
}, },
"/api/user/login": {
"post": {
"description": "Login Endpoint",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"accounts"
],
"summary": "Login",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.TotpPendingResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"429": {
"description": "Too Many Requests",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/user/logout": {
"post": {
"description": "Logout Endpoint",
"produces": [
"application/json"
],
"tags": [
"accounts"
],
"summary": "Logout",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/user/tailscale": {
"post": {
"description": "Tailscale Auth Endpoint (Experimental)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"accounts"
],
"summary": "Tailscale",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/api/user/totp": {
"post": {
"description": "TOTP Endpoint",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"accounts"
],
"summary": "TOTP",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"429": {
"description": "Too Many Requests",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
},
"/authorize": { "/authorize": {
"get": { "get": {
"description": "OpenID Connect Authorize Endpoint", "description": "OpenID Connect Authorize Endpoint",
@@ -717,6 +1420,41 @@
} }
} }
} }
},
"/resources/{resource}": {
"get": {
"description": "Get a resource by file name",
"tags": [
"resources"
],
"summary": "Resources Endpoint",
"parameters": [
{
"type": "string",
"description": "Resource Name",
"name": "resource",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/controller.SimpleResponse"
}
}
}
}
} }
}, },
"definitions": { "definitions": {
@@ -829,6 +1567,80 @@
} }
} }
}, },
"controller.OpenIDConnectConfiguration": {
"type": "object",
"properties": {
"authorization_endpoint": {
"type": "string"
},
"claims_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"grant_types_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"id_token_signing_alg_values_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"issuer": {
"type": "string"
},
"jwks_uri": {
"type": "string"
},
"request_object_signing_alg_values_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"request_parameter_supported": {
"type": "boolean"
},
"response_types_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"scopes_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"service_documentation": {
"type": "string"
},
"subject_types_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"token_endpoint": {
"type": "string"
},
"token_endpoint_auth_methods_supported": {
"type": "array",
"items": {
"type": "string"
}
},
"userinfo_endpoint": {
"type": "string"
}
}
},
"controller.SimpleResponse": { "controller.SimpleResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -840,6 +1652,20 @@
} }
} }
}, },
"controller.TotpPendingResponse": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"status": {
"type": "integer"
},
"totpPending": {
"type": "boolean"
}
}
},
"controller.UCRAuth": { "controller.UCRAuth": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -910,6 +1736,31 @@
} }
} }
}, },
"controller.WebfingerResponse": {
"type": "object",
"properties": {
"links": {
"type": "array",
"items": {
"$ref": "#/definitions/controller.WebfingerResponseLink"
}
},
"subject": {
"type": "string"
}
}
},
"controller.WebfingerResponseLink": {
"type": "object",
"properties": {
"href": {
"type": "string"
},
"rel": {
"type": "string"
}
}
},
"model.AddressClaim": { "model.AddressClaim": {
"type": "object", "type": "object",
"properties": { "properties": {
+562
View File
@@ -70,6 +70,55 @@ definitions:
error: error:
type: string type: string
type: object type: object
controller.OpenIDConnectConfiguration:
properties:
authorization_endpoint:
type: string
claims_supported:
items:
type: string
type: array
grant_types_supported:
items:
type: string
type: array
id_token_signing_alg_values_supported:
items:
type: string
type: array
issuer:
type: string
jwks_uri:
type: string
request_object_signing_alg_values_supported:
items:
type: string
type: array
request_parameter_supported:
type: boolean
response_types_supported:
items:
type: string
type: array
scopes_supported:
items:
type: string
type: array
service_documentation:
type: string
subject_types_supported:
items:
type: string
type: array
token_endpoint:
type: string
token_endpoint_auth_methods_supported:
items:
type: string
type: array
userinfo_endpoint:
type: string
type: object
controller.SimpleResponse: controller.SimpleResponse:
properties: properties:
message: message:
@@ -77,6 +126,15 @@ definitions:
status: status:
type: integer type: integer
type: object type: object
controller.TotpPendingResponse:
properties:
message:
type: string
status:
type: integer
totpPending:
type: boolean
type: object
controller.UCRAuth: controller.UCRAuth:
properties: properties:
authenticated: authenticated:
@@ -122,6 +180,22 @@ definitions:
totp: totp:
$ref: '#/definitions/controller.UCRTOTP' $ref: '#/definitions/controller.UCRTOTP'
type: object type: object
controller.WebfingerResponse:
properties:
links:
items:
$ref: '#/definitions/controller.WebfingerResponseLink'
type: array
subject:
type: string
type: object
controller.WebfingerResponseLink:
properties:
href:
type: string
rel:
type: string
type: object
model.AddressClaim: model.AddressClaim:
properties: properties:
country: country:
@@ -217,6 +291,369 @@ info:
title: Tinyauth API title: Tinyauth API
version: development version: development
paths: paths:
/.well-known/jwks.json:
get:
description: JWKS Endpoint
produces:
- application/json
responses:
"200":
description: OK
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: JWKS
tags:
- well-known
/.well-known/openid-configuration:
get:
description: OpenID Connect Configuration Discovery Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.OpenIDConnectConfiguration'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: OpenID Connect Configuration
tags:
- well-known
/.well-known/webfinger:
get:
description: WebFinger Endpoint
parameters:
- description: Resource
in: query
name: resource
required: true
type: string
- description: Rel
in: query
name: rel
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.WebfingerResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: WebFinger
tags:
- well-known
/api/auth/caddy:
get:
description: Forward-Auth Proxy Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"302":
description: Found
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Proxy
tags:
- forward-auth
/api/auth/envoy:
delete:
description: Forward-Auth Proxy Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"302":
description: Found
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Proxy
tags:
- forward-auth
get:
description: Forward-Auth Proxy Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"302":
description: Found
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Proxy
tags:
- forward-auth
head:
description: Forward-Auth Proxy Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"302":
description: Found
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Proxy
tags:
- forward-auth
options:
description: Forward-Auth Proxy Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"302":
description: Found
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Proxy
tags:
- forward-auth
patch:
description: Forward-Auth Proxy Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"302":
description: Found
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Proxy
tags:
- forward-auth
post:
description: Forward-Auth Proxy Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"302":
description: Found
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Proxy
tags:
- forward-auth
put:
description: Forward-Auth Proxy Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"302":
description: Found
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Proxy
tags:
- forward-auth
/api/auth/nginx:
get:
description: Forward-Auth Proxy Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"302":
description: Found
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Proxy
tags:
- forward-auth
/api/auth/traefik:
get:
description: Forward-Auth Proxy Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"302":
description: Found
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Proxy
tags:
- forward-auth
/api/context/app: /api/context/app:
get: get:
description: Get the app context description: Get the app context
@@ -358,6 +795,108 @@ paths:
summary: Authorize Complete summary: Authorize Complete
tags: tags:
- oidc - oidc
/api/user/login:
post:
consumes:
- application/json
description: Login Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.TotpPendingResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"429":
description: Too Many Requests
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Login
tags:
- accounts
/api/user/logout:
post:
description: Logout Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Logout
tags:
- accounts
/api/user/tailscale:
post:
consumes:
- application/json
description: Tailscale Auth Endpoint (Experimental)
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Tailscale
tags:
- accounts
/api/user/totp:
post:
consumes:
- application/json
description: TOTP Endpoint
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controller.SimpleResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/controller.SimpleResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/controller.SimpleResponse'
"429":
description: Too Many Requests
schema:
$ref: '#/definitions/controller.SimpleResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: TOTP
tags:
- accounts
/authorize: /authorize:
get: get:
consumes: consumes:
@@ -687,4 +1226,27 @@ paths:
summary: Userinfo summary: Userinfo
tags: tags:
- oidc - oidc
/resources/{resource}:
get:
description: Get a resource by file name
parameters:
- description: Resource Name
in: path
name: resource
required: true
type: string
responses:
"200":
description: OK
"403":
description: Forbidden
schema:
$ref: '#/definitions/controller.SimpleResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/controller.SimpleResponse'
summary: Resources Endpoint
tags:
- resources
swagger: "2.0" swagger: "2.0"