79 lines
2.4 KiB
Go
79 lines
2.4 KiB
Go
package middleware
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/Wei-Shaw/sub2api/internal/pkg/response"
|
|
"github.com/Wei-Shaw/sub2api/internal/service"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// BackendModeUserGuard blocks non-admin users from accessing user routes when backend mode is enabled.
|
|
// Must be placed AFTER JWT auth middleware so that the user role is available in context.
|
|
func BackendModeUserGuard(settingService *service.SettingService) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
if settingService == nil || !settingService.IsBackendModeEnabled(c.Request.Context()) {
|
|
c.Next()
|
|
return
|
|
}
|
|
role, _ := GetUserRoleFromContext(c)
|
|
if role == "admin" {
|
|
c.Next()
|
|
return
|
|
}
|
|
response.Forbidden(c, "Backend mode is active. User self-service is disabled.")
|
|
c.Abort()
|
|
}
|
|
}
|
|
|
|
func backendModeAllowsAuthPath(path string) bool {
|
|
path = strings.ToLower(strings.TrimSpace(path))
|
|
for _, suffix := range []string{"/auth/login", "/auth/login/2fa", "/auth/logout", "/auth/refresh"} {
|
|
if strings.HasSuffix(path, suffix) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
for _, suffix := range []string{
|
|
"/auth/oauth/linuxdo/callback",
|
|
"/auth/oauth/wechat/callback",
|
|
"/auth/oauth/wechat/payment/callback",
|
|
"/auth/oauth/oidc/callback",
|
|
"/auth/oauth/linuxdo/complete-registration",
|
|
"/auth/oauth/wechat/complete-registration",
|
|
"/auth/oauth/oidc/complete-registration",
|
|
"/auth/oauth/linuxdo/create-account",
|
|
"/auth/oauth/wechat/create-account",
|
|
"/auth/oauth/oidc/create-account",
|
|
"/auth/oauth/linuxdo/bind-login",
|
|
"/auth/oauth/wechat/bind-login",
|
|
"/auth/oauth/oidc/bind-login",
|
|
} {
|
|
if strings.HasSuffix(path, suffix) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return strings.Contains(path, "/auth/oauth/pending/")
|
|
}
|
|
|
|
// BackendModeAuthGuard selectively blocks auth endpoints when backend mode is enabled.
|
|
// Allows the minimal auth surface admins still need in backend mode, including
|
|
// OAuth callbacks and pending continuations. Handler-level backend mode checks
|
|
// still enforce admin-only login and forbid self-service registration.
|
|
func BackendModeAuthGuard(settingService *service.SettingService) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
if settingService == nil || !settingService.IsBackendModeEnabled(c.Request.Context()) {
|
|
c.Next()
|
|
return
|
|
}
|
|
if backendModeAllowsAuthPath(c.Request.URL.Path) {
|
|
c.Next()
|
|
return
|
|
}
|
|
response.Forbidden(c, "Backend mode is active. Registration and self-service auth flows are disabled.")
|
|
c.Abort()
|
|
}
|
|
}
|