mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2025-10-28 12:45:47 +00:00
refactor: move resource handling to a controller
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -23,4 +23,7 @@ secret*
|
|||||||
tmp
|
tmp
|
||||||
|
|
||||||
# version files
|
# version files
|
||||||
internal/assets/version
|
internal/assets/version
|
||||||
|
|
||||||
|
# data directory
|
||||||
|
data
|
||||||
@@ -33,6 +33,7 @@ var rootCmd = &cobra.Command{
|
|||||||
conf.GoogleClientSecret = utils.GetSecret(conf.GoogleClientSecret, conf.GoogleClientSecretFile)
|
conf.GoogleClientSecret = utils.GetSecret(conf.GoogleClientSecret, conf.GoogleClientSecretFile)
|
||||||
conf.GenericClientSecret = utils.GetSecret(conf.GenericClientSecret, conf.GenericClientSecretFile)
|
conf.GenericClientSecret = utils.GetSecret(conf.GenericClientSecret, conf.GenericClientSecretFile)
|
||||||
|
|
||||||
|
// Validate config
|
||||||
validator := validator.New()
|
validator := validator.New()
|
||||||
|
|
||||||
err = validator.Struct(conf)
|
err = validator.Struct(conf)
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ export default defineConfig({
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(/^\/api/, ""),
|
rewrite: (path) => path.replace(/^\/api/, ""),
|
||||||
},
|
},
|
||||||
|
"/resources": {
|
||||||
|
target: "http://tinyauth-backend:3000/resources",
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (path) => path.replace(/^\/resources/, ""),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
allowedHosts: true,
|
allowedHosts: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ type Controller interface {
|
|||||||
type Middleware interface {
|
type Middleware interface {
|
||||||
Middleware() gin.HandlerFunc
|
Middleware() gin.HandlerFunc
|
||||||
Init() error
|
Init() error
|
||||||
Name() string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
@@ -103,6 +102,7 @@ func (app *BootstrapApp) Setup() error {
|
|||||||
err := ldapService.Init()
|
err := ldapService.Init()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Warn().Err(err).Msg("Failed to initialize LDAP service, continuing without LDAP")
|
||||||
ldapService = nil
|
ldapService = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,6 +120,7 @@ func (app *BootstrapApp) Setup() error {
|
|||||||
|
|
||||||
for _, svc := range services {
|
for _, svc := range services {
|
||||||
if svc != nil {
|
if svc != nil {
|
||||||
|
log.Debug().Str("service", fmt.Sprintf("%T", svc)).Msg("Initializing service")
|
||||||
err := svc.Init()
|
err := svc.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -142,7 +143,13 @@ func (app *BootstrapApp) Setup() error {
|
|||||||
|
|
||||||
// Create engine
|
// Create engine
|
||||||
engine := gin.New()
|
engine := gin.New()
|
||||||
router := engine.Group("/api")
|
|
||||||
|
if config.Version != "development" {
|
||||||
|
gin.SetMode(gin.ReleaseMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
router := engine.Group("/")
|
||||||
|
apiRouter := router.Group("/api")
|
||||||
|
|
||||||
// Create middlewares
|
// Create middlewares
|
||||||
var middlewares []Middleware
|
var middlewares []Middleware
|
||||||
@@ -151,18 +158,16 @@ func (app *BootstrapApp) Setup() error {
|
|||||||
Domain: domain,
|
Domain: domain,
|
||||||
}, authService, oauthBrokerService)
|
}, authService, oauthBrokerService)
|
||||||
|
|
||||||
uiMiddleware := middleware.NewUIMiddleware(middleware.UIMiddlewareConfig{
|
uiMiddleware := middleware.NewUIMiddleware()
|
||||||
ResourcesDir: app.Config.ResourcesDir,
|
|
||||||
})
|
|
||||||
zerologMiddleware := middleware.NewZerologMiddleware()
|
zerologMiddleware := middleware.NewZerologMiddleware()
|
||||||
|
|
||||||
middlewares = append(middlewares, contextMiddleware, uiMiddleware, zerologMiddleware)
|
middlewares = append(middlewares, contextMiddleware, uiMiddleware, zerologMiddleware)
|
||||||
|
|
||||||
for _, middleware := range middlewares {
|
for _, middleware := range middlewares {
|
||||||
log.Debug().Str("middleware", middleware.Name()).Msg("Initializing middleware")
|
log.Debug().Str("middleware", fmt.Sprintf("%T", middleware)).Msg("Initializing middleware")
|
||||||
err := middleware.Init()
|
err := middleware.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to initialize %s middleware: %w", middleware.Name(), err)
|
return fmt.Errorf("failed to initialize %s middleware: %T", middleware, err)
|
||||||
}
|
}
|
||||||
router.Use(middleware.Middleware())
|
router.Use(middleware.Middleware())
|
||||||
}
|
}
|
||||||
@@ -177,24 +182,28 @@ func (app *BootstrapApp) Setup() error {
|
|||||||
ForgotPasswordMessage: app.Config.FogotPasswordMessage,
|
ForgotPasswordMessage: app.Config.FogotPasswordMessage,
|
||||||
BackgroundImage: app.Config.BackgroundImage,
|
BackgroundImage: app.Config.BackgroundImage,
|
||||||
OAuthAutoRedirect: app.Config.OAuthAutoRedirect,
|
OAuthAutoRedirect: app.Config.OAuthAutoRedirect,
|
||||||
}, router)
|
}, apiRouter)
|
||||||
|
|
||||||
oauthController := controller.NewOAuthController(controller.OAuthControllerConfig{
|
oauthController := controller.NewOAuthController(controller.OAuthControllerConfig{
|
||||||
AppURL: app.Config.AppURL,
|
AppURL: app.Config.AppURL,
|
||||||
SecureCookie: app.Config.SecureCookie,
|
SecureCookie: app.Config.SecureCookie,
|
||||||
CSRFCookieName: csrfCookieName,
|
CSRFCookieName: csrfCookieName,
|
||||||
RedirectCookieName: redirectCookieName,
|
RedirectCookieName: redirectCookieName,
|
||||||
}, router, authService, oauthBrokerService)
|
}, apiRouter, authService, oauthBrokerService)
|
||||||
|
|
||||||
proxyController := controller.NewProxyController(controller.ProxyControllerConfig{
|
proxyController := controller.NewProxyController(controller.ProxyControllerConfig{
|
||||||
AppURL: app.Config.AppURL,
|
AppURL: app.Config.AppURL,
|
||||||
}, router, dockerService, authService)
|
}, apiRouter, dockerService, authService)
|
||||||
|
|
||||||
userController := controller.NewUserController(controller.UserControllerConfig{
|
userController := controller.NewUserController(controller.UserControllerConfig{
|
||||||
Domain: domain,
|
Domain: domain,
|
||||||
}, router, authService)
|
}, apiRouter, authService)
|
||||||
|
|
||||||
healthController := controller.NewHealthController(router)
|
resourcesController := controller.NewResourcesController(controller.ResourcesControllerConfig{
|
||||||
|
ResourcesDir: app.Config.ResourcesDir,
|
||||||
|
}, router)
|
||||||
|
|
||||||
|
healthController := controller.NewHealthController(apiRouter)
|
||||||
|
|
||||||
// Setup routes
|
// Setup routes
|
||||||
controller := []Controller{
|
controller := []Controller{
|
||||||
@@ -203,10 +212,11 @@ func (app *BootstrapApp) Setup() error {
|
|||||||
proxyController,
|
proxyController,
|
||||||
userController,
|
userController,
|
||||||
healthController,
|
healthController,
|
||||||
|
resourcesController,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ctrl := range controller {
|
for _, ctrl := range controller {
|
||||||
log.Debug().Msgf("Setting up %T routes", ctrl)
|
log.Debug().Msgf("Setting up %T controller", ctrl)
|
||||||
ctrl.SetupRoutes()
|
ctrl.SetupRoutes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ func NewHealthController(router *gin.RouterGroup) *HealthController {
|
|||||||
|
|
||||||
func (controller *HealthController) SetupRoutes() {
|
func (controller *HealthController) SetupRoutes() {
|
||||||
controller.Router.GET("/health", controller.healthHandler)
|
controller.Router.GET("/health", controller.healthHandler)
|
||||||
|
controller.Router.HEAD("/health", controller.healthHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (controller *HealthController) healthHandler(c *gin.Context) {
|
func (controller *HealthController) healthHandler(c *gin.Context) {
|
||||||
|
|||||||
32
internal/controller/resources_controller.go
Normal file
32
internal/controller/resources_controller.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ResourcesControllerConfig struct {
|
||||||
|
ResourcesDir string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResourcesController struct {
|
||||||
|
Config ResourcesControllerConfig
|
||||||
|
Router *gin.RouterGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewResourcesController(config ResourcesControllerConfig, router *gin.RouterGroup) *ResourcesController {
|
||||||
|
return &ResourcesController{
|
||||||
|
Config: config,
|
||||||
|
Router: router,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (controller *ResourcesController) SetupRoutes() {
|
||||||
|
controller.Router.GET("/resources/*resource", controller.resourcesHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (controller *ResourcesController) resourcesHandler(c *gin.Context) {
|
||||||
|
fileServer := http.StripPrefix("/resources", http.FileServer(http.Dir(controller.Config.ResourcesDir)))
|
||||||
|
fileServer.ServeHTTP(c.Writer, c.Request)
|
||||||
|
}
|
||||||
@@ -32,10 +32,6 @@ func (m *ContextMiddleware) Init() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ContextMiddleware) Name() string {
|
|
||||||
return "ContextMiddleware"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ContextMiddleware) Middleware() gin.HandlerFunc {
|
func (m *ContextMiddleware) Middleware() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
cookie, err := m.Auth.GetSessionCookie(c)
|
cookie, err := m.Auth.GetSessionCookie(c)
|
||||||
|
|||||||
@@ -4,28 +4,19 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"tinyauth/internal/assets"
|
"tinyauth/internal/assets"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UIMiddlewareConfig struct {
|
|
||||||
ResourcesDir string
|
|
||||||
}
|
|
||||||
|
|
||||||
type UIMiddleware struct {
|
type UIMiddleware struct {
|
||||||
Config UIMiddlewareConfig
|
UIFS fs.FS
|
||||||
UIFS fs.FS
|
UIFileServer http.Handler
|
||||||
UIFileServer http.Handler
|
|
||||||
ResourcesFileServer http.Handler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUIMiddleware(config UIMiddlewareConfig) *UIMiddleware {
|
func NewUIMiddleware() *UIMiddleware {
|
||||||
return &UIMiddleware{
|
return &UIMiddleware{}
|
||||||
Config: config,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *UIMiddleware) Init() error {
|
func (m *UIMiddleware) Init() error {
|
||||||
@@ -37,15 +28,10 @@ func (m *UIMiddleware) Init() error {
|
|||||||
|
|
||||||
m.UIFS = ui
|
m.UIFS = ui
|
||||||
m.UIFileServer = http.FileServer(http.FS(ui))
|
m.UIFileServer = http.FileServer(http.FS(ui))
|
||||||
m.ResourcesFileServer = http.FileServer(http.Dir(m.Config.ResourcesDir))
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *UIMiddleware) Name() string {
|
|
||||||
return "UIMiddleware"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UIMiddleware) Middleware() gin.HandlerFunc {
|
func (m *UIMiddleware) Middleware() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
switch strings.Split(c.Request.URL.Path, "/")[1] {
|
switch strings.Split(c.Request.URL.Path, "/")[1] {
|
||||||
@@ -53,24 +39,7 @@ func (m *UIMiddleware) Middleware() gin.HandlerFunc {
|
|||||||
c.Next()
|
c.Next()
|
||||||
return
|
return
|
||||||
case "resources":
|
case "resources":
|
||||||
requestFilePath := m.Config.ResourcesDir + strings.TrimPrefix(c.Request.URL.Path, "/resources/")
|
c.Next()
|
||||||
|
|
||||||
if !filepath.IsLocal(requestFilePath) {
|
|
||||||
c.Status(404)
|
|
||||||
c.Abort()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := os.Stat(requestFilePath)
|
|
||||||
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
c.Status(404)
|
|
||||||
c.Abort()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
m.ResourcesFileServer.ServeHTTP(c.Writer, c.Request)
|
|
||||||
c.Abort()
|
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
_, err := fs.Stat(m.UIFS, strings.TrimPrefix(c.Request.URL.Path, "/"))
|
_, err := fs.Stat(m.UIFS, strings.TrimPrefix(c.Request.URL.Path, "/"))
|
||||||
|
|||||||
@@ -26,10 +26,6 @@ func (m *ZerologMiddleware) Init() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ZerologMiddleware) Name() string {
|
|
||||||
return "ZerologMiddleware"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ZerologMiddleware) logPath(path string) bool {
|
func (m *ZerologMiddleware) logPath(path string) bool {
|
||||||
for _, prefix := range loggerSkipPathsPrefix {
|
for _, prefix := range loggerSkipPathsPrefix {
|
||||||
if strings.HasPrefix(path, prefix) {
|
if strings.HasPrefix(path, prefix) {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"tinyauth/internal/config"
|
"tinyauth/internal/config"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/traefik/paerser/parser"
|
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
)
|
)
|
||||||
@@ -39,17 +38,6 @@ func ParseFileToLine(content string) string {
|
|||||||
return strings.Join(users, ",")
|
return strings.Join(users, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLabels(labels map[string]string) (config.Labels, error) {
|
|
||||||
var labelsParsed config.Labels
|
|
||||||
|
|
||||||
err := parser.Decode(labels, &labelsParsed, "tinyauth", "tinyauth.users", "tinyauth.allowed", "tinyauth.headers", "tinyauth.domain", "tinyauth.basic", "tinyauth.oauth", "tinyauth.ip")
|
|
||||||
if err != nil {
|
|
||||||
return config.Labels{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return labelsParsed, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Filter[T any](slice []T, test func(T) bool) (res []T) {
|
func Filter[T any](slice []T, test func(T) bool) (res []T) {
|
||||||
for _, value := range slice {
|
for _, value := range slice {
|
||||||
if test(value) {
|
if test(value) {
|
||||||
@@ -2,8 +2,22 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
"tinyauth/internal/config"
|
||||||
|
|
||||||
|
"github.com/traefik/paerser/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func GetLabels(labels map[string]string) (config.Labels, error) {
|
||||||
|
var labelsParsed config.Labels
|
||||||
|
|
||||||
|
err := parser.Decode(labels, &labelsParsed, "tinyauth", "tinyauth.users", "tinyauth.allowed", "tinyauth.headers", "tinyauth.domain", "tinyauth.basic", "tinyauth.oauth", "tinyauth.ip")
|
||||||
|
if err != nil {
|
||||||
|
return config.Labels{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return labelsParsed, nil
|
||||||
|
}
|
||||||
|
|
||||||
func ParseHeaders(headers []string) map[string]string {
|
func ParseHeaders(headers []string) map[string]string {
|
||||||
headerMap := make(map[string]string)
|
headerMap := make(map[string]string)
|
||||||
for _, header := range headers {
|
for _, header := range headers {
|
||||||
2
main.go
2
main.go
@@ -10,6 +10,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}).With().Timestamp().Logger().Level(zerolog.FatalLevel)
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}).With().Timestamp().Caller().Logger().Level(zerolog.FatalLevel)
|
||||||
cmd.Execute()
|
cmd.Execute()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user