session.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright 2017 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package storage // import "miniflux.app/storage"
  5. import (
  6. "database/sql"
  7. "fmt"
  8. "miniflux.app/crypto"
  9. "miniflux.app/model"
  10. )
  11. // CreateSession creates a new session.
  12. func (s *Storage) CreateSession() (*model.Session, error) {
  13. session := model.Session{
  14. ID: crypto.GenerateRandomString(32),
  15. Data: &model.SessionData{CSRF: crypto.GenerateRandomString(64)},
  16. }
  17. query := "INSERT INTO sessions (id, data) VALUES ($1, $2)"
  18. _, err := s.db.Exec(query, session.ID, session.Data)
  19. if err != nil {
  20. return nil, fmt.Errorf("unable to create session: %v", err)
  21. }
  22. return &session, nil
  23. }
  24. // UpdateSessionField updates only one session field.
  25. func (s *Storage) UpdateSessionField(sessionID, field string, value interface{}) error {
  26. query := `UPDATE sessions
  27. SET data = jsonb_set(data, '{%s}', to_jsonb($1::text), true)
  28. WHERE id=$2`
  29. _, err := s.db.Exec(fmt.Sprintf(query, field), value, sessionID)
  30. if err != nil {
  31. return fmt.Errorf("unable to update session field: %v", err)
  32. }
  33. return nil
  34. }
  35. // Session returns the given session.
  36. func (s *Storage) Session(id string) (*model.Session, error) {
  37. var session model.Session
  38. query := "SELECT id, data FROM sessions WHERE id=$1"
  39. err := s.db.QueryRow(query, id).Scan(
  40. &session.ID,
  41. &session.Data,
  42. )
  43. if err == sql.ErrNoRows {
  44. return nil, fmt.Errorf("session not found: %s", id)
  45. } else if err != nil {
  46. return nil, fmt.Errorf("unable to fetch session: %v", err)
  47. }
  48. return &session, nil
  49. }
  50. // FlushAllSessions removes all sessions from the database.
  51. func (s *Storage) FlushAllSessions() (err error) {
  52. _, err = s.db.Exec(`DELETE FROM user_sessions`)
  53. if err != nil {
  54. return err
  55. }
  56. _, err = s.db.Exec(`DELETE FROM sessions`)
  57. if err != nil {
  58. return err
  59. }
  60. return nil
  61. }
  62. // CleanOldSessions removes sessions older than 30 days.
  63. func (s *Storage) CleanOldSessions() int64 {
  64. query := `DELETE FROM sessions
  65. WHERE id IN (SELECT id FROM sessions WHERE created_at < now() - interval '30 days')`
  66. result, err := s.db.Exec(query)
  67. if err != nil {
  68. return 0
  69. }
  70. n, _ := result.RowsAffected()
  71. return n
  72. }