registry.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. package gorm
  2. import (
  3. "github.com/porter-dev/porter/internal/encryption"
  4. "github.com/porter-dev/porter/internal/models"
  5. ints "github.com/porter-dev/porter/internal/models/integrations"
  6. "github.com/porter-dev/porter/internal/repository"
  7. "gorm.io/gorm"
  8. )
  9. // RegistryRepository uses gorm.DB for querying the database
  10. type RegistryRepository struct {
  11. db *gorm.DB
  12. key *[32]byte
  13. }
  14. // NewRegistryRepository returns a RegistryRepository which uses
  15. // gorm.DB for querying the database
  16. func NewRegistryRepository(db *gorm.DB, key *[32]byte) repository.RegistryRepository {
  17. return &RegistryRepository{db, key}
  18. }
  19. // CreateRegistry creates a new registry
  20. func (repo *RegistryRepository) CreateRegistry(reg *models.Registry) (*models.Registry, error) {
  21. err := repo.EncryptRegistryData(reg, repo.key)
  22. if err != nil {
  23. return nil, err
  24. }
  25. project := &models.Project{}
  26. if err := repo.db.Where("id = ?", reg.ProjectID).First(&project).Error; err != nil {
  27. return nil, err
  28. }
  29. assoc := repo.db.Model(&project).Association("Registries")
  30. if assoc.Error != nil {
  31. return nil, assoc.Error
  32. }
  33. if err := assoc.Append(reg); err != nil {
  34. return nil, err
  35. }
  36. // create a token cache by default
  37. assoc = repo.db.Model(reg).Association("TokenCache")
  38. if assoc.Error != nil {
  39. return nil, assoc.Error
  40. }
  41. if err := assoc.Append(&reg.TokenCache); err != nil {
  42. return nil, err
  43. }
  44. err = repo.DecryptRegistryData(reg, repo.key)
  45. if err != nil {
  46. return nil, err
  47. }
  48. return reg, nil
  49. }
  50. // ReadRegistry gets a registry specified by a unique id
  51. func (repo *RegistryRepository) ReadRegistry(projectID, regID uint) (*models.Registry, error) {
  52. reg := &models.Registry{}
  53. if err := repo.db.Preload("TokenCache").Where("project_id = ? AND id = ?", projectID, regID).First(&reg).Error; err != nil {
  54. return nil, err
  55. }
  56. repo.DecryptRegistryData(reg, repo.key)
  57. return reg, nil
  58. }
  59. func (repo *RegistryRepository) ReadRegistryByInfraID(projectID, infraID uint) (*models.Registry, error) {
  60. reg := &models.Registry{}
  61. if err := repo.db.Preload("TokenCache").Where("project_id = ? AND infra_id = ?", projectID, infraID).First(&reg).Error; err != nil {
  62. return nil, err
  63. }
  64. repo.DecryptRegistryData(reg, repo.key)
  65. return reg, nil
  66. }
  67. // ListRegistriesByProjectID finds all registries
  68. // for a given project id
  69. func (repo *RegistryRepository) ListRegistriesByProjectID(
  70. projectID uint,
  71. ) ([]*models.Registry, error) {
  72. regs := []*models.Registry{}
  73. if err := repo.db.Preload("TokenCache").Where("project_id = ?", projectID).Find(&regs).Error; err != nil {
  74. return nil, err
  75. }
  76. for _, reg := range regs {
  77. repo.DecryptRegistryData(reg, repo.key)
  78. }
  79. return regs, nil
  80. }
  81. // UpdateRegistry modifies an existing Registry in the database
  82. func (repo *RegistryRepository) UpdateRegistry(
  83. reg *models.Registry,
  84. ) (*models.Registry, error) {
  85. if err := repo.db.Save(reg).Error; err != nil {
  86. return nil, err
  87. }
  88. return reg, nil
  89. }
  90. // UpdateRegistryTokenCache updates the token cache for a registry
  91. func (repo *RegistryRepository) UpdateRegistryTokenCache(
  92. tokenCache *ints.RegTokenCache,
  93. ) (*models.Registry, error) {
  94. if tok := tokenCache.Token; len(tok) > 0 {
  95. cipherData, err := encryption.Encrypt(tok, repo.key)
  96. if err != nil {
  97. return nil, err
  98. }
  99. tokenCache.Token = cipherData
  100. }
  101. registry := &models.Registry{}
  102. if err := repo.db.Where("id = ?", tokenCache.RegistryID).First(&registry).Error; err != nil {
  103. return nil, err
  104. }
  105. registry.TokenCache.Token = tokenCache.Token
  106. registry.TokenCache.Expiry = tokenCache.Expiry
  107. if err := repo.db.Save(registry).Error; err != nil {
  108. return nil, err
  109. }
  110. return registry, nil
  111. }
  112. // DeleteRegistry removes a registry from the db
  113. func (repo *RegistryRepository) DeleteRegistry(
  114. reg *models.Registry,
  115. ) error {
  116. // clear TokenCache association
  117. assoc := repo.db.Model(reg).Association("TokenCache")
  118. if assoc.Error != nil {
  119. return assoc.Error
  120. }
  121. if err := assoc.Clear(); err != nil {
  122. return err
  123. }
  124. if err := repo.db.Where("id = ?", reg.ID).Delete(&models.Registry{}).Error; err != nil {
  125. return err
  126. }
  127. return nil
  128. }
  129. // EncryptRegistryData will encrypt the user's registry data before writing
  130. // to the DB
  131. func (repo *RegistryRepository) EncryptRegistryData(
  132. registry *models.Registry,
  133. key *[32]byte,
  134. ) error {
  135. if tok := registry.TokenCache.Token; len(tok) > 0 {
  136. cipherData, err := encryption.Encrypt(tok, key)
  137. if err != nil {
  138. return err
  139. }
  140. registry.TokenCache.Token = cipherData
  141. }
  142. return nil
  143. }
  144. // DecryptRegistryData will decrypt the user's registry data before returning it
  145. // from the DB
  146. func (repo *RegistryRepository) DecryptRegistryData(
  147. registry *models.Registry,
  148. key *[32]byte,
  149. ) error {
  150. if tok := registry.TokenCache.Token; len(tok) > 0 {
  151. plaintext, err := encryption.Decrypt(tok, key)
  152. if err != nil {
  153. return err
  154. }
  155. registry.TokenCache.Token = plaintext
  156. }
  157. return nil
  158. }