From 0506ed6491c085929ddc57b2379f88d8661d7df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Z=C3=BCrcher?= Date: Fri, 7 Nov 2025 13:51:58 +0100 Subject: [PATCH] add new user defined user exiration --- handlers/login.go | 45 +++++++++++++++++++++++++++++++++++---------- models/user.go | 14 ++++++++++++++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/handlers/login.go b/handlers/login.go index 154f38b..3245a46 100644 --- a/handlers/login.go +++ b/handlers/login.go @@ -49,6 +49,10 @@ func (aH *AccessHandler) Login(c *gin.Context) { aH.logger.Error("Login", "user empty") c.JSON(http.StatusBadRequest, models.NewJsonMessageResponse("user empty")) return + } else if !user.ExpirationIsValid() { + aH.logger.Error("Login", fmt.Sprintf("user %s is expired", user.Name)) + c.JSON(http.StatusUnauthorized, models.NewJsonMessageResponse("user "+user.Name+" is expired")) + return } // Fetch user record from DB @@ -84,20 +88,22 @@ func (aH *AccessHandler) Login(c *gin.Context) { // Create access token accessToken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ - "id": user.Id, - "username": user.Name, - "role": user.Role, - "type": "access", - "exp": accessTokenExp.Unix(), + "id": user.Id, + "username": user.Name, + "role": user.Role, + "type": "access", + "exp": accessTokenExp.Unix(), + "userExpiration": user.Expiration, }) // Create refresh token refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ - "id": user.Id, - "username": user.Name, - "role": user.Role, - "type": "refresh", - "exp": refreshTokenExp.Unix(), + "id": user.Id, + "username": user.Name, + "role": user.Role, + "type": "refresh", + "exp": refreshTokenExp.Unix(), + "userExpiration": user.GetExpiration(), }) // Sign tokens @@ -175,6 +181,12 @@ func (aH *AccessHandler) Refresh(c *gin.Context) { id := int(claims["id"].(float64)) role := claims["role"].(string) + if !expirationDateValid(claims["userExpiration"].(string)) { + aH.logger.Error("Login", fmt.Sprintf("user %s is expired", username)) + c.JSON(http.StatusUnauthorized, models.NewJsonMessageResponse("user "+username+" is expired")) + return + } + // Create new access token aH.logger.Debug("Refresh", "create new access token") accessExp := time.Now().Add(ACCESS_TOKEN_TIME) @@ -240,3 +252,16 @@ func (aH *AccessHandler) Logout(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "logged out"}) } + +func expirationDateValid(expiration string) bool { + if expiration == "" { + return true // No expiration = always valid + } + + t, err := time.Parse(time.RFC3339, expiration) + if err != nil { + return false // Invalid date format + } + + return time.Now().Before(t) +} diff --git a/models/user.go b/models/user.go index a748991..8e59b7f 100644 --- a/models/user.go +++ b/models/user.go @@ -15,3 +15,17 @@ type User struct { func (u *User) IsValid() bool { return u.Name != "" } + +func (u *User) ExpirationIsValid() bool { + if u.Expiration == nil { + return true + } + return time.Now().Before(*u.Expiration) +} + +func (u *User) GetExpiration() string { + if u.Expiration == nil { + return "" + } + return u.Expiration.Format(time.RFC3339) +}