registry.go 4.3 KB

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