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

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