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.

session.go 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package auth
  4. import (
  5. "fmt"
  6. "code.gitea.io/gitea/models/db"
  7. "code.gitea.io/gitea/modules/timeutil"
  8. )
  9. // Session represents a session compatible for go-chi session
  10. type Session struct {
  11. Key string `xorm:"pk CHAR(16)"` // has to be Key to match with go-chi/session
  12. Data []byte `xorm:"BLOB"` // on MySQL this has a maximum size of 64Kb - this may need to be increased
  13. Expiry timeutil.TimeStamp // has to be Expiry to match with go-chi/session
  14. }
  15. func init() {
  16. db.RegisterModel(new(Session))
  17. }
  18. // UpdateSession updates the session with provided id
  19. func UpdateSession(key string, data []byte) error {
  20. _, err := db.GetEngine(db.DefaultContext).ID(key).Update(&Session{
  21. Data: data,
  22. Expiry: timeutil.TimeStampNow(),
  23. })
  24. return err
  25. }
  26. // ReadSession reads the data for the provided session
  27. func ReadSession(key string) (*Session, error) {
  28. session := Session{
  29. Key: key,
  30. }
  31. ctx, committer, err := db.TxContext(db.DefaultContext)
  32. if err != nil {
  33. return nil, err
  34. }
  35. defer committer.Close()
  36. if has, err := db.GetByBean(ctx, &session); err != nil {
  37. return nil, err
  38. } else if !has {
  39. session.Expiry = timeutil.TimeStampNow()
  40. if err := db.Insert(ctx, &session); err != nil {
  41. return nil, err
  42. }
  43. }
  44. return &session, committer.Commit()
  45. }
  46. // ExistSession checks if a session exists
  47. func ExistSession(key string) (bool, error) {
  48. session := Session{
  49. Key: key,
  50. }
  51. return db.GetEngine(db.DefaultContext).Get(&session)
  52. }
  53. // DestroySession destroys a session
  54. func DestroySession(key string) error {
  55. _, err := db.GetEngine(db.DefaultContext).Delete(&Session{
  56. Key: key,
  57. })
  58. return err
  59. }
  60. // RegenerateSession regenerates a session from the old id
  61. func RegenerateSession(oldKey, newKey string) (*Session, error) {
  62. ctx, committer, err := db.TxContext(db.DefaultContext)
  63. if err != nil {
  64. return nil, err
  65. }
  66. defer committer.Close()
  67. if has, err := db.GetByBean(ctx, &Session{
  68. Key: newKey,
  69. }); err != nil {
  70. return nil, err
  71. } else if has {
  72. return nil, fmt.Errorf("session Key: %s already exists", newKey)
  73. }
  74. if has, err := db.GetByBean(ctx, &Session{
  75. Key: oldKey,
  76. }); err != nil {
  77. return nil, err
  78. } else if !has {
  79. if err := db.Insert(ctx, &Session{
  80. Key: oldKey,
  81. Expiry: timeutil.TimeStampNow(),
  82. }); err != nil {
  83. return nil, err
  84. }
  85. }
  86. if _, err := db.Exec(ctx, "UPDATE "+db.TableName(&Session{})+" SET `key` = ? WHERE `key`=?", newKey, oldKey); err != nil {
  87. return nil, err
  88. }
  89. s := Session{
  90. Key: newKey,
  91. }
  92. if _, err := db.GetByBean(ctx, &s); err != nil {
  93. return nil, err
  94. }
  95. return &s, committer.Commit()
  96. }
  97. // CountSessions returns the number of sessions
  98. func CountSessions() (int64, error) {
  99. return db.GetEngine(db.DefaultContext).Count(&Session{})
  100. }
  101. // CleanupSessions cleans up expired sessions
  102. func CleanupSessions(maxLifetime int64) error {
  103. _, err := db.GetEngine(db.DefaultContext).Where("expiry <= ?", timeutil.TimeStampNow().Add(-maxLifetime)).Delete(&Session{})
  104. return err
  105. }