mirror of https://github.com/harness/drone.git
address comments
parent
c1ebb1837a
commit
d1d50377fc
|
@ -90,10 +90,8 @@ func getSanitizedMachineName() (string, error) {
|
|||
// ProvideDatabaseConfig loads the database config from the main config.
|
||||
func ProvideDatabaseConfig(config *types.Config) database.Config {
|
||||
return database.Config{
|
||||
Driver: config.Database.Driver,
|
||||
Datasource: config.Database.Datasource,
|
||||
Secret: config.Database.Secret,
|
||||
EncryptMixedContent: config.Database.EncryptMixedContent,
|
||||
Driver: config.Database.Driver,
|
||||
Datasource: config.Database.Datasource,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"context"
|
||||
|
||||
cliserver "github.com/harness/gitness/cli/server"
|
||||
"github.com/harness/gitness/encrypt"
|
||||
"github.com/harness/gitness/events"
|
||||
"github.com/harness/gitness/gitrpc"
|
||||
gitrpcserver "github.com/harness/gitness/gitrpc/server"
|
||||
|
@ -82,6 +83,7 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
|
|||
gitrpc.WireSet,
|
||||
store.WireSet,
|
||||
check.WireSet,
|
||||
encrypt.WireSet,
|
||||
cliserver.ProvideEventsConfig,
|
||||
events.WireSet,
|
||||
cliserver.ProvideWebhookConfig,
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/harness/gitness/cli/server"
|
||||
"github.com/harness/gitness/encrypt"
|
||||
"github.com/harness/gitness/events"
|
||||
"github.com/harness/gitness/gitrpc"
|
||||
server3 "github.com/harness/gitness/gitrpc/server"
|
||||
|
@ -94,7 +95,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
secretStore := database.ProvideSecretStore(db)
|
||||
spaceController := space.ProvideController(db, provider, pathUID, authorizer, pathStore, pipelineStore, secretStore, spaceStore, repoStore, principalStore, repoController, membershipStore)
|
||||
pipelineController := pipeline.ProvideController(db, pathUID, pathStore, repoStore, authorizer, pipelineStore, spaceStore)
|
||||
encrypter, err := database.ProvideEncryptor(databaseConfig)
|
||||
encrypter, err := encrypt.ProvideEncrypter(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package encrypt
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
|
@ -68,3 +69,16 @@ func (e *Aesgcm) Decrypt(ciphertext []byte) (string, error) {
|
|||
}
|
||||
return string(plaintext), err
|
||||
}
|
||||
|
||||
// New provides a new aesgcm encrypter
|
||||
func New(key string, compat bool) (Encrypter, error) {
|
||||
if len(key) != 32 {
|
||||
return nil, errKeySize
|
||||
}
|
||||
b := []byte(key)
|
||||
block, err := aes.NewCipher(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Aesgcm{block: block, Compat: compat}, nil
|
||||
}
|
||||
|
|
|
@ -5,33 +5,16 @@
|
|||
package encrypt
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// indicates key size is too small.
|
||||
var errKeySize = errors.New("encryption key must be 32 bytes")
|
||||
|
||||
// Encrypter provides database field encryption and decryption.
|
||||
// Encrypter provides field encryption and decryption.
|
||||
// Encrypted values are currently limited to strings, which is
|
||||
// reflected in the interface design.
|
||||
type Encrypter interface {
|
||||
Encrypt(plaintext string) ([]byte, error)
|
||||
Decrypt(ciphertext []byte) (string, error)
|
||||
}
|
||||
|
||||
// New provides a new database field encrypter.
|
||||
func New(key string) (Encrypter, error) {
|
||||
if key == "" {
|
||||
return &none{}, nil
|
||||
}
|
||||
if len(key) != 32 {
|
||||
return nil, errKeySize
|
||||
}
|
||||
b := []byte(key)
|
||||
block, err := aes.NewCipher(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Aesgcm{block: block}, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package encrypt
|
||||
|
||||
import (
|
||||
"github.com/harness/gitness/types"
|
||||
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
// WireSet provides a wire set for this package.
|
||||
var WireSet = wire.NewSet(
|
||||
ProvideEncrypter,
|
||||
)
|
||||
|
||||
func ProvideEncrypter(config *types.Config) (Encrypter, error) {
|
||||
if config.Encrypter.Secret == "" {
|
||||
return &none{}, nil
|
||||
}
|
||||
return New(config.Encrypter.Secret, config.Encrypter.EncryptMixedContent)
|
||||
}
|
|
@ -39,18 +39,17 @@ func (c *Controller) List(
|
|||
var executions []*types.Execution
|
||||
|
||||
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) (err error) {
|
||||
var dbErr error
|
||||
count, dbErr = c.executionStore.Count(ctx, pipeline.ID)
|
||||
if dbErr != nil {
|
||||
count, err = c.executionStore.Count(ctx, pipeline.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to count child executions: %w", err)
|
||||
}
|
||||
|
||||
executions, dbErr = c.executionStore.List(ctx, pipeline.ID, pagination)
|
||||
if dbErr != nil {
|
||||
executions, err = c.executionStore.List(ctx, pipeline.ID, pagination)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list child executions: %w", err)
|
||||
}
|
||||
|
||||
return dbErr
|
||||
return
|
||||
}, dbtx.TxDefaultReadOnly)
|
||||
if err != nil {
|
||||
return executions, count, fmt.Errorf("failed to fetch list: %w", err)
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
apiauth "github.com/harness/gitness/internal/api/auth"
|
||||
"github.com/harness/gitness/internal/api/usererror"
|
||||
"github.com/harness/gitness/internal/auth"
|
||||
"github.com/harness/gitness/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/check"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
@ -50,33 +49,24 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea
|
|||
}
|
||||
|
||||
var secret *types.Secret
|
||||
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) error {
|
||||
// lock parent space path to ensure it doesn't get updated while we setup new pipeline
|
||||
_, err := c.pathStore.FindPrimaryWithLock(ctx, enum.PathTargetTypeSpace, parentSpace.ID)
|
||||
if err != nil {
|
||||
return usererror.BadRequest("Parent not found")
|
||||
}
|
||||
|
||||
now := time.Now().UnixMilli()
|
||||
secret = &types.Secret{
|
||||
Description: in.Description,
|
||||
Data: in.Data,
|
||||
SpaceID: parentSpace.ID,
|
||||
UID: in.UID,
|
||||
Created: now,
|
||||
Updated: now,
|
||||
Version: 0,
|
||||
}
|
||||
secret, err = enc(c.encrypter, secret)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not encrypt secret: %w", err)
|
||||
}
|
||||
err = c.secretStore.Create(ctx, secret)
|
||||
if err != nil {
|
||||
return fmt.Errorf("secret creation failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
now := time.Now().UnixMilli()
|
||||
secret = &types.Secret{
|
||||
Description: in.Description,
|
||||
Data: in.Data,
|
||||
SpaceID: parentSpace.ID,
|
||||
UID: in.UID,
|
||||
Created: now,
|
||||
Updated: now,
|
||||
Version: 0,
|
||||
}
|
||||
secret, err = enc(c.encrypter, secret)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not encrypt secret: %w", err)
|
||||
}
|
||||
err = c.secretStore.Create(ctx, secret)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("secret creation failed: %w", err)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ func (c *Controller) Update(
|
|||
if in.Data != "" {
|
||||
data, err := c.encrypter.Encrypt(original.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("could not encrypt secret: %w", err)
|
||||
}
|
||||
original.Data = string(data)
|
||||
}
|
||||
|
|
|
@ -19,14 +19,14 @@ func (c *Controller) ListPipelines(
|
|||
ctx context.Context,
|
||||
session *auth.Session,
|
||||
spaceRef string,
|
||||
pagination types.Pagination,
|
||||
filter types.ListQueryFilter,
|
||||
) ([]*types.Pipeline, int64, error) {
|
||||
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to find parent space: %w", err)
|
||||
}
|
||||
|
||||
err = apiauth.CheckSpace(ctx, c.authorizer, session, space, enum.PermissionSpaceView, true)
|
||||
err = apiauth.CheckSpace(ctx, c.authorizer, session, space, enum.PermissionPipelineView, false)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("could not authorize: %w", err)
|
||||
}
|
||||
|
@ -35,16 +35,14 @@ func (c *Controller) ListPipelines(
|
|||
var pipelines []*types.Pipeline
|
||||
|
||||
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) (err error) {
|
||||
count, err = c.pipelineStore.Count(ctx, space.ID, pagination)
|
||||
count, err = c.pipelineStore.Count(ctx, space.ID, filter)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to count child executions: %w", err)
|
||||
return
|
||||
return fmt.Errorf("failed to count child executions: %w", err)
|
||||
}
|
||||
|
||||
pipelines, err = c.pipelineStore.List(ctx, space.ID, pagination)
|
||||
pipelines, err = c.pipelineStore.List(ctx, space.ID, filter)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to count child executions: %w", err)
|
||||
return
|
||||
return fmt.Errorf("failed to count child executions: %w", err)
|
||||
}
|
||||
return
|
||||
}, dbtx.TxDefaultReadOnly)
|
||||
|
|
|
@ -19,14 +19,14 @@ func (c *Controller) ListSecrets(
|
|||
ctx context.Context,
|
||||
session *auth.Session,
|
||||
spaceRef string,
|
||||
pagination types.Pagination,
|
||||
filter types.ListQueryFilter,
|
||||
) ([]*types.Secret, int64, error) {
|
||||
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to find parent space: %w", err)
|
||||
}
|
||||
|
||||
err = apiauth.CheckSpace(ctx, c.authorizer, session, space, enum.PermissionSpaceView, true)
|
||||
err = apiauth.CheckSpace(ctx, c.authorizer, session, space, enum.PermissionSecretView, false)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("could not authorize: %w", err)
|
||||
}
|
||||
|
@ -35,16 +35,14 @@ func (c *Controller) ListSecrets(
|
|||
var secrets []*types.Secret
|
||||
|
||||
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) (err error) {
|
||||
count, err = c.secretStore.Count(ctx, space.ID, pagination)
|
||||
count, err = c.secretStore.Count(ctx, space.ID, filter)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to count child executions: %w", err)
|
||||
return
|
||||
return fmt.Errorf("failed to count child executions: %w", err)
|
||||
}
|
||||
|
||||
secrets, err = c.secretStore.List(ctx, space.ID, pagination)
|
||||
secrets, err = c.secretStore.List(ctx, space.ID, filter)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to list child executions: %w", err)
|
||||
return
|
||||
return fmt.Errorf("failed to list child executions: %w", err)
|
||||
}
|
||||
return
|
||||
}, dbtx.TxDefaultReadOnly)
|
||||
|
|
|
@ -22,14 +22,14 @@ func HandleListPipelines(spaceCtrl *space.Controller) http.HandlerFunc {
|
|||
return
|
||||
}
|
||||
|
||||
pagination := request.ParsePaginationFromRequest(r)
|
||||
repos, totalCount, err := spaceCtrl.ListPipelines(ctx, session, spaceRef, pagination)
|
||||
filter := request.ParseListQueryFilterFromRequest(r)
|
||||
repos, totalCount, err := spaceCtrl.ListPipelines(ctx, session, spaceRef, filter)
|
||||
if err != nil {
|
||||
render.TranslatedUserError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
render.Pagination(r, w, pagination.Page, pagination.Page, int(totalCount))
|
||||
render.Pagination(r, w, filter.Page, filter.Size, int(totalCount))
|
||||
render.JSON(w, http.StatusOK, repos)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ func HandleListSecrets(spaceCtrl *space.Controller) http.HandlerFunc {
|
|||
return
|
||||
}
|
||||
|
||||
pagination := request.ParsePaginationFromRequest(r)
|
||||
ret, totalCount, err := spaceCtrl.ListSecrets(ctx, session, spaceRef, pagination)
|
||||
filter := request.ParseListQueryFilterFromRequest(r)
|
||||
ret, totalCount, err := spaceCtrl.ListSecrets(ctx, session, spaceRef, filter)
|
||||
if err != nil {
|
||||
render.TranslatedUserError(w, err)
|
||||
return
|
||||
|
@ -36,7 +36,7 @@ func HandleListSecrets(spaceCtrl *space.Controller) http.HandlerFunc {
|
|||
secrets = append(secrets, *s.CopyWithoutData())
|
||||
}
|
||||
|
||||
render.Pagination(r, w, pagination.Page, pagination.Size, int(totalCount))
|
||||
render.Pagination(r, w, filter.Page, filter.Size, int(totalCount))
|
||||
render.JSON(w, http.StatusOK, secrets)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,13 +10,12 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
PipelinePathRef = "pipeline_ref"
|
||||
PipelineUID = "pipeline_uid"
|
||||
ExecutionNumber = "execution_number"
|
||||
PathParamPipelineRef = "pipeline_ref"
|
||||
PathParamExecutionNumber = "execution_number"
|
||||
)
|
||||
|
||||
func GetPipelineRefFromPath(r *http.Request) (string, error) {
|
||||
rawRef, err := PathParamOrError(r, PipelinePathRef)
|
||||
rawRef, err := PathParamOrError(r, PathParamPipelineRef)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -26,5 +25,5 @@ func GetPipelineRefFromPath(r *http.Request) (string, error) {
|
|||
}
|
||||
|
||||
func GetExecutionNumberFromPath(r *http.Request) (int64, error) {
|
||||
return PathParamAsPositiveInt64(r, ExecutionNumber)
|
||||
return PathParamAsPositiveInt64(r, PathParamExecutionNumber)
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
SecretRef = "secret_ref"
|
||||
PathParamSecretRef = "secret_ref"
|
||||
)
|
||||
|
||||
func GetSecretRefFromPath(r *http.Request) (string, error) {
|
||||
rawRef, err := PathParamOrError(r, SecretRef)
|
||||
rawRef, err := PathParamOrError(r, PathParamSecretRef)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -205,13 +205,18 @@ func ParseSort(r *http.Request) string {
|
|||
return r.URL.Query().Get(QueryParamSort)
|
||||
}
|
||||
|
||||
// ParsePaginationFromRequest extracts the pagination info from the url.
|
||||
// ParsePaginationFromRequest parses pagination related info from the url.
|
||||
func ParsePaginationFromRequest(r *http.Request) types.Pagination {
|
||||
return types.Pagination{
|
||||
Page: ParsePage(r),
|
||||
Size: ParseLimit(r),
|
||||
Query: ParseQuery(r),
|
||||
Sort: ParseSort(r),
|
||||
Order: ParseOrder(r),
|
||||
Page: ParsePage(r),
|
||||
Size: ParseLimit(r),
|
||||
}
|
||||
}
|
||||
|
||||
// ParseListQueryFilterFromRequest parses pagination and query related info from the url.
|
||||
func ParseListQueryFilterFromRequest(r *http.Request) types.ListQueryFilter {
|
||||
return types.ListQueryFilter{
|
||||
Query: ParseQuery(r),
|
||||
Pagination: ParsePaginationFromRequest(r),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -286,7 +286,7 @@ func setupPipelines(r chi.Router, pipelineCtrl *pipeline.Controller, executionCt
|
|||
r.Route("/pipelines", func(r chi.Router) {
|
||||
// Create takes path and parentId via body, not uri
|
||||
r.Post("/", handlerpipeline.HandleCreate(pipelineCtrl))
|
||||
r.Route(fmt.Sprintf("/{%s}", request.PipelinePathRef), func(r chi.Router) {
|
||||
r.Route(fmt.Sprintf("/{%s}", request.PathParamPipelineRef), func(r chi.Router) {
|
||||
r.Get("/", handlerpipeline.HandleFind(pipelineCtrl))
|
||||
r.Patch("/", handlerpipeline.HandleUpdate(pipelineCtrl))
|
||||
r.Delete("/", handlerpipeline.HandleDelete(pipelineCtrl))
|
||||
|
@ -299,7 +299,7 @@ func setupSecrets(r chi.Router, secretCtrl *secret.Controller) {
|
|||
r.Route("/secrets", func(r chi.Router) {
|
||||
// Create takes path and parentId via body, not uri
|
||||
r.Post("/", handlersecret.HandleCreate(secretCtrl))
|
||||
r.Route(fmt.Sprintf("/{%s}", request.SecretRef), func(r chi.Router) {
|
||||
r.Route(fmt.Sprintf("/{%s}", request.PathParamSecretRef), func(r chi.Router) {
|
||||
r.Get("/", handlersecret.HandleFind(secretCtrl))
|
||||
r.Patch("/", handlersecret.HandleUpdate(secretCtrl))
|
||||
r.Delete("/", handlersecret.HandleDelete(secretCtrl))
|
||||
|
@ -311,7 +311,7 @@ func setupExecutions(r chi.Router, pipelineCtrl *pipeline.Controller, executionC
|
|||
r.Route("/executions", func(r chi.Router) {
|
||||
r.Get("/", handlerexecution.HandleList(executionCtrl))
|
||||
r.Post("/", handlerexecution.HandleCreate(executionCtrl))
|
||||
r.Route(fmt.Sprintf("/{%s}", request.ExecutionNumber), func(r chi.Router) {
|
||||
r.Route(fmt.Sprintf("/{%s}", request.PathParamExecutionNumber), func(r chi.Router) {
|
||||
r.Get("/", handlerexecution.HandleFind(executionCtrl))
|
||||
r.Patch("/", handlerexecution.HandleUpdate(executionCtrl))
|
||||
r.Delete("/", handlerexecution.HandleDelete(executionCtrl))
|
||||
|
|
|
@ -453,7 +453,7 @@ type (
|
|||
Update(ctx context.Context, pipeline *types.Pipeline) error
|
||||
|
||||
// List lists the pipelines present in a parent space ID in the datastore.
|
||||
List(ctx context.Context, spaceID int64, pagination types.Pagination) ([]*types.Pipeline, error)
|
||||
List(ctx context.Context, spaceID int64, pagination types.ListQueryFilter) ([]*types.Pipeline, error)
|
||||
|
||||
// UpdateOptLock updates the pipeline using the optimistic locking mechanism.
|
||||
UpdateOptLock(ctx context.Context, pipeline *types.Pipeline,
|
||||
|
@ -463,7 +463,7 @@ type (
|
|||
Delete(ctx context.Context, id int64) error
|
||||
|
||||
// Count the number of pipelines in a space matching the given filter.
|
||||
Count(ctx context.Context, spaceID int64, filter types.Pagination) (int64, error)
|
||||
Count(ctx context.Context, spaceID int64, filter types.ListQueryFilter) (int64, error)
|
||||
|
||||
// DeleteByUID deletes a pipeline with a given UID in a space
|
||||
DeleteByUID(ctx context.Context, spaceID int64, uid string) error
|
||||
|
@ -483,7 +483,7 @@ type (
|
|||
Create(ctx context.Context, secret *types.Secret) error
|
||||
|
||||
// Count the number of secrets in a space matching the given filter.
|
||||
Count(ctx context.Context, spaceID int64, pagination types.Pagination) (int64, error)
|
||||
Count(ctx context.Context, spaceID int64, pagination types.ListQueryFilter) (int64, error)
|
||||
|
||||
// UpdateOptLock updates the secret using the optimistic locking mechanism.
|
||||
UpdateOptLock(ctx context.Context, secret *types.Secret,
|
||||
|
@ -499,7 +499,7 @@ type (
|
|||
DeleteByUID(ctx context.Context, spaceID int64, uid string) error
|
||||
|
||||
// List lists the secrets in a given space
|
||||
List(ctx context.Context, spaceID int64, filter types.Pagination) ([]*types.Secret, error)
|
||||
List(ctx context.Context, spaceID int64, filter types.ListQueryFilter) ([]*types.Secret, error)
|
||||
}
|
||||
|
||||
ExecutionStore interface {
|
||||
|
|
|
@ -176,7 +176,7 @@ func (s *executionStore) Create(ctx context.Context, execution *types.Execution)
|
|||
}
|
||||
|
||||
// Update tries to update an execution in the datastore with optimistic locking.
|
||||
func (s *executionStore) Update(ctx context.Context, execution *types.Execution) error {
|
||||
func (s *executionStore) Update(ctx context.Context, e *types.Execution) error {
|
||||
const executionUpdateStmt = `
|
||||
UPDATE executions
|
||||
SET
|
||||
|
@ -190,6 +190,8 @@ func (s *executionStore) Update(ctx context.Context, execution *types.Execution)
|
|||
WHERE execution_id = :execution_id AND execution_version = :execution_version - 1`
|
||||
updatedAt := time.Now()
|
||||
|
||||
execution := *e
|
||||
|
||||
execution.Version++
|
||||
execution.Updated = updatedAt.UnixMilli()
|
||||
|
||||
|
@ -214,6 +216,8 @@ func (s *executionStore) Update(ctx context.Context, execution *types.Execution)
|
|||
return gitness_store.ErrVersionConflict
|
||||
}
|
||||
|
||||
e.Version = execution.Version
|
||||
e.Updated = execution.Updated
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -14,16 +14,16 @@ CREATE TABLE IF NOT EXISTS pipelines (
|
|||
,pipeline_version INTEGER NOT NULL
|
||||
|
||||
-- Ensure unique combination of UID and ParentID
|
||||
UNIQUE (pipeline_space_id, pipeline_uid),
|
||||
,UNIQUE (pipeline_space_id, pipeline_uid)
|
||||
|
||||
-- Foreign key to spaces table
|
||||
CONSTRAINT fk_pipeline_space_id FOREIGN KEY (pipeline_space_id)
|
||||
,CONSTRAINT fk_pipeline_space_id FOREIGN KEY (pipeline_space_id)
|
||||
REFERENCES spaces (space_id) MATCH SIMPLE
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE CASCADE
|
||||
|
||||
-- Foreign key to repositories table
|
||||
CONSTRAINT fk_pipelines_repo_id FOREIGN KEY (pipeline_repo_id)
|
||||
,CONSTRAINT fk_pipelines_repo_id FOREIGN KEY (pipeline_repo_id)
|
||||
REFERENCES repositories (repo_id) MATCH SIMPLE
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE CASCADE
|
||||
|
@ -67,16 +67,16 @@ CREATE TABLE IF NOT EXISTS executions (
|
|||
,execution_version INTEGER NOT NULL
|
||||
|
||||
-- Ensure unique combination of pipeline ID and number
|
||||
UNIQUE (execution_pipeline_id, execution_number),
|
||||
,UNIQUE (execution_pipeline_id, execution_number)
|
||||
|
||||
-- Foreign key to pipelines table
|
||||
CONSTRAINT fk_executions_pipeline_id FOREIGN KEY (,execution_pipeline_id)
|
||||
,CONSTRAINT fk_executions_pipeline_id FOREIGN KEY (execution_pipeline_id)
|
||||
REFERENCES pipelines (pipeline_id) MATCH SIMPLE
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE CASCADE
|
||||
|
||||
-- Foreign key to repositories table
|
||||
CONSTRAINT fk_executions_repo_id FOREIGN KEY (,execution_repo_id)
|
||||
,CONSTRAINT fk_executions_repo_id FOREIGN KEY (execution_repo_id)
|
||||
REFERENCES repositories (repo_id) MATCH SIMPLE
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE CASCADE
|
||||
|
@ -93,10 +93,10 @@ CREATE TABLE IF NOT EXISTS secrets (
|
|||
,secret_version INTEGER NOT NULL
|
||||
|
||||
-- Ensure unique combination of space ID and UID
|
||||
UNIQUE (secret_space_id, secret_uid),
|
||||
,UNIQUE (secret_space_id, secret_uid)
|
||||
|
||||
-- Foreign key to spaces table
|
||||
CONSTRAINT fk_secrets_space_id FOREIGN KEY (secret_space_id)
|
||||
,CONSTRAINT fk_secrets_space_id FOREIGN KEY (secret_space_id)
|
||||
REFERENCES spaces (space_id) MATCH SIMPLE
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE CASCADE
|
||||
|
|
|
@ -127,7 +127,7 @@ func (s *pipelineStore) Create(ctx context.Context, pipeline *types.Pipeline) er
|
|||
}
|
||||
|
||||
// Update updates a pipeline.
|
||||
func (s *pipelineStore) Update(ctx context.Context, pipeline *types.Pipeline) error {
|
||||
func (s *pipelineStore) Update(ctx context.Context, p *types.Pipeline) error {
|
||||
const pipelineUpdateStmt = `
|
||||
UPDATE pipelines
|
||||
SET
|
||||
|
@ -140,6 +140,7 @@ func (s *pipelineStore) Update(ctx context.Context, pipeline *types.Pipeline) er
|
|||
pipeline_version = :pipeline_version
|
||||
WHERE pipeline_id = :pipeline_id AND pipeline_version = :pipeline_version - 1`
|
||||
updatedAt := time.Now()
|
||||
pipeline := *p
|
||||
|
||||
pipeline.Version++
|
||||
pipeline.Updated = updatedAt.UnixMilli()
|
||||
|
@ -165,6 +166,8 @@ func (s *pipelineStore) Update(ctx context.Context, pipeline *types.Pipeline) er
|
|||
return gitness_store.ErrVersionConflict
|
||||
}
|
||||
|
||||
p.Updated = pipeline.Updated
|
||||
p.Version = pipeline.Version
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -172,19 +175,19 @@ func (s *pipelineStore) Update(ctx context.Context, pipeline *types.Pipeline) er
|
|||
func (s *pipelineStore) List(
|
||||
ctx context.Context,
|
||||
parentID int64,
|
||||
pagination types.Pagination,
|
||||
filter types.ListQueryFilter,
|
||||
) ([]*types.Pipeline, error) {
|
||||
stmt := database.Builder.
|
||||
Select(pipelineColumns).
|
||||
From("pipelines").
|
||||
Where("pipeline_space_id = ?", fmt.Sprint(parentID))
|
||||
|
||||
if pagination.Query != "" {
|
||||
stmt = stmt.Where("LOWER(pipeline_uid) LIKE ?", fmt.Sprintf("%%%s%%", strings.ToLower(pagination.Query)))
|
||||
if filter.Query != "" {
|
||||
stmt = stmt.Where("LOWER(pipeline_uid) LIKE ?", fmt.Sprintf("%%%s%%", strings.ToLower(filter.Query)))
|
||||
}
|
||||
|
||||
stmt = stmt.Limit(database.Limit(pagination.Size))
|
||||
stmt = stmt.Offset(database.Offset(pagination.Page, pagination.Size))
|
||||
stmt = stmt.Limit(database.Limit(filter.Size))
|
||||
stmt = stmt.Offset(database.Offset(filter.Page, filter.Size))
|
||||
|
||||
sql, args, err := stmt.ToSql()
|
||||
if err != nil {
|
||||
|
@ -229,7 +232,7 @@ func (s *pipelineStore) UpdateOptLock(ctx context.Context,
|
|||
}
|
||||
|
||||
// Count of pipelines in a space.
|
||||
func (s *pipelineStore) Count(ctx context.Context, parentID int64, filter types.Pagination) (int64, error) {
|
||||
func (s *pipelineStore) Count(ctx context.Context, parentID int64, filter types.ListQueryFilter) (int64, error) {
|
||||
stmt := database.Builder.
|
||||
Select("count(*)").
|
||||
From("pipelines").
|
||||
|
|
|
@ -110,7 +110,7 @@ func (s *secretStore) Create(ctx context.Context, secret *types.Secret) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *secretStore) Update(ctx context.Context, secret *types.Secret) error {
|
||||
func (s *secretStore) Update(ctx context.Context, p *types.Secret) error {
|
||||
const secretUpdateStmt = `
|
||||
UPDATE secrets
|
||||
SET
|
||||
|
@ -121,6 +121,7 @@ func (s *secretStore) Update(ctx context.Context, secret *types.Secret) error {
|
|||
secret_version = :secret_version
|
||||
WHERE secret_id = :secret_id AND secret_version = :secret_version - 1`
|
||||
updatedAt := time.Now()
|
||||
secret := *p
|
||||
|
||||
secret.Version++
|
||||
secret.Updated = updatedAt.UnixMilli()
|
||||
|
@ -146,6 +147,8 @@ func (s *secretStore) Update(ctx context.Context, secret *types.Secret) error {
|
|||
return gitness_store.ErrVersionConflict
|
||||
}
|
||||
|
||||
p.Version = secret.Version
|
||||
p.Updated = secret.Updated
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -178,18 +181,18 @@ func (s *secretStore) UpdateOptLock(ctx context.Context,
|
|||
}
|
||||
|
||||
// List lists all the secrets present in a space.
|
||||
func (s *secretStore) List(ctx context.Context, parentID int64, pagination types.Pagination) ([]*types.Secret, error) {
|
||||
func (s *secretStore) List(ctx context.Context, parentID int64, filter types.ListQueryFilter) ([]*types.Secret, error) {
|
||||
stmt := database.Builder.
|
||||
Select(secretColumns).
|
||||
From("secrets").
|
||||
Where("secret_space_id = ?", fmt.Sprint(parentID))
|
||||
|
||||
if pagination.Query != "" {
|
||||
stmt = stmt.Where("LOWER(secret_uid) LIKE ?", fmt.Sprintf("%%%s%%", strings.ToLower(pagination.Query)))
|
||||
if filter.Query != "" {
|
||||
stmt = stmt.Where("LOWER(secret_uid) LIKE ?", fmt.Sprintf("%%%s%%", strings.ToLower(filter.Query)))
|
||||
}
|
||||
|
||||
stmt = stmt.Limit(database.Limit(pagination.Size))
|
||||
stmt = stmt.Offset(database.Offset(pagination.Page, pagination.Size))
|
||||
stmt = stmt.Limit(database.Limit(filter.Size))
|
||||
stmt = stmt.Offset(database.Offset(filter.Page, filter.Size))
|
||||
|
||||
sql, args, err := stmt.ToSql()
|
||||
if err != nil {
|
||||
|
@ -237,7 +240,7 @@ func (s *secretStore) DeleteByUID(ctx context.Context, spaceID int64, uid string
|
|||
}
|
||||
|
||||
// Count of secrets in a space.
|
||||
func (s *secretStore) Count(ctx context.Context, parentID int64, filter types.Pagination) (int64, error) {
|
||||
func (s *secretStore) Count(ctx context.Context, parentID int64, filter types.ListQueryFilter) (int64, error) {
|
||||
stmt := database.Builder.
|
||||
Select("count(*)").
|
||||
From("secrets").
|
||||
|
|
|
@ -7,7 +7,6 @@ package database
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/encrypt"
|
||||
"github.com/harness/gitness/internal/store"
|
||||
"github.com/harness/gitness/internal/store/database/migrate"
|
||||
"github.com/harness/gitness/store/database"
|
||||
|
@ -27,7 +26,6 @@ var WireSet = wire.NewSet(
|
|||
ProvideExecutionStore,
|
||||
ProvidePipelineStore,
|
||||
ProvideSecretStore,
|
||||
ProvideEncryptor,
|
||||
ProvideRepoGitInfoView,
|
||||
ProvideMembershipStore,
|
||||
ProvideTokenStore,
|
||||
|
@ -63,22 +61,6 @@ func ProvidePrincipalStore(db *sqlx.DB, uidTransformation store.PrincipalUIDTran
|
|||
return NewPrincipalStore(db, uidTransformation)
|
||||
}
|
||||
|
||||
// ProvideEncryptor provides an encryptor implementation.
|
||||
func ProvideEncryptor(config database.Config) (encrypt.Encrypter, error) {
|
||||
enc, err := encrypt.New(config.Secret)
|
||||
// mixed-content mode should be set to true if the database
|
||||
// originally had encryption disabled and therefore has
|
||||
// plaintext entries. This prevents gitness from returning an
|
||||
// error if decryption fails; on failure, the ciphertext is
|
||||
// returned as-is and the error is ignored.
|
||||
if aesgcm, ok := enc.(*encrypt.Aesgcm); ok {
|
||||
if config.EncryptMixedContent {
|
||||
aesgcm.Compat = true
|
||||
}
|
||||
}
|
||||
return enc, err
|
||||
}
|
||||
|
||||
// ProvidePrincipalInfoView provides a principal info store.
|
||||
func ProvidePrincipalInfoView(db *sqlx.DB) store.PrincipalInfoView {
|
||||
return NewPrincipalInfoView(db)
|
||||
|
|
|
@ -8,9 +8,10 @@ import (
|
|||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
user "github.com/harness/gitness/internal/api/controller/user"
|
||||
types "github.com/harness/gitness/types"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockClient is a mock of Client interface.
|
||||
|
|
|
@ -8,9 +8,10 @@ import (
|
|||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
types "github.com/harness/gitness/types"
|
||||
enum "github.com/harness/gitness/types/enum"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockPrincipalStore is a mock of PrincipalStore interface.
|
||||
|
|
|
@ -6,8 +6,6 @@ package database
|
|||
|
||||
// Config specifies the config for the database package.
|
||||
type Config struct {
|
||||
Driver string
|
||||
Datasource string
|
||||
Secret string
|
||||
EncryptMixedContent bool
|
||||
Driver string
|
||||
Datasource string
|
||||
}
|
||||
|
|
|
@ -52,6 +52,12 @@ type Config struct {
|
|||
DefaultBranch string `envconfig:"GITNESS_GIT_DEFAULTBRANCH" default:"main"`
|
||||
}
|
||||
|
||||
// Encrypter defines the parameters for the encrypter
|
||||
Encrypter struct {
|
||||
Secret string `envconfig:"GITNESS_ENCRYPTER_SECRET"` // key used for encryption
|
||||
EncryptMixedContent bool `envconfig:"GITNESS_ENCRYPT_MIXED_CONTENT"`
|
||||
}
|
||||
|
||||
// Server defines the server configuration parameters.
|
||||
Server struct {
|
||||
// HTTP defines the http configuration parameters
|
||||
|
@ -75,9 +81,6 @@ type Config struct {
|
|||
Database struct {
|
||||
Driver string `envconfig:"GITNESS_DATABASE_DRIVER" default:"sqlite3"`
|
||||
Datasource string `envconfig:"GITNESS_DATABASE_DATASOURCE" default:"database.sqlite3"`
|
||||
// secret used for encryption/decryption in the DB
|
||||
Secret string `envconfig:"GITNESS_DATABASE_SECRET"`
|
||||
EncryptMixedContent bool `envconfig:"GITNESS_ENCRYPT_MIXED_CONTENT"`
|
||||
}
|
||||
|
||||
// Token defines token configuration parameters.
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package types
|
||||
|
||||
// ListQueryFilter has pagination related info and a query param
|
||||
type ListQueryFilter struct {
|
||||
Pagination
|
||||
Query string `json:"query"`
|
||||
}
|
|
@ -1,12 +1,7 @@
|
|||
package types
|
||||
|
||||
import "github.com/harness/gitness/types/enum"
|
||||
|
||||
// Pagination stores pagination related params
|
||||
type Pagination struct {
|
||||
Page int `json:"page"`
|
||||
Size int `json:"size"`
|
||||
Query string `json:"query"`
|
||||
Sort string `json:"sort"`
|
||||
Order enum.Order `json:"order"`
|
||||
Page int `json:"page"`
|
||||
Size int `json:"size"`
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ type Secret struct {
|
|||
Description string `db:"secret_description" json:"description"`
|
||||
SpaceID int64 `db:"secret_space_id" json:"space_id"`
|
||||
UID string `db:"secret_uid" json:"uid"`
|
||||
Data string `db:"secret_data" json:"data"`
|
||||
Data string `db:"secret_data" json:"-"`
|
||||
Created int64 `db:"secret_created" json:"created"`
|
||||
Updated int64 `db:"secret_updated" json:"updated"`
|
||||
Version int64 `db:"secret_version" json:"version"`
|
||||
|
|
Loading…
Reference in New Issue