mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-06-08 04:20:15 +00:00
Compare commits
3 Commits
35cd3b9ce5
...
b6df4b9f0a
| Author | SHA1 | Date | |
|---|---|---|---|
| b6df4b9f0a | |||
| c298d0b158 | |||
| b8b0e45ec4 |
@@ -86,7 +86,7 @@
|
|||||||
"addressScopeName": "Address",
|
"addressScopeName": "Address",
|
||||||
"addressScopeDescription": "Allows the app to access your address.",
|
"addressScopeDescription": "Allows the app to access your address.",
|
||||||
"loginTailscaleTitle": "Continue with Tailscale",
|
"loginTailscaleTitle": "Continue with Tailscale",
|
||||||
"loginTailscaleDescription": "We detected that you are accessing Tinyauth from an authorized Tailscale device. Would you like to continue with your Tailscale connection?",
|
"loginTailscaleDescription": "You appear to be accessing Tinyauth from an authorized Tailscale device. Would you like to continue with your Tailscale connection?",
|
||||||
"loginTailscaleDeviceName": "Device name:",
|
"loginTailscaleDeviceName": "Device name:",
|
||||||
"loginTailscaleSubmit": "Continue with Tailscale",
|
"loginTailscaleSubmit": "Continue with Tailscale",
|
||||||
"loginTailscaleOtherMethod": "Login with another method",
|
"loginTailscaleOtherMethod": "Login with another method",
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
"addressScopeName": "Address",
|
"addressScopeName": "Address",
|
||||||
"addressScopeDescription": "Allows the app to access your address.",
|
"addressScopeDescription": "Allows the app to access your address.",
|
||||||
"loginTailscaleTitle": "Continue with Tailscale",
|
"loginTailscaleTitle": "Continue with Tailscale",
|
||||||
"loginTailscaleDescription": "We detected that you are accessing Tinyauth from an authorized Tailscale device. Would you like to continue with your Tailscale connection?",
|
"loginTailscaleDescription": "You appear to be accessing Tinyauth from an authorized Tailscale device. Would you like to continue with your Tailscale connection?",
|
||||||
"loginTailscaleDeviceName": "Device name:",
|
"loginTailscaleDeviceName": "Device name:",
|
||||||
"loginTailscaleSubmit": "Continue with Tailscale",
|
"loginTailscaleSubmit": "Continue with Tailscale",
|
||||||
"loginTailscaleOtherMethod": "Login with another method",
|
"loginTailscaleOtherMethod": "Login with another method",
|
||||||
|
|||||||
@@ -255,21 +255,7 @@ func (app *BootstrapApp) Setup() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup listeners
|
// setup listeners
|
||||||
runUnix := app.config.Server.SocketPath != ""
|
app.listeners = app.calculateListenerPolicy()
|
||||||
runHTTP := app.config.Server.SocketPath == "" || app.config.Server.ConcurrentListenersEnabled
|
|
||||||
runTailscale := app.services.tailscaleService != nil
|
|
||||||
|
|
||||||
if runHTTP {
|
|
||||||
app.listeners = append(app.listeners, ListenerHTTP)
|
|
||||||
}
|
|
||||||
|
|
||||||
if runUnix {
|
|
||||||
app.listeners = append(app.listeners, ListenerUnix)
|
|
||||||
}
|
|
||||||
|
|
||||||
if runTailscale {
|
|
||||||
app.listeners = append(app.listeners, ListenerTailscale)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.config.Server.ConcurrentListenersEnabled {
|
if app.config.Server.ConcurrentListenersEnabled {
|
||||||
app.log.App.Info().Msg("Concurrent listeners enabled, will run on all available listeners")
|
app.log.App.Info().Msg("Concurrent listeners enabled, will run on all available listeners")
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
package bootstrap
|
package bootstrap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"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/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
@@ -85,6 +88,43 @@ func (app *BootstrapApp) runListeners() (chan error, error) {
|
|||||||
return lec, nil
|
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.config.Tailscale.Enabled {
|
||||||
|
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 != "" {
|
||||||
|
l = append(l, ListenerUnix)
|
||||||
|
}
|
||||||
|
|
||||||
|
if app.config.Tailscale.Enabled {
|
||||||
|
l = append(l, ListenerTailscale)
|
||||||
|
}
|
||||||
|
|
||||||
|
l = append(l, ListenerHTTP)
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
func (app *BootstrapApp) listenerFromType(listenerType Listener) (func() error, error) {
|
func (app *BootstrapApp) listenerFromType(listenerType Listener) (func() error, error) {
|
||||||
switch listenerType {
|
switch listenerType {
|
||||||
case ListenerHTTP:
|
case ListenerHTTP:
|
||||||
@@ -162,7 +202,12 @@ func (app *BootstrapApp) serveTailscale() error {
|
|||||||
|
|
||||||
func (app *BootstrapApp) serve(listener net.Listener, server *http.Server, name string) error {
|
func (app *BootstrapApp) serve(listener net.Listener, server *http.Server, name string) error {
|
||||||
shutdown := func() {
|
shutdown := func() {
|
||||||
server.Shutdown(app.ctx)
|
ctx, cancel := context.WithTimeout(context.Background(), model.GracefulShutdownTimeout*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
err := server.Shutdown(ctx)
|
||||||
|
if err != nil {
|
||||||
|
app.log.App.Error().Err(err).Msgf("Failed to shutdown %s listener gracefully", name)
|
||||||
|
}
|
||||||
listener.Close()
|
listener.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -424,7 +424,7 @@ func (controller *UserController) tailscaleHandler(c *gin.Context) {
|
|||||||
cookie, err := controller.auth.CreateSession(c, sessionCookie)
|
cookie, err := controller.auth.CreateSession(c, sessionCookie)
|
||||||
|
|
||||||
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 Tailscale login")
|
||||||
c.JSON(500, gin.H{
|
c.JSON(500, gin.H{
|
||||||
"status": 500,
|
"status": 500,
|
||||||
"message": "Internal Server Error",
|
"message": "Internal Server Error",
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc {
|
|||||||
if tailscaleContext != nil {
|
if tailscaleContext != nil {
|
||||||
c.Set("context", &model.UserContext{
|
c.Set("context", &model.UserContext{
|
||||||
Authenticated: false,
|
Authenticated: false,
|
||||||
|
Provider: model.ProviderTailscale,
|
||||||
Tailscale: tailscaleContext,
|
Tailscale: tailscaleContext,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,3 +21,5 @@ const SessionCookieName = "tinyauth-session"
|
|||||||
const CSRFCookieName = "tinyauth-csrf"
|
const CSRFCookieName = "tinyauth-csrf"
|
||||||
const RedirectCookieName = "tinyauth-redirect"
|
const RedirectCookieName = "tinyauth-redirect"
|
||||||
const OAuthSessionCookieName = "tinyauth-oauth"
|
const OAuthSessionCookieName = "tinyauth-oauth"
|
||||||
|
|
||||||
|
const GracefulShutdownTimeout = 5 // seconds
|
||||||
|
|||||||
@@ -292,6 +292,10 @@ func (auth *AuthService) IsEmailWhitelisted(email string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (auth *AuthService) CreateSession(ctx context.Context, data repository.Session) (*http.Cookie, error) {
|
func (auth *AuthService) CreateSession(ctx context.Context, data repository.Session) (*http.Cookie, error) {
|
||||||
|
if data.Provider == "tailscale" && auth.tailscale == nil {
|
||||||
|
return nil, fmt.Errorf("tailscale service not configured, cannot create session for tailscale user")
|
||||||
|
}
|
||||||
|
|
||||||
uuid, err := uuid.NewRandom()
|
uuid, err := uuid.NewRandom()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -329,10 +333,6 @@ func (auth *AuthService) CreateSession(ctx context.Context, data repository.Sess
|
|||||||
}
|
}
|
||||||
|
|
||||||
if data.Provider == "tailscale" {
|
if data.Provider == "tailscale" {
|
||||||
if auth.tailscale == nil {
|
|
||||||
return nil, fmt.Errorf("tailscale service not configured, cannot create session for tailscale user")
|
|
||||||
}
|
|
||||||
|
|
||||||
auth.log.App.Trace().Str("url", fmt.Sprintf("https://%s", auth.tailscale.GetHostname())).Msg("Extracting root domain from Tailscale hostname")
|
auth.log.App.Trace().Str("url", fmt.Sprintf("https://%s", auth.tailscale.GetHostname())).Msg("Extracting root domain from Tailscale hostname")
|
||||||
|
|
||||||
tsCookieDomain, err := utils.GetCookieDomain(fmt.Sprintf("https://%s", auth.tailscale.GetHostname()))
|
tsCookieDomain, err := utils.GetCookieDomain(fmt.Sprintf("https://%s", auth.tailscale.GetHostname()))
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ func NewTailscaleService(log *logger.Logger, config model.Config, ctx context.Co
|
|||||||
lc: lc,
|
lc: lc,
|
||||||
}
|
}
|
||||||
|
|
||||||
connectCtx, cancel := context.WithTimeout(ctx, 2*time.Minute)
|
connectCtx, cancel := context.WithTimeout(ctx, 2*time.Minute) // large enough timeout to allow for user to manually authenticate with link if needed
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
err = service.waitForConn(connectCtx)
|
err = service.waitForConn(connectCtx)
|
||||||
|
|||||||
Reference in New Issue
Block a user