A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
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.
 
 
 
 
 

147 lines
3.2 KiB

  1. /*
  2. * Copyright © 2018-2019 Musing Studio LLC.
  3. *
  4. * This file is part of WriteFreely.
  5. *
  6. * WriteFreely is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License, included
  8. * in the LICENSE file in this source code package.
  9. */
  10. package writefreely
  11. import (
  12. "encoding/gob"
  13. "github.com/gorilla/sessions"
  14. "github.com/writeas/web-core/log"
  15. "net/http"
  16. "strings"
  17. )
  18. const (
  19. day = 86400
  20. sessionLength = 180 * day
  21. userEmailCookieName = "ue"
  22. userEmailCookieVal = "email"
  23. cookieName = "wfu"
  24. cookieUserVal = "u"
  25. blogPassCookieName = "ub"
  26. )
  27. // InitSession creates the cookie store. It depends on the keychain already
  28. // being loaded.
  29. func (app *App) InitSession() {
  30. // Register complex data types we'll be storing in cookies
  31. gob.Register(&User{})
  32. // Create the cookie store
  33. store := sessions.NewCookieStore(app.keys.CookieAuthKey, app.keys.CookieKey)
  34. store.Options = &sessions.Options{
  35. Path: "/",
  36. MaxAge: sessionLength,
  37. HttpOnly: true,
  38. Secure: strings.HasPrefix(app.cfg.App.Host, "https://"),
  39. }
  40. if store.Options.Secure {
  41. store.Options.SameSite = http.SameSiteNoneMode
  42. }
  43. app.sessionStore = store
  44. }
  45. func getSessionFlashes(app *App, w http.ResponseWriter, r *http.Request, session *sessions.Session) ([]string, error) {
  46. var err error
  47. if session == nil {
  48. session, err = app.sessionStore.Get(r, cookieName)
  49. if err != nil {
  50. return nil, err
  51. }
  52. }
  53. f := []string{}
  54. if flashes := session.Flashes(); len(flashes) > 0 {
  55. for _, flash := range flashes {
  56. if str, ok := flash.(string); ok {
  57. f = append(f, str)
  58. }
  59. }
  60. }
  61. saveUserSession(app, r, w)
  62. return f, nil
  63. }
  64. func addSessionFlash(app *App, w http.ResponseWriter, r *http.Request, m string, session *sessions.Session) error {
  65. var err error
  66. if session == nil {
  67. session, err = app.sessionStore.Get(r, cookieName)
  68. }
  69. if err != nil {
  70. log.Error("Unable to add flash '%s': %v", m, err)
  71. return err
  72. }
  73. session.AddFlash(m)
  74. saveUserSession(app, r, w)
  75. return nil
  76. }
  77. func getUserAndSession(app *App, r *http.Request) (*User, *sessions.Session) {
  78. session, err := app.sessionStore.Get(r, cookieName)
  79. if err == nil {
  80. // Got the currently logged-in user
  81. val := session.Values[cookieUserVal]
  82. var u = &User{}
  83. var ok bool
  84. if u, ok = val.(*User); ok {
  85. return u, session
  86. }
  87. }
  88. return nil, nil
  89. }
  90. func getUserSession(app *App, r *http.Request) *User {
  91. u, _ := getUserAndSession(app, r)
  92. return u
  93. }
  94. func saveUserSession(app *App, r *http.Request, w http.ResponseWriter) error {
  95. session, err := app.sessionStore.Get(r, cookieName)
  96. if err != nil {
  97. return ErrInternalCookieSession
  98. }
  99. // Extend the session
  100. session.Options.MaxAge = int(sessionLength)
  101. // Remove any information that accidentally got added
  102. // FIXME: find where Plan information is getting saved to cookie.
  103. val := session.Values[cookieUserVal]
  104. var u = &User{}
  105. var ok bool
  106. if u, ok = val.(*User); ok {
  107. session.Values[cookieUserVal] = u.Cookie()
  108. }
  109. err = session.Save(r, w)
  110. if err != nil {
  111. log.Error("Couldn't saveUserSession: %v", err)
  112. }
  113. return err
  114. }
  115. func getFullUserSession(app *App, r *http.Request) (*User, error) {
  116. u := getUserSession(app, r)
  117. if u == nil {
  118. return nil, nil
  119. }
  120. var err error
  121. u, err = app.db.GetUserByID(u.ID)
  122. return u, err
  123. }