Compare commits

...

2 Commits

Author SHA1 Message Date
Stavros
07933ad71c tests: fix tests 2025-05-22 22:30:54 +03:00
Stavros
7151832cc7 feat: generate a unique id for the cookie names based on the domain 2025-05-22 22:21:29 +03:00
8 changed files with 77 additions and 31 deletions

View File

@@ -2,6 +2,7 @@ package cmd
import (
"errors"
"fmt"
"os"
"strings"
"time"
@@ -67,6 +68,12 @@ var rootCmd = &cobra.Command{
HandleError(err, "Failed to get upper domain")
log.Info().Str("domain", domain).Msg("Using domain for cookie store")
// Generate cookie name
cookieId := utils.GenerateIdentifier(strings.Split(domain, ".")[0])
sessionCookieName := fmt.Sprintf("%s-%s", constants.SessionCookieName, cookieId)
csrfCookieName := fmt.Sprintf("%s-%s", constants.CsrfCookieName, cookieId)
redirectCookieName := fmt.Sprintf("%s-%s", constants.RedirectCookieName, cookieId)
// Create OAuth config
oauthConfig := types.OAuthConfig{
GithubClientId: config.GithubClientId,
@@ -93,6 +100,8 @@ var rootCmd = &cobra.Command{
ForgotPasswordMessage: config.FogotPasswordMessage,
BackgroundImage: config.BackgroundImage,
OAuthAutoRedirect: config.OAuthAutoRedirect,
CsrfCookieName: csrfCookieName,
RedirectCookieName: redirectCookieName,
}
// Create api config
@@ -103,14 +112,15 @@ var rootCmd = &cobra.Command{
// Create auth config
authConfig := types.AuthConfig{
Users: users,
OauthWhitelist: config.OAuthWhitelist,
Secret: config.Secret,
CookieSecure: config.CookieSecure,
SessionExpiry: config.SessionExpiry,
Domain: domain,
LoginTimeout: config.LoginTimeout,
LoginMaxRetries: config.LoginMaxRetries,
Users: users,
OauthWhitelist: config.OAuthWhitelist,
Secret: config.Secret,
CookieSecure: config.CookieSecure,
SessionExpiry: config.SessionExpiry,
Domain: domain,
LoginTimeout: config.LoginTimeout,
LoginMaxRetries: config.LoginMaxRetries,
SessionCookieName: sessionCookieName,
}
// Create hooks config

1
go.mod
View File

@@ -6,6 +6,7 @@ require (
github.com/gin-gonic/gin v1.10.0
github.com/go-playground/validator/v10 v10.26.0
github.com/google/go-querystring v1.1.0
github.com/google/uuid v1.6.0
github.com/mdp/qrterminal/v3 v3.2.1
github.com/rs/zerolog v1.34.0
github.com/spf13/cobra v1.9.1

View File

@@ -28,21 +28,29 @@ var apiConfig = types.APIConfig{
// Simple handlers config for tests
var handlersConfig = types.HandlersConfig{
AppURL: "http://localhost:8080",
Domain: "localhost",
DisableContinue: false,
CookieSecure: false,
Title: "Tinyauth",
GenericName: "Generic",
ForgotPasswordMessage: "Some message",
CsrfCookieName: "tinyauth-csrf",
RedirectCookieName: "tinyauth-redirect",
BackgroundImage: "https://example.com/image.png",
OAuthAutoRedirect: "none",
}
// Simple auth config for tests
var authConfig = types.AuthConfig{
Users: types.Users{},
OauthWhitelist: "",
Secret: "super-secret-api-thing-for-tests", // It is 32 chars long
CookieSecure: false,
SessionExpiry: 3600,
LoginTimeout: 0,
LoginMaxRetries: 0,
Users: types.Users{},
OauthWhitelist: "",
Secret: "super-secret-api-thing-for-tests", // It is 32 chars long
CookieSecure: false,
SessionExpiry: 3600,
LoginTimeout: 0,
LoginMaxRetries: 0,
SessionCookieName: "tinyauth-session",
Domain: "localhost",
}
// Simple hooks config for tests
@@ -206,6 +214,9 @@ func TestAppContext(t *testing.T) {
Title: "Tinyauth",
GenericName: "Generic",
ForgotPasswordMessage: "Some message",
BackgroundImage: "https://example.com/image.png",
OAuthAutoRedirect: "none",
Domain: "localhost",
}
// We should get the username back
@@ -234,7 +245,7 @@ func TestUserContext(t *testing.T) {
// Set the cookie
req.AddCookie(&http.Cookie{
Name: "tinyauth",
Name: "tinyauth-session",
Value: cookie,
})

View File

@@ -45,7 +45,7 @@ func (auth *Auth) GetSession(c *gin.Context) (*sessions.Session, error) {
}
// Get session
session, err := store.Get(c.Request, "tinyauth")
session, err := store.Get(c.Request, auth.Config.SessionCookieName)
if err != nil {
log.Error().Err(err).Msg("Failed to get session")
return nil, err

View File

@@ -21,3 +21,8 @@ type Claims struct {
var Version = "development"
var CommitHash = "n/a"
var BuildTimestamp = "n/a"
// Cookie names
var SessionCookieName = "tinyauth-session"
var CsrfCookieName = "tinyauth-csrf"
var RedirectCookieName = "tinyauth-redirect"

View File

@@ -581,7 +581,7 @@ func (h *Handlers) OauthUrlHandler(c *gin.Context) {
log.Debug().Msg("Got auth URL")
// Set CSRF cookie
c.SetCookie("tinyauth-csrf", state, int(time.Hour.Seconds()), "/", "", h.Config.CookieSecure, true)
c.SetCookie(h.Config.CsrfCookieName, state, int(time.Hour.Seconds()), "/", "", h.Config.CookieSecure, true)
// Get redirect URI
redirectURI := c.Query("redirect_uri")
@@ -589,7 +589,7 @@ func (h *Handlers) OauthUrlHandler(c *gin.Context) {
// Set redirect cookie if redirect URI is provided
if redirectURI != "" {
log.Debug().Str("redirectURI", redirectURI).Msg("Setting redirect cookie")
c.SetCookie("tinyauth-redirect", redirectURI, int(time.Hour.Seconds()), "/", "", h.Config.CookieSecure, true)
c.SetCookie(h.Config.RedirectCookieName, redirectURI, int(time.Hour.Seconds()), "/", "", h.Config.CookieSecure, true)
}
// Return auth URL
@@ -620,7 +620,7 @@ func (h *Handlers) OauthCallbackHandler(c *gin.Context) {
state := c.Query("state")
// Get CSRF cookie
csrfCookie, err := c.Cookie("tinyauth-csrf")
csrfCookie, err := c.Cookie(h.Config.CsrfCookieName)
if err != nil {
log.Debug().Msg("No CSRF cookie")
@@ -638,7 +638,7 @@ func (h *Handlers) OauthCallbackHandler(c *gin.Context) {
}
// Clean up CSRF cookie
c.SetCookie("tinyauth-csrf", "", -1, "/", "", h.Config.CookieSecure, true)
c.SetCookie(h.Config.CsrfCookieName, "", -1, "/", "", h.Config.CookieSecure, true)
// Get code
code := c.Query("code")
@@ -737,7 +737,7 @@ func (h *Handlers) OauthCallbackHandler(c *gin.Context) {
})
// Check if we have a redirect URI
redirectCookie, err := c.Cookie("tinyauth-redirect")
redirectCookie, err := c.Cookie(h.Config.RedirectCookieName)
if err != nil {
log.Debug().Msg("No redirect cookie")
@@ -762,7 +762,7 @@ func (h *Handlers) OauthCallbackHandler(c *gin.Context) {
}
// Clean up redirect cookie
c.SetCookie("tinyauth-redirect", "", -1, "/", "", h.Config.CookieSecure, true)
c.SetCookie(h.Config.RedirectCookieName, "", -1, "/", "", h.Config.CookieSecure, true)
// Redirect to continue with the redirect URI
c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/continue?%s", h.Config.AppURL, queries.Encode()))

View File

@@ -48,6 +48,8 @@ type HandlersConfig struct {
ForgotPasswordMessage string
BackgroundImage string
OAuthAutoRedirect string
CsrfCookieName string
RedirectCookieName string
}
// OAuthConfig is the configuration for the providers
@@ -73,14 +75,15 @@ type APIConfig struct {
// AuthConfig is the configuration for the auth service
type AuthConfig struct {
Users Users
OauthWhitelist string
SessionExpiry int
Secret string
CookieSecure bool
Domain string
LoginTimeout int
LoginMaxRetries int
Users Users
OauthWhitelist string
SessionExpiry int
Secret string
CookieSecure bool
Domain string
LoginTimeout int
LoginMaxRetries int
SessionCookieName string
}
// HooksConfig is the configuration for the hooks service

View File

@@ -10,6 +10,7 @@ import (
"tinyauth/internal/constants"
"tinyauth/internal/types"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
@@ -344,3 +345,18 @@ func SanitizeHeader(header string) string {
return -1
}, header)
}
// Generate a static identifier from a string
func GenerateIdentifier(str string) string {
// Create a new UUID
uuid := uuid.NewSHA1(uuid.NameSpaceURL, []byte(str))
// Convert the UUID to a string
uuidString := uuid.String()
// Show the UUID
log.Debug().Str("uuid", uuidString).Msg("Generated UUID")
// Convert the UUID to a string
return strings.Split(uuidString, "-")[0]
}