feat: add session expiry inside cookie (breaking)

This commit is contained in:
Stavros
2025-02-05 19:08:23 +02:00
parent 97830a309b
commit 87393d3c64
3 changed files with 21 additions and 9 deletions

View File

@@ -89,7 +89,7 @@ var rootCmd = &cobra.Command{
HandleError(dockerErr, "Failed to initialize docker") HandleError(dockerErr, "Failed to initialize docker")
// Create auth service // Create auth service
auth := auth.NewAuth(docker, users, oauthWhitelist) auth := auth.NewAuth(docker, users, oauthWhitelist, config.SessionExpiry)
// Create OAuth providers service // Create OAuth providers service
providers := providers.NewProviders(oauthConfig) providers := providers.NewProviders(oauthConfig)
@@ -108,7 +108,7 @@ var rootCmd = &cobra.Command{
AppURL: config.AppURL, AppURL: config.AppURL,
CookieSecure: config.CookieSecure, CookieSecure: config.CookieSecure,
DisableContinue: config.DisableContinue, DisableContinue: config.DisableContinue,
CookieExpiry: config.CookieExpiry, CookieExpiry: config.SessionExpiry,
}, hooks, auth, providers) }, hooks, auth, providers)
// Setup routes // Setup routes
@@ -162,7 +162,7 @@ func init() {
rootCmd.Flags().String("generic-user-url", "", "Generic OAuth user info URL.") rootCmd.Flags().String("generic-user-url", "", "Generic OAuth user info URL.")
rootCmd.Flags().Bool("disable-continue", false, "Disable continue screen and redirect to app directly.") rootCmd.Flags().Bool("disable-continue", false, "Disable continue screen and redirect to app directly.")
rootCmd.Flags().String("oauth-whitelist", "", "Comma separated list of email addresses to whitelist when using OAuth.") rootCmd.Flags().String("oauth-whitelist", "", "Comma separated list of email addresses to whitelist when using OAuth.")
rootCmd.Flags().Int("cookie-expiry", 86400, "Cookie expiration time in seconds.") rootCmd.Flags().Int("session-expiry", 86400, "Session (cookie) expiration time in seconds.")
rootCmd.Flags().Int("log-level", 1, "Log level.") rootCmd.Flags().Int("log-level", 1, "Log level.")
viper.BindEnv("port", "PORT") viper.BindEnv("port", "PORT")
viper.BindEnv("address", "ADDRESS") viper.BindEnv("address", "ADDRESS")
@@ -190,7 +190,7 @@ func init() {
viper.BindEnv("generic-user-url", "GENERIC_USER_URL") viper.BindEnv("generic-user-url", "GENERIC_USER_URL")
viper.BindEnv("disable-continue", "DISABLE_CONTINUE") viper.BindEnv("disable-continue", "DISABLE_CONTINUE")
viper.BindEnv("oauth-whitelist", "OAUTH_WHITELIST") viper.BindEnv("oauth-whitelist", "OAUTH_WHITELIST")
viper.BindEnv("cookie-expiry", "COOKIE_EXPIRY") viper.BindEnv("session-expiry", "SESSION_EXPIRY")
viper.BindEnv("log-level", "LOG_LEVEL") viper.BindEnv("log-level", "LOG_LEVEL")
viper.BindPFlags(rootCmd.Flags()) viper.BindPFlags(rootCmd.Flags())
} }

View File

@@ -3,6 +3,7 @@ package auth
import ( import (
"slices" "slices"
"strings" "strings"
"time"
"tinyauth/internal/docker" "tinyauth/internal/docker"
"tinyauth/internal/types" "tinyauth/internal/types"
"tinyauth/internal/utils" "tinyauth/internal/utils"
@@ -13,11 +14,12 @@ import (
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
func NewAuth(docker *docker.Docker, userList types.Users, oauthWhitelist []string) *Auth { func NewAuth(docker *docker.Docker, userList types.Users, oauthWhitelist []string, sessionExpiry int) *Auth {
return &Auth{ return &Auth{
Docker: docker, Docker: docker,
Users: userList, Users: userList,
OAuthWhitelist: oauthWhitelist, OAuthWhitelist: oauthWhitelist,
SessionExpiry: sessionExpiry,
} }
} }
@@ -25,6 +27,7 @@ type Auth struct {
Users types.Users Users types.Users
Docker *docker.Docker Docker *docker.Docker
OAuthWhitelist []string OAuthWhitelist []string
SessionExpiry int
} }
func (auth *Auth) GetUser(username string) *types.User { func (auth *Auth) GetUser(username string) *types.User {
@@ -59,6 +62,7 @@ func (auth *Auth) CreateSessionCookie(c *gin.Context, data *types.SessionCookie)
log.Debug().Msg("Setting session cookie") log.Debug().Msg("Setting session cookie")
sessions.Set("username", data.Username) sessions.Set("username", data.Username)
sessions.Set("provider", data.Provider) sessions.Set("provider", data.Provider)
sessions.Set("expiry", time.Now().Add(time.Duration(auth.SessionExpiry)*time.Second).Unix())
sessions.Save() sessions.Save()
} }
@@ -75,17 +79,25 @@ func (auth *Auth) GetSessionCookie(c *gin.Context) (types.SessionCookie, error)
cookieUsername := sessions.Get("username") cookieUsername := sessions.Get("username")
cookieProvider := sessions.Get("provider") cookieProvider := sessions.Get("provider")
cookieExpiry := sessions.Get("expiry")
username, usernameOk := cookieUsername.(string) username, usernameOk := cookieUsername.(string)
provider, providerOk := cookieProvider.(string) provider, providerOk := cookieProvider.(string)
expiry, expiryOk := cookieExpiry.(int64)
log.Debug().Str("username", username).Str("provider", provider).Msg("Parsed cookie") if !usernameOk || !providerOk || !expiryOk {
if !usernameOk || !providerOk {
log.Warn().Msg("Session cookie invalid") log.Warn().Msg("Session cookie invalid")
return types.SessionCookie{}, nil return types.SessionCookie{}, nil
} }
if time.Now().Unix() > expiry {
log.Warn().Msg("Session cookie expired")
auth.DeleteSessionCookie(c)
return types.SessionCookie{}, nil
}
log.Debug().Str("username", username).Str("provider", provider).Int64("expiry", expiry).Msg("Parsed cookie")
return types.SessionCookie{ return types.SessionCookie{
Username: username, Username: username,
Provider: provider, Provider: provider,

View File

@@ -45,7 +45,7 @@ type Config struct {
GenericUserURL string `mapstructure:"generic-user-url"` GenericUserURL string `mapstructure:"generic-user-url"`
DisableContinue bool `mapstructure:"disable-continue"` DisableContinue bool `mapstructure:"disable-continue"`
OAuthWhitelist string `mapstructure:"oauth-whitelist"` OAuthWhitelist string `mapstructure:"oauth-whitelist"`
CookieExpiry int `mapstructure:"cookie-expiry"` SessionExpiry int `mapstructure:"session-expiry"`
LogLevel int8 `mapstructure:"log-level" validate:"min=-1,max=5"` LogLevel int8 `mapstructure:"log-level" validate:"min=-1,max=5"`
} }