api_key.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package storage // import "miniflux.app/v2/internal/storage"
  4. import (
  5. "errors"
  6. "fmt"
  7. "miniflux.app/v2/internal/crypto"
  8. "miniflux.app/v2/internal/model"
  9. )
  10. var ErrAPIKeyNotFound = errors.New("store: API Key not found")
  11. // APIKeyExists checks if an API Key with the same description exists.
  12. func (s *Storage) APIKeyExists(userID int64, description string) bool {
  13. var result bool
  14. query := `SELECT true FROM api_keys WHERE user_id=$1 AND lower(description)=lower($2) LIMIT 1`
  15. s.db.QueryRow(query, userID, description).Scan(&result)
  16. return result
  17. }
  18. // SetAPIKeyUsedTimestamp updates the last used date of an API Key.
  19. func (s *Storage) SetAPIKeyUsedTimestamp(userID int64, token string) error {
  20. query := `UPDATE api_keys SET last_used_at=now() WHERE user_id=$1 and token=$2`
  21. _, err := s.db.Exec(query, userID, token)
  22. if err != nil {
  23. return fmt.Errorf(`store: unable to update last used date for API key: %v`, err)
  24. }
  25. return nil
  26. }
  27. // APIKeys returns all API Keys that belongs to the given user.
  28. func (s *Storage) APIKeys(userID int64) (model.APIKeys, error) {
  29. query := `
  30. SELECT
  31. id, user_id, token, description, last_used_at, created_at
  32. FROM
  33. api_keys
  34. WHERE
  35. user_id=$1
  36. ORDER BY description ASC
  37. `
  38. rows, err := s.db.Query(query, userID)
  39. if err != nil {
  40. return nil, fmt.Errorf(`store: unable to fetch API Keys: %v`, err)
  41. }
  42. defer rows.Close()
  43. apiKeys := make(model.APIKeys, 0)
  44. for rows.Next() {
  45. var apiKey model.APIKey
  46. if err := rows.Scan(
  47. &apiKey.ID,
  48. &apiKey.UserID,
  49. &apiKey.Token,
  50. &apiKey.Description,
  51. &apiKey.LastUsedAt,
  52. &apiKey.CreatedAt,
  53. ); err != nil {
  54. return nil, fmt.Errorf(`store: unable to fetch API Key row: %v`, err)
  55. }
  56. apiKeys = append(apiKeys, apiKey)
  57. }
  58. return apiKeys, nil
  59. }
  60. // CreateAPIKey inserts a new API key.
  61. func (s *Storage) CreateAPIKey(userID int64, description string) (*model.APIKey, error) {
  62. query := `
  63. INSERT INTO api_keys
  64. (user_id, token, description)
  65. VALUES
  66. ($1, $2, $3)
  67. RETURNING
  68. id, user_id, token, description, last_used_at, created_at
  69. `
  70. var apiKey model.APIKey
  71. err := s.db.QueryRow(
  72. query,
  73. userID,
  74. crypto.GenerateRandomStringHex(32),
  75. description,
  76. ).Scan(
  77. &apiKey.ID,
  78. &apiKey.UserID,
  79. &apiKey.Token,
  80. &apiKey.Description,
  81. &apiKey.LastUsedAt,
  82. &apiKey.CreatedAt,
  83. )
  84. if err != nil {
  85. return nil, fmt.Errorf(`store: unable to create API Key: %v`, err)
  86. }
  87. return &apiKey, nil
  88. }
  89. // DeleteAPIKey deletes an API Key.
  90. func (s *Storage) DeleteAPIKey(userID, keyID int64) error {
  91. result, err := s.db.Exec(`DELETE FROM api_keys WHERE id = $1 AND user_id = $2`, keyID, userID)
  92. if err != nil {
  93. return fmt.Errorf(`store: unable to delete this API Key: %v`, err)
  94. }
  95. count, err := result.RowsAffected()
  96. if err != nil {
  97. return fmt.Errorf(`store: unable to delete this API Key: %v`, err)
  98. }
  99. if count == 0 {
  100. return ErrAPIKeyNotFound
  101. }
  102. return nil
  103. }