mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-20 23:46:49 +00:00
Integrated store layer for org secrets
This commit is contained in:
parent
0e424a2527
commit
889b88d38f
7 changed files with 371 additions and 110 deletions
53
store/datastore/repo_secret.go
Normal file
53
store/datastore/repo_secret.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package datastore
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
func (db *datastore) GetSecretList(repo *model.Repo) ([]*model.RepoSecret, error) {
|
||||
var secrets = []*model.RepoSecret{}
|
||||
var err = meddler.QueryAll(db, &secrets, rebind(secretListQuery), repo.ID)
|
||||
return secrets, err
|
||||
}
|
||||
|
||||
func (db *datastore) GetSecret(repo *model.Repo, name string) (*model.RepoSecret, error) {
|
||||
var secret = new(model.RepoSecret)
|
||||
var err = meddler.QueryRow(db, secret, rebind(secretNameQuery), repo.ID, name)
|
||||
return secret, err
|
||||
}
|
||||
|
||||
func (db *datastore) SetSecret(sec *model.RepoSecret) error {
|
||||
var got = new(model.RepoSecret)
|
||||
var err = meddler.QueryRow(db, got, rebind(secretNameQuery), sec.RepoID, sec.Name)
|
||||
if err == nil && got.ID != 0 {
|
||||
sec.ID = got.ID // update existing id
|
||||
}
|
||||
return meddler.Save(db, secretTable, sec)
|
||||
}
|
||||
|
||||
func (db *datastore) DeleteSecret(sec *model.RepoSecret) error {
|
||||
_, err := db.Exec(rebind(secretDeleteStmt), sec.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const secretTable = "secrets"
|
||||
|
||||
const secretListQuery = `
|
||||
SELECT *
|
||||
FROM secrets
|
||||
WHERE secret_repo_id = ?
|
||||
`
|
||||
|
||||
const secretNameQuery = `
|
||||
SELECT *
|
||||
FROM secrets
|
||||
WHERE secret_repo_id = ?
|
||||
AND secret_name = ?
|
||||
LIMIT 1;
|
||||
`
|
||||
|
||||
const secretDeleteStmt = `
|
||||
DELETE FROM secrets
|
||||
WHERE secret_id = ?
|
||||
`
|
94
store/datastore/repo_secret_test.go
Normal file
94
store/datastore/repo_secret_test.go
Normal file
|
@ -0,0 +1,94 @@
|
|||
package datastore
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func TestRepoSecrets(t *testing.T) {
|
||||
db := openTest()
|
||||
defer db.Close()
|
||||
|
||||
s := From(db)
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("RepoSecrets", func() {
|
||||
|
||||
// before each test be sure to purge the package
|
||||
// table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec(rebind("DELETE FROM secrets"))
|
||||
})
|
||||
|
||||
g.It("Should set and get a secret", func() {
|
||||
secret := &model.RepoSecret{
|
||||
RepoID: 1,
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
Images: []string{"docker", "gcr"},
|
||||
Events: []string{"push", "tag"},
|
||||
}
|
||||
err := s.SetSecret(secret)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(secret.ID != 0).IsTrue()
|
||||
|
||||
got, err := s.GetSecret(&model.Repo{ID: 1}, secret.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(got.Name).Equal(secret.Name)
|
||||
g.Assert(got.Value).Equal(secret.Value)
|
||||
g.Assert(got.Images).Equal(secret.Images)
|
||||
g.Assert(got.Events).Equal(secret.Events)
|
||||
})
|
||||
|
||||
g.It("Should update a secret", func() {
|
||||
secret := &model.RepoSecret{
|
||||
RepoID: 1,
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
}
|
||||
s.SetSecret(secret)
|
||||
secret.Value = "baz"
|
||||
s.SetSecret(secret)
|
||||
|
||||
got, err := s.GetSecret(&model.Repo{ID: 1}, secret.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(got.Name).Equal(secret.Name)
|
||||
g.Assert(got.Value).Equal(secret.Value)
|
||||
})
|
||||
|
||||
g.It("Should list secrets", func() {
|
||||
s.SetSecret(&model.RepoSecret{
|
||||
RepoID: 1,
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
})
|
||||
s.SetSecret(&model.RepoSecret{
|
||||
RepoID: 1,
|
||||
Name: "bar",
|
||||
Value: "baz",
|
||||
})
|
||||
secrets, err := s.GetSecretList(&model.Repo{ID: 1})
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(secrets)).Equal(2)
|
||||
})
|
||||
|
||||
g.It("Should delete a secret", func() {
|
||||
secret := &model.RepoSecret{
|
||||
RepoID: 1,
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
}
|
||||
s.SetSecret(secret)
|
||||
|
||||
_, err := s.GetSecret(&model.Repo{ID: 1}, secret.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
|
||||
err = s.DeleteSecret(secret)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
|
||||
_, err = s.GetSecret(&model.Repo{ID: 1}, secret.Name)
|
||||
g.Assert(err != nil).IsTrue("expect a no rows in result set error")
|
||||
})
|
||||
})
|
||||
}
|
|
@ -2,52 +2,32 @@ package datastore
|
|||
|
||||
import (
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
func (db *datastore) GetSecretList(repo *model.Repo) ([]*model.Secret, error) {
|
||||
var secrets = []*model.Secret{}
|
||||
var err = meddler.QueryAll(db, &secrets, rebind(secretListQuery), repo.ID)
|
||||
return secrets, err
|
||||
func (db *datastore) GetMergedSecretList(repo *model.Repo) ([]*model.Secret, error) {
|
||||
var (
|
||||
secrets []*model.Secret
|
||||
)
|
||||
|
||||
repoSecs, err := db.GetSecretList(repo)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (db *datastore) GetSecret(repo *model.Repo, name string) (*model.Secret, error) {
|
||||
var secret = new(model.Secret)
|
||||
var err = meddler.QueryRow(db, secret, rebind(secretNameQuery), repo.ID, name)
|
||||
return secret, err
|
||||
for _, secret := range repoSecs {
|
||||
secrets = append(secrets, secret.Secret())
|
||||
}
|
||||
|
||||
func (db *datastore) SetSecret(sec *model.Secret) error {
|
||||
var got = new(model.Secret)
|
||||
var err = meddler.QueryRow(db, got, rebind(secretNameQuery), sec.RepoID, sec.Name)
|
||||
if err == nil && got.ID != 0 {
|
||||
sec.ID = got.ID // update existing id
|
||||
}
|
||||
return meddler.Save(db, secretTable, sec)
|
||||
teamSecs, err := db.GetTeamSecretList(repo.Owner)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (db *datastore) DeleteSecret(sec *model.Secret) error {
|
||||
_, err := db.Exec(rebind(secretDeleteStmt), sec.ID)
|
||||
return err
|
||||
for _, secret := range teamSecs {
|
||||
secrets = append(secrets, secret.Secret())
|
||||
}
|
||||
|
||||
const secretTable = "secrets"
|
||||
|
||||
const secretListQuery = `
|
||||
SELECT *
|
||||
FROM secrets
|
||||
WHERE secret_repo_id = ?
|
||||
`
|
||||
|
||||
const secretNameQuery = `
|
||||
SELECT *
|
||||
FROM secrets
|
||||
WHERE secret_repo_id = ?
|
||||
AND secret_name = ?
|
||||
LIMIT 1;
|
||||
`
|
||||
|
||||
const secretDeleteStmt = `
|
||||
DELETE FROM secrets
|
||||
WHERE secret_id = ?
|
||||
`
|
||||
return secrets, nil
|
||||
}
|
||||
|
|
|
@ -19,76 +19,28 @@ func TestSecrets(t *testing.T) {
|
|||
// table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec(rebind("DELETE FROM secrets"))
|
||||
db.Exec(rebind("DELETE FROM team_secrets"))
|
||||
})
|
||||
|
||||
g.It("Should set and get a secret", func() {
|
||||
secret := &model.Secret{
|
||||
RepoID: 1,
|
||||
g.It("Should list all secrets", func() {
|
||||
teamSec := &model.TeamSecret{
|
||||
Key: "octocat",
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
Images: []string{"docker", "gcr"},
|
||||
Events: []string{"push", "tag"},
|
||||
Value: "team",
|
||||
}
|
||||
err := s.SetSecret(secret)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(secret.ID != 0).IsTrue()
|
||||
|
||||
got, err := s.GetSecret(&model.Repo{ID: 1}, secret.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(got.Name).Equal(secret.Name)
|
||||
g.Assert(got.Value).Equal(secret.Value)
|
||||
g.Assert(got.Images).Equal(secret.Images)
|
||||
g.Assert(got.Events).Equal(secret.Events)
|
||||
})
|
||||
|
||||
g.It("Should update a secret", func() {
|
||||
secret := &model.Secret{
|
||||
repoSec := &model.RepoSecret{
|
||||
RepoID: 1,
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
Value: "repo",
|
||||
}
|
||||
s.SetSecret(secret)
|
||||
secret.Value = "baz"
|
||||
s.SetSecret(secret)
|
||||
|
||||
got, err := s.GetSecret(&model.Repo{ID: 1}, secret.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(got.Name).Equal(secret.Name)
|
||||
g.Assert(got.Value).Equal(secret.Value)
|
||||
})
|
||||
s.SetSecret(repoSec)
|
||||
s.SetTeamSecret(teamSec)
|
||||
|
||||
g.It("Should list secrets", func() {
|
||||
s.SetSecret(&model.Secret{
|
||||
RepoID: 1,
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
})
|
||||
s.SetSecret(&model.Secret{
|
||||
RepoID: 1,
|
||||
Name: "bar",
|
||||
Value: "baz",
|
||||
})
|
||||
secrets, err := s.GetSecretList(&model.Repo{ID: 1})
|
||||
secrets, err := s.GetMergedSecretList(&model.Repo{ID: 1, Owner: "octocat"})
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(secrets)).Equal(2)
|
||||
})
|
||||
|
||||
g.It("Should delete a secret", func() {
|
||||
secret := &model.Secret{
|
||||
RepoID: 1,
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
}
|
||||
s.SetSecret(secret)
|
||||
|
||||
_, err := s.GetSecret(&model.Repo{ID: 1}, secret.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
|
||||
err = s.DeleteSecret(secret)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
|
||||
_, err = s.GetSecret(&model.Repo{ID: 1}, secret.Name)
|
||||
g.Assert(err != nil).IsTrue("expect a no rows in result set error")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
53
store/datastore/team_secret.go
Normal file
53
store/datastore/team_secret.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package datastore
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
func (db *datastore) GetTeamSecretList(team string) ([]*model.TeamSecret, error) {
|
||||
var secrets = []*model.TeamSecret{}
|
||||
var err = meddler.QueryAll(db, &secrets, rebind(teamSecretListQuery), team)
|
||||
return secrets, err
|
||||
}
|
||||
|
||||
func (db *datastore) GetTeamSecret(team, name string) (*model.TeamSecret, error) {
|
||||
var secret = new(model.TeamSecret)
|
||||
var err = meddler.QueryRow(db, secret, rebind(teamSecretNameQuery), team, name)
|
||||
return secret, err
|
||||
}
|
||||
|
||||
func (db *datastore) SetTeamSecret(sec *model.TeamSecret) error {
|
||||
var got = new(model.TeamSecret)
|
||||
var err = meddler.QueryRow(db, got, rebind(teamSecretNameQuery), sec.Key, sec.Name)
|
||||
if err == nil && got.ID != 0 {
|
||||
sec.ID = got.ID // update existing id
|
||||
}
|
||||
return meddler.Save(db, teamSecretTable, sec)
|
||||
}
|
||||
|
||||
func (db *datastore) DeleteTeamSecret(sec *model.TeamSecret) error {
|
||||
_, err := db.Exec(rebind(teamSecretDeleteStmt), sec.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const teamSecretTable = "team_secrets"
|
||||
|
||||
const teamSecretListQuery = `
|
||||
SELECT *
|
||||
FROM team_secrets
|
||||
WHERE team_secret_key = ?
|
||||
`
|
||||
|
||||
const teamSecretNameQuery = `
|
||||
SELECT *
|
||||
FROM team_secrets
|
||||
WHERE team_secret_key = ?
|
||||
AND team_secret_name = ?
|
||||
LIMIT 1;
|
||||
`
|
||||
|
||||
const teamSecretDeleteStmt = `
|
||||
DELETE FROM team_secrets
|
||||
WHERE team_secret_id = ?
|
||||
`
|
94
store/datastore/team_secret_test.go
Normal file
94
store/datastore/team_secret_test.go
Normal file
|
@ -0,0 +1,94 @@
|
|||
package datastore
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func TestTeamSecrets(t *testing.T) {
|
||||
db := openTest()
|
||||
defer db.Close()
|
||||
|
||||
s := From(db)
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("TeamSecrets", func() {
|
||||
|
||||
// before each test be sure to purge the package
|
||||
// table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec(rebind("DELETE FROM team_secrets"))
|
||||
})
|
||||
|
||||
g.It("Should set and get a secret", func() {
|
||||
secret := &model.TeamSecret{
|
||||
Key: "octocat",
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
Images: []string{"docker", "gcr"},
|
||||
Events: []string{"push", "tag"},
|
||||
}
|
||||
err := s.SetTeamSecret(secret)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(secret.ID != 0).IsTrue()
|
||||
|
||||
got, err := s.GetTeamSecret("octocat", secret.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(got.Name).Equal(secret.Name)
|
||||
g.Assert(got.Value).Equal(secret.Value)
|
||||
g.Assert(got.Images).Equal(secret.Images)
|
||||
g.Assert(got.Events).Equal(secret.Events)
|
||||
})
|
||||
|
||||
g.It("Should update a secret", func() {
|
||||
secret := &model.TeamSecret{
|
||||
Key: "octocat",
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
}
|
||||
s.SetTeamSecret(secret)
|
||||
secret.Value = "baz"
|
||||
s.SetTeamSecret(secret)
|
||||
|
||||
got, err := s.GetTeamSecret("octocat", secret.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(got.Name).Equal(secret.Name)
|
||||
g.Assert(got.Value).Equal(secret.Value)
|
||||
})
|
||||
|
||||
g.It("Should list secrets", func() {
|
||||
s.SetTeamSecret(&model.TeamSecret{
|
||||
Key: "octocat",
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
})
|
||||
s.SetTeamSecret(&model.TeamSecret{
|
||||
Key: "octocat",
|
||||
Name: "bar",
|
||||
Value: "baz",
|
||||
})
|
||||
secrets, err := s.GetTeamSecretList("octocat")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(secrets)).Equal(2)
|
||||
})
|
||||
|
||||
g.It("Should delete a secret", func() {
|
||||
secret := &model.TeamSecret{
|
||||
Key: "octocat",
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
}
|
||||
s.SetTeamSecret(secret)
|
||||
|
||||
_, err := s.GetTeamSecret("octocat", secret.Name)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
|
||||
err = s.DeleteTeamSecret(secret)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
|
||||
_, err = s.GetTeamSecret("octocat", secret.Name)
|
||||
g.Assert(err != nil).IsTrue("expect a no rows in result set error")
|
||||
})
|
||||
})
|
||||
}
|
|
@ -59,16 +59,31 @@ type Store interface {
|
|||
DeleteRepo(*model.Repo) error
|
||||
|
||||
// GetSecretList gets a list of repository secrets
|
||||
GetSecretList(*model.Repo) ([]*model.Secret, error)
|
||||
GetSecretList(*model.Repo) ([]*model.RepoSecret, error)
|
||||
|
||||
// GetSecret gets the named repository secret.
|
||||
GetSecret(*model.Repo, string) (*model.Secret, error)
|
||||
GetSecret(*model.Repo, string) (*model.RepoSecret, error)
|
||||
|
||||
// SetSecret sets the named repository secret.
|
||||
SetSecret(*model.Secret) error
|
||||
SetSecret(*model.RepoSecret) error
|
||||
|
||||
// DeleteSecret deletes the named repository secret.
|
||||
DeleteSecret(*model.Secret) error
|
||||
DeleteSecret(*model.RepoSecret) error
|
||||
|
||||
// GetTeamSecretList gets a list of team secrets
|
||||
GetTeamSecretList(string) ([]*model.TeamSecret, error)
|
||||
|
||||
// GetTeamSecret gets the named team secret.
|
||||
GetTeamSecret(string, string) (*model.TeamSecret, error)
|
||||
|
||||
// SetTeamSecret sets the named team secret.
|
||||
SetTeamSecret(*model.TeamSecret) error
|
||||
|
||||
// DeleteTeamSecret deletes the named team secret.
|
||||
DeleteTeamSecret(*model.TeamSecret) error
|
||||
|
||||
// GetMergedSecretList gets a list of repo and team secrets
|
||||
GetMergedSecretList(*model.Repo) ([]*model.Secret, error)
|
||||
|
||||
// GetBuild gets a build by unique ID.
|
||||
GetBuild(int64) (*model.Build, error)
|
||||
|
@ -202,22 +217,42 @@ func DeleteRepo(c context.Context, repo *model.Repo) error {
|
|||
return FromContext(c).DeleteRepo(repo)
|
||||
}
|
||||
|
||||
func GetSecretList(c context.Context, r *model.Repo) ([]*model.Secret, error) {
|
||||
func GetSecretList(c context.Context, r *model.Repo) ([]*model.RepoSecret, error) {
|
||||
return FromContext(c).GetSecretList(r)
|
||||
}
|
||||
|
||||
func GetSecret(c context.Context, r *model.Repo, name string) (*model.Secret, error) {
|
||||
func GetSecret(c context.Context, r *model.Repo, name string) (*model.RepoSecret, error) {
|
||||
return FromContext(c).GetSecret(r, name)
|
||||
}
|
||||
|
||||
func SetSecret(c context.Context, s *model.Secret) error {
|
||||
func SetSecret(c context.Context, s *model.RepoSecret) error {
|
||||
return FromContext(c).SetSecret(s)
|
||||
}
|
||||
|
||||
func DeleteSecret(c context.Context, s *model.Secret) error {
|
||||
func DeleteSecret(c context.Context, s *model.RepoSecret) error {
|
||||
return FromContext(c).DeleteSecret(s)
|
||||
}
|
||||
|
||||
func GetTeamSecretList(c context.Context, team string) ([]*model.TeamSecret, error) {
|
||||
return FromContext(c).GetTeamSecretList(team)
|
||||
}
|
||||
|
||||
func GetTeamSecret(c context.Context, team, name string) (*model.TeamSecret, error) {
|
||||
return FromContext(c).GetTeamSecret(team, name)
|
||||
}
|
||||
|
||||
func SetTeamSecret(c context.Context, s *model.TeamSecret) error {
|
||||
return FromContext(c).SetTeamSecret(s)
|
||||
}
|
||||
|
||||
func DeleteTeamSecret(c context.Context, s *model.TeamSecret) error {
|
||||
return FromContext(c).DeleteTeamSecret(s)
|
||||
}
|
||||
|
||||
func GetMergedSecretList(c context.Context, r *model.Repo) ([]*model.Secret, error) {
|
||||
return FromContext(c).GetMergedSecretList(r)
|
||||
}
|
||||
|
||||
func GetBuild(c context.Context, id int64) (*model.Build, error) {
|
||||
return FromContext(c).GetBuild(id)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue