diff --git a/store/datastore/repo_secret.go b/store/datastore/repo_secret.go new file mode 100644 index 000000000..6252c0bc8 --- /dev/null +++ b/store/datastore/repo_secret.go @@ -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 = ? +` diff --git a/store/datastore/repo_secret_test.go b/store/datastore/repo_secret_test.go new file mode 100644 index 000000000..945ed305f --- /dev/null +++ b/store/datastore/repo_secret_test.go @@ -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") + }) + }) +} diff --git a/store/datastore/secret.go b/store/datastore/secret.go index d25079a3d..3f3399c6e 100644 --- a/store/datastore/secret.go +++ b/store/datastore/secret.go @@ -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 + ) -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 -} + repoSecs, err := db.GetSecretList(repo) -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 + if err != nil { + return nil, err } - return meddler.Save(db, secretTable, sec) + + for _, secret := range repoSecs { + secrets = append(secrets, secret.Secret()) + } + + teamSecs, err := db.GetTeamSecretList(repo.Owner) + + if err != nil { + return nil, err + } + + for _, secret := range teamSecs { + secrets = append(secrets, secret.Secret()) + } + + return secrets, nil } - -func (db *datastore) DeleteSecret(sec *model.Secret) 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 = ? -` diff --git a/store/datastore/secret_test.go b/store/datastore/secret_test.go index 5de32f71e..c955ac0df 100644 --- a/store/datastore/secret_test.go +++ b/store/datastore/secret_test.go @@ -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, - Name: "foo", - Value: "bar", - Images: []string{"docker", "gcr"}, - Events: []string{"push", "tag"}, + g.It("Should list all secrets", func() { + teamSec := &model.TeamSecret{ + Key: "octocat", + Name: "foo", + 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") - }) }) } diff --git a/store/datastore/team_secret.go b/store/datastore/team_secret.go new file mode 100644 index 000000000..edf86b8ed --- /dev/null +++ b/store/datastore/team_secret.go @@ -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 = ? +` diff --git a/store/datastore/team_secret_test.go b/store/datastore/team_secret_test.go new file mode 100644 index 000000000..92beb42ef --- /dev/null +++ b/store/datastore/team_secret_test.go @@ -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") + }) + }) +} diff --git a/store/store.go b/store/store.go index 7c7e1de19..624ae58d0 100644 --- a/store/store.go +++ b/store/store.go @@ -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) }