Skip to content

Commit 84d9a73

Browse files
committed
feat(secrets): working storages for var groups
1 parent 62fe428 commit 84d9a73

File tree

9 files changed

+142
-58
lines changed

9 files changed

+142
-58
lines changed

api/projects/environment.go

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"github.com/semaphoreui/semaphore/api/helpers"
66
"github.com/semaphoreui/semaphore/db"
7+
"github.com/semaphoreui/semaphore/pkg/random"
78
"github.com/semaphoreui/semaphore/services/server"
89
"net/http"
910
)
@@ -27,44 +28,65 @@ func NewEnvironmentController(
2728
}
2829

2930
func (c *EnvironmentController) updateEnvironmentSecrets(env db.Environment) error {
31+
32+
errors := make([]error, 0)
33+
3034
for _, secret := range env.Secrets {
3135
err := secret.Validate()
3236
if err != nil {
37+
errors = append(errors, err)
3338
continue
3439
}
3540

3641
var key db.AccessKey
3742

3843
switch secret.Operation {
3944
case db.EnvironmentSecretCreate:
40-
key, err = c.accessKeyService.CreateAccessKey(db.AccessKey{
41-
Name: secret.Name,
42-
String: secret.Secret,
43-
EnvironmentID: &env.ID,
44-
ProjectID: &env.ProjectID,
45-
Type: db.AccessKeyString,
46-
Owner: secret.Type.GetAccessKeyOwner(),
45+
var sourceStorageKey *string
46+
if env.SecretStorageKeyPrefix != nil {
47+
tmp := *env.SecretStorageKeyPrefix + random.String(10)
48+
sourceStorageKey = &tmp
49+
}
50+
51+
key, err = c.accessKeyService.Create(db.AccessKey{
52+
Name: secret.Name,
53+
String: secret.Secret,
54+
EnvironmentID: &env.ID,
55+
ProjectID: &env.ProjectID,
56+
Type: db.AccessKeyString,
57+
Owner: secret.Type.GetAccessKeyOwner(),
58+
SourceStorageID: env.SecretStorageID,
59+
SourceStorageKey: sourceStorageKey,
4760
})
61+
62+
if err != nil {
63+
errors = append(errors, err)
64+
continue
65+
}
4866
case db.EnvironmentSecretDelete:
4967
key, err = c.accessKeyRepo.GetAccessKey(env.ProjectID, secret.ID)
5068

5169
if err != nil {
70+
errors = append(errors, err)
5271
continue
5372
}
5473

5574
if key.EnvironmentID == nil && *key.EnvironmentID == env.ID {
75+
errors = append(errors, err)
5676
continue
5777
}
5878

59-
err = c.accessKeyService.DeleteAccessKey(env.ProjectID, secret.ID)
79+
err = c.accessKeyService.Delete(env.ProjectID, secret.ID)
6080
case db.EnvironmentSecretUpdate:
6181
key, err = c.accessKeyRepo.GetAccessKey(env.ProjectID, secret.ID)
6282

6383
if err != nil {
84+
errors = append(errors, err)
6485
continue
6586
}
6687

6788
if key.EnvironmentID == nil && *key.EnvironmentID == env.ID {
89+
errors = append(errors, err)
6890
continue
6991
}
7092

@@ -80,10 +102,14 @@ func (c *EnvironmentController) updateEnvironmentSecrets(env db.Environment) err
80102
updateKey.OverrideSecret = true
81103
}
82104

83-
err = c.accessKeyService.UpdateAccessKey(updateKey)
105+
err = c.accessKeyService.Update(updateKey)
84106
}
85107
}
86108

109+
if len(errors) > 0 {
110+
return errors[0]
111+
}
112+
87113
return nil
88114
}
89115

api/projects/keys.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func (c *KeyController) AddKey(w http.ResponseWriter, r *http.Request) {
9898
return
9999
}
100100

101-
newKey, err := c.accessKeyService.CreateAccessKey(key)
101+
newKey, err := c.accessKeyService.Create(key)
102102

103103
if err != nil {
104104
helpers.WriteError(w, err)
@@ -150,7 +150,7 @@ func (c *KeyController) UpdateKey(w http.ResponseWriter, r *http.Request) {
150150
}
151151
}
152152

153-
err = c.accessKeyService.UpdateAccessKey(key)
153+
err = c.accessKeyService.Update(key)
154154
if err != nil {
155155
helpers.WriteError(w, err)
156156
return
@@ -171,7 +171,7 @@ func (c *KeyController) UpdateKey(w http.ResponseWriter, r *http.Request) {
171171
func (c *KeyController) RemoveKey(w http.ResponseWriter, r *http.Request) {
172172
key := helpers.GetFromContext(r, "accessKey").(db.AccessKey)
173173

174-
err := c.accessKeyService.DeleteAccessKey(*key.ProjectID, key.ID)
174+
err := c.accessKeyService.Delete(*key.ProjectID, key.ID)
175175
if errors.Is(err, db.ErrInvalidOperation) {
176176
helpers.WriteJSON(w, http.StatusBadRequest, map[string]any{
177177
"error": "Access Key is in use by one or more templates",

api/projects/projects.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func (c *ProjectsController) createDemoProject(projectID int, noneKeyID int, emp
8383
return
8484
}
8585

86-
vaultKey, err := c.accessKeyService.CreateAccessKey(db.AccessKey{
86+
vaultKey, err := c.accessKeyService.Create(db.AccessKey{
8787
Name: "Vault Password",
8888
Type: db.AccessKeyLoginPassword,
8989
ProjectID: &projectID,
@@ -343,7 +343,7 @@ func (c *ProjectsController) AddProject(w http.ResponseWriter, r *http.Request)
343343
return
344344
}
345345

346-
noneKey, err := c.accessKeyService.CreateAccessKey(db.AccessKey{
346+
noneKey, err := c.accessKeyService.Create(db.AccessKey{
347347
Name: "None",
348348
Type: db.AccessKeyNone,
349349
ProjectID: &body.ID,

api/projects/secret_storages.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (c *SecretStorageController) Update(w http.ResponseWriter, r *http.Request)
9393
return
9494
}
9595

96-
err := c.secretStorageService.UpdateSecretStorage(storage)
96+
err := c.secretStorageService.Update(storage)
9797
if err != nil {
9898
helpers.WriteError(w, err)
9999
return
@@ -125,7 +125,7 @@ func (c *SecretStorageController) Add(w http.ResponseWriter, r *http.Request) {
125125
return
126126
}
127127

128-
newStorage, err := c.secretRepo.CreateSecretStorage(storage)
128+
newStorage, err := c.secretStorageService.Create(storage)
129129

130130
if err != nil {
131131
helpers.WriteError(w, err)
@@ -151,7 +151,7 @@ func (c *SecretStorageController) Remove(w http.ResponseWriter, r *http.Request)
151151
return
152152
}
153153

154-
err = c.secretStorageService.DeleteSecretStorage(project.ID, storageID)
154+
err = c.secretStorageService.Delete(project.ID, storageID)
155155
if err != nil {
156156
helpers.WriteError(w, err)
157157
return

cli/cmd/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ func runService() {
8080
store,
8181
encryptionService,
8282
)
83-
secretStorageService := server.NewSecretStorageService(store, store)
84-
accessKeyService := server.NewAccessKeyService(store, secretStorageService, encryptionService)
83+
accessKeyService := server.NewAccessKeyService(store, encryptionService)
84+
secretStorageService := server.NewSecretStorageService(store, accessKeyService)
8585

8686
taskPool := tasks.CreateTaskPool(
8787
store,

db/sql/SqlDb.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,13 @@ func (d *SqlDb) Connect(_ string) {
402402
d.sql.AddTableWithName(db.Template{}, "project__template").SetKeys(true, "id")
403403
d.sql.AddTableWithName(db.User{}, "user").SetKeys(true, "id")
404404
d.sql.AddTableWithName(db.Session{}, "session").SetKeys(true, "id")
405+
406+
if d.GetDialect() == util.DbDriverSQLite {
407+
_, err = d.exec("PRAGMA foreign_keys = ON")
408+
if err != nil {
409+
panic(err)
410+
}
411+
}
405412
}
406413

407414
func (d *SqlDb) getObjectRefs(projectID int, objectProps db.ObjectProps, objectID int) (refs db.ObjectReferrers, err error) {

services/server/access_key_svc.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package server
33
import "github.com/semaphoreui/semaphore/db"
44

55
type AccessKeyService interface {
6-
UpdateAccessKey(key db.AccessKey) error
7-
CreateAccessKey(key db.AccessKey) (newKey db.AccessKey, err error)
8-
GetAccessKeys(projectID int, options db.GetAccessKeyOptions, params db.RetrieveQueryParams) ([]db.AccessKey, error)
9-
DeleteAccessKey(projectID int, keyID int) (err error)
6+
Update(key db.AccessKey) error
7+
Create(key db.AccessKey) (newKey db.AccessKey, err error)
8+
GetAll(projectID int, options db.GetAccessKeyOptions, params db.RetrieveQueryParams) ([]db.AccessKey, error)
9+
Delete(projectID int, keyID int) (err error)
1010
}
1111

1212
type AccessKeyServiceImpl struct {
@@ -17,17 +17,15 @@ type AccessKeyServiceImpl struct {
1717

1818
func NewAccessKeyService(
1919
accessKeyRepo db.AccessKeyManager,
20-
storageService SecretStorageService,
2120
encryptionService AccessKeyEncryptionService,
2221
) AccessKeyService {
2322
return &AccessKeyServiceImpl{
24-
accessKeyRepo: accessKeyRepo,
25-
encryptionService: encryptionService,
26-
secretStorageService: storageService,
23+
accessKeyRepo: accessKeyRepo,
24+
encryptionService: encryptionService,
2725
}
2826
}
2927

30-
func (s *AccessKeyServiceImpl) DeleteAccessKey(projectID int, keyID int) (err error) {
28+
func (s *AccessKeyServiceImpl) Delete(projectID int, keyID int) (err error) {
3129
key, err := s.accessKeyRepo.GetAccessKey(projectID, keyID)
3230
if err != nil {
3331
return
@@ -53,11 +51,17 @@ func (s *AccessKeyServiceImpl) DeleteAccessKey(projectID int, keyID int) (err er
5351
return
5452
}
5553

56-
func (s *AccessKeyServiceImpl) GetAccessKeys(projectID int, options db.GetAccessKeyOptions, params db.RetrieveQueryParams) ([]db.AccessKey, error) {
54+
func (s *AccessKeyServiceImpl) GetAll(projectID int, options db.GetAccessKeyOptions, params db.RetrieveQueryParams) ([]db.AccessKey, error) {
5755
return s.accessKeyRepo.GetAccessKeys(projectID, options, params)
5856
}
5957

60-
func (s *AccessKeyServiceImpl) CreateAccessKey(key db.AccessKey) (newKey db.AccessKey, err error) {
58+
func (s *AccessKeyServiceImpl) Create(key db.AccessKey) (newKey db.AccessKey, err error) {
59+
60+
err = key.Validate(true)
61+
if err != nil {
62+
return
63+
}
64+
6165
err = s.encryptionService.SerializeSecret(&key)
6266
if err != nil {
6367
return
@@ -67,7 +71,7 @@ func (s *AccessKeyServiceImpl) CreateAccessKey(key db.AccessKey) (newKey db.Acce
6771
return
6872
}
6973

70-
func (s *AccessKeyServiceImpl) UpdateAccessKey(key db.AccessKey) (err error) {
74+
func (s *AccessKeyServiceImpl) Update(key db.AccessKey) (err error) {
7175
if key.OverrideSecret {
7276
err = s.encryptionService.SerializeSecret(&key)
7377
if err != nil {

services/server/secret_storage_svc.go

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ package server
22

33
import (
44
"github.com/semaphoreui/semaphore/db"
5+
"github.com/semaphoreui/semaphore/pkg/random"
56
pro "github.com/semaphoreui/semaphore/pro/services/server"
67
)
78

89
type SecretStorageService interface {
910
GetSecretStorage(projectID int, storageID int) (db.SecretStorage, error)
10-
UpdateSecretStorage(storage db.SecretStorage) error
11-
DeleteSecretStorage(projectID int, storageID int) error
11+
Update(storage db.SecretStorage) error
12+
Delete(projectID int, storageID int) error
1213
GetSecretStorages(projectID int) ([]db.SecretStorage, error)
14+
Create(storage db.SecretStorage) (res db.SecretStorage, err error)
1315
}
1416

1517
func NewSecretStorageService(
@@ -27,21 +29,60 @@ type SecretStorageServiceImpl struct {
2729
accessKeyService AccessKeyService
2830
}
2931

30-
func (s *SecretStorageServiceImpl) DeleteSecretStorage(projectID int, storageID int) error {
31-
return s.secretStorageRepo.DeleteSecretStorage(projectID, storageID)
32+
func (s *SecretStorageServiceImpl) Delete(projectID int, storageID int) (err error) {
33+
err = s.secretStorageRepo.DeleteSecretStorage(projectID, storageID)
34+
if err != nil {
35+
return
36+
}
37+
38+
keys, err := s.accessKeyService.GetAll(projectID, db.GetAccessKeyOptions{
39+
Owner: db.AccessKeyVault,
40+
StorageID: &storageID,
41+
}, db.RetrieveQueryParams{})
42+
43+
if err != nil {
44+
return
45+
}
46+
47+
for _, key := range keys {
48+
err = s.accessKeyService.Delete(projectID, key.ID)
49+
}
50+
51+
return
3252
}
3353

3454
func (s *SecretStorageServiceImpl) GetSecretStorage(projectID int, storageID int) (res db.SecretStorage, err error) {
3555
return s.secretStorageRepo.GetSecretStorage(projectID, storageID)
3656
}
3757

38-
func (s *SecretStorageServiceImpl) UpdateSecretStorage(storage db.SecretStorage) (err error) {
58+
func (s *SecretStorageServiceImpl) Create(storage db.SecretStorage) (res db.SecretStorage, err error) {
59+
res, err = s.secretStorageRepo.CreateSecretStorage(storage)
60+
61+
if err != nil {
62+
return
63+
}
64+
65+
key := db.AccessKey{
66+
Name: random.String(10),
67+
Type: db.AccessKeyString,
68+
ProjectID: &storage.ProjectID,
69+
String: storage.VaultToken,
70+
Owner: db.AccessKeyVault,
71+
StorageID: &res.ID,
72+
}
73+
74+
_, err = s.accessKeyService.Create(key)
75+
76+
return
77+
}
78+
79+
func (s *SecretStorageServiceImpl) Update(storage db.SecretStorage) (err error) {
3980
err = s.secretStorageRepo.UpdateSecretStorage(storage)
4081
if err != nil {
4182
return
4283
}
4384

44-
keys, err := s.accessKeyService.GetAccessKeys(storage.ProjectID, db.GetAccessKeyOptions{
85+
keys, err := s.accessKeyService.GetAll(storage.ProjectID, db.GetAccessKeyOptions{
4586
Owner: db.AccessKeyVault,
4687
StorageID: &storage.ID,
4788
}, db.RetrieveQueryParams{})
@@ -52,15 +93,17 @@ func (s *SecretStorageServiceImpl) UpdateSecretStorage(storage db.SecretStorage)
5293

5394
if len(keys) == 0 {
5495
if storage.VaultToken != "" {
55-
_, err = s.accessKeyService.CreateAccessKey(db.AccessKey{
96+
_, err = s.accessKeyService.Create(db.AccessKey{
97+
Name: random.String(10),
5698
Type: db.AccessKeyString,
5799
ProjectID: &storage.ProjectID,
58-
Secret: nil,
59100
String: storage.VaultToken,
60101
Owner: db.AccessKeyVault,
61-
Plain: nil,
62102
StorageID: &storage.ID,
63103
})
104+
} else {
105+
// empty vault token means the user didn't set a new token,
106+
// so we don't create a new access key.
64107
}
65108
} else {
66109
vault := keys[0]
@@ -72,7 +115,7 @@ func (s *SecretStorageServiceImpl) UpdateSecretStorage(storage db.SecretStorage)
72115
} else {
73116
vault.OverrideSecret = true
74117
vault.String = storage.VaultToken
75-
err = s.accessKeyService.UpdateAccessKey(vault)
118+
err = s.accessKeyService.Update(vault)
76119
}
77120
}
78121

0 commit comments

Comments
 (0)