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.
 
 
 
 
 

139 lines
3.1 KiB

  1. /*
  2. * Copyright © 2018 A Bunch Tell 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. cookieName = "wfu"
  22. cookieUserVal = "u"
  23. blogPassCookieName = "ub"
  24. )
  25. // initSession creates the cookie store. It depends on the keychain already
  26. // being loaded.
  27. func initSession(app *app) *sessions.CookieStore {
  28. // Register complex data types we'll be storing in cookies
  29. gob.Register(&User{})
  30. // Create the cookie store
  31. store := sessions.NewCookieStore(app.keys.cookieAuthKey, app.keys.cookieKey)
  32. store.Options = &sessions.Options{
  33. Path: "/",
  34. MaxAge: sessionLength,
  35. HttpOnly: true,
  36. Secure: strings.HasPrefix(app.cfg.App.Host, "https://"),
  37. }
  38. return store
  39. }
  40. func getSessionFlashes(app *app, w http.ResponseWriter, r *http.Request, session *sessions.Session) ([]string, error) {
  41. var err error
  42. if session == nil {
  43. session, err = app.sessionStore.Get(r, cookieName)
  44. if err != nil {
  45. return nil, err
  46. }
  47. }
  48. f := []string{}
  49. if flashes := session.Flashes(); len(flashes) > 0 {
  50. for _, flash := range flashes {
  51. if str, ok := flash.(string); ok {
  52. f = append(f, str)
  53. }
  54. }
  55. }
  56. saveUserSession(app, r, w)
  57. return f, nil
  58. }
  59. func addSessionFlash(app *app, w http.ResponseWriter, r *http.Request, m string, session *sessions.Session) error {
  60. var err error
  61. if session == nil {
  62. session, err = app.sessionStore.Get(r, cookieName)
  63. }
  64. if err != nil {
  65. log.Error("Unable to add flash '%s': %v", m, err)
  66. return err
  67. }
  68. session.AddFlash(m)
  69. saveUserSession(app, r, w)
  70. return nil
  71. }
  72. func getUserAndSession(app *app, r *http.Request) (*User, *sessions.Session) {
  73. session, err := app.sessionStore.Get(r, cookieName)
  74. if err == nil {
  75. // Got the currently logged-in user
  76. val := session.Values[cookieUserVal]
  77. var u = &User{}
  78. var ok bool
  79. if u, ok = val.(*User); ok {
  80. return u, session
  81. }
  82. }
  83. return nil, nil
  84. }
  85. func getUserSession(app *app, r *http.Request) *User {
  86. u, _ := getUserAndSession(app, r)
  87. return u
  88. }
  89. func saveUserSession(app *app, r *http.Request, w http.ResponseWriter) error {
  90. session, err := app.sessionStore.Get(r, cookieName)
  91. if err != nil {
  92. return ErrInternalCookieSession
  93. }
  94. // Extend the session
  95. session.Options.MaxAge = int(sessionLength)
  96. // Remove any information that accidentally got added
  97. // FIXME: find where Plan information is getting saved to cookie.
  98. val := session.Values[cookieUserVal]
  99. var u = &User{}
  100. var ok bool
  101. if u, ok = val.(*User); ok {
  102. session.Values[cookieUserVal] = u.Cookie()
  103. }
  104. err = session.Save(r, w)
  105. if err != nil {
  106. log.Error("Couldn't saveUserSession: %v", err)
  107. }
  108. return err
  109. }
  110. func getFullUserSession(app *app, r *http.Request) *User {
  111. u := getUserSession(app, r)
  112. if u == nil {
  113. return nil
  114. }
  115. u, _ = app.db.GetUserByID(u.ID)
  116. return u
  117. }