Core functionality for new aiterp.net servers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
1.9 KiB

7 years ago
  1. package auth
  2. import (
  3. "log"
  4. "sync"
  5. "time"
  6. "git.aiterp.net/gisle/wrouter/generate"
  7. )
  8. const SessionMaxTime = time.Hour * 72
  9. var sessionMutex sync.RWMutex
  10. var sessions = make(map[string]*Session, 512)
  11. var lastCheck = time.Now()
  12. // SessionCookieName for the session cookie
  13. var SessionCookieName = "sessid"
  14. // Session is a simple in-memory structure describing a suer session
  15. type Session struct {
  16. ID string `json:"id"`
  17. UserID string `json:"user"`
  18. Time time.Time `json:"time"`
  19. }
  20. // OpenSession creates a new session from the supplied user's ID
  21. func OpenSession(user *User) *Session {
  22. session := &Session{generate.SessionID(), user.FullID(), time.Now()}
  23. sessionMutex.Lock()
  24. sessions[session.ID] = session
  25. sessionMutex.Unlock()
  26. // No need to do these checks when there's no activity.
  27. if time.Since(lastCheck) > time.Hour {
  28. lastCheck = time.Now()
  29. go cleanup()
  30. }
  31. return session
  32. }
  33. // FindSession returns a session if the id maps to a still valid session
  34. func FindSession(id string) *Session {
  35. sessionMutex.RLock()
  36. defer sessionMutex.RUnlock()
  37. session := sessions[id]
  38. // Check expiry and update
  39. if session != nil {
  40. if time.Since(session.Time) > SessionMaxTime {
  41. return nil
  42. }
  43. if time.Since(session.Time) > time.Hour {
  44. session.Time = time.Now()
  45. }
  46. }
  47. return session
  48. }
  49. // CloseSession deletes a session by the id
  50. func CloseSession(id string) {
  51. sessionMutex.Lock()
  52. delete(sessions, id)
  53. sessionMutex.Unlock()
  54. }
  55. // ClearSessions removes all sessions with the given user ID
  56. func ClearSessions(user *User) {
  57. sessionMutex.Lock()
  58. for _, sess := range sessions {
  59. if sess.UserID == user.FullID() {
  60. delete(sessions, sess.ID)
  61. }
  62. }
  63. sessionMutex.Unlock()
  64. }
  65. func cleanup() {
  66. count := 0
  67. sessionMutex.Lock()
  68. for key, session := range sessions {
  69. if time.Since(session.Time) > SessionMaxTime {
  70. delete(sessions, key)
  71. count++
  72. }
  73. }
  74. sessionMutex.Unlock()
  75. if count > 0 {
  76. log.Println("Removed", count, "sessions.")
  77. }
  78. }