flash.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright (C) 2019 Nicola Murino
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU Affero General Public License as published
  5. // by the Free Software Foundation, version 3.
  6. //
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU Affero General Public License for more details.
  11. //
  12. // You should have received a copy of the GNU Affero General Public License
  13. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. package httpd
  15. import (
  16. "encoding/base64"
  17. "encoding/json"
  18. "net/http"
  19. "time"
  20. "github.com/drakkan/sftpgo/v2/internal/util"
  21. )
  22. const (
  23. flashCookieName = "message"
  24. )
  25. func newFlashMessage(errorStrig, i18nMessage string) flashMessage {
  26. return flashMessage{
  27. ErrorString: errorStrig,
  28. I18nMessage: i18nMessage,
  29. }
  30. }
  31. type flashMessage struct {
  32. ErrorString string `json:"error"`
  33. I18nMessage string `json:"message"`
  34. }
  35. func (m *flashMessage) getI18nError() *util.I18nError {
  36. if m.ErrorString == "" && m.I18nMessage == "" {
  37. return nil
  38. }
  39. return util.NewI18nError(
  40. util.NewGenericError(m.ErrorString),
  41. m.I18nMessage,
  42. )
  43. }
  44. func setFlashMessage(w http.ResponseWriter, r *http.Request, message flashMessage) {
  45. value, err := json.Marshal(message)
  46. if err != nil {
  47. return
  48. }
  49. http.SetCookie(w, &http.Cookie{
  50. Name: flashCookieName,
  51. Value: base64.URLEncoding.EncodeToString(value),
  52. Path: "/",
  53. Expires: time.Now().Add(60 * time.Second),
  54. MaxAge: 60,
  55. HttpOnly: true,
  56. Secure: isTLS(r),
  57. SameSite: http.SameSiteLaxMode,
  58. })
  59. w.Header().Add("Cache-Control", `no-cache="Set-Cookie"`)
  60. }
  61. func getFlashMessage(w http.ResponseWriter, r *http.Request) flashMessage {
  62. var msg flashMessage
  63. cookie, err := r.Cookie(flashCookieName)
  64. if err != nil {
  65. return msg
  66. }
  67. http.SetCookie(w, &http.Cookie{
  68. Name: flashCookieName,
  69. Value: "",
  70. Path: "/",
  71. Expires: time.Unix(0, 0),
  72. MaxAge: -1,
  73. HttpOnly: true,
  74. Secure: isTLS(r),
  75. SameSite: http.SameSiteLaxMode,
  76. })
  77. value, err := base64.URLEncoding.DecodeString(cookie.Value)
  78. if err != nil {
  79. return msg
  80. }
  81. err = json.Unmarshal(value, &msg)
  82. if err != nil {
  83. return flashMessage{}
  84. }
  85. return msg
  86. }