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.

116 lines
2.4 KiB

7 years ago
7 years ago
7 years ago
7 years ago
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. data map[string]string
  20. }
  21. // SetData sets session data
  22. func (sess *Session) SetData(key, value string) {
  23. sess.data[key] = value
  24. }
  25. // GetData gets session data for the following key
  26. func (sess *Session) GetData(key string) string {
  27. return sess.data[key]
  28. }
  29. // HasData checks if the session data contains the key
  30. func (sess *Session) HasData(key string) bool {
  31. _, ok := sess.data[key]
  32. return ok
  33. }
  34. // OpenSession creates a new session from the supplied user's ID
  35. func OpenSession(user *User) *Session {
  36. session := &Session{generate.SessionID(), user.FullID(), time.Now(), make(map[string]string)}
  37. sessionMutex.Lock()
  38. sessions[session.ID] = session
  39. sessionMutex.Unlock()
  40. // No need to do these checks when there's no activity.
  41. if time.Since(lastCheck) > time.Hour {
  42. lastCheck = time.Now()
  43. go cleanup()
  44. }
  45. user.Session = session
  46. return session
  47. }
  48. // FindSession returns a session if the id maps to a still valid session
  49. func FindSession(id string) *Session {
  50. sessionMutex.RLock()
  51. session := sessions[id]
  52. sessionMutex.RUnlock()
  53. // Check expiry and update
  54. if session != nil {
  55. if time.Since(session.Time) > SessionMaxTime {
  56. return nil
  57. }
  58. if time.Since(session.Time) > time.Hour {
  59. session.Time = time.Now()
  60. }
  61. }
  62. return session
  63. }
  64. // CloseSession deletes a session by the id
  65. func CloseSession(id string) {
  66. sessionMutex.Lock()
  67. delete(sessions, id)
  68. sessionMutex.Unlock()
  69. }
  70. // ClearSessions removes all sessions with the given user ID
  71. func ClearSessions(user *User) {
  72. sessionMutex.Lock()
  73. for _, sess := range sessions {
  74. if sess.UserID == user.FullID() {
  75. delete(sessions, sess.ID)
  76. }
  77. }
  78. sessionMutex.Unlock()
  79. }
  80. func cleanup() {
  81. count := 0
  82. sessionMutex.Lock()
  83. for key, session := range sessions {
  84. if time.Since(session.Time) > SessionMaxTime {
  85. delete(sessions, key)
  86. count++
  87. }
  88. }
  89. sessionMutex.Unlock()
  90. if count > 0 {
  91. log.Println("Removed", count, "sessions.")
  92. }
  93. }