mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-06-22 19:30:15 +00:00
feat: add option to listen on tailscale
This commit is contained in:
@@ -46,18 +46,17 @@ type Services struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BootstrapApp struct {
|
type BootstrapApp struct {
|
||||||
config model.Config
|
config model.Config
|
||||||
runtime model.RuntimeConfig
|
runtime model.RuntimeConfig
|
||||||
services Services
|
services Services
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
queries repository.Store
|
queries repository.Store
|
||||||
router *gin.Engine
|
router *gin.Engine
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
ding *ding.Ding
|
ding *ding.Ding
|
||||||
listeners []Listener
|
dig *dig.Container
|
||||||
dig *dig.Container
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBootstrapApp(config model.Config) *BootstrapApp {
|
func NewBootstrapApp(config model.Config) *BootstrapApp {
|
||||||
@@ -285,11 +284,11 @@ func (app *BootstrapApp) Setup() error {
|
|||||||
|
|
||||||
app.runtime.ConfiguredProviders = configuredProviders
|
app.runtime.ConfiguredProviders = configuredProviders
|
||||||
|
|
||||||
// replace the default app url with the tailscale hostname if tailscale is enabled
|
// force tailscale app url if listening on a tailscale address
|
||||||
if app.services.tailscaleService != nil {
|
if app.services.tailscaleService != nil && app.config.Tailscale.Listen {
|
||||||
tailscaleUrl := "https://" + app.services.tailscaleService.GetHostname()
|
tailscaleUrl := "https://" + app.services.tailscaleService.GetHostname()
|
||||||
if tailscaleUrl != app.runtime.AppURL {
|
if tailscaleUrl != app.runtime.AppURL {
|
||||||
app.log.App.Info().Msg("Tailscale is enabled, replacing app url with tailscale hostname")
|
app.log.App.Info().Msg("Listening on tailscale, replacing app url with tailscale hostname")
|
||||||
app.runtime.AppURL = tailscaleUrl
|
app.runtime.AppURL = tailscaleUrl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,19 +310,15 @@ func (app *BootstrapApp) Setup() error {
|
|||||||
app.ding.Go(app.heartbeatRoutine, ding.RingMinor)
|
app.ding.Go(app.heartbeatRoutine, ding.RingMinor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup listeners
|
// get listener
|
||||||
app.listeners = app.calculateListenerPolicy()
|
listenerFunc := app.getListenerFunc()
|
||||||
|
|
||||||
if app.config.Server.ConcurrentListenersEnabled {
|
// run listener
|
||||||
app.log.App.Info().Msg("Concurrent listeners enabled, will run on all available listeners")
|
lec := make(chan error, 1)
|
||||||
}
|
|
||||||
|
|
||||||
// run listeners
|
app.ding.Go(func(ctx context.Context) {
|
||||||
lec, err := app.runListeners()
|
lec <- listenerFunc(ctx)
|
||||||
|
}, ding.RingNormal)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to run listeners: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// monitor cancellation and server errors
|
// monitor cancellation and server errors
|
||||||
for {
|
for {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/steveiliop56/ding"
|
|
||||||
"github.com/tinyauthapp/tinyauth/internal/controller"
|
"github.com/tinyauthapp/tinyauth/internal/controller"
|
||||||
"github.com/tinyauthapp/tinyauth/internal/middleware"
|
"github.com/tinyauthapp/tinyauth/internal/middleware"
|
||||||
"github.com/tinyauthapp/tinyauth/internal/model"
|
"github.com/tinyauthapp/tinyauth/internal/model"
|
||||||
@@ -18,14 +17,6 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Listener int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ListenerHTTP Listener = iota
|
|
||||||
ListenerUnix
|
|
||||||
ListenerTailscale
|
|
||||||
)
|
|
||||||
|
|
||||||
func (app *BootstrapApp) setupRouter() error {
|
func (app *BootstrapApp) setupRouter() error {
|
||||||
// we don't want gin debug mode
|
// we don't want gin debug mode
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
@@ -134,73 +125,20 @@ func (app *BootstrapApp) setupRouter() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BootstrapApp) runListeners() (chan error, error) {
|
// Top down
|
||||||
// lec -> listener error channel
|
// 1. Tailscale (if tailscale.listen)
|
||||||
lec := make(chan error, len(app.listeners))
|
// 2. Unix socket (if server.socketPath)
|
||||||
|
// 3. HTTP - default
|
||||||
for _, listenerType := range app.listeners {
|
func (app *BootstrapApp) getListenerFunc() func(ctx context.Context) error {
|
||||||
listenerFunc, err := app.listenerFromType(listenerType)
|
if app.services.tailscaleService != nil && app.config.Tailscale.Listen {
|
||||||
|
return app.serveTailscale
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to get listener function: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
app.ding.Go(func(ctx context.Context) {
|
|
||||||
lec <- listenerFunc(ctx)
|
|
||||||
}, ding.RingNormal)
|
|
||||||
}
|
|
||||||
|
|
||||||
return lec, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// The way we calculate listeners is as follows:
|
|
||||||
// If concurrent listeners are disabled, we pick the first available listener, so:
|
|
||||||
// 1. If tailscale is enabled, we use tailscale
|
|
||||||
// 2. If socket path is configured, we use unix socket
|
|
||||||
// 3. Finally if none is configured we use http
|
|
||||||
// If concurrent listeners are enabled, we add all available listeners in the following order
|
|
||||||
func (app *BootstrapApp) calculateListenerPolicy() []Listener {
|
|
||||||
l := []Listener{}
|
|
||||||
|
|
||||||
if !app.config.Server.ConcurrentListenersEnabled {
|
|
||||||
if app.services.tailscaleService != nil {
|
|
||||||
l = append(l, ListenerTailscale)
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.config.Server.SocketPath != "" {
|
|
||||||
l = append(l, ListenerUnix)
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
||||||
l = append(l, ListenerHTTP)
|
|
||||||
return l
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.config.Server.SocketPath != "" {
|
if app.config.Server.SocketPath != "" {
|
||||||
l = append(l, ListenerUnix)
|
return app.serveUnix
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.services.tailscaleService != nil {
|
return app.serveHTTP
|
||||||
l = append(l, ListenerTailscale)
|
|
||||||
}
|
|
||||||
|
|
||||||
l = append(l, ListenerHTTP)
|
|
||||||
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
||||||
func (app *BootstrapApp) listenerFromType(listenerType Listener) (func(ctx context.Context) error, error) {
|
|
||||||
switch listenerType {
|
|
||||||
case ListenerHTTP:
|
|
||||||
return app.serveHTTP, nil
|
|
||||||
case ListenerUnix:
|
|
||||||
return app.serveUnix, nil
|
|
||||||
case ListenerTailscale:
|
|
||||||
return app.serveTailscale, nil
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid listener type: %d", listenerType)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BootstrapApp) serveHTTP(ctx context.Context) error {
|
func (app *BootstrapApp) serveHTTP(ctx context.Context) error {
|
||||||
|
|||||||
@@ -15,9 +15,8 @@ func NewDefaultConfiguration() *Config {
|
|||||||
Path: "./resources",
|
Path: "./resources",
|
||||||
},
|
},
|
||||||
Server: ServerConfig{
|
Server: ServerConfig{
|
||||||
Port: 3000,
|
Port: 3000,
|
||||||
Address: "0.0.0.0",
|
Address: "0.0.0.0",
|
||||||
ConcurrentListenersEnabled: false,
|
|
||||||
},
|
},
|
||||||
Auth: AuthConfig{
|
Auth: AuthConfig{
|
||||||
SubdomainsEnabled: true,
|
SubdomainsEnabled: true,
|
||||||
@@ -104,10 +103,9 @@ type ResourcesConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ServerConfig struct {
|
type ServerConfig struct {
|
||||||
Port int `description:"The port on which the server listens." yaml:"port"`
|
Port int `description:"The port on which the server listens." yaml:"port"`
|
||||||
Address string `description:"The address on which the server listens." yaml:"address"`
|
Address string `description:"The address on which the server listens." yaml:"address"`
|
||||||
SocketPath string `description:"The path to the Unix socket." yaml:"socketPath"`
|
SocketPath string `description:"The path to the Unix socket." yaml:"socketPath"`
|
||||||
ConcurrentListenersEnabled bool `description:"Enable listening on both TCP and Unix socket at the same time." yaml:"concurrentListenersEnabled"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthConfig struct {
|
type AuthConfig struct {
|
||||||
@@ -218,6 +216,7 @@ type TailscaleConfig struct {
|
|||||||
Hostname string `description:"Tailscale hostname." yaml:"hostname"`
|
Hostname string `description:"Tailscale hostname." yaml:"hostname"`
|
||||||
AuthKey string `description:"Tailscale auth key." yaml:"authKey"`
|
AuthKey string `description:"Tailscale auth key." yaml:"authKey"`
|
||||||
Ephemeral bool `description:"Use ephemeral Tailscale node." yaml:"ephemeral"`
|
Ephemeral bool `description:"Use ephemeral Tailscale node." yaml:"ephemeral"`
|
||||||
|
Listen bool `description:"Listen on the Tailscale address instead of standard address." yaml:"listen"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// OAuth/OIDC config
|
// OAuth/OIDC config
|
||||||
|
|||||||
Reference in New Issue
Block a user