mirror of
https://github.com/photoprism/photoprism.git
synced 2025-10-08 10:10:38 +08:00
141 lines
3.4 KiB
Go
141 lines
3.4 KiB
Go
package entity
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/dustin/go-humanize/english"
|
|
|
|
"github.com/photoprism/photoprism/internal/event"
|
|
"github.com/photoprism/photoprism/pkg/authn"
|
|
"github.com/photoprism/photoprism/pkg/rnd"
|
|
"github.com/photoprism/photoprism/pkg/time/unix"
|
|
)
|
|
|
|
// DeleteSession permanently deletes a session.
|
|
func DeleteSession(s *Session) error {
|
|
if s == nil {
|
|
return nil
|
|
} else if !rnd.IsSessionID(s.ID) {
|
|
return fmt.Errorf("invalid session id")
|
|
}
|
|
|
|
// Delete any other sessions that were authenticated with the specified session.
|
|
if n := DeleteChildSessions(s); n > 0 {
|
|
event.AuditInfo([]string{s.IP(), "session %s", "deleted %s"}, s.RefID, english.Plural(n, "child session", "child sessions"))
|
|
}
|
|
|
|
// Delete session from cache.
|
|
DeleteFromSessionCache(s.ID)
|
|
|
|
if s.PreviewToken != "" {
|
|
PreviewToken.Set(s.PreviewToken, s.ID)
|
|
}
|
|
|
|
if s.DownloadToken != "" {
|
|
DownloadToken.Set(s.DownloadToken, s.ID)
|
|
}
|
|
|
|
return UnscopedDb().Delete(s).Error
|
|
}
|
|
|
|
// DeleteChildSessions deletes any other sessions that were authenticated with the specified session.
|
|
func DeleteChildSessions(s *Session) (deleted int) {
|
|
if s == nil {
|
|
return 0
|
|
} else if !rnd.IsSessionID(s.ID) || s.Method().Is(authn.MethodSession) {
|
|
return 0
|
|
}
|
|
|
|
found := Sessions{}
|
|
|
|
if err := Db().Where("auth_id = ? AND auth_method = ?", s.ID, authn.MethodSession.String()).Find(&found).Error; err != nil {
|
|
event.AuditErr([]string{"failed to find child sessions", "%s"}, err)
|
|
return deleted
|
|
}
|
|
|
|
for _, sess := range found {
|
|
if err := sess.Delete(); err != nil {
|
|
event.AuditErr([]string{sess.IP(), "session %s", "failed to delete child session %s", "%s"}, s.RefID, sess.RefID, err)
|
|
} else {
|
|
deleted++
|
|
}
|
|
}
|
|
|
|
return deleted
|
|
}
|
|
|
|
// DeleteClientSessions deletes client sessions above the specified limit.
|
|
func DeleteClientSessions(client *Client, authMethod authn.MethodType, limit int64) (deleted int) {
|
|
if limit < 0 {
|
|
return 0
|
|
} else if client == nil {
|
|
return 0
|
|
}
|
|
|
|
q := Db()
|
|
|
|
if client.HasUID() {
|
|
q = q.Where("client_uid = ?", client.GetUID())
|
|
} else if client.HasName() {
|
|
q = q.Where("client_name = ?", client.Name())
|
|
} else {
|
|
return 0
|
|
}
|
|
|
|
if client.HasUser() {
|
|
q = q.Where("user_uid = ?", client.UserUID)
|
|
}
|
|
|
|
if !authMethod.IsUndefined() {
|
|
q = q.Where("auth_method = ?", authMethod.String())
|
|
}
|
|
|
|
q = q.Order("created_at DESC").Limit(1000000000).Offset(limit)
|
|
|
|
found := Sessions{}
|
|
|
|
if err := q.Find(&found).Error; err != nil {
|
|
event.AuditErr([]string{"failed to fetch client sessions", "%s"}, err)
|
|
return deleted
|
|
}
|
|
|
|
for _, sess := range found {
|
|
if err := sess.Delete(); err != nil {
|
|
event.AuditErr([]string{sess.IP(), "session %s", "failed to delete", "%s"}, sess.RefID, err)
|
|
} else {
|
|
deleted++
|
|
}
|
|
}
|
|
|
|
return deleted
|
|
}
|
|
|
|
// DeleteExpiredSessions deletes all expired sessions.
|
|
func DeleteExpiredSessions() (deleted int) {
|
|
found := Sessions{}
|
|
|
|
if err := Db().Where("sess_expires > 0 AND sess_expires < ?", unix.Now()).Find(&found).Error; err != nil {
|
|
event.AuditErr([]string{"failed to fetch expired sessions", "%s"}, err)
|
|
return deleted
|
|
}
|
|
|
|
for _, sess := range found {
|
|
if err := sess.Delete(); err != nil {
|
|
event.AuditErr([]string{sess.IP(), "session %s", "failed to delete", "%s"}, sess.RefID, err)
|
|
} else {
|
|
deleted++
|
|
}
|
|
}
|
|
|
|
return deleted
|
|
}
|
|
|
|
// DeleteFromSessionCache deletes a session from the cache.
|
|
func DeleteFromSessionCache(id string) {
|
|
if id == "" {
|
|
return
|
|
}
|
|
|
|
sessionCache.Delete(id)
|
|
}
|