Skip to content

Commit 8623da5

Browse files
committed
feat(session): Added user session limit and device eviction logic
- Renamed `CountSessionsByUser` to `CountActiveSessionsByUser` and added session status filtering - Added user and device session limit, with policy handling when exceeding the limit - Introduced device eviction policy: If the maximum number of devices is exceeded, the oldest session will be evicted using the "evict_oldest" policy - Modified `LastActive` update logic to ensure accurate session activity time
1 parent 84adba3 commit 8623da5

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

internal/db/session.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ func DeleteSession(userID uint, deviceKey string) error {
2626
return errors.WithStack(db.Where("user_id = ? AND device_key = ?", userID, deviceKey).Delete(&model.Session{}).Error)
2727
}
2828

29-
func CountSessionsByUser(userID uint) (int64, error) {
29+
func CountActiveSessionsByUser(userID uint) (int64, error) {
3030
var count int64
31-
err := db.Model(&model.Session{}).Where("user_id = ?", userID).Count(&count).Error
31+
err := db.Model(&model.Session{}).
32+
Where("user_id = ? AND status = ?", userID, model.SessionActive).
33+
Count(&count).Error
3234
return count, errors.WithStack(err)
3335
}
3436

internal/device/session.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,25 @@ func Handle(userID uint, deviceKey, ua, ip string) error {
2525
now := time.Now().Unix()
2626
sess, err := db.GetSession(userID, deviceKey)
2727
if err == nil {
28-
// reactivate existing session if it was inactive
28+
if sess.Status == model.SessionInactive {
29+
max := setting.GetInt(conf.MaxDevices, 0)
30+
if max > 0 {
31+
count, cerr := db.CountActiveSessionsByUser(userID)
32+
if cerr != nil {
33+
return cerr
34+
}
35+
if count >= int64(max) {
36+
policy := setting.GetStr(conf.DeviceEvictPolicy, "deny")
37+
if policy == "evict_oldest" {
38+
if oldest, gerr := db.GetOldestSession(userID); gerr == nil {
39+
_ = db.DeleteSession(userID, oldest.DeviceKey)
40+
}
41+
} else {
42+
return errors.WithStack(errs.TooManyDevices)
43+
}
44+
}
45+
}
46+
}
2947
sess.Status = model.SessionActive
3048
sess.LastActive = now
3149
sess.UserAgent = ua
@@ -38,7 +56,7 @@ func Handle(userID uint, deviceKey, ua, ip string) error {
3856

3957
max := setting.GetInt(conf.MaxDevices, 0)
4058
if max > 0 {
41-
count, err := db.CountSessionsByUser(userID)
59+
count, err := db.CountActiveSessionsByUser(userID)
4260
if err != nil {
4361
return err
4462
}

0 commit comments

Comments
 (0)