session.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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
  5. import (
  6. "database/sql"
  7. "fmt"
  8. "github.com/miniflux/miniflux2/helper"
  9. "github.com/miniflux/miniflux2/model"
  10. )
  11. // Sessions returns the list of sessions for the given user.
  12. func (s *Storage) Sessions(userID int64) (model.Sessions, error) {
  13. query := `SELECT id, user_id, token, created_at, user_agent, ip FROM sessions WHERE user_id=$1 ORDER BY id DESC`
  14. rows, err := s.db.Query(query, userID)
  15. if err != nil {
  16. return nil, fmt.Errorf("unable to fetch sessions: %v", err)
  17. }
  18. defer rows.Close()
  19. var sessions model.Sessions
  20. for rows.Next() {
  21. var session model.Session
  22. err := rows.Scan(
  23. &session.ID,
  24. &session.UserID,
  25. &session.Token,
  26. &session.CreatedAt,
  27. &session.UserAgent,
  28. &session.IP,
  29. )
  30. if err != nil {
  31. return nil, fmt.Errorf("unable to fetch session row: %v", err)
  32. }
  33. sessions = append(sessions, &session)
  34. }
  35. return sessions, nil
  36. }
  37. // CreateSession creates a new sessions.
  38. func (s *Storage) CreateSession(username, userAgent, ip string) (sessionID string, err error) {
  39. var userID int64
  40. err = s.db.QueryRow("SELECT id FROM users WHERE username = $1", username).Scan(&userID)
  41. if err != nil {
  42. return "", fmt.Errorf("unable to fetch UserID: %v", err)
  43. }
  44. token := helper.GenerateRandomString(64)
  45. query := "INSERT INTO sessions (token, user_id, user_agent, ip) VALUES ($1, $2, $3, $4)"
  46. _, err = s.db.Exec(query, token, userID, userAgent, ip)
  47. if err != nil {
  48. return "", fmt.Errorf("unable to create session: %v", err)
  49. }
  50. s.SetLastLogin(userID)
  51. return token, nil
  52. }
  53. // SessionByToken finds a session by the token.
  54. func (s *Storage) SessionByToken(token string) (*model.Session, error) {
  55. var session model.Session
  56. query := "SELECT id, user_id, token, created_at, user_agent, ip FROM sessions WHERE token = $1"
  57. err := s.db.QueryRow(query, token).Scan(
  58. &session.ID,
  59. &session.UserID,
  60. &session.Token,
  61. &session.CreatedAt,
  62. &session.UserAgent,
  63. &session.IP,
  64. )
  65. if err == sql.ErrNoRows {
  66. return nil, fmt.Errorf("session not found: %s", token)
  67. } else if err != nil {
  68. return nil, fmt.Errorf("unable to fetch session: %v", err)
  69. }
  70. return &session, nil
  71. }
  72. // RemoveSessionByToken remove a session by using the token.
  73. func (s *Storage) RemoveSessionByToken(userID int64, token string) error {
  74. result, err := s.db.Exec(`DELETE FROM sessions WHERE user_id=$1 AND token=$2`, userID, token)
  75. if err != nil {
  76. return fmt.Errorf("unable to remove this session: %v", err)
  77. }
  78. count, err := result.RowsAffected()
  79. if err != nil {
  80. return fmt.Errorf("unable to remove this session: %v", err)
  81. }
  82. if count != 1 {
  83. return fmt.Errorf("nothing has been removed")
  84. }
  85. return nil
  86. }
  87. // RemoveSessionByID remove a session by using the ID.
  88. func (s *Storage) RemoveSessionByID(userID, sessionID int64) error {
  89. result, err := s.db.Exec(`DELETE FROM sessions WHERE user_id=$1 AND id=$2`, userID, sessionID)
  90. if err != nil {
  91. return fmt.Errorf("unable to remove this session: %v", err)
  92. }
  93. count, err := result.RowsAffected()
  94. if err != nil {
  95. return fmt.Errorf("unable to remove this session: %v", err)
  96. }
  97. if count != 1 {
  98. return fmt.Errorf("nothing has been removed")
  99. }
  100. return nil
  101. }
  102. // FlushAllSessions removes all sessions from the database.
  103. func (s *Storage) FlushAllSessions() (err error) {
  104. _, err = s.db.Exec(`DELETE FROM sessions`)
  105. return
  106. }