upstash.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package gorm
  2. import (
  3. "context"
  4. "github.com/porter-dev/porter/internal/encryption"
  5. ints "github.com/porter-dev/porter/internal/models/integrations"
  6. "github.com/porter-dev/porter/internal/repository"
  7. "github.com/porter-dev/porter/internal/telemetry"
  8. "gorm.io/gorm"
  9. )
  10. // UpstashIntegrationRepository is a repository that manages upstash integrations
  11. type UpstashIntegrationRepository struct {
  12. db *gorm.DB
  13. key *[32]byte
  14. }
  15. // NewUpstashIntegrationRepository returns a UpstashIntegrationRepository
  16. func NewUpstashIntegrationRepository(db *gorm.DB, key *[32]byte) repository.UpstashIntegrationRepository {
  17. return &UpstashIntegrationRepository{db, key}
  18. }
  19. // Insert creates a new upstash integration
  20. func (repo *UpstashIntegrationRepository) Insert(
  21. ctx context.Context, upstashInt ints.UpstashIntegration,
  22. ) (ints.UpstashIntegration, error) {
  23. ctx, span := telemetry.NewSpan(ctx, "gorm-create-upstash-integration")
  24. defer span.End()
  25. var created ints.UpstashIntegration
  26. encrypted, err := repo.EncryptUpstashIntegration(upstashInt, repo.key)
  27. if err != nil {
  28. return created, telemetry.Error(ctx, span, err, "failed to encrypt")
  29. }
  30. if err := repo.db.Create(&encrypted).Error; err != nil {
  31. return created, telemetry.Error(ctx, span, err, "failed to create upstash integration")
  32. }
  33. return created, nil
  34. }
  35. // Integrations returns all upstash integrations for a given project
  36. func (repo *UpstashIntegrationRepository) Integrations(
  37. ctx context.Context, projectID uint,
  38. ) ([]ints.UpstashIntegration, error) {
  39. ctx, span := telemetry.NewSpan(ctx, "gorm-list-upstash-integrations")
  40. defer span.End()
  41. var integrations []ints.UpstashIntegration
  42. if err := repo.db.Where("project_id = ?", projectID).Find(&integrations).Error; err != nil {
  43. return integrations, telemetry.Error(ctx, span, err, "failed to list upstash integrations")
  44. }
  45. for i, integration := range integrations {
  46. decrypted, err := repo.DecryptUpstashIntegration(integration, repo.key)
  47. if err != nil {
  48. return integrations, telemetry.Error(ctx, span, err, "failed to decrypt")
  49. }
  50. integrations[i] = decrypted
  51. }
  52. return integrations, nil
  53. }
  54. // EncryptUpstashIntegration will encrypt the upstash integration data before
  55. // writing to the DB
  56. func (repo *UpstashIntegrationRepository) EncryptUpstashIntegration(
  57. upstashInt ints.UpstashIntegration,
  58. key *[32]byte,
  59. ) (ints.UpstashIntegration, error) {
  60. encrypted := upstashInt
  61. if len(encrypted.ClientID) > 0 {
  62. cipherData, err := encryption.Encrypt(encrypted.ClientID, key)
  63. if err != nil {
  64. return encrypted, err
  65. }
  66. encrypted.ClientID = cipherData
  67. }
  68. if len(encrypted.AccessToken) > 0 {
  69. cipherData, err := encryption.Encrypt(encrypted.AccessToken, key)
  70. if err != nil {
  71. return encrypted, err
  72. }
  73. encrypted.AccessToken = cipherData
  74. }
  75. if len(encrypted.RefreshToken) > 0 {
  76. cipherData, err := encryption.Encrypt(encrypted.RefreshToken, key)
  77. if err != nil {
  78. return encrypted, err
  79. }
  80. encrypted.RefreshToken = cipherData
  81. }
  82. if len(encrypted.DeveloperApiKey) > 0 {
  83. cipherData, err := encryption.Encrypt(encrypted.DeveloperApiKey, key)
  84. if err != nil {
  85. return encrypted, err
  86. }
  87. encrypted.DeveloperApiKey = cipherData
  88. }
  89. return encrypted, nil
  90. }
  91. // DecryptUpstashIntegration will decrypt the upstash integration data before
  92. // returning it from the DB
  93. func (repo *UpstashIntegrationRepository) DecryptUpstashIntegration(
  94. upstashInt ints.UpstashIntegration,
  95. key *[32]byte,
  96. ) (ints.UpstashIntegration, error) {
  97. decrypted := upstashInt
  98. if len(decrypted.ClientID) > 0 {
  99. plaintext, err := encryption.Decrypt(decrypted.ClientID, key)
  100. if err != nil {
  101. return decrypted, err
  102. }
  103. decrypted.ClientID = plaintext
  104. }
  105. if len(decrypted.AccessToken) > 0 {
  106. plaintext, err := encryption.Decrypt(decrypted.AccessToken, key)
  107. if err != nil {
  108. return decrypted, err
  109. }
  110. decrypted.AccessToken = plaintext
  111. }
  112. if len(decrypted.RefreshToken) > 0 {
  113. plaintext, err := encryption.Decrypt(decrypted.RefreshToken, key)
  114. if err != nil {
  115. return decrypted, err
  116. }
  117. decrypted.RefreshToken = plaintext
  118. }
  119. if len(decrypted.DeveloperApiKey) > 0 {
  120. plaintext, err := encryption.Decrypt(decrypted.DeveloperApiKey, key)
  121. if err != nil {
  122. return decrypted, err
  123. }
  124. decrypted.DeveloperApiKey = plaintext
  125. }
  126. return decrypted, nil
  127. }