The new Ripple frontend.
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.

sessions.go 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package main
  2. import (
  3. "net/http"
  4. "net/url"
  5. "time"
  6. "github.com/gin-gonic/contrib/sessions"
  7. "github.com/gin-gonic/gin"
  8. "zxq.co/ripple/rippleapi/common"
  9. "zxq.co/x/rs"
  10. )
  11. func sessionInitializer() func(c *gin.Context) {
  12. return func(c *gin.Context) {
  13. sess := sessions.Default(c)
  14. var ctx context
  15. var passwordChanged bool
  16. userid := sess.Get("userid")
  17. if userid, ok := userid.(int); ok {
  18. ctx.User.ID = userid
  19. var (
  20. pRaw int64
  21. password string
  22. )
  23. err := db.QueryRow("SELECT username, privileges, flags, password_md5 FROM users WHERE id = ?", userid).
  24. Scan(&ctx.User.Username, &pRaw, &ctx.User.Flags, &password)
  25. if err != nil {
  26. c.Error(err)
  27. }
  28. if sess.Get("logout") == nil {
  29. sess.Set("logout", rs.String(15))
  30. }
  31. ctx.User.Privileges = common.UserPrivileges(pRaw)
  32. db.Exec("UPDATE users SET latest_activity = ? WHERE id = ?", time.Now().Unix(), userid)
  33. if s, ok := sess.Get("pw").(string); !ok || cmd5(password) != s {
  34. ctx = context{}
  35. sess.Clear()
  36. passwordChanged = true
  37. }
  38. }
  39. if v, _ := sess.Get("2fa_must_validate").(bool); !v && ctx.User.ID != 0 {
  40. tok := sess.Get("token")
  41. if tok, ok := tok.(string); ok {
  42. ctx.Token = tok
  43. }
  44. oldToken := ctx.Token
  45. ctx.Token, _ = checkToken(ctx.Token, ctx.User.ID, c)
  46. // Set rt cookie in case:
  47. // - User has not got a token in rt
  48. // - Token has been updated with checkToken
  49. // - user still has old token in rt
  50. if x, _ := c.Cookie("rt"); oldToken != ctx.Token || x != ctx.Token {
  51. http.SetCookie(c.Writer, &http.Cookie{
  52. Name: "rt",
  53. Value: ctx.Token,
  54. Expires: time.Now().Add(time.Hour * 24 * 30 * 1),
  55. })
  56. sess.Set("token", ctx.Token)
  57. }
  58. }
  59. var addBannedMessage bool
  60. if ctx.User.ID != 0 && (ctx.User.Privileges&common.UserPrivilegeNormal == 0) {
  61. ctx = context{}
  62. sess.Clear()
  63. addBannedMessage = true
  64. }
  65. ctx.Language = getLanguageFromGin(c)
  66. c.Set("context", ctx)
  67. c.Set("session", sess)
  68. if addBannedMessage {
  69. addMessage(c, warningMessage{T(c, "You have been automatically logged out of your account because your account has either been banned or locked. Should you believe this is a mistake, you can contact our support team at support@ripple.moe.")})
  70. }
  71. if passwordChanged {
  72. addMessage(c, warningMessage{T(c, "You have been automatically logged out for security reasons. Please <a href='/login?redir=%s'>log back in</a>.", url.QueryEscape(c.Request.URL.Path))})
  73. }
  74. c.Next()
  75. }
  76. }
  77. func addMessage(c *gin.Context, m message) {
  78. sess := getSession(c)
  79. var messages []message
  80. messagesRaw := sess.Get("messages")
  81. if messagesRaw != nil {
  82. messages = messagesRaw.([]message)
  83. }
  84. messages = append(messages, m)
  85. sess.Set("messages", messages)
  86. }
  87. func getMessages(c *gin.Context) []message {
  88. sess := getSession(c)
  89. messagesRaw := sess.Get("messages")
  90. if messagesRaw == nil {
  91. return nil
  92. }
  93. sess.Delete("messages")
  94. return messagesRaw.([]message)
  95. }
  96. func getSession(c *gin.Context) sessions.Session {
  97. return c.MustGet("session").(sessions.Session)
  98. }