gitea源码

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