diff --git a/app/api/auth/auth.go b/app/api/auth/auth.go index 08eaa33ce..3d20fd2f8 100644 --- a/app/api/auth/auth.go +++ b/app/api/auth/auth.go @@ -76,8 +76,8 @@ func CheckChild(ctx context.Context, authorizer authz.Authorizer, session *auth. } resource := &types.Resource{ - Type: resourceType, - Name: resourceName, + Type: resourceType, + Identifier: resourceName, } return Check(ctx, authorizer, session, scope, resource, permission) diff --git a/app/api/auth/connector.go b/app/api/auth/connector.go index 3c55e7241..2249a3e1e 100644 --- a/app/api/auth/connector.go +++ b/app/api/auth/connector.go @@ -32,13 +32,13 @@ func CheckConnector( authorizer authz.Authorizer, session *auth.Session, parentPath, - uid string, + identifier string, permission enum.Permission, ) error { scope := &types.Scope{SpacePath: parentPath} resource := &types.Resource{ - Type: enum.ResourceTypeConnector, - Name: uid, + Type: enum.ResourceTypeConnector, + Identifier: identifier, } return Check(ctx, authorizer, session, scope, resource, permission) diff --git a/app/api/auth/pipeline.go b/app/api/auth/pipeline.go index b5839ed5c..73a2ab561 100644 --- a/app/api/auth/pipeline.go +++ b/app/api/auth/pipeline.go @@ -31,15 +31,15 @@ import ( // Returns nil if the permission is granted, otherwise returns an error. // NotAuthenticated, NotAuthorized, or any underlying error. func CheckPipeline(ctx context.Context, authorizer authz.Authorizer, session *auth.Session, - repoPath string, pipelineUID string, permission enum.Permission) error { + repoPath string, pipelineIdentifier string, permission enum.Permission) error { spacePath, repoName, err := paths.DisectLeaf(repoPath) if err != nil { return errors.Wrapf(err, "Failed to disect path '%s'", repoPath) } scope := &types.Scope{SpacePath: spacePath, Repo: repoName} resource := &types.Resource{ - Type: enum.ResourceTypePipeline, - Name: pipelineUID, + Type: enum.ResourceTypePipeline, + Identifier: pipelineIdentifier, } return Check(ctx, authorizer, session, scope, resource, permission) } diff --git a/app/api/auth/repo.go b/app/api/auth/repo.go index f9fdb429c..dd89a1053 100644 --- a/app/api/auth/repo.go +++ b/app/api/auth/repo.go @@ -50,8 +50,8 @@ func CheckRepo( scope := &types.Scope{SpacePath: parentSpace} resource := &types.Resource{ - Type: enum.ResourceTypeRepo, - Name: name, + Type: enum.ResourceTypeRepo, + Identifier: name, } return Check(ctx, authorizer, session, scope, resource, permission) diff --git a/app/api/auth/secret.go b/app/api/auth/secret.go index 50fc52307..a7df8b517 100644 --- a/app/api/auth/secret.go +++ b/app/api/auth/secret.go @@ -28,11 +28,11 @@ import ( // Returns nil if the permission is granted, otherwise returns an error. // NotAuthenticated, NotAuthorized, or any underlying error. func CheckSecret(ctx context.Context, authorizer authz.Authorizer, session *auth.Session, - parentPath, uid string, permission enum.Permission) error { + parentPath, identifier string, permission enum.Permission) error { scope := &types.Scope{SpacePath: parentPath} resource := &types.Resource{ - Type: enum.ResourceTypeSecret, - Name: uid, + Type: enum.ResourceTypeSecret, + Identifier: identifier, } return Check(ctx, authorizer, session, scope, resource, permission) diff --git a/app/api/auth/service.go b/app/api/auth/service.go index 2c6d69e98..dc01b2fd3 100644 --- a/app/api/auth/service.go +++ b/app/api/auth/service.go @@ -32,8 +32,8 @@ func CheckService(ctx context.Context, authorizer authz.Authorizer, session *aut // a service exists outside any scope scope := &types.Scope{} resource := &types.Resource{ - Type: enum.ResourceTypeService, - Name: svc.UID, + Type: enum.ResourceTypeService, + Identifier: svc.UID, } return Check(ctx, authorizer, session, scope, resource, permission) diff --git a/app/api/auth/space.go b/app/api/auth/space.go index d06ba679f..83458e9c6 100644 --- a/app/api/auth/space.go +++ b/app/api/auth/space.go @@ -44,8 +44,8 @@ func CheckSpace(ctx context.Context, authorizer authz.Authorizer, session *auth. scope := &types.Scope{SpacePath: parentSpace} resource := &types.Resource{ - Type: enum.ResourceTypeSpace, - Name: name, + Type: enum.ResourceTypeSpace, + Identifier: name, } return Check(ctx, authorizer, session, scope, resource, permission) diff --git a/app/api/auth/template.go b/app/api/auth/template.go index 6d9103ef7..d68a7ba90 100644 --- a/app/api/auth/template.go +++ b/app/api/auth/template.go @@ -28,11 +28,11 @@ import ( // Returns nil if the permission is granted, otherwise returns an error. // NotAuthenticated, NotAuthorized, or any underlying error. func CheckTemplate(ctx context.Context, authorizer authz.Authorizer, session *auth.Session, - parentPath, uid string, permission enum.Permission) error { + parentPath, identifier string, permission enum.Permission) error { scope := &types.Scope{SpacePath: parentPath} resource := &types.Resource{ - Type: enum.ResourceTypeTemplate, - Name: uid, + Type: enum.ResourceTypeTemplate, + Identifier: identifier, } return Check(ctx, authorizer, session, scope, resource, permission) diff --git a/app/api/auth/user.go b/app/api/auth/user.go index 86628935c..dfbe7ab3b 100644 --- a/app/api/auth/user.go +++ b/app/api/auth/user.go @@ -32,8 +32,8 @@ func CheckUser(ctx context.Context, authorizer authz.Authorizer, session *auth.S // a user exists outside any scope scope := &types.Scope{} resource := &types.Resource{ - Type: enum.ResourceTypeUser, - Name: user.UID, + Type: enum.ResourceTypeUser, + Identifier: user.UID, } return Check(ctx, authorizer, session, scope, resource, permission) diff --git a/app/api/controller/check/check_list.go b/app/api/controller/check/check_list.go index c26017073..8f5a163f8 100644 --- a/app/api/controller/check/check_list.go +++ b/app/api/controller/check/check_list.go @@ -42,7 +42,7 @@ func (c *Controller) ListChecks( err = c.tx.WithTx(ctx, func(ctx context.Context) (err error) { checks, err = c.checkStore.List(ctx, repo.ID, commitSHA, opts) if err != nil { - return fmt.Errorf("failed to list status check results for repo=%s: %w", repo.UID, err) + return fmt.Errorf("failed to list status check results for repo=%s: %w", repo.Identifier, err) } if opts.Page == 1 && len(checks) < opts.Size { @@ -52,7 +52,7 @@ func (c *Controller) ListChecks( count, err = c.checkStore.Count(ctx, repo.ID, commitSHA, opts) if err != nil { - return fmt.Errorf("failed to count status check results for repo=%s: %w", repo.UID, err) + return fmt.Errorf("failed to count status check results for repo=%s: %w", repo.Identifier, err) } return nil diff --git a/app/api/controller/check/check_recent.go b/app/api/controller/check/check_recent.go index b9cbf1c6b..27248fc61 100644 --- a/app/api/controller/check/check_recent.go +++ b/app/api/controller/check/check_recent.go @@ -40,10 +40,10 @@ func (c *Controller) ListRecentChecks( opts.Since = time.Now().Add(-30 * 24 * time.Hour).UnixMilli() } - checkUIDs, err := c.checkStore.ListRecent(ctx, repo.ID, opts) + checkIdentifiers, err := c.checkStore.ListRecent(ctx, repo.ID, opts) if err != nil { - return nil, fmt.Errorf("failed to list status check results for repo=%s: %w", repo.UID, err) + return nil, fmt.Errorf("failed to list status check results for repo=%s: %w", repo.Identifier, err) } - return checkUIDs, nil + return checkIdentifiers, nil } diff --git a/app/api/controller/check/check_report.go b/app/api/controller/check/check_report.go index 2fc1b1be5..1c831183d 100644 --- a/app/api/controller/check/check_report.go +++ b/app/api/controller/check/check_report.go @@ -32,29 +32,37 @@ import ( ) type ReportInput struct { - CheckUID string `json:"check_uid"` - Status enum.CheckStatus `json:"status"` - Summary string `json:"summary"` - Link string `json:"link"` - Payload types.CheckPayload `json:"payload"` + // TODO [CODE-1363]: remove after identifier migration. + CheckUID string `json:"check_uid" deprecated:"true"` + Identifier string `json:"identifier"` + Status enum.CheckStatus `json:"status"` + Summary string `json:"summary"` + Link string `json:"link"` + Payload types.CheckPayload `json:"payload"` Started int64 `json:"started,omitempty"` Ended int64 `json:"ended,omitempty"` } -var regexpCheckUID = "^[0-9a-zA-Z-_.$]{1,127}$" -var matcherCheckUID = regexp.MustCompile(regexpCheckUID) +// TODO: Can we drop the '$' - depends on whether harness allows it. +var regexpCheckIdentifier = "^[0-9a-zA-Z-_.$]{1,127}$" +var matcherCheckIdentifier = regexp.MustCompile(regexpCheckIdentifier) -// Validate validates and sanitizes the ReportInput data. -func (in *ReportInput) Validate( +// Sanitize validates and sanitizes the ReportInput data. +func (in *ReportInput) Sanitize( sanitizers map[enum.CheckPayloadKind]func(in *ReportInput, session *auth.Session) error, session *auth.Session, ) error { - if in.CheckUID == "" { - return usererror.BadRequest("Status check UID is missing") + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.CheckUID } - if !matcherCheckUID.MatchString(in.CheckUID) { - return usererror.BadRequestf("Status check UID must match the regular expression: %s", regexpCheckUID) + if in.Identifier == "" { + return usererror.BadRequest("Identifier is missing") + } + + if !matcherCheckIdentifier.MatchString(in.Identifier) { + return usererror.BadRequestf("Identifier must match the regular expression: %s", regexpCheckIdentifier) } _, ok := in.Status.Sanitize() @@ -123,7 +131,7 @@ func (c *Controller) Report( return nil, fmt.Errorf("failed to acquire access access to repo: %w", err) } - if errValidate := in.Validate(c.sanitizers, session); errValidate != nil { + if errValidate := in.Sanitize(c.sanitizers, session); errValidate != nil { return nil, errValidate } @@ -143,10 +151,10 @@ func (c *Controller) Report( metadataJSON, _ := json.Marshal(metadata) - existingCheck, err := c.checkStore.Find(ctx, repo.ID, commitSHA, in.CheckUID) + existingCheck, err := c.checkStore.FindByIdentifier(ctx, repo.ID, commitSHA, in.Identifier) if err != nil && !errors.Is(err, store.ErrResourceNotFound) { - return nil, fmt.Errorf("failed to find existing check for UID=%q: %w", in.CheckUID, err) + return nil, fmt.Errorf("failed to find existing check for Identifier %q: %w", in.Identifier, err) } started := getStartTime(in, existingCheck, now) @@ -158,7 +166,7 @@ func (c *Controller) Report( Updated: now, RepoID: repo.ID, CommitSHA: commitSHA, - UID: in.CheckUID, + Identifier: in.Identifier, Status: in.Status, Summary: in.Summary, Link: in.Link, @@ -171,7 +179,7 @@ func (c *Controller) Report( err = c.checkStore.Upsert(ctx, statusCheckReport) if err != nil { - return nil, fmt.Errorf("failed to upsert status check result for repo=%s: %w", repo.UID, err) + return nil, fmt.Errorf("failed to upsert status check result for repo=%s: %w", repo.Identifier, err) } return statusCheckReport, nil diff --git a/app/api/controller/connector/controller.go b/app/api/controller/connector/controller.go index b6783c432..273d59f54 100644 --- a/app/api/controller/connector/controller.go +++ b/app/api/controller/connector/controller.go @@ -17,24 +17,20 @@ package connector import ( "github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/store" - "github.com/harness/gitness/types/check" ) type Controller struct { - uidCheck check.PathUID connectorStore store.ConnectorStore authorizer authz.Authorizer spaceStore store.SpaceStore } func NewController( - uidCheck check.PathUID, authorizer authz.Authorizer, connectorStore store.ConnectorStore, spaceStore store.SpaceStore, ) *Controller { return &Controller{ - uidCheck: uidCheck, connectorStore: connectorStore, authorizer: authorizer, spaceStore: spaceStore, diff --git a/app/api/controller/connector/create.go b/app/api/controller/connector/create.go index 55ec00eaf..bcacbfe8b 100644 --- a/app/api/controller/connector/create.go +++ b/app/api/controller/connector/create.go @@ -38,9 +38,11 @@ var ( type CreateInput struct { Description string `json:"description"` SpaceRef string `json:"space_ref"` // Ref of the parent space - UID string `json:"uid"` - Type string `json:"type"` - Data string `json:"data"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` + Type string `json:"type"` + Data string `json:"data"` } func (c *Controller) Create( @@ -51,12 +53,13 @@ func (c *Controller) Create( if err := c.sanitizeCreateInput(in); err != nil { return nil, fmt.Errorf("failed to sanitize input: %w", err) } + parentSpace, err := c.spaceStore.FindByRef(ctx, in.SpaceRef) if err != nil { return nil, fmt.Errorf("failed to find parent by ref: %w", err) } - err = apiauth.CheckConnector(ctx, c.authorizer, session, parentSpace.Path, in.UID, enum.PermissionConnectorEdit) + err = apiauth.CheckConnector(ctx, c.authorizer, session, parentSpace.Path, in.Identifier, enum.PermissionConnectorEdit) if err != nil { return nil, err } @@ -67,7 +70,7 @@ func (c *Controller) Create( Data: in.Data, Type: in.Type, SpaceID: parentSpace.ID, - UID: in.UID, + Identifier: in.Identifier, Created: now, Updated: now, Version: 0, @@ -81,13 +84,18 @@ func (c *Controller) Create( } func (c *Controller) sanitizeCreateInput(in *CreateInput) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + parentRefAsID, _ := strconv.ParseInt(in.SpaceRef, 10, 64) if parentRefAsID <= 0 || len(strings.TrimSpace(in.SpaceRef)) == 0 { return errConnectorRequiresParent } - if err := c.uidCheck(in.UID, false); err != nil { + if err := check.Identifier(in.Identifier); err != nil { return err } diff --git a/app/api/controller/connector/delete.go b/app/api/controller/connector/delete.go index 5aafbbf9c..2da27d53d 100644 --- a/app/api/controller/connector/delete.go +++ b/app/api/controller/connector/delete.go @@ -23,17 +23,22 @@ import ( "github.com/harness/gitness/types/enum" ) -func (c *Controller) Delete(ctx context.Context, session *auth.Session, spaceRef string, uid string) error { +func (c *Controller) Delete( + ctx context.Context, + session *auth.Session, + spaceRef string, + identifier string, +) error { space, err := c.spaceStore.FindByRef(ctx, spaceRef) if err != nil { return fmt.Errorf("failed to find space: %w", err) } - err = apiauth.CheckConnector(ctx, c.authorizer, session, space.Path, uid, enum.PermissionConnectorDelete) + err = apiauth.CheckConnector(ctx, c.authorizer, session, space.Path, identifier, enum.PermissionConnectorDelete) if err != nil { return fmt.Errorf("failed to authorize: %w", err) } - err = c.connectorStore.DeleteByUID(ctx, space.ID, uid) + err = c.connectorStore.DeleteByIdentifier(ctx, space.ID, identifier) if err != nil { return fmt.Errorf("could not delete connector: %w", err) } diff --git a/app/api/controller/connector/find.go b/app/api/controller/connector/find.go index 5fef945f4..178eb669d 100644 --- a/app/api/controller/connector/find.go +++ b/app/api/controller/connector/find.go @@ -28,17 +28,17 @@ func (c *Controller) Find( ctx context.Context, session *auth.Session, spaceRef string, - uid string, + identifier string, ) (*types.Connector, error) { space, err := c.spaceStore.FindByRef(ctx, spaceRef) if err != nil { return nil, fmt.Errorf("failed to find space: %w", err) } - err = apiauth.CheckConnector(ctx, c.authorizer, session, space.Path, uid, enum.PermissionConnectorView) + err = apiauth.CheckConnector(ctx, c.authorizer, session, space.Path, identifier, enum.PermissionConnectorView) if err != nil { return nil, fmt.Errorf("failed to authorize: %w", err) } - connector, err := c.connectorStore.FindByUID(ctx, space.ID, uid) + connector, err := c.connectorStore.FindByIdentifier(ctx, space.ID, identifier) if err != nil { return nil, fmt.Errorf("failed to find connector: %w", err) } diff --git a/app/api/controller/connector/update.go b/app/api/controller/connector/update.go index 2139ce79d..5df1c801c 100644 --- a/app/api/controller/connector/update.go +++ b/app/api/controller/connector/update.go @@ -28,7 +28,9 @@ import ( // UpdateInput is used for updating a connector. type UpdateInput struct { - UID *string `json:"uid"` + // TODO [CODE-1363]: remove after identifier migration. + UID *string `json:"uid" deprecated:"true"` + Identifier *string `json:"identifier"` Description *string `json:"description"` Data *string `json:"data"` } @@ -37,31 +39,31 @@ func (c *Controller) Update( ctx context.Context, session *auth.Session, spaceRef string, - uid string, + identifier string, in *UpdateInput, ) (*types.Connector, error) { + if err := c.sanitizeUpdateInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) + } + space, err := c.spaceStore.FindByRef(ctx, spaceRef) if err != nil { return nil, fmt.Errorf("failed to find space: %w", err) } - err = apiauth.CheckConnector(ctx, c.authorizer, session, space.Path, uid, enum.PermissionConnectorEdit) + err = apiauth.CheckConnector(ctx, c.authorizer, session, space.Path, identifier, enum.PermissionConnectorEdit) if err != nil { return nil, fmt.Errorf("failed to authorize: %w", err) } - if err = c.sanitizeUpdateInput(in); err != nil { - return nil, fmt.Errorf("failed to sanitize input: %w", err) - } - - connector, err := c.connectorStore.FindByUID(ctx, space.ID, uid) + connector, err := c.connectorStore.FindByIdentifier(ctx, space.ID, identifier) if err != nil { return nil, fmt.Errorf("failed to find connector: %w", err) } return c.connectorStore.UpdateOptLock(ctx, connector, func(original *types.Connector) error { - if in.UID != nil { - original.UID = *in.UID + if in.Identifier != nil { + original.Identifier = *in.Identifier } if in.Description != nil { original.Description = *in.Description @@ -75,8 +77,13 @@ func (c *Controller) Update( } func (c *Controller) sanitizeUpdateInput(in *UpdateInput) error { - if in.UID != nil { - if err := c.uidCheck(*in.UID, false); err != nil { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == nil { + in.Identifier = in.UID + } + + if in.Identifier != nil { + if err := check.Identifier(*in.Identifier); err != nil { return err } } diff --git a/app/api/controller/connector/wire.go b/app/api/controller/connector/wire.go index f9b9102f1..8df233d0e 100644 --- a/app/api/controller/connector/wire.go +++ b/app/api/controller/connector/wire.go @@ -17,7 +17,6 @@ package connector import ( "github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/store" - "github.com/harness/gitness/types/check" "github.com/google/wire" ) @@ -28,10 +27,9 @@ var WireSet = wire.NewSet( ) func ProvideController( - uidCheck check.PathUID, connectorStore store.ConnectorStore, authorizer authz.Authorizer, spaceStore store.SpaceStore, ) *Controller { - return NewController(uidCheck, authorizer, connectorStore, spaceStore) + return NewController(authorizer, connectorStore, spaceStore) } diff --git a/app/api/controller/execution/cancel.go b/app/api/controller/execution/cancel.go index be175cfe9..0effaf23a 100644 --- a/app/api/controller/execution/cancel.go +++ b/app/api/controller/execution/cancel.go @@ -31,19 +31,19 @@ func (c *Controller) Cancel( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, + pipelineIdentifier string, executionNum int64, ) (*types.Execution, error) { repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return nil, fmt.Errorf("failed to find repo by ref: %w", err) } - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineExecute) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineExecute) if err != nil { return nil, fmt.Errorf("failed to authorize: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return nil, fmt.Errorf("failed to find pipeline: %w", err) } diff --git a/app/api/controller/execution/create.go b/app/api/controller/execution/create.go index 2d25d75a1..091fe8fe9 100644 --- a/app/api/controller/execution/create.go +++ b/app/api/controller/execution/create.go @@ -31,7 +31,7 @@ func (c *Controller) Create( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, + pipelineIdentifier string, branch string, ) (*types.Execution, error) { repo, err := c.repoStore.FindByRef(ctx, repoRef) @@ -39,12 +39,12 @@ func (c *Controller) Create( return nil, fmt.Errorf("failed to find repo by ref: %w", err) } err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, - pipelineUID, enum.PermissionPipelineExecute) + pipelineIdentifier, enum.PermissionPipelineExecute) if err != nil { return nil, fmt.Errorf("failed to authorize: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return nil, fmt.Errorf("failed to find pipeline: %w", err) } diff --git a/app/api/controller/execution/delete.go b/app/api/controller/execution/delete.go index 6915036cf..7c8a3532c 100644 --- a/app/api/controller/execution/delete.go +++ b/app/api/controller/execution/delete.go @@ -27,19 +27,19 @@ func (c *Controller) Delete( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, + pipelineIdentifier string, executionNum int64, ) error { repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return fmt.Errorf("failed to find repo by ref: %w", err) } - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineDelete) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineDelete) if err != nil { return fmt.Errorf("failed to authorize: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return fmt.Errorf("failed to find pipeline: %w", err) } diff --git a/app/api/controller/execution/find.go b/app/api/controller/execution/find.go index 425ed061f..7040e11be 100644 --- a/app/api/controller/execution/find.go +++ b/app/api/controller/execution/find.go @@ -28,19 +28,19 @@ func (c *Controller) Find( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, + pipelineIdentifier string, executionNum int64, ) (*types.Execution, error) { repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return nil, fmt.Errorf("failed to find repo by ref: %w", err) } - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineView) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineView) if err != nil { return nil, fmt.Errorf("failed to authorize: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return nil, fmt.Errorf("failed to find pipeline: %w", err) } diff --git a/app/api/controller/execution/list.go b/app/api/controller/execution/list.go index 3cda998a3..94886b3af 100644 --- a/app/api/controller/execution/list.go +++ b/app/api/controller/execution/list.go @@ -29,7 +29,7 @@ func (c *Controller) List( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, + pipelineIdentifier string, pagination types.Pagination, ) ([]*types.Execution, int64, error) { repo, err := c.repoStore.FindByRef(ctx, repoRef) @@ -37,12 +37,12 @@ func (c *Controller) List( return nil, 0, fmt.Errorf("failed to find repo by ref: %w", err) } - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineView) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineView) if err != nil { return nil, 0, fmt.Errorf("failed to authorize: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return nil, 0, fmt.Errorf("failed to find pipeline: %w", err) } diff --git a/app/api/controller/githook/pre_receive.go b/app/api/controller/githook/pre_receive.go index 601833395..6230faa2a 100644 --- a/app/api/controller/githook/pre_receive.go +++ b/app/api/controller/githook/pre_receive.go @@ -155,7 +155,7 @@ func (c *Controller) checkProtectionRules( for _, ruleViolation := range ruleViolations { criticalViolation = criticalViolation || ruleViolation.IsCritical() for _, violation := range ruleViolation.Violations { - message := fmt.Sprintf("Rule %q violation: %s", ruleViolation.Rule.UID, violation.Message) + message := fmt.Sprintf("Rule %q violation: %s", ruleViolation.Rule.Identifier, violation.Message) output.Messages = append(output.Messages, message) } } diff --git a/app/api/controller/logs/find.go b/app/api/controller/logs/find.go index 740813a08..3e572b71d 100644 --- a/app/api/controller/logs/find.go +++ b/app/api/controller/logs/find.go @@ -30,7 +30,7 @@ func (c *Controller) Find( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, + pipelineIdentifier string, executionNum int64, stageNum int, stepNum int, @@ -39,12 +39,12 @@ func (c *Controller) Find( if err != nil { return nil, fmt.Errorf("failed to find repo by ref: %w", err) } - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineView) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineView) if err != nil { return nil, fmt.Errorf("failed to authorize pipeline: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return nil, fmt.Errorf("failed to find pipeline: %w", err) } diff --git a/app/api/controller/logs/tail.go b/app/api/controller/logs/tail.go index 1c49f2009..bb27bd6f9 100644 --- a/app/api/controller/logs/tail.go +++ b/app/api/controller/logs/tail.go @@ -28,7 +28,7 @@ func (c *Controller) Tail( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, + pipelineIdentifier string, executionNum int64, stageNum int, stepNum int, @@ -37,11 +37,11 @@ func (c *Controller) Tail( if err != nil { return nil, nil, fmt.Errorf("failed to find repo by ref: %w", err) } - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineView) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineView) if err != nil { return nil, nil, fmt.Errorf("failed to authorize pipeline: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return nil, nil, fmt.Errorf("failed to find pipeline: %w", err) } diff --git a/app/api/controller/pipeline/controller.go b/app/api/controller/pipeline/controller.go index d0618917e..04c3589ef 100644 --- a/app/api/controller/pipeline/controller.go +++ b/app/api/controller/pipeline/controller.go @@ -17,12 +17,10 @@ package pipeline import ( "github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/store" - "github.com/harness/gitness/types/check" ) type Controller struct { defaultBranch string - uidCheck check.PathUID repoStore store.RepoStore triggerStore store.TriggerStore authorizer authz.Authorizer @@ -30,14 +28,12 @@ type Controller struct { } func NewController( - uidCheck check.PathUID, authorizer authz.Authorizer, repoStore store.RepoStore, triggerStore store.TriggerStore, pipelineStore store.PipelineStore, ) *Controller { return &Controller{ - uidCheck: uidCheck, repoStore: repoStore, triggerStore: triggerStore, authorizer: authorizer, diff --git a/app/api/controller/pipeline/create.go b/app/api/controller/pipeline/create.go index 327e54404..250c5b248 100644 --- a/app/api/controller/pipeline/create.go +++ b/app/api/controller/pipeline/create.go @@ -37,8 +37,10 @@ var ( ) type CreateInput struct { - Description string `json:"description"` - UID string `json:"uid"` + Description string `json:"description"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` Disabled bool `json:"disabled"` DefaultBranch string `json:"default_branch"` ConfigPath string `json:"config_path"` @@ -50,6 +52,10 @@ func (c *Controller) Create( repoRef string, in *CreateInput, ) (*types.Pipeline, error) { + if err := c.sanitizeCreateInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) + } + repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return nil, fmt.Errorf("failed to find repo by ref: %w", err) @@ -60,16 +66,12 @@ func (c *Controller) Create( return nil, fmt.Errorf("failed to authorize pipeline: %w", err) } - if err := c.sanitizeCreateInput(in); err != nil { - return nil, fmt.Errorf("failed to sanitize input: %w", err) - } - var pipeline *types.Pipeline now := time.Now().UnixMilli() pipeline = &types.Pipeline{ Description: in.Description, RepoID: repo.ID, - UID: in.UID, + Identifier: in.Identifier, Disabled: in.Disabled, CreatedBy: session.Principal.ID, Seq: 0, @@ -94,7 +96,7 @@ func (c *Controller) Create( PipelineID: pipeline.ID, RepoID: pipeline.RepoID, CreatedBy: session.Principal.ID, - UID: "default", + Identifier: "default", Actions: []enum.TriggerAction{enum.TriggerActionPullReqCreated, enum.TriggerActionPullReqReopened, enum.TriggerActionPullReqBranchUpdated}, Disabled: false, @@ -109,7 +111,12 @@ func (c *Controller) Create( } func (c *Controller) sanitizeCreateInput(in *CreateInput) error { - if err := c.uidCheck(in.UID, false); err != nil { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + + if err := check.Identifier(in.Identifier); err != nil { return err } diff --git a/app/api/controller/pipeline/delete.go b/app/api/controller/pipeline/delete.go index ea6d31d44..129179c9f 100644 --- a/app/api/controller/pipeline/delete.go +++ b/app/api/controller/pipeline/delete.go @@ -23,18 +23,23 @@ import ( "github.com/harness/gitness/types/enum" ) -func (c *Controller) Delete(ctx context.Context, session *auth.Session, repoRef string, uid string) error { +func (c *Controller) Delete( + ctx context.Context, + session *auth.Session, + repoRef string, + identifier string, +) error { repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return fmt.Errorf("failed to find repo by ref: %w", err) } - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, uid, enum.PermissionPipelineDelete) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, identifier, enum.PermissionPipelineDelete) if err != nil { return fmt.Errorf("failed to authorize pipeline: %w", err) } - err = c.pipelineStore.DeleteByUID(ctx, repo.ID, uid) + err = c.pipelineStore.DeleteByIdentifier(ctx, repo.ID, identifier) if err != nil { return fmt.Errorf("could not delete pipeline: %w", err) } diff --git a/app/api/controller/pipeline/find.go b/app/api/controller/pipeline/find.go index 1ec4a6acf..d1ce827f8 100644 --- a/app/api/controller/pipeline/find.go +++ b/app/api/controller/pipeline/find.go @@ -28,15 +28,15 @@ func (c *Controller) Find( ctx context.Context, session *auth.Session, repoRef string, - uid string, + identifier string, ) (*types.Pipeline, error) { repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return nil, fmt.Errorf("failed to find repo by ref: %w", err) } - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, uid, enum.PermissionPipelineView) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, identifier, enum.PermissionPipelineView) if err != nil { return nil, fmt.Errorf("failed to authorize pipeline: %w", err) } - return c.pipelineStore.FindByUID(ctx, repo.ID, uid) + return c.pipelineStore.FindByIdentifier(ctx, repo.ID, identifier) } diff --git a/app/api/controller/pipeline/update.go b/app/api/controller/pipeline/update.go index d8d99a131..7f046fad4 100644 --- a/app/api/controller/pipeline/update.go +++ b/app/api/controller/pipeline/update.go @@ -27,7 +27,9 @@ import ( ) type UpdateInput struct { - UID *string `json:"uid"` + // TODO [CODE-1363]: remove after identifier migration. + UID *string `json:"uid" deprecated:"true"` + Identifier *string `json:"identifier"` Description *string `json:"description"` Disabled *bool `json:"disabled"` ConfigPath *string `json:"config_path"` @@ -37,14 +39,14 @@ func (c *Controller) Update( ctx context.Context, session *auth.Session, repoRef string, - uid string, + identifier string, in *UpdateInput, ) (*types.Pipeline, error) { repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return nil, fmt.Errorf("failed to find repo by ref: %w", err) } - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, uid, enum.PermissionPipelineEdit) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, identifier, enum.PermissionPipelineEdit) if err != nil { return nil, fmt.Errorf("failed to authorize pipeline: %w", err) } @@ -53,14 +55,14 @@ func (c *Controller) Update( return nil, fmt.Errorf("failed to sanitize input: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, uid) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, identifier) if err != nil { return nil, fmt.Errorf("failed to find pipeline: %w", err) } return c.pipelineStore.UpdateOptLock(ctx, pipeline, func(pipeline *types.Pipeline) error { - if in.UID != nil { - pipeline.UID = *in.UID + if in.Identifier != nil { + pipeline.Identifier = *in.Identifier } if in.Description != nil { pipeline.Description = *in.Description @@ -77,8 +79,13 @@ func (c *Controller) Update( } func (c *Controller) sanitizeUpdateInput(in *UpdateInput) error { - if in.UID != nil { - if err := c.uidCheck(*in.UID, false); err != nil { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == nil { + in.Identifier = in.UID + } + + if in.Identifier != nil { + if err := check.Identifier(*in.Identifier); err != nil { return err } } diff --git a/app/api/controller/pipeline/wire.go b/app/api/controller/pipeline/wire.go index 592add22e..44909b6bc 100644 --- a/app/api/controller/pipeline/wire.go +++ b/app/api/controller/pipeline/wire.go @@ -17,7 +17,6 @@ package pipeline import ( "github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/store" - "github.com/harness/gitness/types/check" "github.com/google/wire" ) @@ -28,12 +27,15 @@ var WireSet = wire.NewSet( ) func ProvideController( - uidCheck check.PathUID, repoStore store.RepoStore, triggerStore store.TriggerStore, authorizer authz.Authorizer, pipelineStore store.PipelineStore, ) *Controller { - return NewController(uidCheck, authorizer, - repoStore, triggerStore, pipelineStore) + return NewController( + authorizer, + repoStore, + triggerStore, + pipelineStore, + ) } diff --git a/app/api/controller/pullreq/codeowner.go b/app/api/controller/pullreq/codeowner.go index b1c827003..097b39982 100644 --- a/app/api/controller/pullreq/codeowner.go +++ b/app/api/controller/pullreq/codeowner.go @@ -73,7 +73,7 @@ func mapCodeOwnerEvaluation(ownerEvaluation *codeowners.Evaluation) []types.Code userGroupEvaluations[k] = mapOwner(userGroupOwner) } userGroupOwnerEvaluations[j] = types.UserGroupOwnerEvaluation{ - ID: userGroupOwnerEvaluation.ID, + ID: userGroupOwnerEvaluation.Identifier, Name: userGroupOwnerEvaluation.Name, Evaluations: userGroupEvaluations, } diff --git a/app/api/controller/pullreq/controller.go b/app/api/controller/pullreq/controller.go index d23b9d1de..f948af791 100644 --- a/app/api/controller/pullreq/controller.go +++ b/app/api/controller/pullreq/controller.go @@ -126,12 +126,12 @@ func (c *Controller) verifyBranchExistence(ctx context.Context, }) if errors.AsStatus(err) == errors.StatusNotFound { return "", usererror.BadRequest( - fmt.Sprintf("branch %s does not exist in the repository %s", branch, repo.UID)) + fmt.Sprintf("branch %q does not exist in the repository %q", branch, repo.Identifier)) } if err != nil { return "", fmt.Errorf( - "failed to check existence of the branch %s in the repository %s: %w", - branch, repo.UID, err) + "failed to check existence of the branch %q in the repository %q: %w", + branch, repo.Identifier, err) } return ref.SHA, nil diff --git a/app/api/controller/pullreq/locks.go b/app/api/controller/pullreq/locks.go index 6adceb47e..6f6738da9 100644 --- a/app/api/controller/pullreq/locks.go +++ b/app/api/controller/pullreq/locks.go @@ -30,11 +30,11 @@ import ( func (c *Controller) lockPR( ctx context.Context, - repoUID string, + repoID int64, prNum int64, expiry time.Duration, ) (func(), error) { - key := repoUID + "/pulls" + key := fmt.Sprintf("%d/pulls", repoID) if prNum != 0 { key += "/" + strconv.FormatInt(prNum, 10) } @@ -44,7 +44,7 @@ func (c *Controller) lockPR( ctx = logging.NewContext(ctx, func(c zerolog.Context) zerolog.Context { return c. Str("pullreq_lock", key). - Str("repo_uid", repoUID) + Int64("repo_id", repoID) }) mutex, err := c.mtxManager.NewMutex( @@ -54,11 +54,11 @@ func (c *Controller) lockPR( lock.WithTimeoutFactor(4/expiry.Seconds()), // 4s ) if err != nil { - return nil, fmt.Errorf("failed to create new mutex for pr %d in repo %q: %w", prNum, repoUID, err) + return nil, fmt.Errorf("failed to create new mutex for pr %d in repo %q: %w", prNum, repoID, err) } err = mutex.Lock(ctx) if err != nil { - return nil, fmt.Errorf("failed to lock mutex for pr %d in repo %q: %w", prNum, repoUID, err) + return nil, fmt.Errorf("failed to lock mutex for pr %d in repo %q: %w", prNum, repoID, err) } log.Ctx(ctx).Debug().Msgf("successfully locked PR (expiry: %s)", expiry) diff --git a/app/api/controller/pullreq/merge.go b/app/api/controller/pullreq/merge.go index e48877f5c..6a31acc66 100644 --- a/app/api/controller/pullreq/merge.go +++ b/app/api/controller/pullreq/merge.go @@ -106,7 +106,7 @@ func (c *Controller) Merge( // pr is already merged. unlock, err := c.lockPR( ctx, - targetRepo.GitUID, + targetRepo.ID, 0, // 0 means locks all PRs for this repo timeout+30*time.Second, // add 30s to the lock to give enough time for pre + post merge ) diff --git a/app/api/controller/repo/controller.go b/app/api/controller/repo/controller.go index 7427f2f5f..6b4abcd30 100644 --- a/app/api/controller/repo/controller.go +++ b/app/api/controller/repo/controller.go @@ -36,7 +36,6 @@ import ( "github.com/harness/gitness/lock" "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,7 +49,6 @@ type Controller struct { tx dbtx.Transactor urlProvider url.Provider - uidCheck check.PathUID authorizer authz.Authorizer repoStore store.RepoStore spaceStore store.SpaceStore @@ -72,7 +70,6 @@ func NewController( config *types.Config, tx dbtx.Transactor, urlProvider url.Provider, - uidCheck check.PathUID, authorizer authz.Authorizer, repoStore store.RepoStore, spaceStore store.SpaceStore, @@ -94,7 +91,6 @@ func NewController( publicResourceCreationEnabled: config.PublicResourceCreationEnabled, tx: tx, urlProvider: urlProvider, - uidCheck: uidCheck, authorizer: authorizer, repoStore: repoStore, spaceStore: spaceStore, diff --git a/app/api/controller/repo/create.go b/app/api/controller/repo/create.go index d9636c5fb..f7fb48920 100644 --- a/app/api/controller/repo/create.go +++ b/app/api/controller/repo/create.go @@ -44,8 +44,10 @@ var ( ) type CreateInput struct { - ParentRef string `json:"parent_ref"` - UID string `json:"uid"` + ParentRef string `json:"parent_ref"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` DefaultBranch string `json:"default_branch"` Description string `json:"description"` IsPublic bool `json:"is_public"` @@ -59,15 +61,15 @@ type CreateInput struct { // //nolint:gocognit func (c *Controller) Create(ctx context.Context, session *auth.Session, in *CreateInput) (*types.Repository, error) { + if err := c.sanitizeCreateInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) + } + parentSpace, err := c.getSpaceCheckAuthRepoCreation(ctx, session, in.ParentRef) if err != nil { return nil, err } - if err := c.sanitizeCreateInput(in); err != nil { - return nil, fmt.Errorf("failed to sanitize input: %w", err) - } - var repo *types.Repository err = c.tx.WithTx(ctx, func(ctx context.Context) error { if err := c.resourceLimiter.RepoCount(ctx, parentSpace.ID, 1); err != nil { @@ -83,7 +85,7 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea repo = &types.Repository{ Version: 0, ParentID: parentSpace.ID, - UID: in.UID, + Identifier: in.Identifier, GitUID: gitResp.UID, Description: in.Description, IsPublic: in.IsPublic, @@ -134,8 +136,8 @@ func (c *Controller) getSpaceCheckAuthRepoCreation( // create is a special case - check permission without specific resource scope := &types.Scope{SpacePath: space.Path} resource := &types.Resource{ - Type: enum.ResourceTypeRepo, - Name: "", + Type: enum.ResourceTypeRepo, + Identifier: "", } err = apiauth.Check(ctx, c.authorizer, session, scope, resource, enum.PermissionRepoEdit) @@ -147,6 +149,11 @@ func (c *Controller) getSpaceCheckAuthRepoCreation( } func (c *Controller) sanitizeCreateInput(in *CreateInput) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + if in.IsPublic && !c.publicResourceCreationEnabled { return errPublicRepoCreationDisabled } @@ -155,7 +162,7 @@ func (c *Controller) sanitizeCreateInput(in *CreateInput) error { return err } - if err := c.uidCheck(in.UID, false); err != nil { + if err := check.RepoIdentifier(in.Identifier); err != nil { return err } @@ -179,7 +186,7 @@ func (c *Controller) createGitRepository(ctx context.Context, session *auth.Sess ) files := make([]git.File, 0, 3) // readme, gitignore, licence if in.Readme { - content = createReadme(in.UID, in.Description) + content = createReadme(in.Identifier, in.Description) files = append(files, git.File{ Path: "README.md", Content: content, diff --git a/app/api/controller/repo/import.go b/app/api/controller/repo/import.go index 51c00a97f..595f7f8d7 100644 --- a/app/api/controller/repo/import.go +++ b/app/api/controller/repo/import.go @@ -22,11 +22,14 @@ import ( "github.com/harness/gitness/app/auth" "github.com/harness/gitness/app/services/importer" "github.com/harness/gitness/types" + "github.com/harness/gitness/types/check" ) type ImportInput struct { - ParentRef string `json:"parent_ref"` - UID string `json:"uid"` + ParentRef string `json:"parent_ref"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` Description string `json:"description"` Provider importer.Provider `json:"provider"` @@ -37,16 +40,15 @@ type ImportInput struct { // Import creates a new empty repository and starts git import to it from a remote repository. func (c *Controller) Import(ctx context.Context, session *auth.Session, in *ImportInput) (*types.Repository, error) { + if err := c.sanitizeImportInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) + } + parentSpace, err := c.getSpaceCheckAuthRepoCreation(ctx, session, in.ParentRef) if err != nil { return nil, err } - err = c.sanitizeImportInput(in) - if err != nil { - return nil, fmt.Errorf("failed to sanitize input: %w", err) - } - var repo *types.Repository err = c.tx.WithTx(ctx, func(ctx context.Context) error { if err := c.resourceLimiter.RepoCount(ctx, parentSpace.ID, 1); err != nil { @@ -59,7 +61,7 @@ func (c *Controller) Import(ctx context.Context, session *auth.Session, in *Impo } repo = remoteRepository.ToRepo( parentSpace.ID, - in.UID, + in.Identifier, in.Description, &session.Principal, c.publicResourceCreationEnabled, @@ -87,11 +89,16 @@ func (c *Controller) Import(ctx context.Context, session *auth.Session, in *Impo } func (c *Controller) sanitizeImportInput(in *ImportInput) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + if err := c.validateParentRef(in.ParentRef); err != nil { return err } - if err := c.uidCheck(in.UID, false); err != nil { + if err := check.RepoIdentifier(in.Identifier); err != nil { return err } diff --git a/app/api/controller/repo/move.go b/app/api/controller/repo/move.go index ab4132881..cc7023483 100644 --- a/app/api/controller/repo/move.go +++ b/app/api/controller/repo/move.go @@ -22,23 +22,26 @@ import ( "github.com/harness/gitness/app/api/usererror" "github.com/harness/gitness/app/auth" "github.com/harness/gitness/types" + "github.com/harness/gitness/types/check" "github.com/harness/gitness/types/enum" ) // MoveInput is used for moving a repo. type MoveInput struct { - UID *string `json:"uid"` + // TODO [CODE-1363]: remove after identifier migration. + UID *string `json:"uid" deprecated:"true"` + Identifier *string `json:"identifier"` } func (i *MoveInput) hasChanges(repo *types.Repository) bool { - if i.UID != nil && *i.UID != repo.UID { + if i.Identifier != nil && *i.Identifier != repo.Identifier { return true } return false } -// Move moves a repository to a new space uid. +// Move moves a repository to a new identifier. // TODO: Add support for moving to other parents and aliases. // //nolint:gocognit // refactor if needed @@ -47,6 +50,10 @@ func (c *Controller) Move(ctx context.Context, repoRef string, in *MoveInput, ) (*types.Repository, error) { + if err := c.sanitizeMoveInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) + } + repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return nil, err @@ -64,13 +71,9 @@ func (c *Controller) Move(ctx context.Context, return repo, nil } - if err = c.sanitizeMoveInput(in); err != nil { - return nil, fmt.Errorf("failed to sanitize input: %w", err) - } - repo, err = c.repoStore.UpdateOptLock(ctx, repo, func(r *types.Repository) error { - if in.UID != nil { - r.UID = *in.UID + if in.Identifier != nil { + r.Identifier = *in.Identifier } return nil }) @@ -84,8 +87,13 @@ func (c *Controller) Move(ctx context.Context, } func (c *Controller) sanitizeMoveInput(in *MoveInput) error { - if in.UID != nil { - if err := c.uidCheck(*in.UID, false); err != nil { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == nil { + in.Identifier = in.UID + } + + if in.Identifier != nil { + if err := check.RepoIdentifier(*in.Identifier); err != nil { return err } } diff --git a/app/api/controller/repo/rule_create.go b/app/api/controller/repo/rule_create.go index 5b94506a0..8ccb56ead 100644 --- a/app/api/controller/repo/rule_create.go +++ b/app/api/controller/repo/rule_create.go @@ -29,9 +29,11 @@ import ( ) type RuleCreateInput struct { - Type types.RuleType `json:"type"` - State enum.RuleState `json:"state"` - UID string `json:"uid"` + Type types.RuleType `json:"type"` + State enum.RuleState `json:"state"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` Description string `json:"description"` Pattern protection.Pattern `json:"pattern"` Definition json.RawMessage `json:"definition"` @@ -39,7 +41,12 @@ type RuleCreateInput struct { // sanitize validates and sanitizes the create rule input data. func (in *RuleCreateInput) sanitize() error { - if err := check.UID(in.UID); err != nil { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + + if err := check.Identifier(in.Identifier); err != nil { return err } @@ -70,12 +77,11 @@ func (c *Controller) RuleCreate(ctx context.Context, repoRef string, in *RuleCreateInput, ) (*types.Rule, error) { - repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit, false) - if err != nil { + if err := in.sanitize(); err != nil { return nil, err } - err = in.sanitize() + repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit, false) if err != nil { return nil, err } @@ -94,7 +100,7 @@ func (c *Controller) RuleCreate(ctx context.Context, SpaceID: nil, Type: in.Type, State: in.State, - UID: in.UID, + Identifier: in.Identifier, Description: in.Description, Pattern: in.Pattern.JSON(), Definition: in.Definition, diff --git a/app/api/controller/repo/rule_delete.go b/app/api/controller/repo/rule_delete.go index 1c61e76c6..96e4a71eb 100644 --- a/app/api/controller/repo/rule_delete.go +++ b/app/api/controller/repo/rule_delete.go @@ -22,20 +22,20 @@ import ( "github.com/harness/gitness/types/enum" ) -// RuleDelete deletes a protection rule by UID. +// RuleDelete deletes a protection rule by identifier. func (c *Controller) RuleDelete(ctx context.Context, session *auth.Session, repoRef string, - uid string, + identifier string, ) error { repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit, false) if err != nil { return err } - r, err := c.ruleStore.FindByUID(ctx, nil, &repo.ID, uid) + r, err := c.ruleStore.FindByIdentifier(ctx, nil, &repo.ID, identifier) if err != nil { - return fmt.Errorf("failed to find repository-level protection rule by uid: %w", err) + return fmt.Errorf("failed to find repository-level protection rule by identifier: %w", err) } err = c.ruleStore.Delete(ctx, r.ID) diff --git a/app/api/controller/repo/rule_find.go b/app/api/controller/repo/rule_find.go index dd24d72f4..bedef7ec2 100644 --- a/app/api/controller/repo/rule_find.go +++ b/app/api/controller/repo/rule_find.go @@ -23,20 +23,20 @@ import ( "github.com/harness/gitness/types/enum" ) -// RuleFind returns the protection rule by UID. +// RuleFind returns the protection rule by identifier. func (c *Controller) RuleFind(ctx context.Context, session *auth.Session, repoRef string, - uid string, + identifier string, ) (*types.Rule, error) { repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoView, true) if err != nil { return nil, err } - r, err := c.ruleStore.FindByUID(ctx, nil, &repo.ID, uid) + r, err := c.ruleStore.FindByIdentifier(ctx, nil, &repo.ID, identifier) if err != nil { - return nil, fmt.Errorf("failed to find repository-level protection rule by uid: %w", err) + return nil, fmt.Errorf("failed to find repository-level protection rule by identifier: %w", err) } r.Users, err = c.getRuleUsers(ctx, r) diff --git a/app/api/controller/repo/rule_update.go b/app/api/controller/repo/rule_update.go index 38bc4cd9f..947f2cfa8 100644 --- a/app/api/controller/repo/rule_update.go +++ b/app/api/controller/repo/rule_update.go @@ -28,7 +28,9 @@ import ( ) type RuleUpdateInput struct { - UID string `json:"uid"` + // TODO [CODE-1363]: remove after identifier migration. + UID *string `json:"uid" deprecated:"true"` + Identifier *string `json:"identifier"` State *enum.RuleState `json:"state"` Description *string `json:"description"` Pattern *protection.Pattern `json:"pattern"` @@ -37,8 +39,13 @@ type RuleUpdateInput struct { // sanitize validates and sanitizes the update rule input data. func (in *RuleUpdateInput) sanitize() error { - if in.UID != "" { - if err := check.UID(in.UID); err != nil { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == nil { + in.Identifier = in.UID + } + + if in.Identifier != nil { + if err := check.Identifier(*in.Identifier); err != nil { return err } } @@ -66,29 +73,28 @@ func (in *RuleUpdateInput) sanitize() error { } func (in *RuleUpdateInput) isEmpty() bool { - return in.UID == "" && in.State == nil && in.Description == nil && in.Pattern == nil && in.Definition == nil + return in.Identifier == nil && in.State == nil && in.Description == nil && in.Pattern == nil && in.Definition == nil } // RuleUpdate updates an existing protection rule for a repository. func (c *Controller) RuleUpdate(ctx context.Context, session *auth.Session, repoRef string, - uid string, + identifier string, in *RuleUpdateInput, ) (*types.Rule, error) { + if err := in.sanitize(); err != nil { + return nil, err + } + repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit, false) if err != nil { return nil, err } - err = in.sanitize() + r, err := c.ruleStore.FindByIdentifier(ctx, nil, &repo.ID, identifier) if err != nil { - return nil, err - } - - r, err := c.ruleStore.FindByUID(ctx, nil, &repo.ID, uid) - if err != nil { - return nil, fmt.Errorf("failed to get a repository rule by its uid: %w", err) + return nil, fmt.Errorf("failed to get a repository rule by its identifier: %w", err) } if in.isEmpty() { @@ -99,8 +105,8 @@ func (c *Controller) RuleUpdate(ctx context.Context, return r, nil } - if in.UID != "" { - r.UID = in.UID + if in.Identifier != nil { + r.Identifier = *in.Identifier } if in.State != nil { r.State = *in.State diff --git a/app/api/controller/repo/wire.go b/app/api/controller/repo/wire.go index cb4c0c5d3..6d0b41756 100644 --- a/app/api/controller/repo/wire.go +++ b/app/api/controller/repo/wire.go @@ -28,7 +28,6 @@ import ( "github.com/harness/gitness/lock" "github.com/harness/gitness/store/database/dbtx" "github.com/harness/gitness/types" - "github.com/harness/gitness/types/check" "github.com/google/wire" ) @@ -42,7 +41,6 @@ func ProvideController( config *types.Config, tx dbtx.Transactor, urlProvider url.Provider, - uidCheck check.PathUID, authorizer authz.Authorizer, repoStore store.RepoStore, spaceStore store.SpaceStore, @@ -60,7 +58,7 @@ func ProvideController( mtxManager lock.MutexManager, ) *Controller { return NewController(config, tx, urlProvider, - uidCheck, authorizer, repoStore, + authorizer, repoStore, spaceStore, pipelineStore, principalStore, ruleStore, principalInfoCache, protectionManager, rpcClient, importer, codeOwners, reporeporter, indexer, limiter, mtxManager) diff --git a/app/api/controller/secret/controller.go b/app/api/controller/secret/controller.go index 9e96039d1..f5e28b83e 100644 --- a/app/api/controller/secret/controller.go +++ b/app/api/controller/secret/controller.go @@ -18,11 +18,9 @@ import ( "github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/store" "github.com/harness/gitness/encrypt" - "github.com/harness/gitness/types/check" ) type Controller struct { - uidCheck check.PathUID encrypter encrypt.Encrypter secretStore store.SecretStore authorizer authz.Authorizer @@ -30,14 +28,12 @@ type Controller struct { } func NewController( - uidCheck check.PathUID, authorizer authz.Authorizer, encrypter encrypt.Encrypter, secretStore store.SecretStore, spaceStore store.SpaceStore, ) *Controller { return &Controller{ - uidCheck: uidCheck, encrypter: encrypter, secretStore: secretStore, authorizer: authorizer, diff --git a/app/api/controller/secret/create.go b/app/api/controller/secret/create.go index ddbd9551a..910c7df61 100644 --- a/app/api/controller/secret/create.go +++ b/app/api/controller/secret/create.go @@ -39,25 +39,27 @@ var ( type CreateInput struct { Description string `json:"description"` SpaceRef string `json:"space_ref"` // Ref of the parent space - UID string `json:"uid"` - Data string `json:"data"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` + Data string `json:"data"` } func (c *Controller) Create(ctx context.Context, session *auth.Session, in *CreateInput) (*types.Secret, error) { + if err := c.sanitizeCreateInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) + } + parentSpace, err := c.spaceStore.FindByRef(ctx, in.SpaceRef) if err != nil { return nil, fmt.Errorf("failed to find parent by ref: %w", err) } - err = apiauth.CheckSecret(ctx, c.authorizer, session, parentSpace.Path, in.UID, enum.PermissionSecretEdit) + err = apiauth.CheckSecret(ctx, c.authorizer, session, parentSpace.Path, in.Identifier, enum.PermissionSecretEdit) if err != nil { return nil, err } - if err := c.sanitizeCreateInput(in); err != nil { - return nil, fmt.Errorf("failed to sanitize input: %w", err) - } - var secret *types.Secret now := time.Now().UnixMilli() secret = &types.Secret{ @@ -65,7 +67,7 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea Description: in.Description, Data: in.Data, SpaceID: parentSpace.ID, - UID: in.UID, + Identifier: in.Identifier, Created: now, Updated: now, Version: 0, @@ -83,13 +85,18 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea } func (c *Controller) sanitizeCreateInput(in *CreateInput) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + parentRefAsID, err := strconv.ParseInt(in.SpaceRef, 10, 64) if (err == nil && parentRefAsID <= 0) || (len(strings.TrimSpace(in.SpaceRef)) == 0) { return errSecretRequiresParent } - if err := c.uidCheck(in.UID, false); err != nil { + if err := check.Identifier(in.Identifier); err != nil { return err } diff --git a/app/api/controller/secret/delete.go b/app/api/controller/secret/delete.go index 2b7b3a614..efbbe6c34 100644 --- a/app/api/controller/secret/delete.go +++ b/app/api/controller/secret/delete.go @@ -23,17 +23,18 @@ import ( "github.com/harness/gitness/types/enum" ) -func (c *Controller) Delete(ctx context.Context, session *auth.Session, spaceRef string, uid string) error { +func (c *Controller) Delete(ctx context.Context, session *auth.Session, spaceRef string, identifier string) error { space, err := c.spaceStore.FindByRef(ctx, spaceRef) if err != nil { return fmt.Errorf("failed to find space: %w", err) } - err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, uid, enum.PermissionSecretDelete) + err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, identifier, enum.PermissionSecretDelete) if err != nil { return fmt.Errorf("failed to authorize: %w", err) } - err = c.secretStore.DeleteByUID(ctx, space.ID, uid) + + err = c.secretStore.DeleteByIdentifier(ctx, space.ID, identifier) if err != nil { return fmt.Errorf("could not delete secret: %w", err) } diff --git a/app/api/controller/secret/find.go b/app/api/controller/secret/find.go index d6a8d1b7b..7923e32a0 100644 --- a/app/api/controller/secret/find.go +++ b/app/api/controller/secret/find.go @@ -28,17 +28,17 @@ func (c *Controller) Find( ctx context.Context, session *auth.Session, spaceRef string, - uid string, + identifier string, ) (*types.Secret, error) { space, err := c.spaceStore.FindByRef(ctx, spaceRef) if err != nil { return nil, fmt.Errorf("failed to find space: %w", err) } - err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, uid, enum.PermissionSecretView) + err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, identifier, enum.PermissionSecretView) if err != nil { return nil, fmt.Errorf("failed to authorize: %w", err) } - secret, err := c.secretStore.FindByUID(ctx, space.ID, uid) + secret, err := c.secretStore.FindByIdentifier(ctx, space.ID, identifier) if err != nil { return nil, fmt.Errorf("failed to find secret: %w", err) } diff --git a/app/api/controller/secret/update.go b/app/api/controller/secret/update.go index f2d8a4f8c..8435b13c8 100644 --- a/app/api/controller/secret/update.go +++ b/app/api/controller/secret/update.go @@ -28,7 +28,9 @@ import ( // UpdateInput is used for updating a repo. type UpdateInput struct { - UID *string `json:"uid"` + // TODO [CODE-1363]: remove after identifier migration. + UID *string `json:"uid" deprecated:"true"` + Identifier *string `json:"identifier"` Description *string `json:"description"` Data *string `json:"data"` } @@ -37,31 +39,31 @@ func (c *Controller) Update( ctx context.Context, session *auth.Session, spaceRef string, - uid string, + identifier string, in *UpdateInput, ) (*types.Secret, error) { + if err := c.sanitizeUpdateInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) + } + space, err := c.spaceStore.FindByRef(ctx, spaceRef) if err != nil { return nil, fmt.Errorf("failed to find space: %w", err) } - err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, uid, enum.PermissionSecretEdit) + err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, identifier, enum.PermissionSecretEdit) if err != nil { return nil, fmt.Errorf("failed to authorize: %w", err) } - if err = c.sanitizeUpdateInput(in); err != nil { - return nil, fmt.Errorf("failed to sanitize input: %w", err) - } - - secret, err := c.secretStore.FindByUID(ctx, space.ID, uid) + secret, err := c.secretStore.FindByIdentifier(ctx, space.ID, identifier) if err != nil { return nil, fmt.Errorf("failed to find secret: %w", err) } return c.secretStore.UpdateOptLock(ctx, secret, func(original *types.Secret) error { - if in.UID != nil { - original.UID = *in.UID + if in.Identifier != nil { + original.Identifier = *in.Identifier } if in.Description != nil { original.Description = *in.Description @@ -79,8 +81,13 @@ func (c *Controller) Update( } func (c *Controller) sanitizeUpdateInput(in *UpdateInput) error { - if in.UID != nil { - if err := c.uidCheck(*in.UID, false); err != nil { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == nil { + in.Identifier = in.UID + } + + if in.Identifier != nil { + if err := check.Identifier(*in.Identifier); err != nil { return err } } diff --git a/app/api/controller/secret/wire.go b/app/api/controller/secret/wire.go index 2681d2b43..9cb681094 100644 --- a/app/api/controller/secret/wire.go +++ b/app/api/controller/secret/wire.go @@ -18,7 +18,6 @@ import ( "github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/store" "github.com/harness/gitness/encrypt" - "github.com/harness/gitness/types/check" "github.com/google/wire" ) @@ -29,11 +28,10 @@ var WireSet = wire.NewSet( ) func ProvideController( - uidCheck check.PathUID, encrypter encrypt.Encrypter, secretStore store.SecretStore, authorizer authz.Authorizer, spaceStore store.SpaceStore, ) *Controller { - return NewController(uidCheck, authorizer, encrypter, secretStore, spaceStore) + return NewController(authorizer, encrypter, secretStore, spaceStore) } diff --git a/app/api/controller/serviceaccount/create_token.go b/app/api/controller/serviceaccount/create_token.go index 074e09294..ebecadfb1 100644 --- a/app/api/controller/serviceaccount/create_token.go +++ b/app/api/controller/serviceaccount/create_token.go @@ -16,6 +16,7 @@ package serviceaccount import ( "context" + "fmt" "time" apiauth "github.com/harness/gitness/app/api/auth" @@ -27,8 +28,10 @@ import ( ) type CreateTokenInput struct { - UID string `json:"uid"` - Lifetime *time.Duration `json:"lifetime"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` + Lifetime *time.Duration `json:"lifetime"` } // CreateToken creates a new service account access token. @@ -38,15 +41,12 @@ func (c *Controller) CreateToken( saUID string, in *CreateTokenInput, ) (*types.TokenResponse, error) { - sa, err := findServiceAccountFromUID(ctx, c.principalStore, saUID) - if err != nil { - return nil, err + if err := c.sanitizeCreateTokenInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) } - if err = check.UID(in.UID); err != nil { - return nil, err - } - if err = check.TokenLifetime(in.Lifetime, true); err != nil { + sa, err := findServiceAccountFromUID(ctx, c.principalStore, saUID) + if err != nil { return nil, err } @@ -55,12 +55,13 @@ func (c *Controller) CreateToken( sa.ParentType, sa.ParentID, sa.UID, enum.PermissionServiceAccountEdit); err != nil { return nil, err } + token, jwtToken, err := token.CreateSAT( ctx, c.tokenStore, &session.Principal, sa, - in.UID, + in.Identifier, in.Lifetime, ) if err != nil { @@ -69,3 +70,21 @@ func (c *Controller) CreateToken( return &types.TokenResponse{Token: *token, AccessToken: jwtToken}, nil } + +func (c *Controller) sanitizeCreateTokenInput(in *CreateTokenInput) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + + if err := check.Identifier(in.Identifier); err != nil { + return err + } + + //nolint:revive + if err := check.TokenLifetime(in.Lifetime, true); err != nil { + return err + } + + return nil +} diff --git a/app/api/controller/serviceaccount/delete_token.go b/app/api/controller/serviceaccount/delete_token.go index 7722a6ed9..7f05defa4 100644 --- a/app/api/controller/serviceaccount/delete_token.go +++ b/app/api/controller/serviceaccount/delete_token.go @@ -26,8 +26,12 @@ import ( ) // DeleteToken deletes a token of a service account. -func (c *Controller) DeleteToken(ctx context.Context, session *auth.Session, - saUID string, tokenUID string) error { +func (c *Controller) DeleteToken( + ctx context.Context, + session *auth.Session, + saUID string, + identifier string, +) error { sa, err := findServiceAccountFromUID(ctx, c.principalStore, saUID) if err != nil { return err @@ -39,7 +43,7 @@ func (c *Controller) DeleteToken(ctx context.Context, session *auth.Session, return err } - token, err := c.tokenStore.FindByUID(ctx, sa.ID, tokenUID) + token, err := c.tokenStore.FindByIdentifier(ctx, sa.ID, identifier) if err != nil { return err } diff --git a/app/api/controller/space/controller.go b/app/api/controller/space/controller.go index 1bdcf7bca..295f4f925 100644 --- a/app/api/controller/space/controller.go +++ b/app/api/controller/space/controller.go @@ -42,7 +42,7 @@ type Controller struct { tx dbtx.Transactor urlProvider url.Provider sseStreamer sse.Streamer - uidCheck check.PathUID + identifierCheck check.SpaceIdentifier authorizer authz.Authorizer spacePathStore store.SpacePathStore pipelineStore store.PipelineStore @@ -60,7 +60,7 @@ type Controller struct { } func NewController(config *types.Config, tx dbtx.Transactor, urlProvider url.Provider, - sseStreamer sse.Streamer, uidCheck check.PathUID, authorizer authz.Authorizer, + sseStreamer sse.Streamer, identifierCheck check.SpaceIdentifier, authorizer authz.Authorizer, spacePathStore store.SpacePathStore, pipelineStore store.PipelineStore, secretStore store.SecretStore, connectorStore store.ConnectorStore, templateStore store.TemplateStore, spaceStore store.SpaceStore, repoStore store.RepoStore, principalStore store.PrincipalStore, repoCtrl *repo.Controller, @@ -73,7 +73,7 @@ func NewController(config *types.Config, tx dbtx.Transactor, urlProvider url.Pro tx: tx, urlProvider: urlProvider, sseStreamer: sseStreamer, - uidCheck: uidCheck, + identifierCheck: identifierCheck, authorizer: authorizer, spacePathStore: spacePathStore, pipelineStore: pipelineStore, diff --git a/app/api/controller/space/create.go b/app/api/controller/space/create.go index b87dc7819..8dd833b0d 100644 --- a/app/api/controller/space/create.go +++ b/app/api/controller/space/create.go @@ -37,8 +37,10 @@ var ( ) type CreateInput struct { - ParentRef string `json:"parent_ref"` - UID string `json:"uid"` + ParentRef string `json:"parent_ref"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` Description string `json:"description"` IsPublic bool `json:"is_public"` } @@ -51,14 +53,15 @@ func (c *Controller) Create( session *auth.Session, in *CreateInput, ) (*types.Space, error) { + if err := c.sanitizeCreateInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) + } + parentSpace, err := c.getSpaceCheckAuthSpaceCreation(ctx, session, in.ParentRef) if err != nil { return nil, err } - if err := c.sanitizeCreateInput(in); err != nil { - return nil, fmt.Errorf("failed to sanitize input: %w", err) - } var space *types.Space err = c.tx.WithTx(ctx, func(ctx context.Context) error { space, err = c.createSpaceInnerInTX(ctx, session, parentSpace.ID, in) @@ -77,14 +80,14 @@ func (c *Controller) createSpaceInnerInTX( parentID int64, in *CreateInput, ) (*types.Space, error) { - spacePath := in.UID + spacePath := in.Identifier if parentID > 0 { // (re-)read parent path in transaction to ensure correctness parentPath, err := c.spacePathStore.FindPrimaryBySpaceID(ctx, parentID) if err != nil { return nil, fmt.Errorf("failed to find primary path for parent '%d': %w", parentID, err) } - spacePath = paths.Concatinate(parentPath.Value, in.UID) + spacePath = paths.Concatinate(parentPath.Value, in.Identifier) // ensure path is within accepted depth! err = check.PathDepth(spacePath, true) @@ -97,7 +100,7 @@ func (c *Controller) createSpaceInnerInTX( space := &types.Space{ Version: 0, ParentID: parentID, - UID: in.UID, + Identifier: in.Identifier, Description: in.Description, IsPublic: in.IsPublic, Path: spacePath, @@ -111,13 +114,13 @@ func (c *Controller) createSpaceInnerInTX( } pathSegment := &types.SpacePathSegment{ - UID: space.UID, - IsPrimary: true, - SpaceID: space.ID, - ParentID: parentID, - CreatedBy: space.CreatedBy, - Created: now, - Updated: now, + Identifier: space.Identifier, + IsPrimary: true, + SpaceID: space.ID, + ParentID: parentID, + CreatedBy: space.CreatedBy, + Created: now, + Updated: now, } err = c.spacePathStore.InsertSegment(ctx, pathSegment) if err != nil { @@ -170,8 +173,8 @@ func (c *Controller) getSpaceCheckAuthSpaceCreation( // create is a special case - check permission without specific resource scope := &types.Scope{SpacePath: parentSpace.Path} resource := &types.Resource{ - Type: enum.ResourceTypeSpace, - Name: "", + Type: enum.ResourceTypeSpace, + Identifier: "", } if err = apiauth.Check(ctx, c.authorizer, session, scope, resource, enum.PermissionSpaceCreate); err != nil { return nil, fmt.Errorf("authorization failed: %w", err) @@ -181,6 +184,11 @@ func (c *Controller) getSpaceCheckAuthSpaceCreation( } func (c *Controller) sanitizeCreateInput(in *CreateInput) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + if len(in.ParentRef) > 0 && !c.nestedSpacesEnabled { // TODO (Nested Spaces): Remove once support is added return errNestedSpacesNotSupported @@ -200,7 +208,7 @@ func (c *Controller) sanitizeCreateInput(in *CreateInput) error { isRoot = true } - if err := c.uidCheck(in.UID, isRoot); err != nil { + if err := c.identifierCheck(in.Identifier, isRoot); err != nil { return err } diff --git a/app/api/controller/space/import.go b/app/api/controller/space/import.go index 026a6284e..094c5f095 100644 --- a/app/api/controller/space/import.go +++ b/app/api/controller/space/import.go @@ -43,8 +43,8 @@ func (c *Controller) Import(ctx context.Context, session *auth.Session, in *Impo return nil, err } - if in.UID == "" { - in.UID = in.ProviderSpace + if in.Identifier == "" && in.UID == "" { + in.Identifier = in.ProviderSpace } err = c.sanitizeImportInput(in) @@ -80,7 +80,7 @@ func (c *Controller) Import(ctx context.Context, session *auth.Session, in *Impo for i, remoteRepository := range remoteRepositories { repo := remoteRepository.ToRepo( space.ID, - remoteRepository.UID, + remoteRepository.Identifier, "", &session.Principal, c.publicResourceCreationEnabled, diff --git a/app/api/controller/space/import_repositories.go b/app/api/controller/space/import_repositories.go index 866f23080..eaf353b9f 100644 --- a/app/api/controller/space/import_repositories.go +++ b/app/api/controller/space/import_repositories.go @@ -55,8 +55,8 @@ func (c *Controller) getSpaceCheckAuthRepoCreation( // create is a special case - check permission without specific resource scope := &types.Scope{SpacePath: space.Path} resource := &types.Resource{ - Type: enum.ResourceTypeRepo, - Name: "", + Type: enum.ResourceTypeRepo, + Identifier: "", } err = apiauth.Check(ctx, c.authorizer, session, scope, resource, enum.PermissionRepoEdit) @@ -104,7 +104,7 @@ func (c *Controller) ImportRepositories( for _, remoteRepository := range remoteRepositories { repo := remoteRepository.ToRepo( space.ID, - remoteRepository.UID, + remoteRepository.Identifier, "", &session.Principal, c.publicResourceCreationEnabled, diff --git a/app/api/controller/space/move.go b/app/api/controller/space/move.go index a9b6b14fa..7ab78a875 100644 --- a/app/api/controller/space/move.go +++ b/app/api/controller/space/move.go @@ -27,18 +27,20 @@ import ( // MoveInput is used for moving a space. type MoveInput struct { - UID *string `json:"uid"` + // TODO [CODE-1363]: remove after identifier migration. + UID *string `json:"uid" deprecated:"true"` + Identifier *string `json:"identifier"` } func (i *MoveInput) hasChanges(space *types.Space) bool { - if i.UID != nil && *i.UID != space.UID { + if i.Identifier != nil && *i.Identifier != space.Identifier { return true } return false } -// Move moves a space to a new UID. +// Move moves a space to a new identifier. // TODO: Add support for moving to other parents and alias. // //nolint:gocognit // refactor if needed @@ -70,7 +72,7 @@ func (c *Controller) Move( ctx, session, space, - in.UID, + in.Identifier, ); err != nil { return nil, err } @@ -79,8 +81,12 @@ func (c *Controller) Move( } func (c *Controller) sanitizeMoveInput(in *MoveInput, isRoot bool) error { - if in.UID != nil { - if err := c.uidCheck(*in.UID, isRoot); err != nil { + if in.Identifier == nil { + in.Identifier = in.UID + } + + if in.Identifier != nil { + if err := c.identifierCheck(*in.Identifier, isRoot); err != nil { return err } } @@ -92,7 +98,7 @@ func (c *Controller) moveInner( ctx context.Context, session *auth.Session, space *types.Space, - inUID *string, + inIdentifier *string, ) error { return c.tx.WithTx(ctx, func(ctx context.Context) error { // delete old primary segment @@ -102,20 +108,20 @@ func (c *Controller) moveInner( } // update space with move inputs - if inUID != nil { - space.UID = *inUID + if inIdentifier != nil { + space.Identifier = *inIdentifier } // add new primary segment using updated space data now := time.Now().UnixMilli() newPrimarySegment := &types.SpacePathSegment{ - ParentID: space.ParentID, - UID: space.UID, - SpaceID: space.ID, - IsPrimary: true, - CreatedBy: session.Principal.ID, - Created: now, - Updated: now, + ParentID: space.ParentID, + Identifier: space.Identifier, + SpaceID: space.ID, + IsPrimary: true, + CreatedBy: session.Principal.ID, + Created: now, + Updated: now, } err = c.spacePathStore.InsertSegment(ctx, newPrimarySegment) if err != nil { diff --git a/app/api/controller/space/wire.go b/app/api/controller/space/wire.go index 09b319cf7..3fe6f4e30 100644 --- a/app/api/controller/space/wire.go +++ b/app/api/controller/space/wire.go @@ -36,14 +36,14 @@ var WireSet = wire.NewSet( ) func ProvideController(config *types.Config, tx dbtx.Transactor, urlProvider url.Provider, sseStreamer sse.Streamer, - uidCheck check.PathUID, authorizer authz.Authorizer, spacePathStore store.SpacePathStore, + identifierCheck check.SpaceIdentifier, authorizer authz.Authorizer, spacePathStore store.SpacePathStore, pipelineStore store.PipelineStore, secretStore store.SecretStore, connectorStore store.ConnectorStore, templateStore store.TemplateStore, spaceStore store.SpaceStore, repoStore store.RepoStore, principalStore store.PrincipalStore, repoCtrl *repo.Controller, membershipStore store.MembershipStore, importer *importer.Repository, exporter *exporter.Repository, limiter limiter.ResourceLimiter, ) *Controller { - return NewController(config, tx, urlProvider, sseStreamer, uidCheck, authorizer, + return NewController(config, tx, urlProvider, sseStreamer, identifierCheck, authorizer, spacePathStore, pipelineStore, secretStore, connectorStore, templateStore, spaceStore, repoStore, principalStore, diff --git a/app/api/controller/template/controller.go b/app/api/controller/template/controller.go index e3f84f777..11ef58e62 100644 --- a/app/api/controller/template/controller.go +++ b/app/api/controller/template/controller.go @@ -17,24 +17,20 @@ package template import ( "github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/store" - "github.com/harness/gitness/types/check" ) type Controller struct { - uidCheck check.PathUID templateStore store.TemplateStore authorizer authz.Authorizer spaceStore store.SpaceStore } func NewController( - uidCheck check.PathUID, authorizer authz.Authorizer, templateStore store.TemplateStore, spaceStore store.SpaceStore, ) *Controller { return &Controller{ - uidCheck: uidCheck, templateStore: templateStore, authorizer: authorizer, spaceStore: spaceStore, diff --git a/app/api/controller/template/create.go b/app/api/controller/template/create.go index a7f53b3dc..26e917ca2 100644 --- a/app/api/controller/template/create.go +++ b/app/api/controller/template/create.go @@ -38,8 +38,10 @@ var ( type CreateInput struct { Description string `json:"description"` SpaceRef string `json:"space_ref"` // Ref of the parent space - UID string `json:"uid"` - Data string `json:"data"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` + Data string `json:"data"` } func (c *Controller) Create(ctx context.Context, session *auth.Session, in *CreateInput) (*types.Template, error) { @@ -52,7 +54,7 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea return nil, fmt.Errorf("failed to find parent by ref: %w", err) } - err = apiauth.CheckTemplate(ctx, c.authorizer, session, parentSpace.Path, in.UID, enum.PermissionTemplateEdit) + err = apiauth.CheckTemplate(ctx, c.authorizer, session, parentSpace.Path, in.Identifier, enum.PermissionTemplateEdit) if err != nil { return nil, err } @@ -67,7 +69,7 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea Description: in.Description, Data: in.Data, SpaceID: parentSpace.ID, - UID: in.UID, + Identifier: in.Identifier, Type: resolverType, Created: now, Updated: now, @@ -82,13 +84,18 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea } func (c *Controller) sanitizeCreateInput(in *CreateInput) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + parentRefAsID, err := strconv.ParseInt(in.SpaceRef, 10, 64) if (err == nil && parentRefAsID <= 0) || (len(strings.TrimSpace(in.SpaceRef)) == 0) { return errTemplateRequiresParent } - if err := c.uidCheck(in.UID, false); err != nil { + if err := check.Identifier(in.Identifier); err != nil { return err } diff --git a/app/api/controller/template/delete.go b/app/api/controller/template/delete.go index 5a3df2e79..e6683dc01 100644 --- a/app/api/controller/template/delete.go +++ b/app/api/controller/template/delete.go @@ -27,7 +27,7 @@ func (c *Controller) Delete( ctx context.Context, session *auth.Session, spaceRef string, - uid string, + identifier string, resolverType enum.ResolverType, ) error { space, err := c.spaceStore.FindByRef(ctx, spaceRef) @@ -35,11 +35,11 @@ func (c *Controller) Delete( return fmt.Errorf("failed to find space: %w", err) } - err = apiauth.CheckTemplate(ctx, c.authorizer, session, space.Path, uid, enum.PermissionTemplateDelete) + err = apiauth.CheckTemplate(ctx, c.authorizer, session, space.Path, identifier, enum.PermissionTemplateDelete) if err != nil { return fmt.Errorf("failed to authorize: %w", err) } - err = c.templateStore.DeleteByUIDAndType(ctx, space.ID, uid, resolverType) + err = c.templateStore.DeleteByIdentifierAndType(ctx, space.ID, identifier, resolverType) if err != nil { return fmt.Errorf("could not delete template: %w", err) } diff --git a/app/api/controller/template/find.go b/app/api/controller/template/find.go index bef63d850..ec64115f7 100644 --- a/app/api/controller/template/find.go +++ b/app/api/controller/template/find.go @@ -28,18 +28,18 @@ func (c *Controller) Find( ctx context.Context, session *auth.Session, spaceRef string, - uid string, + identifier string, resolverType enum.ResolverType, ) (*types.Template, error) { space, err := c.spaceStore.FindByRef(ctx, spaceRef) if err != nil { return nil, fmt.Errorf("failed to find space: %w", err) } - err = apiauth.CheckTemplate(ctx, c.authorizer, session, space.Path, uid, enum.PermissionTemplateView) + err = apiauth.CheckTemplate(ctx, c.authorizer, session, space.Path, identifier, enum.PermissionTemplateView) if err != nil { return nil, fmt.Errorf("failed to authorize: %w", err) } - template, err := c.templateStore.FindByUIDAndType(ctx, space.ID, uid, resolverType) + template, err := c.templateStore.FindByIdentifierAndType(ctx, space.ID, identifier, resolverType) if err != nil { return nil, fmt.Errorf("failed to find template: %w", err) } diff --git a/app/api/controller/template/update.go b/app/api/controller/template/update.go index 60a8c9ec3..0fd820b59 100644 --- a/app/api/controller/template/update.go +++ b/app/api/controller/template/update.go @@ -28,7 +28,9 @@ import ( // UpdateInput is used for updating a template. type UpdateInput struct { - UID *string `json:"uid"` + // TODO [CODE-1363]: remove after identifier migration. + UID *string `json:"uid" deprecated:"true"` + Identifier *string `json:"identifier"` Description *string `json:"description"` Data *string `json:"data"` } @@ -37,32 +39,32 @@ func (c *Controller) Update( ctx context.Context, session *auth.Session, spaceRef string, - uid string, + identifier string, resolverType enum.ResolverType, in *UpdateInput, ) (*types.Template, error) { + if err := c.sanitizeUpdateInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) + } + space, err := c.spaceStore.FindByRef(ctx, spaceRef) if err != nil { return nil, fmt.Errorf("failed to find space: %w", err) } - err = apiauth.CheckTemplate(ctx, c.authorizer, session, space.Path, uid, enum.PermissionTemplateEdit) + err = apiauth.CheckTemplate(ctx, c.authorizer, session, space.Path, identifier, enum.PermissionTemplateEdit) if err != nil { return nil, fmt.Errorf("failed to authorize: %w", err) } - if err = c.sanitizeUpdateInput(in); err != nil { - return nil, fmt.Errorf("failed to sanitize input: %w", err) - } - - template, err := c.templateStore.FindByUIDAndType(ctx, space.ID, uid, resolverType) + template, err := c.templateStore.FindByIdentifierAndType(ctx, space.ID, identifier, resolverType) if err != nil { return nil, fmt.Errorf("failed to find template: %w", err) } return c.templateStore.UpdateOptLock(ctx, template, func(original *types.Template) error { - if in.UID != nil { - original.UID = *in.UID + if in.Identifier != nil { + original.Identifier = *in.Identifier } if in.Description != nil { original.Description = *in.Description @@ -79,8 +81,13 @@ func (c *Controller) Update( } func (c *Controller) sanitizeUpdateInput(in *UpdateInput) error { - if in.UID != nil { - if err := c.uidCheck(*in.UID, false); err != nil { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == nil { + in.Identifier = in.UID + } + + if in.Identifier != nil { + if err := check.Identifier(*in.Identifier); err != nil { return err } } diff --git a/app/api/controller/template/wire.go b/app/api/controller/template/wire.go index 9cc8c9f5b..3829810e7 100644 --- a/app/api/controller/template/wire.go +++ b/app/api/controller/template/wire.go @@ -17,7 +17,6 @@ package template import ( "github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/store" - "github.com/harness/gitness/types/check" "github.com/google/wire" ) @@ -28,10 +27,9 @@ var WireSet = wire.NewSet( ) func ProvideController( - uidCheck check.PathUID, templateStore store.TemplateStore, authorizer authz.Authorizer, spaceStore store.SpaceStore, ) *Controller { - return NewController(uidCheck, authorizer, templateStore, spaceStore) + return NewController(authorizer, templateStore, spaceStore) } diff --git a/app/api/controller/trigger/controller.go b/app/api/controller/trigger/controller.go index 2bbcf3bc0..0d05645bc 100644 --- a/app/api/controller/trigger/controller.go +++ b/app/api/controller/trigger/controller.go @@ -17,13 +17,11 @@ package trigger import ( "github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/store" - "github.com/harness/gitness/types/check" ) type Controller struct { authorizer authz.Authorizer triggerStore store.TriggerStore - uidCheck check.PathUID pipelineStore store.PipelineStore repoStore store.RepoStore } @@ -31,14 +29,12 @@ type Controller struct { func NewController( authorizer authz.Authorizer, triggerStore store.TriggerStore, - uidCheck check.PathUID, pipelineStore store.PipelineStore, repoStore store.RepoStore, ) *Controller { return &Controller{ authorizer: authorizer, triggerStore: triggerStore, - uidCheck: uidCheck, pipelineStore: pipelineStore, repoStore: repoStore, } diff --git a/app/api/controller/trigger/create.go b/app/api/controller/trigger/create.go index fcc82200e..05370a75b 100644 --- a/app/api/controller/trigger/create.go +++ b/app/api/controller/trigger/create.go @@ -28,37 +28,38 @@ import ( // TODO: Add more as needed. type CreateInput struct { - Description string `json:"description"` - UID string `json:"uid"` - Secret string `json:"secret"` - Disabled bool `json:"disabled"` - Actions []enum.TriggerAction `json:"actions"` + Description string `json:"description"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` + Secret string `json:"secret"` + Disabled bool `json:"disabled"` + Actions []enum.TriggerAction `json:"actions"` } func (c *Controller) Create( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, + pipelineIdentifier string, in *CreateInput, ) (*types.Trigger, error) { + if err := c.sanitizeCreateInput(in); err != nil { + return nil, fmt.Errorf("invalid input: %w", err) + } + repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return nil, fmt.Errorf("failed to find repo by ref: %w", err) } // Trigger permissions are associated with pipeline permissions. If a user has permissions // to edit the pipeline, they will have permissions to create a trigger as well. - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineEdit) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineEdit) if err != nil { return nil, fmt.Errorf("failed to authorize pipeline: %w", err) } - err = c.checkCreateInput(in) - if err != nil { - return nil, fmt.Errorf("invalid input: %w", err) - } - - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return nil, fmt.Errorf("failed to find pipeline: %w", err) } @@ -71,7 +72,7 @@ func (c *Controller) Create( CreatedBy: session.Principal.ID, RepoID: repo.ID, Actions: deduplicateActions(in.Actions), - UID: in.UID, + Identifier: in.Identifier, PipelineID: pipeline.ID, Created: now, Updated: now, @@ -85,7 +86,12 @@ func (c *Controller) Create( return trigger, nil } -func (c *Controller) checkCreateInput(in *CreateInput) error { +func (c *Controller) sanitizeCreateInput(in *CreateInput) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + if err := check.Description(in.Description); err != nil { return err } @@ -95,7 +101,7 @@ func (c *Controller) checkCreateInput(in *CreateInput) error { if err := checkActions(in.Actions); err != nil { return err } - if err := c.uidCheck(in.UID, false); err != nil { //nolint:revive + if err := check.Identifier(in.Identifier); err != nil { //nolint:revive return err } diff --git a/app/api/controller/trigger/delete.go b/app/api/controller/trigger/delete.go index 8750882a8..e8ddd931f 100644 --- a/app/api/controller/trigger/delete.go +++ b/app/api/controller/trigger/delete.go @@ -27,8 +27,8 @@ func (c *Controller) Delete( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, - triggerUID string, + pipelineIdentifier string, + triggerIdentifier string, ) error { repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { @@ -36,17 +36,17 @@ func (c *Controller) Delete( } // Trigger permissions are associated with pipeline permissions. If a user has permissions // to edit the pipeline, they will have permissions to remove a trigger as well. - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineEdit) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineEdit) if err != nil { return fmt.Errorf("failed to authorize pipeline: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return fmt.Errorf("failed to find pipeline: %w", err) } - err = c.triggerStore.DeleteByUID(ctx, pipeline.ID, triggerUID) + err = c.triggerStore.DeleteByIdentifier(ctx, pipeline.ID, triggerIdentifier) if err != nil { return fmt.Errorf("could not delete trigger: %w", err) } diff --git a/app/api/controller/trigger/find.go b/app/api/controller/trigger/find.go index d4c258978..51f1f9c4a 100644 --- a/app/api/controller/trigger/find.go +++ b/app/api/controller/trigger/find.go @@ -28,26 +28,26 @@ func (c *Controller) Find( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, - triggerUID string, + pipelineIdentifier string, + triggerIdentifier string, ) (*types.Trigger, error) { repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return nil, fmt.Errorf("failed to find repo by ref: %w", err) } - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineView) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineView) if err != nil { return nil, fmt.Errorf("failed to authorize pipeline: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return nil, fmt.Errorf("failed to find pipeline: %w", err) } - trigger, err := c.triggerStore.FindByUID(ctx, pipeline.ID, triggerUID) + trigger, err := c.triggerStore.FindByIdentifier(ctx, pipeline.ID, triggerIdentifier) if err != nil { - return nil, fmt.Errorf("failed to find trigger %s: %w", triggerUID, err) + return nil, fmt.Errorf("failed to find trigger %s: %w", triggerIdentifier, err) } return trigger, nil diff --git a/app/api/controller/trigger/list.go b/app/api/controller/trigger/list.go index d8cc52e80..02b8dc23b 100644 --- a/app/api/controller/trigger/list.go +++ b/app/api/controller/trigger/list.go @@ -28,7 +28,7 @@ func (c *Controller) List( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, + pipelineIdentifier string, filter types.ListQueryFilter, ) ([]*types.Trigger, int64, error) { repo, err := c.repoStore.FindByRef(ctx, repoRef) @@ -37,12 +37,12 @@ func (c *Controller) List( } // Trigger permissions are associated with pipeline permissions. If a user has permissions // to view the pipeline, they will have permissions to list triggers as well. - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineView) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineView) if err != nil { return nil, 0, fmt.Errorf("failed to authorize pipeline: %w", err) } - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return nil, 0, fmt.Errorf("failed to find pipeline: %w", err) } diff --git a/app/api/controller/trigger/update.go b/app/api/controller/trigger/update.go index 9ba9c2f25..48aee6cf9 100644 --- a/app/api/controller/trigger/update.go +++ b/app/api/controller/trigger/update.go @@ -28,50 +28,52 @@ import ( // UpdateInput is used for updating a trigger. type UpdateInput struct { - Description *string `json:"description"` - UID *string `json:"uid"` - Actions []enum.TriggerAction `json:"actions"` - Secret *string `json:"secret"` - Disabled *bool `json:"disabled"` // can be nil, so keeping it a pointer + Description *string `json:"description"` + // TODO [CODE-1363]: remove after identifier migration. + UID *string `json:"uid" deprecated:"true"` + Identifier *string `json:"identifier"` + Actions []enum.TriggerAction `json:"actions"` + Secret *string `json:"secret"` + Disabled *bool `json:"disabled"` // can be nil, so keeping it a pointer } func (c *Controller) Update( ctx context.Context, session *auth.Session, repoRef string, - pipelineUID string, - triggerUID string, - in *UpdateInput) (*types.Trigger, error) { + pipelineIdentifier string, + triggerIdentifier string, + in *UpdateInput, +) (*types.Trigger, error) { + if err := c.sanitizeUpdateInput(in); err != nil { + return nil, fmt.Errorf("invalid input: %w", err) + } + repo, err := c.repoStore.FindByRef(ctx, repoRef) if err != nil { return nil, fmt.Errorf("failed to find repo by ref: %w", err) } // Trigger permissions are associated with pipeline permissions. If a user has permissions // to edit the pipeline, they will have permissions to edit the trigger as well. - err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineUID, enum.PermissionPipelineEdit) + err = apiauth.CheckPipeline(ctx, c.authorizer, session, repo.Path, pipelineIdentifier, enum.PermissionPipelineEdit) if err != nil { return nil, fmt.Errorf("failed to authorize pipeline: %w", err) } - err = c.checkUpdateInput(in) - if err != nil { - return nil, fmt.Errorf("invalid input: %w", err) - } - - pipeline, err := c.pipelineStore.FindByUID(ctx, repo.ID, pipelineUID) + pipeline, err := c.pipelineStore.FindByIdentifier(ctx, repo.ID, pipelineIdentifier) if err != nil { return nil, fmt.Errorf("failed to find pipeline: %w", err) } - trigger, err := c.triggerStore.FindByUID(ctx, pipeline.ID, triggerUID) + trigger, err := c.triggerStore.FindByIdentifier(ctx, pipeline.ID, triggerIdentifier) if err != nil { return nil, fmt.Errorf("failed to find trigger: %w", err) } return c.triggerStore.UpdateOptLock(ctx, trigger, func(original *types.Trigger) error { - if in.UID != nil { - original.UID = *in.UID + if in.Identifier != nil { + original.Identifier = *in.Identifier } if in.Description != nil { original.Description = *in.Description @@ -90,9 +92,14 @@ func (c *Controller) Update( }) } -func (c *Controller) checkUpdateInput(in *UpdateInput) error { - if in.UID != nil { - if err := c.uidCheck(*in.UID, false); err != nil { +func (c *Controller) sanitizeUpdateInput(in *UpdateInput) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == nil { + in.Identifier = in.UID + } + + if in.Identifier != nil { + if err := check.Identifier(*in.Identifier); err != nil { return err } } diff --git a/app/api/controller/trigger/wire.go b/app/api/controller/trigger/wire.go index 2021b3f88..bb914bf21 100644 --- a/app/api/controller/trigger/wire.go +++ b/app/api/controller/trigger/wire.go @@ -17,7 +17,6 @@ package trigger import ( "github.com/harness/gitness/app/auth/authz" "github.com/harness/gitness/app/store" - "github.com/harness/gitness/types/check" "github.com/google/wire" ) @@ -30,9 +29,8 @@ var WireSet = wire.NewSet( func ProvideController( authorizer authz.Authorizer, triggerStore store.TriggerStore, - uidCheck check.PathUID, pipelineStore store.PipelineStore, repoStore store.RepoStore, ) *Controller { - return NewController(authorizer, triggerStore, uidCheck, pipelineStore, repoStore) + return NewController(authorizer, triggerStore, pipelineStore, repoStore) } diff --git a/app/api/controller/upload/upload.go b/app/api/controller/upload/upload.go index 0a29456eb..9db2c00d9 100644 --- a/app/api/controller/upload/upload.go +++ b/app/api/controller/upload/upload.go @@ -57,8 +57,8 @@ func (c *Controller) Upload(ctx context.Context, return nil, fmt.Errorf("failed to determine file type: %w", err) } - uid := uuid.New().String() - fileName := fmt.Sprintf(fileNameFmt, uid, extn) + identifier := uuid.New().String() + fileName := fmt.Sprintf(fileNameFmt, identifier, extn) fileBucketPath := getFileBucketPath(repo.ID, fileName) err = c.blobStore.Upload(ctx, bufReader, fileBucketPath) diff --git a/app/api/controller/user/create.go b/app/api/controller/user/create.go index d6f416237..15cc75bb3 100644 --- a/app/api/controller/user/create.go +++ b/app/api/controller/user/create.go @@ -117,7 +117,8 @@ func (c *Controller) sanitizeCreateInput(in *CreateInput) error { return err } - if err := check.Password(in.Password); err != nil { //nolint:revive + //nolint:revive + if err := check.Password(in.Password); err != nil { return err } diff --git a/app/api/controller/user/create_access_token.go b/app/api/controller/user/create_access_token.go index 60e2c12bd..c264af3cf 100644 --- a/app/api/controller/user/create_access_token.go +++ b/app/api/controller/user/create_access_token.go @@ -16,6 +16,7 @@ package user import ( "context" + "fmt" "time" apiauth "github.com/harness/gitness/app/api/auth" @@ -27,8 +28,10 @@ import ( ) type CreateTokenInput struct { - UID string `json:"uid"` - Lifetime *time.Duration `json:"lifetime"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` + Lifetime *time.Duration `json:"lifetime"` } /* @@ -40,6 +43,10 @@ func (c *Controller) CreateAccessToken( userUID string, in *CreateTokenInput, ) (*types.TokenResponse, error) { + if err := c.sanitizeCreateTokenInput(in); err != nil { + return nil, fmt.Errorf("failed to sanitize input: %w", err) + } + user, err := findUserFromUID(ctx, c.principalStore, userUID) if err != nil { return nil, err @@ -50,19 +57,12 @@ func (c *Controller) CreateAccessToken( return nil, err } - if err = check.UID(in.UID); err != nil { - return nil, err - } - if err = check.TokenLifetime(in.Lifetime, true); err != nil { - return nil, err - } - token, jwtToken, err := token.CreatePAT( ctx, c.tokenStore, &session.Principal, user, - in.UID, + in.Identifier, in.Lifetime, ) if err != nil { @@ -71,3 +71,21 @@ func (c *Controller) CreateAccessToken( return &types.TokenResponse{Token: *token, AccessToken: jwtToken}, nil } + +func (c *Controller) sanitizeCreateTokenInput(in *CreateTokenInput) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + + if err := check.Identifier(in.Identifier); err != nil { + return err + } + + //nolint:revive + if err := check.TokenLifetime(in.Lifetime, true); err != nil { + return err + } + + return nil +} diff --git a/app/api/controller/user/delete_token.go b/app/api/controller/user/delete_token.go index d81485ef9..f23639ecb 100644 --- a/app/api/controller/user/delete_token.go +++ b/app/api/controller/user/delete_token.go @@ -28,8 +28,12 @@ import ( /* * DeleteToken deletes a token of a user. */ -func (c *Controller) DeleteToken(ctx context.Context, session *auth.Session, - userUID string, tokenType enum.TokenType, tokenUID string) error { +func (c *Controller) DeleteToken( + ctx context.Context, + session *auth.Session, + userUID string, + tokenType enum.TokenType, + tokenIdentifier string) error { user, err := findUserFromUID(ctx, c.principalStore, userUID) if err != nil { return err @@ -40,7 +44,7 @@ func (c *Controller) DeleteToken(ctx context.Context, session *auth.Session, return err } - token, err := c.tokenStore.FindByUID(ctx, user.ID, tokenUID) + token, err := c.tokenStore.FindByIdentifier(ctx, user.ID, tokenIdentifier) if err != nil { return err } diff --git a/app/api/controller/user/login.go b/app/api/controller/user/login.go index 774acb9d3..e2a522d4f 100644 --- a/app/api/controller/user/login.go +++ b/app/api/controller/user/login.go @@ -70,11 +70,11 @@ func (c *Controller) Login( return nil, usererror.ErrNotFound } - tokenUID, err := generateSessionTokenUID() + tokenIdentifier, err := generateSessionTokenIdentifier() if err != nil { return nil, err } - token, jwtToken, err := token.CreateUserSession(ctx, c.tokenStore, user, tokenUID) + token, jwtToken, err := token.CreateUserSession(ctx, c.tokenStore, user, tokenIdentifier) if err != nil { return nil, err } @@ -82,7 +82,7 @@ func (c *Controller) Login( return &types.TokenResponse{Token: *token, AccessToken: jwtToken}, nil } -func generateSessionTokenUID() (string, error) { +func generateSessionTokenIdentifier() (string, error) { r, err := rand.Int(rand.Reader, big.NewInt(10000)) if err != nil { return "", fmt.Errorf("failed to generate random number: %w", err) diff --git a/app/api/controller/webhook/create.go b/app/api/controller/webhook/create.go index 5db9d9cd8..9d2a11049 100644 --- a/app/api/controller/webhook/create.go +++ b/app/api/controller/webhook/create.go @@ -32,8 +32,10 @@ import ( ) type CreateInput struct { - UID string `json:"uid"` - // TODO: Remove once UID migration is completed. + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid" deprecated:"true"` + Identifier string `json:"identifier"` + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. DisplayName string `json:"display_name"` Description string `json:"description"` URL string `json:"url"` @@ -53,27 +55,15 @@ func (c *Controller) Create( in *CreateInput, internal bool, ) (*types.Webhook, error) { - now := time.Now().UnixMilli() - - repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit) + // validate input + err := sanitizeCreateInput(in, c.allowLoopback, c.allowPrivateNetwork || internal) if err != nil { return nil, err } - // backfill required data - during migration period we have to accept both, displayname only and uid only - // TODO: Remove once UID migration is completed - if in.DisplayName == "" && in.UID != "" { - in.DisplayName = in.UID - } - if in.UID == "" && in.DisplayName != "" { - in.UID, err = migrate.WebhookDisplayNameToUID(in.DisplayName, false) - if err != nil { - return nil, fmt.Errorf("failed to migrate webhook displayname %q to uid: %w", in.DisplayName, err) - } - } + now := time.Now().UnixMilli() - // validate input - err = checkCreateInput(in, c.allowLoopback, c.allowPrivateNetwork || internal) + repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit) if err != nil { return nil, err } @@ -95,7 +85,7 @@ func (c *Controller) Create( Internal: internal, // user input - UID: in.UID, + Identifier: in.Identifier, DisplayName: in.DisplayName, Description: in.Description, URL: in.URL, @@ -111,16 +101,16 @@ func (c *Controller) Create( // internal hooks are hidden from non-internal read requests - properly communicate their existence on duplicate. // This is best effort, any error we just ignore and fallback to original duplicate error. if errors.Is(err, store.ErrDuplicate) && !internal { - existingHook, derr := c.webhookStore.FindByUID(ctx, enum.WebhookParentRepo, repo.ID, hook.UID) + existingHook, derr := c.webhookStore.FindByIdentifier(ctx, enum.WebhookParentRepo, repo.ID, hook.Identifier) if derr != nil { log.Ctx(ctx).Warn().Err(derr).Msgf( - "failed to retrieve webhook for repo %d with uid %q on duplicate error", + "failed to retrieve webhook for repo %d with identifier %q on duplicate error", repo.ID, - hook.UID, + hook.Identifier, ) } if derr == nil && existingHook.Internal { - return nil, usererror.Conflict("The provided uid is reserved for internal purposes.") + return nil, usererror.Conflict("The provided identifier is reserved for internal purposes.") } } @@ -131,8 +121,26 @@ func (c *Controller) Create( return hook, nil } -func checkCreateInput(in *CreateInput, allowLoopback bool, allowPrivateNetwork bool) error { - if err := check.UID(in.UID); err != nil { +func sanitizeCreateInput(in *CreateInput, allowLoopback bool, allowPrivateNetwork bool) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == "" { + in.Identifier = in.UID + } + + // backfill required data - during migration period we have to accept both, displayname only and identifier only + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed + if in.DisplayName == "" && in.Identifier != "" { + in.DisplayName = in.Identifier + } + if in.Identifier == "" && in.DisplayName != "" { + var err error + in.Identifier, err = migrate.WebhookDisplayNameToIdentifier(in.DisplayName, false) + if err != nil { + return fmt.Errorf("failed to migrate webhook displayname %q to identifier: %w", in.DisplayName, err) + } + } + + if err := check.Identifier(in.Identifier); err != nil { return err } if err := check.DisplayName(in.DisplayName); err != nil { diff --git a/app/api/controller/webhook/delete.go b/app/api/controller/webhook/delete.go index 702aad1c6..66012532b 100644 --- a/app/api/controller/webhook/delete.go +++ b/app/api/controller/webhook/delete.go @@ -26,7 +26,7 @@ func (c *Controller) Delete( ctx context.Context, session *auth.Session, repoRef string, - webhookUID string, + webhookIdentifier string, allowDeletingInternal bool, ) error { repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit) @@ -35,7 +35,7 @@ func (c *Controller) Delete( } // get the webhook and ensure it belongs to us - webhook, err := c.getWebhookVerifyOwnership(ctx, repo.ID, webhookUID) + webhook, err := c.getWebhookVerifyOwnership(ctx, repo.ID, webhookIdentifier) if err != nil { return err } diff --git a/app/api/controller/webhook/find.go b/app/api/controller/webhook/find.go index e3a1670d0..8fded0c8a 100644 --- a/app/api/controller/webhook/find.go +++ b/app/api/controller/webhook/find.go @@ -31,32 +31,35 @@ func (c *Controller) Find( ctx context.Context, session *auth.Session, repoRef string, - webhookUID string, + webhookIdentifier string, ) (*types.Webhook, error) { repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoView) if err != nil { return nil, err } - return c.getWebhookVerifyOwnership(ctx, repo.ID, webhookUID) + return c.getWebhookVerifyOwnership(ctx, repo.ID, webhookIdentifier) } -func (c *Controller) getWebhookVerifyOwnership(ctx context.Context, repoID int64, - webhookUID string) (*types.Webhook, error) { - // TODO: Remove once webhook UID migration completed - webhookID, err := strconv.ParseInt(webhookUID, 10, 64) - if (err == nil && webhookID <= 0) || len(strings.TrimSpace(webhookUID)) == 0 { - return nil, usererror.BadRequest("A valid webhook UID must be provided.") +func (c *Controller) getWebhookVerifyOwnership( + ctx context.Context, + repoID int64, + webhookIdentifier string, +) (*types.Webhook, error) { + // TODO: Remove once webhook identifier migration completed + webhookID, err := strconv.ParseInt(webhookIdentifier, 10, 64) + if (err == nil && webhookID <= 0) || len(strings.TrimSpace(webhookIdentifier)) == 0 { + return nil, usererror.BadRequest("A valid webhook identifier must be provided.") } var webhook *types.Webhook if err == nil { webhook, err = c.webhookStore.Find(ctx, webhookID) } else { - webhook, err = c.webhookStore.FindByUID(ctx, enum.WebhookParentRepo, repoID, webhookUID) + webhook, err = c.webhookStore.FindByIdentifier(ctx, enum.WebhookParentRepo, repoID, webhookIdentifier) } if err != nil { - return nil, fmt.Errorf("failed to find webhook with uid %q: %w", webhookUID, err) + return nil, fmt.Errorf("failed to find webhook with identifier %q: %w", webhookIdentifier, err) } // ensure the webhook actually belongs to the repo diff --git a/app/api/controller/webhook/find_execution.go b/app/api/controller/webhook/find_execution.go index 445a3a009..5934bf822 100644 --- a/app/api/controller/webhook/find_execution.go +++ b/app/api/controller/webhook/find_execution.go @@ -29,7 +29,7 @@ func (c *Controller) FindExecution( ctx context.Context, session *auth.Session, repoRef string, - webhookUID string, + webhookIdentifier string, webhookExecutionID int64, ) (*types.WebhookExecution, error) { repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoView) @@ -38,7 +38,7 @@ func (c *Controller) FindExecution( } // get the webhook and ensure it belongs to us - webhook, err := c.getWebhookVerifyOwnership(ctx, repo.ID, webhookUID) + webhook, err := c.getWebhookVerifyOwnership(ctx, repo.ID, webhookIdentifier) if err != nil { return nil, err } diff --git a/app/api/controller/webhook/list_executions.go b/app/api/controller/webhook/list_executions.go index 26b338264..2efe4d3b9 100644 --- a/app/api/controller/webhook/list_executions.go +++ b/app/api/controller/webhook/list_executions.go @@ -28,7 +28,7 @@ func (c *Controller) ListExecutions( ctx context.Context, session *auth.Session, repoRef string, - webhookUID string, + webhookIdentifier string, filter *types.WebhookExecutionFilter, ) ([]*types.WebhookExecution, error) { repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoView) @@ -37,7 +37,7 @@ func (c *Controller) ListExecutions( } // get the webhook and ensure it belongs to us - webhook, err := c.getWebhookVerifyOwnership(ctx, repo.ID, webhookUID) + webhook, err := c.getWebhookVerifyOwnership(ctx, repo.ID, webhookIdentifier) if err != nil { return nil, err } diff --git a/app/api/controller/webhook/retrigger_execution.go b/app/api/controller/webhook/retrigger_execution.go index 8427cb344..8aa4c75b5 100644 --- a/app/api/controller/webhook/retrigger_execution.go +++ b/app/api/controller/webhook/retrigger_execution.go @@ -30,7 +30,7 @@ func (c *Controller) RetriggerExecution( ctx context.Context, session *auth.Session, repoRef string, - webhookUID string, + webhookIdentifier string, webhookExecutionID int64, ) (*types.WebhookExecution, error) { repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit) @@ -39,7 +39,7 @@ func (c *Controller) RetriggerExecution( } // get the webhook and ensure it belongs to us - webhook, err := c.getWebhookVerifyOwnership(ctx, repo.ID, webhookUID) + webhook, err := c.getWebhookVerifyOwnership(ctx, repo.ID, webhookIdentifier) if err != nil { return nil, err } diff --git a/app/api/controller/webhook/update.go b/app/api/controller/webhook/update.go index ec6b30a6e..9a879912b 100644 --- a/app/api/controller/webhook/update.go +++ b/app/api/controller/webhook/update.go @@ -25,8 +25,10 @@ import ( ) type UpdateInput struct { - UID *string `json:"uid"` - // TODO: Remove once UID migration is completed. + // TODO [CODE-1363]: remove after identifier migration. + UID *string `json:"uid" deprecated:"true"` + Identifier *string `json:"identifier"` + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. DisplayName *string `json:"display_name"` Description *string `json:"description"` URL *string `json:"url"` @@ -41,17 +43,21 @@ func (c *Controller) Update( ctx context.Context, session *auth.Session, repoRef string, - webhookUID string, + webhookIdentifier string, in *UpdateInput, allowModifyingInternal bool, ) (*types.Webhook, error) { + if err := sanitizeUpdateInput(in, c.allowLoopback, c.allowPrivateNetwork); err != nil { + return nil, err + } + repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit) if err != nil { return nil, err } // get the hook and ensure it belongs to us - hook, err := c.getWebhookVerifyOwnership(ctx, repo.ID, webhookUID) + hook, err := c.getWebhookVerifyOwnership(ctx, repo.ID, webhookIdentifier) if err != nil { return nil, err } @@ -59,14 +65,10 @@ func (c *Controller) Update( if !allowModifyingInternal && hook.Internal { return nil, ErrInternalWebhookOperationNotAllowed } - // validate input - if err = checkUpdateInput(in, c.allowLoopback, c.allowPrivateNetwork); err != nil { - return nil, err - } // update webhook struct (only for values that are provided) - if in.UID != nil { - hook.UID = *in.UID + if in.Identifier != nil { + hook.Identifier = *in.Identifier } if in.DisplayName != nil { hook.DisplayName = *in.DisplayName @@ -101,9 +103,14 @@ func (c *Controller) Update( return hook, nil } -func checkUpdateInput(in *UpdateInput, allowLoopback bool, allowPrivateNetwork bool) error { - if in.UID != nil { - if err := check.UID(*in.UID); err != nil { +func sanitizeUpdateInput(in *UpdateInput, allowLoopback bool, allowPrivateNetwork bool) error { + // TODO [CODE-1363]: remove after identifier migration. + if in.Identifier == nil { + in.Identifier = in.UID + } + + if in.Identifier != nil { + if err := check.Identifier(*in.Identifier); err != nil { return err } } diff --git a/app/api/handler/check/check_recent.go b/app/api/handler/check/check_recent.go index a81129a0a..28521cb92 100644 --- a/app/api/handler/check/check_recent.go +++ b/app/api/handler/check/check_recent.go @@ -22,7 +22,7 @@ import ( "github.com/harness/gitness/app/api/request" ) -// HandleCheckListRecent is an HTTP handler for listing recently executed status check UIDs for a repository. +// HandleCheckListRecent is an HTTP handler for listing recently executed status check identifiers for a repository. func HandleCheckListRecent(checkCtrl *check.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() @@ -40,12 +40,12 @@ func HandleCheckListRecent(checkCtrl *check.Controller) http.HandlerFunc { return } - checkUIDs, err := checkCtrl.ListRecentChecks(ctx, session, repoRef, opts) + checkIdentifiers, err := checkCtrl.ListRecentChecks(ctx, session, repoRef, opts) if err != nil { render.TranslatedUserError(w, err) return } - render.JSON(w, http.StatusOK, checkUIDs) + render.JSON(w, http.StatusOK, checkIdentifiers) } } diff --git a/app/api/handler/connector/delete.go b/app/api/handler/connector/delete.go index 507a4c622..353e43274 100644 --- a/app/api/handler/connector/delete.go +++ b/app/api/handler/connector/delete.go @@ -32,13 +32,13 @@ func HandleDelete(connectorCtrl *connector.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - spaceRef, connectorUID, err := paths.DisectLeaf(connectorRef) + spaceRef, connectorIdentifier, err := paths.DisectLeaf(connectorRef) if err != nil { render.TranslatedUserError(w, err) return } - err = connectorCtrl.Delete(ctx, session, spaceRef, connectorUID) + err = connectorCtrl.Delete(ctx, session, spaceRef, connectorIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/connector/find.go b/app/api/handler/connector/find.go index 0264f481c..ceee8ed5a 100644 --- a/app/api/handler/connector/find.go +++ b/app/api/handler/connector/find.go @@ -33,13 +33,13 @@ func HandleFind(connectorCtrl *connector.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - spaceRef, connectorUID, err := paths.DisectLeaf(connectorRef) + spaceRef, connectorIdentifier, err := paths.DisectLeaf(connectorRef) if err != nil { render.TranslatedUserError(w, err) return } - connector, err := connectorCtrl.Find(ctx, session, spaceRef, connectorUID) + connector, err := connectorCtrl.Find(ctx, session, spaceRef, connectorIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/connector/update.go b/app/api/handler/connector/update.go index 8e942819c..1f579c034 100644 --- a/app/api/handler/connector/update.go +++ b/app/api/handler/connector/update.go @@ -41,13 +41,13 @@ func HandleUpdate(connectorCtrl *connector.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - spaceRef, connectorUID, err := paths.DisectLeaf(connectorRef) + spaceRef, connectorIdentifier, err := paths.DisectLeaf(connectorRef) if err != nil { render.TranslatedUserError(w, err) return } - connector, err := connectorCtrl.Update(ctx, session, spaceRef, connectorUID, in) + connector, err := connectorCtrl.Update(ctx, session, spaceRef, connectorIdentifier, in) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/execution/cancel.go b/app/api/handler/execution/cancel.go index 0bc888a9a..7966553a0 100644 --- a/app/api/handler/execution/cancel.go +++ b/app/api/handler/execution/cancel.go @@ -26,7 +26,7 @@ func HandleCancel(executionCtrl *execution.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -42,7 +42,7 @@ func HandleCancel(executionCtrl *execution.Controller) http.HandlerFunc { return } - execution, err := executionCtrl.Cancel(ctx, session, repoRef, pipelineUID, n) + execution, err := executionCtrl.Cancel(ctx, session, repoRef, pipelineIdentifier, n) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/execution/create.go b/app/api/handler/execution/create.go index 146d7b8a9..30d5ec80c 100644 --- a/app/api/handler/execution/create.go +++ b/app/api/handler/execution/create.go @@ -26,7 +26,7 @@ func HandleCreate(executionCtrl *execution.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -39,7 +39,7 @@ func HandleCreate(executionCtrl *execution.Controller) http.HandlerFunc { branch := request.GetBranchFromQuery(r) - execution, err := executionCtrl.Create(ctx, session, repoRef, pipelineUID, branch) + execution, err := executionCtrl.Create(ctx, session, repoRef, pipelineIdentifier, branch) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/execution/delete.go b/app/api/handler/execution/delete.go index 02096c95a..15177f060 100644 --- a/app/api/handler/execution/delete.go +++ b/app/api/handler/execution/delete.go @@ -26,7 +26,7 @@ func HandleDelete(executionCtrl *execution.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -42,7 +42,7 @@ func HandleDelete(executionCtrl *execution.Controller) http.HandlerFunc { return } - err = executionCtrl.Delete(ctx, session, repoRef, pipelineUID, n) + err = executionCtrl.Delete(ctx, session, repoRef, pipelineIdentifier, n) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/execution/find.go b/app/api/handler/execution/find.go index 7ede01a7c..059a5570d 100644 --- a/app/api/handler/execution/find.go +++ b/app/api/handler/execution/find.go @@ -26,7 +26,7 @@ func HandleFind(executionCtrl *execution.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -42,7 +42,7 @@ func HandleFind(executionCtrl *execution.Controller) http.HandlerFunc { return } - execution, err := executionCtrl.Find(ctx, session, repoRef, pipelineUID, n) + execution, err := executionCtrl.Find(ctx, session, repoRef, pipelineIdentifier, n) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/execution/list.go b/app/api/handler/execution/list.go index 9e8e13e69..159180a87 100644 --- a/app/api/handler/execution/list.go +++ b/app/api/handler/execution/list.go @@ -26,7 +26,7 @@ func HandleList(executionCtrl *execution.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -39,7 +39,7 @@ func HandleList(executionCtrl *execution.Controller) http.HandlerFunc { pagination := request.ParsePaginationFromRequest(r) - repos, totalCount, err := executionCtrl.List(ctx, session, repoRef, pipelineUID, pagination) + repos, totalCount, err := executionCtrl.List(ctx, session, repoRef, pipelineIdentifier, pagination) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/logs/find.go b/app/api/handler/logs/find.go index 29b686e32..f9a230b9a 100644 --- a/app/api/handler/logs/find.go +++ b/app/api/handler/logs/find.go @@ -32,7 +32,7 @@ func HandleFind(logCtrl *logs.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -53,7 +53,7 @@ func HandleFind(logCtrl *logs.Controller) http.HandlerFunc { return } lines, err := logCtrl.Find( - ctx, session, repoRef, pipelineUID, + ctx, session, repoRef, pipelineIdentifier, executionNum, int(stageNum), int(stepNum)) if err != nil { render.TranslatedUserError(w, err) diff --git a/app/api/handler/logs/tail.go b/app/api/handler/logs/tail.go index 37ca1a43d..494d507b8 100644 --- a/app/api/handler/logs/tail.go +++ b/app/api/handler/logs/tail.go @@ -41,7 +41,7 @@ func HandleTail(logCtrl *logs.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -85,7 +85,7 @@ func HandleTail(logCtrl *logs.Controller) http.HandlerFunc { f.Flush() linec, errc, err := logCtrl.Tail( - ctx, session, repoRef, pipelineUID, + ctx, session, repoRef, pipelineIdentifier, executionNum, int(stageNum), int(stepNum)) if err != nil { render.TranslatedUserError(w, err) diff --git a/app/api/handler/pipeline/delete.go b/app/api/handler/pipeline/delete.go index ce3d08d1c..f1084f32d 100644 --- a/app/api/handler/pipeline/delete.go +++ b/app/api/handler/pipeline/delete.go @@ -26,7 +26,7 @@ func HandleDelete(pipelineCtrl *pipeline.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -37,7 +37,7 @@ func HandleDelete(pipelineCtrl *pipeline.Controller) http.HandlerFunc { return } - err = pipelineCtrl.Delete(ctx, session, repoRef, pipelineUID) + err = pipelineCtrl.Delete(ctx, session, repoRef, pipelineIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/pipeline/find.go b/app/api/handler/pipeline/find.go index 3446abbf4..456106b3b 100644 --- a/app/api/handler/pipeline/find.go +++ b/app/api/handler/pipeline/find.go @@ -26,7 +26,7 @@ func HandleFind(pipelineCtrl *pipeline.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -37,7 +37,7 @@ func HandleFind(pipelineCtrl *pipeline.Controller) http.HandlerFunc { return } - pipeline, err := pipelineCtrl.Find(ctx, session, repoRef, pipelineUID) + pipeline, err := pipelineCtrl.Find(ctx, session, repoRef, pipelineIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/pipeline/update.go b/app/api/handler/pipeline/update.go index 7e77c898f..2da0326a1 100644 --- a/app/api/handler/pipeline/update.go +++ b/app/api/handler/pipeline/update.go @@ -35,7 +35,7 @@ func HandleUpdate(pipelineCtrl *pipeline.Controller) http.HandlerFunc { return } - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -46,7 +46,7 @@ func HandleUpdate(pipelineCtrl *pipeline.Controller) http.HandlerFunc { return } - pipeline, err := pipelineCtrl.Update(ctx, session, repoRef, pipelineUID, in) + pipeline, err := pipelineCtrl.Update(ctx, session, repoRef, pipelineIdentifier, in) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/repo/rule_delete.go b/app/api/handler/repo/rule_delete.go index 0c90d8462..d33b536b5 100644 --- a/app/api/handler/repo/rule_delete.go +++ b/app/api/handler/repo/rule_delete.go @@ -34,13 +34,13 @@ func HandleRuleDelete(repoCtrl *repo.Controller) http.HandlerFunc { return } - ruleUID, err := request.GetRuleUIDFromPath(r) + ruleIdentifier, err := request.GetRuleIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return } - err = repoCtrl.RuleDelete(ctx, session, repoRef, ruleUID) + err = repoCtrl.RuleDelete(ctx, session, repoRef, ruleIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/repo/rule_find.go b/app/api/handler/repo/rule_find.go index 52f071f7e..8e1424772 100644 --- a/app/api/handler/repo/rule_find.go +++ b/app/api/handler/repo/rule_find.go @@ -34,13 +34,13 @@ func HandleRuleFind(repoCtrl *repo.Controller) http.HandlerFunc { return } - ruleUID, err := request.GetRuleUIDFromPath(r) + ruleIdentifier, err := request.GetRuleIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return } - rule, err := repoCtrl.RuleFind(ctx, session, repoRef, ruleUID) + rule, err := repoCtrl.RuleFind(ctx, session, repoRef, ruleIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/repo/rule_update.go b/app/api/handler/repo/rule_update.go index 9c583c5bd..6e16b9bba 100644 --- a/app/api/handler/repo/rule_update.go +++ b/app/api/handler/repo/rule_update.go @@ -35,7 +35,7 @@ func HandleRuleUpdate(repoCtrl *repo.Controller) http.HandlerFunc { return } - ruleUID, err := request.GetRuleUIDFromPath(r) + ruleIdentifier, err := request.GetRuleIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -48,7 +48,7 @@ func HandleRuleUpdate(repoCtrl *repo.Controller) http.HandlerFunc { return } - rule, err := repoCtrl.RuleUpdate(ctx, session, repoRef, ruleUID, in) + rule, err := repoCtrl.RuleUpdate(ctx, session, repoRef, ruleIdentifier, in) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/secret/delete.go b/app/api/handler/secret/delete.go index 2a29fb9b6..528b9067a 100644 --- a/app/api/handler/secret/delete.go +++ b/app/api/handler/secret/delete.go @@ -32,13 +32,13 @@ func HandleDelete(secretCtrl *secret.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - spaceRef, secretUID, err := paths.DisectLeaf(secretRef) + spaceRef, secretIdentifier, err := paths.DisectLeaf(secretRef) if err != nil { render.TranslatedUserError(w, err) return } - err = secretCtrl.Delete(ctx, session, spaceRef, secretUID) + err = secretCtrl.Delete(ctx, session, spaceRef, secretIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/secret/find.go b/app/api/handler/secret/find.go index 9514a45b5..6fbff464c 100644 --- a/app/api/handler/secret/find.go +++ b/app/api/handler/secret/find.go @@ -33,13 +33,13 @@ func HandleFind(secretCtrl *secret.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - spaceRef, secretUID, err := paths.DisectLeaf(secretRef) + spaceRef, secretIdentifier, err := paths.DisectLeaf(secretRef) if err != nil { render.TranslatedUserError(w, err) return } - secret, err := secretCtrl.Find(ctx, session, spaceRef, secretUID) + secret, err := secretCtrl.Find(ctx, session, spaceRef, secretIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/secret/update.go b/app/api/handler/secret/update.go index 60e332fe6..6aaec9092 100644 --- a/app/api/handler/secret/update.go +++ b/app/api/handler/secret/update.go @@ -41,12 +41,12 @@ func HandleUpdate(secretCtrl *secret.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - spaceRef, secretUID, err := paths.DisectLeaf(secretRef) + spaceRef, secretIdentifier, err := paths.DisectLeaf(secretRef) if err != nil { render.TranslatedUserError(w, err) } - secret, err := secretCtrl.Update(ctx, session, spaceRef, secretUID, in) + secret, err := secretCtrl.Update(ctx, session, spaceRef, secretIdentifier, in) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/serviceaccount/delete_token.go b/app/api/handler/serviceaccount/delete_token.go index 983ec5bc2..33393e4d1 100644 --- a/app/api/handler/serviceaccount/delete_token.go +++ b/app/api/handler/serviceaccount/delete_token.go @@ -33,13 +33,13 @@ func HandleDeleteToken(saCrl *serviceaccount.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - tokenUID, err := request.GetTokenUIDFromPath(r) + tokentokenIdentifier, err := request.GetTokenIdentifierFromPath(r) if err != nil { render.BadRequest(w) return } - err = saCrl.DeleteToken(ctx, session, saUID, tokenUID) + err = saCrl.DeleteToken(ctx, session, saUID, tokentokenIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/template/delete.go b/app/api/handler/template/delete.go index a01ccecdd..8d175ac58 100644 --- a/app/api/handler/template/delete.go +++ b/app/api/handler/template/delete.go @@ -33,7 +33,7 @@ func HandleDelete(templateCtrl *template.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - spaceRef, templateUID, err := paths.DisectLeaf(templateRef) + spaceRef, templateIdentifier, err := paths.DisectLeaf(templateRef) if err != nil { render.TranslatedUserError(w, err) return @@ -51,7 +51,7 @@ func HandleDelete(templateCtrl *template.Controller) http.HandlerFunc { return } - err = templateCtrl.Delete(ctx, session, spaceRef, templateUID, tempalateTypeEnum) + err = templateCtrl.Delete(ctx, session, spaceRef, templateIdentifier, tempalateTypeEnum) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/template/find.go b/app/api/handler/template/find.go index ed50ef5ba..567b5a7bd 100644 --- a/app/api/handler/template/find.go +++ b/app/api/handler/template/find.go @@ -34,7 +34,7 @@ func HandleFind(templateCtrl *template.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - spaceRef, templateUID, err := paths.DisectLeaf(templateRef) + spaceRef, templateIdentifier, err := paths.DisectLeaf(templateRef) if err != nil { render.TranslatedUserError(w, err) return @@ -52,7 +52,7 @@ func HandleFind(templateCtrl *template.Controller) http.HandlerFunc { return } - template, err := templateCtrl.Find(ctx, session, spaceRef, templateUID, tempalateTypeEnum) + template, err := templateCtrl.Find(ctx, session, spaceRef, templateIdentifier, tempalateTypeEnum) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/template/update.go b/app/api/handler/template/update.go index 6d2829962..14d53a347 100644 --- a/app/api/handler/template/update.go +++ b/app/api/handler/template/update.go @@ -42,7 +42,7 @@ func HandleUpdate(templateCtrl *template.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - spaceRef, templateUID, err := paths.DisectLeaf(templateRef) + spaceRef, templateIdentifier, err := paths.DisectLeaf(templateRef) if err != nil { render.TranslatedUserError(w, err) return @@ -59,7 +59,7 @@ func HandleUpdate(templateCtrl *template.Controller) http.HandlerFunc { return } - template, err := templateCtrl.Update(ctx, session, spaceRef, templateUID, + template, err := templateCtrl.Update(ctx, session, spaceRef, templateIdentifier, resolverTypeEnum, in) if err != nil { render.TranslatedUserError(w, err) diff --git a/app/api/handler/trigger/create.go b/app/api/handler/trigger/create.go index 387b3b0fb..e677433d0 100644 --- a/app/api/handler/trigger/create.go +++ b/app/api/handler/trigger/create.go @@ -27,7 +27,7 @@ func HandleCreate(triggerCtrl *trigger.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -45,7 +45,7 @@ func HandleCreate(triggerCtrl *trigger.Controller) http.HandlerFunc { return } - trigger, err := triggerCtrl.Create(ctx, session, repoRef, pipelineUID, in) + trigger, err := triggerCtrl.Create(ctx, session, repoRef, pipelineIdentifier, in) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/trigger/delete.go b/app/api/handler/trigger/delete.go index ada7da57c..609650259 100644 --- a/app/api/handler/trigger/delete.go +++ b/app/api/handler/trigger/delete.go @@ -26,7 +26,7 @@ func HandleDelete(triggerCtrl *trigger.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -36,13 +36,13 @@ func HandleDelete(triggerCtrl *trigger.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - triggerUID, err := request.GetTriggerUIDFromPath(r) + triggerIdentifier, err := request.GetTriggerIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return } - err = triggerCtrl.Delete(ctx, session, repoRef, pipelineUID, triggerUID) + err = triggerCtrl.Delete(ctx, session, repoRef, pipelineIdentifier, triggerIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/trigger/find.go b/app/api/handler/trigger/find.go index 6ac0bc501..9d325fded 100644 --- a/app/api/handler/trigger/find.go +++ b/app/api/handler/trigger/find.go @@ -26,12 +26,12 @@ func HandleFind(triggerCtrl *trigger.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return } - triggerUID, err := request.GetTriggerUIDFromPath(r) + triggerIdentifier, err := request.GetTriggerIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -42,7 +42,7 @@ func HandleFind(triggerCtrl *trigger.Controller) http.HandlerFunc { return } - trigger, err := triggerCtrl.Find(ctx, session, repoRef, pipelineUID, triggerUID) + trigger, err := triggerCtrl.Find(ctx, session, repoRef, pipelineIdentifier, triggerIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/trigger/list.go b/app/api/handler/trigger/list.go index e22efd437..7ff5b0de7 100644 --- a/app/api/handler/trigger/list.go +++ b/app/api/handler/trigger/list.go @@ -26,7 +26,7 @@ func HandleList(triggerCtrl *trigger.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -39,7 +39,7 @@ func HandleList(triggerCtrl *trigger.Controller) http.HandlerFunc { filter := request.ParseListQueryFilterFromRequest(r) - repos, totalCount, err := triggerCtrl.List(ctx, session, repoRef, pipelineUID, filter) + repos, totalCount, err := triggerCtrl.List(ctx, session, repoRef, pipelineIdentifier, filter) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/trigger/update.go b/app/api/handler/trigger/update.go index 2a0025243..6e5b4ba57 100644 --- a/app/api/handler/trigger/update.go +++ b/app/api/handler/trigger/update.go @@ -35,7 +35,7 @@ func HandleUpdate(triggerCtrl *trigger.Controller) http.HandlerFunc { return } - pipelineUID, err := request.GetPipelineUIDFromPath(r) + pipelineIdentifier, err := request.GetPipelineIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -45,13 +45,13 @@ func HandleUpdate(triggerCtrl *trigger.Controller) http.HandlerFunc { render.TranslatedUserError(w, err) return } - triggerUID, err := request.GetTriggerUIDFromPath(r) + triggerIdentifier, err := request.GetTriggerIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return } - pipeline, err := triggerCtrl.Update(ctx, session, repoRef, pipelineUID, triggerUID, in) + pipeline, err := triggerCtrl.Update(ctx, session, repoRef, pipelineIdentifier, triggerIdentifier, in) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/user/delete_token.go b/app/api/handler/user/delete_token.go index 4a722fe6c..cab8dbdbe 100644 --- a/app/api/handler/user/delete_token.go +++ b/app/api/handler/user/delete_token.go @@ -31,13 +31,13 @@ func HandleDeleteToken(userCtrl *user.Controller, tokenType enum.TokenType) http session, _ := request.AuthSessionFrom(ctx) userUID := session.Principal.UID - tokenUID, err := request.GetTokenUIDFromPath(r) + tokenIdentifier, err := request.GetTokenIdentifierFromPath(r) if err != nil { render.BadRequest(w) return } - err = userCtrl.DeleteToken(ctx, session, userUID, tokenType, tokenUID) + err = userCtrl.DeleteToken(ctx, session, userUID, tokenType, tokenIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/webhook/delete.go b/app/api/handler/webhook/delete.go index a6300942d..81f4da23b 100644 --- a/app/api/handler/webhook/delete.go +++ b/app/api/handler/webhook/delete.go @@ -34,13 +34,13 @@ func HandleDelete(webhookCtrl *webhook.Controller) http.HandlerFunc { return } - webhookUID, err := request.GetWebhookUIDFromPath(r) + webhookIdentifier, err := request.GetWebhookIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return } - err = webhookCtrl.Delete(ctx, session, repoRef, webhookUID, false) + err = webhookCtrl.Delete(ctx, session, repoRef, webhookIdentifier, false) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/webhook/find.go b/app/api/handler/webhook/find.go index 8668ca746..315bf8d89 100644 --- a/app/api/handler/webhook/find.go +++ b/app/api/handler/webhook/find.go @@ -34,13 +34,13 @@ func HandleFind(webhookCtrl *webhook.Controller) http.HandlerFunc { return } - webhookUID, err := request.GetWebhookUIDFromPath(r) + webhookIdentifier, err := request.GetWebhookIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return } - webhook, err := webhookCtrl.Find(ctx, session, repoRef, webhookUID) + webhook, err := webhookCtrl.Find(ctx, session, repoRef, webhookIdentifier) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/webhook/find_execution.go b/app/api/handler/webhook/find_execution.go index 2e7ddc7a5..5cb8d8315 100644 --- a/app/api/handler/webhook/find_execution.go +++ b/app/api/handler/webhook/find_execution.go @@ -34,7 +34,7 @@ func HandleFindExecution(webhookCtrl *webhook.Controller) http.HandlerFunc { return } - webhookUID, err := request.GetWebhookUIDFromPath(r) + webhookIdentifier, err := request.GetWebhookIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -46,7 +46,7 @@ func HandleFindExecution(webhookCtrl *webhook.Controller) http.HandlerFunc { return } - execution, err := webhookCtrl.FindExecution(ctx, session, repoRef, webhookUID, webhookExecutionID) + execution, err := webhookCtrl.FindExecution(ctx, session, repoRef, webhookIdentifier, webhookExecutionID) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/webhook/list_executions.go b/app/api/handler/webhook/list_executions.go index 206516ece..6e44ba287 100644 --- a/app/api/handler/webhook/list_executions.go +++ b/app/api/handler/webhook/list_executions.go @@ -34,7 +34,7 @@ func HandleListExecutions(webhookCtrl *webhook.Controller) http.HandlerFunc { return } - webhookUID, err := request.GetWebhookUIDFromPath(r) + webhookIdentifier, err := request.GetWebhookIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -42,7 +42,7 @@ func HandleListExecutions(webhookCtrl *webhook.Controller) http.HandlerFunc { filter := request.ParseWebhookExecutionFilter(r) - executions, err := webhookCtrl.ListExecutions(ctx, session, repoRef, webhookUID, filter) + executions, err := webhookCtrl.ListExecutions(ctx, session, repoRef, webhookIdentifier, filter) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/webhook/retrigger_execution.go b/app/api/handler/webhook/retrigger_execution.go index ccecd3b80..de1db29f7 100644 --- a/app/api/handler/webhook/retrigger_execution.go +++ b/app/api/handler/webhook/retrigger_execution.go @@ -34,7 +34,7 @@ func HandleRetriggerExecution(webhookCtrl *webhook.Controller) http.HandlerFunc return } - webhookUID, err := request.GetWebhookUIDFromPath(r) + webhookIdentifier, err := request.GetWebhookIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -46,7 +46,7 @@ func HandleRetriggerExecution(webhookCtrl *webhook.Controller) http.HandlerFunc return } - execution, err := webhookCtrl.RetriggerExecution(ctx, session, repoRef, webhookUID, webhookExecutionID) + execution, err := webhookCtrl.RetriggerExecution(ctx, session, repoRef, webhookIdentifier, webhookExecutionID) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/handler/webhook/update.go b/app/api/handler/webhook/update.go index 5c93efcec..85931dc56 100644 --- a/app/api/handler/webhook/update.go +++ b/app/api/handler/webhook/update.go @@ -35,7 +35,7 @@ func HandleUpdate(webhookCtrl *webhook.Controller) http.HandlerFunc { return } - webhookUID, err := request.GetWebhookUIDFromPath(r) + webhookIdentifier, err := request.GetWebhookIdentifierFromPath(r) if err != nil { render.TranslatedUserError(w, err) return @@ -48,7 +48,7 @@ func HandleUpdate(webhookCtrl *webhook.Controller) http.HandlerFunc { return } - hook, err := webhookCtrl.Update(ctx, session, repoRef, webhookUID, in, false) + hook, err := webhookCtrl.Update(ctx, session, repoRef, webhookIdentifier, in, false) if err != nil { render.TranslatedUserError(w, err) return diff --git a/app/api/openapi/check.go b/app/api/openapi/check.go index bdc86fda9..ac3a217e2 100644 --- a/app/api/openapi/check.go +++ b/app/api/openapi/check.go @@ -30,7 +30,7 @@ var queryParameterStatusCheckQuery = openapi3.ParameterOrRef{ Parameter: &openapi3.Parameter{ Name: request.QueryParamQuery, In: openapi3.ParameterInQuery, - Description: ptr.String("The substring which is used to filter the status checks by their UID."), + Description: ptr.String("The substring which is used to filter the status checks by their Identifier."), Required: ptr.Bool(false), Schema: &openapi3.SchemaOrRef{ Schema: &openapi3.Schema{ diff --git a/app/api/openapi/pipeline.go b/app/api/openapi/pipeline.go index 535b01ee9..733827217 100644 --- a/app/api/openapi/pipeline.go +++ b/app/api/openapi/pipeline.go @@ -30,7 +30,7 @@ import ( type pipelineRequest struct { repoRequest - Ref string `path:"pipeline_uid"` + Identifier string `path:"pipeline_identifier"` } type executionRequest struct { @@ -40,7 +40,7 @@ type executionRequest struct { type triggerRequest struct { pipelineRequest - UID string `path:"trigger_uid"` + Identifier string `path:"trigger_identifier"` } type logRequest struct { @@ -146,7 +146,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&opFind, new(usererror.Error), http.StatusUnauthorized) _ = reflector.SetJSONResponse(&opFind, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&opFind, new(usererror.Error), http.StatusNotFound) - _ = reflector.Spec.AddOperation(http.MethodGet, "/repos/{repo_ref}/pipelines/{pipeline_uid}", opFind) + _ = reflector.Spec.AddOperation(http.MethodGet, "/repos/{repo_ref}/pipelines/{pipeline_identifier}", opFind) opDelete := openapi3.Operation{} opDelete.WithTags("pipeline") @@ -157,7 +157,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&opDelete, new(usererror.Error), http.StatusUnauthorized) _ = reflector.SetJSONResponse(&opDelete, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&opDelete, new(usererror.Error), http.StatusNotFound) - _ = reflector.Spec.AddOperation(http.MethodDelete, "/repos/{repo_ref}/pipelines/{pipeline_uid}", opDelete) + _ = reflector.Spec.AddOperation(http.MethodDelete, "/repos/{repo_ref}/pipelines/{pipeline_identifier}", opDelete) opUpdate := openapi3.Operation{} opUpdate.WithTags("pipeline") @@ -170,7 +170,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&opUpdate, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&opUpdate, new(usererror.Error), http.StatusNotFound) _ = reflector.Spec.AddOperation(http.MethodPatch, - "/repos/{repo_ref}/pipelines/{pipeline_uid}", opUpdate) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}", opUpdate) executionCreate := openapi3.Operation{} executionCreate.WithTags("pipeline") @@ -183,7 +183,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&executionCreate, new(usererror.Error), http.StatusUnauthorized) _ = reflector.SetJSONResponse(&executionCreate, new(usererror.Error), http.StatusForbidden) _ = reflector.Spec.AddOperation(http.MethodPost, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/executions", executionCreate) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/executions", executionCreate) executionFind := openapi3.Operation{} executionFind.WithTags("pipeline") @@ -195,7 +195,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&executionFind, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&executionFind, new(usererror.Error), http.StatusNotFound) _ = reflector.Spec.AddOperation(http.MethodGet, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/executions/{execution_number}", executionFind) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/executions/{execution_number}", executionFind) executionCancel := openapi3.Operation{} executionCancel.WithTags("pipeline") @@ -207,7 +207,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&executionCancel, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&executionCancel, new(usererror.Error), http.StatusNotFound) _ = reflector.Spec.AddOperation(http.MethodPost, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/executions/{execution_number}/cancel", executionCancel) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/executions/{execution_number}/cancel", executionCancel) executionDelete := openapi3.Operation{} executionDelete.WithTags("pipeline") @@ -219,7 +219,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&executionDelete, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&executionDelete, new(usererror.Error), http.StatusNotFound) _ = reflector.Spec.AddOperation(http.MethodDelete, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/executions/{execution_number}", executionDelete) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/executions/{execution_number}", executionDelete) executionList := openapi3.Operation{} executionList.WithTags("pipeline") @@ -232,7 +232,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&executionList, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&executionList, new(usererror.Error), http.StatusNotFound) _ = reflector.Spec.AddOperation(http.MethodGet, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/executions", executionList) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/executions", executionList) triggerCreate := openapi3.Operation{} triggerCreate.WithTags("pipeline") @@ -244,7 +244,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&triggerCreate, new(usererror.Error), http.StatusUnauthorized) _ = reflector.SetJSONResponse(&triggerCreate, new(usererror.Error), http.StatusForbidden) _ = reflector.Spec.AddOperation(http.MethodPost, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/triggers", triggerCreate) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/triggers", triggerCreate) triggerFind := openapi3.Operation{} triggerFind.WithTags("pipeline") @@ -256,7 +256,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&triggerFind, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&triggerFind, new(usererror.Error), http.StatusNotFound) _ = reflector.Spec.AddOperation(http.MethodGet, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/triggers/{trigger_uid}", triggerFind) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/triggers/{trigger_identifier}", triggerFind) triggerDelete := openapi3.Operation{} triggerDelete.WithTags("pipeline") @@ -268,7 +268,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&triggerDelete, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&triggerDelete, new(usererror.Error), http.StatusNotFound) _ = reflector.Spec.AddOperation(http.MethodDelete, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/triggers/{trigger_uid}", triggerDelete) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/triggers/{trigger_identifier}", triggerDelete) triggerUpdate := openapi3.Operation{} triggerUpdate.WithTags("pipeline") @@ -281,7 +281,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&triggerUpdate, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&triggerUpdate, new(usererror.Error), http.StatusNotFound) _ = reflector.Spec.AddOperation(http.MethodPatch, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/triggers/{trigger_uid}", triggerUpdate) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/triggers/{trigger_identifier}", triggerUpdate) triggerList := openapi3.Operation{} triggerList.WithTags("pipeline") @@ -294,7 +294,7 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&triggerList, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&triggerList, new(usererror.Error), http.StatusNotFound) _ = reflector.Spec.AddOperation(http.MethodGet, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/triggers", triggerList) + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/triggers", triggerList) logView := openapi3.Operation{} logView.WithTags("pipeline") @@ -306,6 +306,9 @@ func pipelineOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&logView, new(usererror.Error), http.StatusUnauthorized) _ = reflector.SetJSONResponse(&logView, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&logView, new(usererror.Error), http.StatusNotFound) - _ = reflector.Spec.AddOperation(http.MethodGet, - "/repos/{repo_ref}/pipelines/{pipeline_uid}/executions/{execution_number}/logs/{stage_number}/{step_number}", logView) + _ = reflector.Spec.AddOperation( + http.MethodGet, + "/repos/{repo_ref}/pipelines/{pipeline_identifier}/executions/{execution_number}/logs/{stage_number}/{step_number}", + logView, + ) } diff --git a/app/api/openapi/repo.go b/app/api/openapi/repo.go index c32b617b4..82caade20 100644 --- a/app/api/openapi/repo.go +++ b/app/api/openapi/repo.go @@ -801,21 +801,21 @@ func repoOperations(reflector *openapi3.Reflector) { opRuleDelete.WithMapOfAnything(map[string]interface{}{"operationId": "ruleDelete"}) _ = reflector.SetRequest(&opRuleDelete, struct { repoRequest - RuleUID string `path:"rule_uid"` + RuleIdentifier string `path:"rule_identifier"` }{}, http.MethodDelete) _ = reflector.SetJSONResponse(&opRuleDelete, nil, http.StatusNoContent) _ = reflector.SetJSONResponse(&opRuleDelete, new(usererror.Error), http.StatusInternalServerError) _ = reflector.SetJSONResponse(&opRuleDelete, new(usererror.Error), http.StatusUnauthorized) _ = reflector.SetJSONResponse(&opRuleDelete, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&opRuleDelete, new(usererror.Error), http.StatusNotFound) - _ = reflector.Spec.AddOperation(http.MethodDelete, "/repos/{repo_ref}/rules/{rule_uid}", opRuleDelete) + _ = reflector.Spec.AddOperation(http.MethodDelete, "/repos/{repo_ref}/rules/{rule_identifier}", opRuleDelete) opRuleUpdate := openapi3.Operation{} opRuleUpdate.WithTags("repository") opRuleUpdate.WithMapOfAnything(map[string]interface{}{"operationId": "ruleUpdate"}) _ = reflector.SetRequest(&opRuleUpdate, &struct { repoRequest - RuleUID string `path:"rule_uid"` + Identifier string `path:"rule_identifier"` repo.RuleUpdateInput // overshadow Type and Definition to enable oneof. @@ -827,7 +827,7 @@ func repoOperations(reflector *openapi3.Reflector) { _ = reflector.SetJSONResponse(&opRuleUpdate, new(usererror.Error), http.StatusUnauthorized) _ = reflector.SetJSONResponse(&opRuleUpdate, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&opRuleUpdate, new(usererror.Error), http.StatusNotFound) - _ = reflector.Spec.AddOperation(http.MethodPatch, "/repos/{repo_ref}/rules/{rule_uid}", opRuleUpdate) + _ = reflector.Spec.AddOperation(http.MethodPatch, "/repos/{repo_ref}/rules/{rule_identifier}", opRuleUpdate) opRuleList := openapi3.Operation{} opRuleList.WithTags("repository") @@ -851,14 +851,14 @@ func repoOperations(reflector *openapi3.Reflector) { opRuleGet.WithMapOfAnything(map[string]interface{}{"operationId": "ruleGet"}) _ = reflector.SetRequest(&opRuleGet, &struct { repoRequest - RuleUID string `path:"rule_uid"` + Identifier string `path:"rule_identifier"` }{}, http.MethodGet) _ = reflector.SetJSONResponse(&opRuleGet, []rule{}, http.StatusOK) _ = reflector.SetJSONResponse(&opRuleGet, new(usererror.Error), http.StatusInternalServerError) _ = reflector.SetJSONResponse(&opRuleGet, new(usererror.Error), http.StatusUnauthorized) _ = reflector.SetJSONResponse(&opRuleGet, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&opRuleGet, new(usererror.Error), http.StatusNotFound) - _ = reflector.Spec.AddOperation(http.MethodGet, "/repos/{repo_ref}/rules/{rule_uid}", opRuleGet) + _ = reflector.Spec.AddOperation(http.MethodGet, "/repos/{repo_ref}/rules/{rule_identifier}", opRuleGet) opCodeOwnerValidate := openapi3.Operation{} opCodeOwnerValidate.WithTags("repository") diff --git a/app/api/openapi/space.go b/app/api/openapi/space.go index 84811b1ef..dd3d62037 100644 --- a/app/api/openapi/space.go +++ b/app/api/openapi/space.go @@ -59,9 +59,9 @@ var queryParameterSortRepo = openapi3.ParameterOrRef{ Schema: &openapi3.SchemaOrRef{ Schema: &openapi3.Schema{ Type: ptrSchemaType(openapi3.SchemaTypeString), - Default: ptrptr(enum.RepoAttrUID.String()), + Default: ptrptr(enum.RepoAttrIdentifier.String()), Enum: []interface{}{ - ptr.String(enum.RepoAttrUID.String()), + ptr.String(enum.RepoAttrIdentifier.String()), ptr.String(enum.RepoAttrCreated.String()), ptr.String(enum.RepoAttrUpdated.String()), }, @@ -93,9 +93,9 @@ var queryParameterSortSpace = openapi3.ParameterOrRef{ Schema: &openapi3.SchemaOrRef{ Schema: &openapi3.Schema{ Type: ptrSchemaType(openapi3.SchemaTypeString), - Default: ptrptr(enum.SpaceAttrUID.String()), + Default: ptrptr(enum.SpaceAttrIdentifier.String()), Enum: []interface{}{ - ptr.String(enum.SpaceAttrUID.String()), + ptr.String(enum.SpaceAttrIdentifier.String()), ptr.String(enum.SpaceAttrCreated.String()), ptr.String(enum.SpaceAttrUpdated.String()), }, diff --git a/app/api/openapi/user.go b/app/api/openapi/user.go index 3cd0fe7ca..fc72e43cb 100644 --- a/app/api/openapi/user.go +++ b/app/api/openapi/user.go @@ -54,7 +54,7 @@ var queryParameterSortMembershipSpaces = openapi3.ParameterOrRef{ Schema: &openapi3.SchemaOrRef{ Schema: &openapi3.Schema{ Type: ptrSchemaType(openapi3.SchemaTypeString), - Default: ptrptr(enum.MembershipSpaceSortUID), + Default: ptrptr(enum.MembershipSpaceSortIdentifier), Enum: enum.MembershipSpaceSort("").Enum(), }, }, diff --git a/app/api/openapi/webhook.go b/app/api/openapi/webhook.go index 0289bbad9..b6dc64b6e 100644 --- a/app/api/openapi/webhook.go +++ b/app/api/openapi/webhook.go @@ -82,10 +82,12 @@ var queryParameterSortWebhook = openapi3.ParameterOrRef{ Schema: &openapi3.SchemaOrRef{ Schema: &openapi3.Schema{ Type: ptrSchemaType(openapi3.SchemaTypeString), - Default: ptrptr(enum.WebhookAttrID.String()), + Default: ptrptr(enum.WebhookAttrIdentifier.String()), Enum: []interface{}{ + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. ptr.String(enum.WebhookAttrID.String()), ptr.String(enum.WebhookAttrUID.String()), + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. ptr.String(enum.WebhookAttrDisplayName.String()), ptr.String(enum.WebhookAttrCreated.String()), ptr.String(enum.WebhookAttrUpdated.String()), @@ -99,7 +101,7 @@ var queryParameterQueryWebhook = openapi3.ParameterOrRef{ Parameter: &openapi3.Parameter{ Name: request.QueryParamQuery, In: openapi3.ParameterInQuery, - Description: ptr.String("The substring which is used to filter the webhooks by their uid."), + Description: ptr.String("The substring which is used to filter the webhooks by their identifier."), Required: ptr.Bool(false), Schema: &openapi3.SchemaOrRef{ Schema: &openapi3.Schema{ diff --git a/app/api/request/pipeline.go b/app/api/request/pipeline.go index 0bddd5d77..4a4502c3b 100644 --- a/app/api/request/pipeline.go +++ b/app/api/request/pipeline.go @@ -20,17 +20,17 @@ import ( ) const ( - PathParamPipelineRef = "pipeline_uid" - PathParamExecutionNumber = "execution_number" - PathParamStageNumber = "stage_number" - PathParamStepNumber = "step_number" - PathParamTriggerUID = "trigger_uid" - QueryParamLatest = "latest" - QueryParamBranch = "branch" + PathParamPipelineIdentifier = "pipeline_identifier" + PathParamExecutionNumber = "execution_number" + PathParamStageNumber = "stage_number" + PathParamStepNumber = "step_number" + PathParamTriggerIdentifier = "trigger_identifier" + QueryParamLatest = "latest" + QueryParamBranch = "branch" ) -func GetPipelineUIDFromPath(r *http.Request) (string, error) { - rawRef, err := PathParamOrError(r, PathParamPipelineRef) +func GetPipelineIdentifierFromPath(r *http.Request) (string, error) { + rawRef, err := PathParamOrError(r, PathParamPipelineIdentifier) if err != nil { return "", err } @@ -60,8 +60,8 @@ func GetLatestFromPath(r *http.Request) bool { return v == "true" } -func GetTriggerUIDFromPath(r *http.Request) (string, error) { - rawRef, err := PathParamOrError(r, PathParamTriggerUID) +func GetTriggerIdentifierFromPath(r *http.Request) (string, error) { + rawRef, err := PathParamOrError(r, PathParamTriggerIdentifier) if err != nil { return "", err } diff --git a/app/api/request/rule.go b/app/api/request/rule.go index 6d91a1f78..e923a9932 100644 --- a/app/api/request/rule.go +++ b/app/api/request/rule.go @@ -22,7 +22,7 @@ import ( ) const ( - PathParamRuleUID = "rule_uid" + PathParamRuleIdentifier = "rule_identifier" QueryParamBypassRules = "bypass_rules" ) @@ -55,9 +55,9 @@ func parseRuleStates(r *http.Request) []enum.RuleState { return states } -// GetRuleUIDFromPath extracts the protection rule UID from the URL. -func GetRuleUIDFromPath(r *http.Request) (string, error) { - return PathParamOrError(r, PathParamRuleUID) +// GetRuleIdentifierFromPath extracts the protection rule identifier from the URL. +func GetRuleIdentifierFromPath(r *http.Request) (string, error) { + return PathParamOrError(r, PathParamRuleIdentifier) } // parseRuleSort extracts the protection rule sort parameter from the URL. diff --git a/app/api/request/token.go b/app/api/request/token.go index ea76476d3..2e83e911e 100644 --- a/app/api/request/token.go +++ b/app/api/request/token.go @@ -19,9 +19,9 @@ import ( ) const ( - PathParamTokenUID = "token_uid" + PathParamTokenIdentifier = "token_identifier" ) -func GetTokenUIDFromPath(r *http.Request) (string, error) { - return PathParamOrError(r, PathParamTokenUID) +func GetTokenIdentifierFromPath(r *http.Request) (string, error) { + return PathParamOrError(r, PathParamTokenIdentifier) } diff --git a/app/api/request/webhook.go b/app/api/request/webhook.go index 1d03f5ea7..c49cd1058 100644 --- a/app/api/request/webhook.go +++ b/app/api/request/webhook.go @@ -22,12 +22,12 @@ import ( ) const ( - PathParamWebhookUID = "webhook_uid" + PathParamWebhookIdentifier = "webhook_identifier" PathParamWebhookExecutionID = "webhook_execution_id" ) -func GetWebhookUIDFromPath(r *http.Request) (string, error) { - return PathParamOrError(r, PathParamWebhookUID) +func GetWebhookIdentifierFromPath(r *http.Request) (string, error) { + return PathParamOrError(r, PathParamWebhookIdentifier) } func GetWebhookExecutionIDFromPath(r *http.Request) (int64, error) { diff --git a/app/auth/authz/membership.go b/app/auth/authz/membership.go index 00e8b932b..d98e16c48 100644 --- a/app/auth/authz/membership.go +++ b/app/auth/authz/membership.go @@ -67,7 +67,7 @@ func (a *MembershipAuthorizer) Check( session.Principal.ID, permission, resource.Type, - resource.Name, + resource.Identifier, scope, session.Metadata, ) @@ -81,7 +81,7 @@ func (a *MembershipAuthorizer) Check( //nolint:exhaustive // we want to fail on anything else switch resource.Type { case enum.ResourceTypeSpace: - spacePath = paths.Concatinate(scope.SpacePath, resource.Name) + spacePath = paths.Concatinate(scope.SpacePath, resource.Identifier) case enum.ResourceTypeRepo: spacePath = scope.SpacePath @@ -103,7 +103,7 @@ func (a *MembershipAuthorizer) Check( case enum.ResourceTypeUser: // a user is allowed to view / edit themselves - if resource.Name == session.Principal.UID && + if resource.Identifier == session.Principal.UID && (permission == enum.PermissionUserView || permission == enum.PermissionUserEdit) { return true, nil } diff --git a/app/auth/authz/unsafe.go b/app/auth/authz/unsafe.go index 2c8385c51..3a5f7cb9f 100644 --- a/app/auth/authz/unsafe.go +++ b/app/auth/authz/unsafe.go @@ -43,7 +43,7 @@ func (a *UnsafeAuthorizer) Check(ctx context.Context, session *auth.Session, session.Principal.ID, permission, resource.Type, - resource.Name, + resource.Identifier, scope, session.Metadata, ) diff --git a/app/pipeline/checks/write.go b/app/pipeline/checks/write.go index 822fa6048..08c3c05bc 100644 --- a/app/pipeline/checks/write.go +++ b/app/pipeline/checks/write.go @@ -45,18 +45,18 @@ func Write( now := time.Now().UnixMilli() summary := pipeline.Description if summary == "" { - summary = pipeline.UID + summary = pipeline.Identifier } check := &types.Check{ - RepoID: execution.RepoID, - UID: pipeline.UID, - Summary: summary, - Created: now, - Updated: now, - CreatedBy: execution.CreatedBy, - Status: execution.Status.ConvertToCheckStatus(), - CommitSHA: execution.After, - Metadata: []byte("{}"), + RepoID: execution.RepoID, + Identifier: pipeline.Identifier, + Summary: summary, + Created: now, + Updated: now, + CreatedBy: execution.CreatedBy, + Status: execution.Status.ConvertToCheckStatus(), + CommitSHA: execution.After, + Metadata: []byte("{}"), Payload: types.CheckPayload{ Version: "1", Kind: enum.CheckPayloadKindPipeline, diff --git a/app/pipeline/converter/jsonnet/jsonnet.go b/app/pipeline/converter/jsonnet/jsonnet.go index eb2f35207..b0205a3ef 100644 --- a/app/pipeline/converter/jsonnet/jsonnet.go +++ b/app/pipeline/converter/jsonnet/jsonnet.go @@ -194,8 +194,10 @@ func mapRepo(v *types.Repository, p *types.Pipeline, vm *jsonnet.VM) { if idx != -1 { namespace = v.Path[:idx] } - vm.ExtVar(repo+"uid", v.UID) - vm.ExtVar(repo+"name", v.UID) + // TODO [CODE-1363]: remove after identifier migration. + vm.ExtVar(repo+"uid", v.Identifier) + vm.ExtVar(repo+"identifier", v.Identifier) + vm.ExtVar(repo+"name", v.Identifier) vm.ExtVar(repo+"namespace", namespace) vm.ExtVar(repo+"slug", v.Path) vm.ExtVar(repo+"git_http_url", v.GitURL) diff --git a/app/pipeline/converter/starlark/args.go b/app/pipeline/converter/starlark/args.go index f551a5db4..c4465b875 100644 --- a/app/pipeline/converter/starlark/args.go +++ b/app/pipeline/converter/starlark/args.go @@ -73,8 +73,10 @@ func fromRepo(v *types.Repository, p *types.Pipeline) starlark.StringDict { namespace = v.Path[:idx] } return starlark.StringDict{ - "uid": starlark.String(v.UID), - "name": starlark.String(v.UID), + // TODO [CODE-1363]: remove after identifier migration? + "uid": starlark.String(v.Identifier), + "identifier": starlark.String(v.Identifier), + "name": starlark.String(v.Identifier), "namespace": starlark.String(namespace), "slug": starlark.String(v.Path), "git_http_url": starlark.String(v.GitURL), diff --git a/app/pipeline/converter/starlark/starlark.go b/app/pipeline/converter/starlark/starlark.go index 9269e1791..24c0442b9 100644 --- a/app/pipeline/converter/starlark/starlark.go +++ b/app/pipeline/converter/starlark/starlark.go @@ -69,7 +69,7 @@ func Parse( Print: func(_ *starlark.Thread, msg string) { logrus.WithFields(logrus.Fields{ "namespace": repo.Path, // TODO: update to just be the space - "name": repo.UID, + "name": repo.Identifier, }).Traceln(msg) }, } diff --git a/app/pipeline/manager/convert.go b/app/pipeline/manager/convert.go index 73cbb4b3d..bf0394efa 100644 --- a/app/pipeline/manager/convert.go +++ b/app/pipeline/manager/convert.go @@ -211,10 +211,10 @@ func ConvertToDroneRepo(repo *types.Repository) *drone.Repo { return &drone.Repo{ ID: repo.ID, Trusted: true, // as builds are running on user machines, the repo is marked trusted. - UID: repo.UID, + UID: repo.Identifier, UserID: repo.CreatedBy, Namespace: repo.Path, - Name: repo.UID, + Name: repo.Identifier, HTTPURL: repo.GitURL, Link: repo.GitURL, Private: !repo.IsPublic, @@ -236,7 +236,7 @@ func ConvertToDroneFile(file *file.File) *client.File { func ConvertToDroneSecret(secret *types.Secret) *drone.Secret { return &drone.Secret{ - Name: secret.UID, + Name: secret.Identifier, Data: secret.Data, } } diff --git a/app/pipeline/resolver/manager.go b/app/pipeline/resolver/manager.go index 67b4bb495..b2b2c21a4 100644 --- a/app/pipeline/resolver/manager.go +++ b/app/pipeline/resolver/manager.go @@ -169,7 +169,7 @@ func (m *Manager) traverseAndUpsertPlugins(ctx context.Context, rc *zip.ReadClos // Put the plugins in a map so we don't have to perform frequent DB queries. pluginMap := map[string]*types.Plugin{} for _, p := range plugins { - pluginMap[p.UID] = p + pluginMap[p.Identifier] = p } cnt := 0 for _, file := range rc.File { @@ -212,7 +212,7 @@ func (m *Manager) traverseAndUpsertPlugins(ctx context.Context, rc *zip.ReadClos plugin := &types.Plugin{ Description: desc, - UID: config.Name, + Identifier: config.Name, Type: config.Type, Spec: buf.String(), } @@ -231,7 +231,7 @@ func (m *Manager) traverseAndUpsertPlugins(ctx context.Context, rc *zip.ReadClos } // If plugin already exists in the database, skip upsert - if p, ok := pluginMap[plugin.UID]; ok { + if p, ok := pluginMap[plugin.Identifier]; ok { if p.Matches(plugin) { continue } @@ -241,7 +241,7 @@ func (m *Manager) traverseAndUpsertPlugins(ctx context.Context, rc *zip.ReadClos // TODO: Once we start using versions, we can think of whether we want to // keep different schemas for each version in the database. For now, we will // simply overwrite the existing version with the new version. - if _, ok := pluginMap[plugin.UID]; ok { + if _, ok := pluginMap[plugin.Identifier]; ok { err = m.pluginStore.Update(ctx, plugin) if err != nil { log.Warn().Str("name", file.Name).Err(err).Msg("could not update plugin") diff --git a/app/pipeline/resolver/resolve.go b/app/pipeline/resolver/resolve.go index 4db144f59..550d2294a 100644 --- a/app/pipeline/resolver/resolve.go +++ b/app/pipeline/resolver/resolve.go @@ -60,7 +60,7 @@ func Resolve( } // Search for templates in the space - template, err := templateStore.FindByUIDAndType(ctx, spaceID, name, t) + template, err := templateStore.FindByIdentifierAndType(ctx, spaceID, name, t) if err != nil { return nil, fmt.Errorf("could not find template: %w", err) } diff --git a/app/pipeline/triggerer/env.go b/app/pipeline/triggerer/env.go index 2bf29139c..ee625c789 100644 --- a/app/pipeline/triggerer/env.go +++ b/app/pipeline/triggerer/env.go @@ -37,6 +37,6 @@ func Envs( urlProvider url.Provider, ) map[string]string { return map[string]string{ - "DRONE_BUILD_LINK": urlProvider.GenerateUIBuildURL(repo.Path, pipeline.UID, pipeline.Seq), + "DRONE_BUILD_LINK": urlProvider.GenerateUIBuildURL(repo.Path, pipeline.Identifier, pipeline.Seq), } } diff --git a/app/router/api.go b/app/router/api.go index 37c336448..1006235d9 100644 --- a/app/router/api.go +++ b/app/router/api.go @@ -365,7 +365,7 @@ func setupPipelines( // Create takes path and parentId via body, not uri r.Post("/", handlerpipeline.HandleCreate(pipelineCtrl)) r.Get("/generate", handlerrepo.HandlePipelineGenerate(repoCtrl)) - r.Route(fmt.Sprintf("/{%s}", request.PathParamPipelineRef), func(r chi.Router) { + r.Route(fmt.Sprintf("/{%s}", request.PathParamPipelineIdentifier), func(r chi.Router) { r.Get("/", handlerpipeline.HandleFind(pipelineCtrl)) r.Patch("/", handlerpipeline.HandleUpdate(pipelineCtrl)) r.Delete("/", handlerpipeline.HandleDelete(pipelineCtrl)) @@ -458,7 +458,7 @@ func setupTriggers( r.Route("/triggers", func(r chi.Router) { r.Get("/", handlertrigger.HandleList(triggerCtrl)) r.Post("/", handlertrigger.HandleCreate(triggerCtrl)) - r.Route(fmt.Sprintf("/{%s}", request.PathParamTriggerUID), func(r chi.Router) { + r.Route(fmt.Sprintf("/{%s}", request.PathParamTriggerIdentifier), func(r chi.Router) { r.Get("/", handlertrigger.HandleFind(triggerCtrl)) r.Patch("/", handlertrigger.HandleUpdate(triggerCtrl)) r.Delete("/", handlertrigger.HandleDelete(triggerCtrl)) @@ -529,7 +529,7 @@ func SetupWebhook(r chi.Router, webhookCtrl *webhook.Controller) { r.Post("/", handlerwebhook.HandleCreate(webhookCtrl)) r.Get("/", handlerwebhook.HandleList(webhookCtrl)) - r.Route(fmt.Sprintf("/{%s}", request.PathParamWebhookUID), func(r chi.Router) { + r.Route(fmt.Sprintf("/{%s}", request.PathParamWebhookIdentifier), func(r chi.Router) { r.Get("/", handlerwebhook.HandleFind(webhookCtrl)) r.Patch("/", handlerwebhook.HandleUpdate(webhookCtrl)) r.Delete("/", handlerwebhook.HandleDelete(webhookCtrl)) @@ -560,7 +560,7 @@ func SetupRules(r chi.Router, repoCtrl *repo.Controller) { r.Route("/rules", func(r chi.Router) { r.Post("/", handlerrepo.HandleRuleCreate(repoCtrl)) r.Get("/", handlerrepo.HandleRuleList(repoCtrl)) - r.Route(fmt.Sprintf("/{%s}", request.PathParamRuleUID), func(r chi.Router) { + r.Route(fmt.Sprintf("/{%s}", request.PathParamRuleIdentifier), func(r chi.Router) { r.Patch("/", handlerrepo.HandleRuleUpdate(repoCtrl)) r.Delete("/", handlerrepo.HandleRuleDelete(repoCtrl)) r.Get("/", handlerrepo.HandleRuleFind(repoCtrl)) @@ -582,7 +582,7 @@ func setupUser(r chi.Router, userCtrl *user.Controller) { r.Post("/", handleruser.HandleCreateAccessToken(userCtrl)) // per token operations - r.Route(fmt.Sprintf("/{%s}", request.PathParamTokenUID), func(r chi.Router) { + r.Route(fmt.Sprintf("/{%s}", request.PathParamTokenIdentifier), func(r chi.Router) { r.Delete("/", handleruser.HandleDeleteToken(userCtrl, enum.TokenTypePAT)) }) }) @@ -592,7 +592,7 @@ func setupUser(r chi.Router, userCtrl *user.Controller) { r.Get("/", handleruser.HandleListTokens(userCtrl, enum.TokenTypeSession)) // per token operations - r.Route(fmt.Sprintf("/{%s}", request.PathParamTokenUID), func(r chi.Router) { + r.Route(fmt.Sprintf("/{%s}", request.PathParamTokenIdentifier), func(r chi.Router) { r.Delete("/", handleruser.HandleDeleteToken(userCtrl, enum.TokenTypeSession)) }) }) @@ -614,7 +614,7 @@ func setupServiceAccounts(r chi.Router, saCtrl *serviceaccount.Controller) { r.Post("/", handlerserviceaccount.HandleCreateToken(saCtrl)) // per token operations - r.Route(fmt.Sprintf("/{%s}", request.PathParamTokenUID), func(r chi.Router) { + r.Route(fmt.Sprintf("/{%s}", request.PathParamTokenIdentifier), func(r chi.Router) { r.Delete("/", handlerserviceaccount.HandleDeleteToken(saCtrl)) }) }) diff --git a/app/services/codeowners/service.go b/app/services/codeowners/service.go index 823d3fcdd..9341df85f 100644 --- a/app/services/codeowners/service.go +++ b/app/services/codeowners/service.go @@ -110,7 +110,7 @@ type EvaluationEntry struct { } type UserGroupOwnerEvaluation struct { - ID string + Identifier string Name string Evaluations []OwnerEvaluation } @@ -374,8 +374,8 @@ func (s *Service) resolveUserGroupCodeOwner( return nil, fmt.Errorf("not able to resolve usergroup : %w", err) } userGroupEvaluation := &UserGroupOwnerEvaluation{ - ID: usrgrp.ID, - Name: usrgrp.Name, + Identifier: usrgrp.Identifier, + Name: usrgrp.Name, } ownersEvaluations := make([]OwnerEvaluation, 0, len(usrgrp.Users)) for _, uid := range usrgrp.Users { diff --git a/app/services/exporter/harness_code_client.go b/app/services/exporter/harness_code_client.go index 869512345..92f9a7bd4 100644 --- a/app/services/exporter/harness_code_client.go +++ b/app/services/exporter/harness_code_client.go @@ -162,8 +162,8 @@ func addQueryParams(req *http.Request, params map[string]string) { } } -func (c *harnessCodeClient) DeleteRepo(ctx context.Context, repoUID string) error { - path := fmt.Sprintf(pathDeleteRepo, c.client.accountID, c.client.orgID, c.client.projectID, repoUID) +func (c *harnessCodeClient) DeleteRepo(ctx context.Context, repoIdentifier string) error { + path := fmt.Sprintf(pathDeleteRepo, c.client.accountID, c.client.orgID, c.client.projectID, repoIdentifier) req, err := http.NewRequestWithContext(ctx, http.MethodDelete, appendPath(c.client.baseURL, path), nil) if err != nil { return fmt.Errorf("unable to create new http request : %w", err) diff --git a/app/services/exporter/repository.go b/app/services/exporter/repository.go index 6eeff3288..311ed8fea 100644 --- a/app/services/exporter/repository.go +++ b/app/services/exporter/repository.go @@ -57,7 +57,7 @@ type Repository struct { } type Input struct { - UID string `json:"uid"` + Identifier string `json:"identifier"` ID int64 `json:"id"` Description string `json:"description"` IsPublic bool `json:"is_public"` @@ -115,7 +115,7 @@ func (r *Repository) RunManyForSpace( jobDefinitions := make([]job.Definition, len(repos)) for i, repository := range repos { repoJobData := Input{ - UID: repository.UID, + Identifier: repository.Identifier, ID: repository.ID, Description: repository.Description, IsPublic: repository.IsPublic, @@ -185,7 +185,7 @@ func (r *Repository) Handle(ctx context.Context, data string, _ job.ProgressRepo return "", err } remoteRepo, err := client.CreateRepo(ctx, repo.CreateInput{ - UID: repository.UID, + Identifier: repository.Identifier, DefaultBranch: repository.DefaultBranch, Description: repository.Description, IsPublic: repository.IsPublic, @@ -208,15 +208,15 @@ func (r *Repository) Handle(ctx context.Context, data string, _ job.ProgressRepo RemoteURL: urlWithToken, }) if err != nil && !strings.Contains(err.Error(), "empty") { - errDelete := client.DeleteRepo(ctx, remoteRepo.UID) + errDelete := client.DeleteRepo(ctx, remoteRepo.Identifier) if errDelete != nil { - log.Ctx(ctx).Err(errDelete).Msgf("failed to delete repo '%s' on harness", remoteRepo.UID) + log.Ctx(ctx).Err(errDelete).Msgf("failed to delete repo '%s' on harness", remoteRepo.Identifier) } r.publishSSE(ctx, repository) return "", err } - log.Ctx(ctx).Info().Msgf("completed exporting repository '%s' to harness", repository.UID) + log.Ctx(ctx).Info().Msgf("completed exporting repository '%s' to harness", repository.Identifier) r.publishSSE(ctx, repository) diff --git a/app/services/importer/pipelines.go b/app/services/importer/pipelines.go index 9d8560a64..440e46b9b 100644 --- a/app/services/importer/pipelines.go +++ b/app/services/importer/pipelines.go @@ -95,7 +95,7 @@ func (r *Repository) processPipelines(ctx context.Context, pipeline := &types.Pipeline{ Description: "", RepoID: repo.ID, - UID: p.Name, + Identifier: p.Name, CreatedBy: principal.ID, Seq: 0, DefaultBranch: repo.DefaultBranch, @@ -120,7 +120,7 @@ func (r *Repository) processPipelines(ctx context.Context, PipelineID: pipeline.ID, RepoID: pipeline.RepoID, CreatedBy: principal.ID, - UID: "default", + Identifier: "default", Actions: []enum.TriggerAction{enum.TriggerActionPullReqCreated, enum.TriggerActionPullReqReopened, enum.TriggerActionPullReqBranchUpdated}, Disabled: false, diff --git a/app/services/importer/provider.go b/app/services/importer/provider.go index df524ec68..32ddf7f7c 100644 --- a/app/services/importer/provider.go +++ b/app/services/importer/provider.go @@ -69,7 +69,7 @@ type Provider struct { type RepositoryInfo struct { Space string - UID string + Identifier string CloneURL string IsPublic bool DefaultBranch string @@ -78,17 +78,17 @@ type RepositoryInfo struct { // ToRepo converts the RepositoryInfo into the types.Repository object marked as being imported. func (r *RepositoryInfo) ToRepo( spaceID int64, - uid string, + identifier string, description string, principal *types.Principal, publicResourceCreationEnabled bool, ) *types.Repository { now := time.Now().UnixMilli() - gitTempUID := fmt.Sprintf("importing-%s-%d", hash(fmt.Sprintf("%d:%s", spaceID, uid)), now) + gitTempUID := fmt.Sprintf("importing-%s-%d", hash(fmt.Sprintf("%d:%s", spaceID, identifier)), now) return &types.Repository{ Version: 0, ParentID: spaceID, - UID: uid, + Identifier: identifier, GitUID: gitTempUID, // the correct git UID will be set by the job handler Description: description, IsPublic: publicResourceCreationEnabled && r.IsPublic, @@ -258,7 +258,7 @@ func LoadRepositoryFromProvider( return RepositoryInfo{ Space: scmRepo.Namespace, - UID: scmRepo.Name, + Identifier: scmRepo.Name, CloneURL: scmRepo.Clone, IsPublic: !scmRepo.Private, DefaultBranch: scmRepo.Branch, @@ -339,7 +339,7 @@ func LoadRepositoriesFromProviderSpace( repos = append(repos, RepositoryInfo{ Space: scmRepo.Namespace, - UID: scmRepo.Name, + Identifier: scmRepo.Name, CloneURL: scmRepo.Clone, IsPublic: !scmRepo.Private, DefaultBranch: scmRepo.Branch, diff --git a/app/services/importer/repository.go b/app/services/importer/repository.go index a53ab3154..5f4ae0a3e 100644 --- a/app/services/importer/repository.go +++ b/app/services/importer/repository.go @@ -229,7 +229,7 @@ func (r *Repository) Handle(ctx context.Context, data string, _ job.ProgressRepo } if !repo.Importing { - return "", fmt.Errorf("repository %s is not being imported", repo.UID) + return "", fmt.Errorf("repository %s is not being imported", repo.Identifier) } log := log.Ctx(ctx).With(). diff --git a/app/services/notification/mail_client.go b/app/services/notification/mail_client.go index b775f83fd..b25622ea7 100644 --- a/app/services/notification/mail_client.go +++ b/app/services/notification/mail_client.go @@ -132,11 +132,11 @@ func (m MailClient) SendPullReqStateChanged( } func GetSubjectPullRequest( - repoUID string, + repoIdentifier string, prNum int64, prTitle string, ) string { - return fmt.Sprintf(subjectPullReqEvent, repoUID, prTitle, prNum) + return fmt.Sprintf(subjectPullReqEvent, repoIdentifier, prTitle, prNum) } func GetHTMLBody(templateName string, data interface{}) ([]byte, error) { @@ -156,7 +156,7 @@ func GenerateEmailFromPayload( base *BasePullReqPayload, payload interface{}, ) (*mailer.Payload, error) { - subject := GetSubjectPullRequest(base.Repo.UID, base.PullReq.Number, + subject := GetSubjectPullRequest(base.Repo.Identifier, base.PullReq.Number, base.PullReq.Title) body, err := GetHTMLBody(templateName, payload) diff --git a/app/services/protection/json.go b/app/services/protection/json.go index d3775dc48..a617e8d9d 100644 --- a/app/services/protection/json.go +++ b/app/services/protection/json.go @@ -19,9 +19,9 @@ import ( "encoding/json" ) -// toJSON is utility function that converts types to a JSON message. +// ToJSON is utility function that converts types to a JSON message. // It's used to sanitize protection definition data. -func toJSON(v any) (json.RawMessage, error) { +func ToJSON(v any) (json.RawMessage, error) { buffer := bytes.NewBuffer(nil) enc := json.NewEncoder(buffer) diff --git a/app/services/protection/pattern.go b/app/services/protection/pattern.go index 8bcd84267..608cbd2db 100644 --- a/app/services/protection/pattern.go +++ b/app/services/protection/pattern.go @@ -28,7 +28,7 @@ type Pattern struct { } func (p *Pattern) JSON() json.RawMessage { - message, _ := toJSON(p) + message, _ := ToJSON(p) return message } diff --git a/app/services/protection/rule_branch_test.go b/app/services/protection/rule_branch_test.go index 60a2a54c3..4f9a46137 100644 --- a/app/services/protection/rule_branch_test.go +++ b/app/services/protection/rule_branch_test.go @@ -50,7 +50,7 @@ func TestBranch_MergeVerify(t *testing.T) { branch: Branch{ Bypass: DefBypass{}, PullReq: DefPullReq{ - StatusChecks: DefStatusChecks{RequireUIDs: []string{"abc"}}, + StatusChecks: DefStatusChecks{RequireIdentifiers: []string{"abc"}}, Comments: DefComments{RequireResolveAll: true}, Merge: DefMerge{DeleteBranch: true}, }, @@ -70,7 +70,7 @@ func TestBranch_MergeVerify(t *testing.T) { Bypassed: false, Violations: []types.Violation{ {Code: codePullReqCommentsReqResolveAll}, - {Code: codePullReqStatusChecksReqUIDs}, + {Code: codePullReqStatusChecksReqIdentifiers}, }, }, }, @@ -80,7 +80,7 @@ func TestBranch_MergeVerify(t *testing.T) { branch: Branch{ Bypass: DefBypass{UserIDs: []int64{user.ID}}, PullReq: DefPullReq{ - StatusChecks: DefStatusChecks{RequireUIDs: []string{"abc"}}, + StatusChecks: DefStatusChecks{RequireIdentifiers: []string{"abc"}}, Comments: DefComments{RequireResolveAll: true}, Merge: DefMerge{DeleteBranch: true}, }, @@ -100,7 +100,7 @@ func TestBranch_MergeVerify(t *testing.T) { Bypassed: true, Violations: []types.Violation{ {Code: codePullReqCommentsReqResolveAll}, - {Code: codePullReqStatusChecksReqUIDs}, + {Code: codePullReqStatusChecksReqIdentifiers}, }, }, }, @@ -109,7 +109,7 @@ func TestBranch_MergeVerify(t *testing.T) { name: "user-no-bypass", branch: Branch{ PullReq: DefPullReq{ - StatusChecks: DefStatusChecks{RequireUIDs: []string{"abc"}}, + StatusChecks: DefStatusChecks{RequireIdentifiers: []string{"abc"}}, Comments: DefComments{RequireResolveAll: true}, Merge: DefMerge{DeleteBranch: true}, }, @@ -129,7 +129,7 @@ func TestBranch_MergeVerify(t *testing.T) { Bypassed: false, Violations: []types.Violation{ {Code: codePullReqCommentsReqResolveAll}, - {Code: codePullReqStatusChecksReqUIDs}, + {Code: codePullReqStatusChecksReqIdentifiers}, }, }, }, diff --git a/app/services/protection/service.go b/app/services/protection/service.go index 22bfdfdbb..b5b1c4b7a 100644 --- a/app/services/protection/service.go +++ b/app/services/protection/service.go @@ -120,7 +120,7 @@ func (m *Manager) SanitizeJSON(ruleType types.RuleType, message json.RawMessage) return nil, err } - return toJSON(r) + return ToJSON(r) } func (m *Manager) ForRepository(ctx context.Context, repoID int64) (Protection, error) { diff --git a/app/services/protection/set_test.go b/app/services/protection/set_test.go index 4ce5987d4..c3f9c5f50 100644 --- a/app/services/protection/set_test.go +++ b/app/services/protection/set_test.go @@ -66,24 +66,24 @@ func TestRuleSet_MergeVerify(t *testing.T) { rules: []types.RuleInfoInternal{ { RuleInfo: types.RuleInfo{ - SpacePath: "", - RepoPath: "space/repo", - ID: 1, - UID: "rule1", - Type: TypeBranch, - State: enum.RuleStateActive, + SpacePath: "", + RepoPath: "space/repo", + ID: 1, + Identifier: "rule1", + Type: TypeBranch, + State: enum.RuleStateActive, }, Pattern: []byte(`{"default":true}`), Definition: []byte(`{"pullreq":{"merge":{"strategies_allowed":["merge"],"delete_branch":true}}}`), }, { RuleInfo: types.RuleInfo{ - SpacePath: "space", - RepoPath: "", - ID: 2, - UID: "rule2", - Type: TypeBranch, - State: enum.RuleStateActive, + SpacePath: "space", + RepoPath: "", + ID: 2, + Identifier: "rule2", + Type: TypeBranch, + State: enum.RuleStateActive, }, Pattern: []byte(`{"default":true}`), Definition: []byte(`{"pullreq":{"approvals":{"require_minimum_count":1}}}`), @@ -102,12 +102,12 @@ func TestRuleSet_MergeVerify(t *testing.T) { expViol: []types.RuleViolations{ { Rule: types.RuleInfo{ - SpacePath: "", - RepoPath: "space/repo", - ID: 1, - UID: "rule1", - Type: TypeBranch, - State: enum.RuleStateActive, + SpacePath: "", + RepoPath: "space/repo", + ID: 1, + Identifier: "rule1", + Type: TypeBranch, + State: enum.RuleStateActive, }, Bypassed: false, Violations: []types.Violation{ @@ -116,12 +116,12 @@ func TestRuleSet_MergeVerify(t *testing.T) { }, { Rule: types.RuleInfo{ - SpacePath: "space", - RepoPath: "", - ID: 2, - UID: "rule2", - Type: TypeBranch, - State: enum.RuleStateActive, + SpacePath: "space", + RepoPath: "", + ID: 2, + Identifier: "rule2", + Type: TypeBranch, + State: enum.RuleStateActive, }, Bypassed: false, Violations: []types.Violation{ @@ -135,24 +135,24 @@ func TestRuleSet_MergeVerify(t *testing.T) { rules: []types.RuleInfoInternal{ { RuleInfo: types.RuleInfo{ - SpacePath: "", - RepoPath: "space/repo", - ID: 1, - UID: "rule1", - Type: TypeBranch, - State: enum.RuleStateActive, + SpacePath: "", + RepoPath: "space/repo", + ID: 1, + Identifier: "rule1", + Type: TypeBranch, + State: enum.RuleStateActive, }, Pattern: []byte(`{"default":true}`), Definition: []byte(`{"pullreq":{"merge":{"strategies_allowed":["merge","rebase"]}}}`), }, { RuleInfo: types.RuleInfo{ - SpacePath: "space", - RepoPath: "", - ID: 2, - UID: "rule2", - Type: TypeBranch, - State: enum.RuleStateActive, + SpacePath: "space", + RepoPath: "", + ID: 2, + Identifier: "rule2", + Type: TypeBranch, + State: enum.RuleStateActive, }, Pattern: []byte(`{"default":true}`), Definition: []byte(`{"pullreq":{"merge":{"strategies_allowed":["rebase"]}}}`), diff --git a/app/services/protection/validators.go b/app/services/protection/validators.go index 09258a7c4..b0bf679de 100644 --- a/app/services/protection/validators.go +++ b/app/services/protection/validators.go @@ -32,14 +32,14 @@ func validateIDSlice(ids []int64) error { return nil } -func validateUIDSlice(uids []string) error { - if len(uids) > maxElements { - return errors.New("too many UIDs provided") +func validateIdentifierSlice(identifiers []string) error { + if len(identifiers) > maxElements { + return errors.New("too many Identifiers provided") } - for _, uid := range uids { - if uid == "" { - return errors.New("UID mustn't be an empty string") + for _, identifier := range identifiers { + if identifier == "" { + return errors.New("identifier mustn't be an empty string") } } diff --git a/app/services/protection/verify_pullreq.go b/app/services/protection/verify_pullreq.go index d75d4072d..877a93660 100644 --- a/app/services/protection/verify_pullreq.go +++ b/app/services/protection/verify_pullreq.go @@ -16,6 +16,7 @@ package protection import ( "context" + "encoding/json" "errors" "fmt" "strings" @@ -65,7 +66,7 @@ const ( codePullReqApprovalReqCodeOwnersChangeRequested = "pullreq.approvals.require_code_owners:change_requested" codePullReqApprovalReqCodeOwnersNoLatestApproval = "pullreq.approvals.require_code_owners:no_latest_approval" codePullReqCommentsReqResolveAll = "pullreq.comments.require_resolve_all" - codePullReqStatusChecksReqUIDs = "pullreq.status_checks.required_uids" + codePullReqStatusChecksReqIdentifiers = "pullreq.status_checks.required_identifiers" codePullReqMergeStrategiesAllowed = "pullreq.merge.strategies_allowed" codePullReqMergeDeleteBranch = "pullreq.merge.delete_branch" ) @@ -146,26 +147,26 @@ func (v *DefPullReq) MergeVerify( // pullreq.status_checks - var violatingStatusCheckUIDs []string - for _, requiredUID := range v.StatusChecks.RequireUIDs { + var violatingStatusCheckIdentifiers []string + for _, requiredIdentifier := range v.StatusChecks.RequireIdentifiers { var succeeded bool for i := range in.CheckResults { - if in.CheckResults[i].UID == requiredUID { + if in.CheckResults[i].Identifier == requiredIdentifier { succeeded = in.CheckResults[i].Status == enum.CheckStatusSuccess break } } if !succeeded { - violatingStatusCheckUIDs = append(violatingStatusCheckUIDs, requiredUID) + violatingStatusCheckIdentifiers = append(violatingStatusCheckIdentifiers, requiredIdentifier) } } - if len(violatingStatusCheckUIDs) > 0 { + if len(violatingStatusCheckIdentifiers) > 0 { violations.Addf( - codePullReqStatusChecksReqUIDs, + codePullReqStatusChecksReqIdentifiers, "The following status checks are required to be completed successfully: %s", - strings.Join(violatingStatusCheckUIDs, ", "), + strings.Join(violatingStatusCheckIdentifiers, ", "), ) } @@ -224,12 +225,47 @@ func (DefComments) Sanitize() error { } type DefStatusChecks struct { - RequireUIDs []string `json:"require_uids,omitempty"` + RequireIdentifiers []string `json:"require_identifiers,omitempty"` } -func (v *DefStatusChecks) Sanitize() error { - if err := validateUIDSlice(v.RequireUIDs); err != nil { - return fmt.Errorf("required UIDs error: %w", err) +// TODO [CODE-1363]: remove after identifier migration. +func (c DefStatusChecks) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias DefStatusChecks + return json.Marshal(&struct { + alias + RequireUIDs []string `json:"require_uids"` + }{ + alias: (alias)(c), + RequireUIDs: c.RequireIdentifiers, + }) +} + +// TODO [CODE-1363]: remove if we don't have any require_uids left in our DB. +func (c *DefStatusChecks) UnmarshalJSON(data []byte) error { + // alias allows us to extract the original object while avoiding an infinite loop of unmarshaling. + type alias DefStatusChecks + res := struct { + alias + RequireUIDs []string `json:"require_uids"` + }{} + + err := json.Unmarshal(data, &res) + if err != nil { + return fmt.Errorf("failed to unmarshal to alias type with required uids: %w", err) + } + + *c = DefStatusChecks(res.alias) + if len(c.RequireIdentifiers) == 0 { + c.RequireIdentifiers = res.RequireUIDs + } + + return nil +} + +func (c *DefStatusChecks) Sanitize() error { + if err := validateIdentifierSlice(c.RequireIdentifiers); err != nil { + return fmt.Errorf("required identifiers error: %w", err) } return nil diff --git a/app/services/protection/verify_pullreq_test.go b/app/services/protection/verify_pullreq_test.go index e65c99e6a..7b52f2154 100644 --- a/app/services/protection/verify_pullreq_test.go +++ b/app/services/protection/verify_pullreq_test.go @@ -249,39 +249,39 @@ func TestDefPullReq_MergeVerify(t *testing.T) { expOut: MergeVerifyOutput{}, }, { - name: codePullReqStatusChecksReqUIDs + "-fail", - def: DefPullReq{StatusChecks: DefStatusChecks{RequireUIDs: []string{"check1"}}}, + name: codePullReqStatusChecksReqIdentifiers + "-fail", + def: DefPullReq{StatusChecks: DefStatusChecks{RequireIdentifiers: []string{"check1"}}}, in: MergeVerifyInput{ CheckResults: []types.CheckResult{ - {UID: "check1", Status: enum.CheckStatusFailure}, - {UID: "check2", Status: enum.CheckStatusSuccess}, + {Identifier: "check1", Status: enum.CheckStatusFailure}, + {Identifier: "check2", Status: enum.CheckStatusSuccess}, }, Method: enum.MergeMethodMerge, }, - expCodes: []string{codePullReqStatusChecksReqUIDs}, + expCodes: []string{codePullReqStatusChecksReqIdentifiers}, expParams: [][]any{{"check1"}}, expOut: MergeVerifyOutput{}, }, { - name: codePullReqStatusChecksReqUIDs + "-missing", - def: DefPullReq{StatusChecks: DefStatusChecks{RequireUIDs: []string{"check1"}}}, + name: codePullReqStatusChecksReqIdentifiers + "-missing", + def: DefPullReq{StatusChecks: DefStatusChecks{RequireIdentifiers: []string{"check1"}}}, in: MergeVerifyInput{ CheckResults: []types.CheckResult{ - {UID: "check2", Status: enum.CheckStatusSuccess}, + {Identifier: "check2", Status: enum.CheckStatusSuccess}, }, Method: enum.MergeMethodMerge, }, - expCodes: []string{codePullReqStatusChecksReqUIDs}, + expCodes: []string{codePullReqStatusChecksReqIdentifiers}, expParams: [][]any{{"check1"}}, expOut: MergeVerifyOutput{}, }, { - name: codePullReqStatusChecksReqUIDs + "-success", - def: DefPullReq{StatusChecks: DefStatusChecks{RequireUIDs: []string{"check1"}}}, + name: codePullReqStatusChecksReqIdentifiers + "-success", + def: DefPullReq{StatusChecks: DefStatusChecks{RequireIdentifiers: []string{"check1"}}}, in: MergeVerifyInput{ CheckResults: []types.CheckResult{ - {UID: "check1", Status: enum.CheckStatusSuccess}, - {UID: "check2", Status: enum.CheckStatusFailure}, + {Identifier: "check1", Status: enum.CheckStatusSuccess}, + {Identifier: "check2", Status: enum.CheckStatusFailure}, }, Method: enum.MergeMethodMerge, }, diff --git a/app/services/webhook/trigger.go b/app/services/webhook/trigger.go index f78a56029..361a39d5f 100644 --- a/app/services/webhook/trigger.go +++ b/app/services/webhook/trigger.go @@ -338,7 +338,9 @@ func (s *Service) prepareHTTPRequest(ctx context.Context, execution *types.Webho req.Header.Add(s.toXHeader("Trigger"), string(triggerType)) req.Header.Add(s.toXHeader("Webhook-Parent-Type"), string(webhook.ParentType)) req.Header.Add(s.toXHeader("Webhook-Parent-Id"), fmt.Sprint(webhook.ParentID)) - req.Header.Add(s.toXHeader("Webhook-Uid"), fmt.Sprint(webhook.UID)) + // TODO [CODE-1363]: remove after identifier migration. + req.Header.Add(s.toXHeader("Webhook-Uid"), fmt.Sprint(webhook.Identifier)) + req.Header.Add(s.toXHeader("Webhook-Identifier"), fmt.Sprint(webhook.Identifier)) // add HMAC only if a secret was provided if webhook.Secret != "" { diff --git a/app/services/webhook/types.go b/app/services/webhook/types.go index 9fde9a8d5..30e1efc0c 100644 --- a/app/services/webhook/types.go +++ b/app/services/webhook/types.go @@ -15,6 +15,7 @@ package webhook import ( + "encoding/json" "time" "github.com/harness/gitness/app/url" @@ -73,17 +74,30 @@ type PullReqCommentSegment struct { type RepositoryInfo struct { ID int64 `json:"id"` Path string `json:"path"` - UID string `json:"uid"` + Identifier string `json:"identifier"` DefaultBranch string `json:"default_branch"` GitURL string `json:"git_url"` } +// TODO [CODE-1363]: remove after identifier migration. +func (r RepositoryInfo) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias RepositoryInfo + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(r), + UID: r.Identifier, + }) +} + // repositoryInfoFrom gets the RespositoryInfo from a types.Repository. func repositoryInfoFrom(repo *types.Repository, urlProvider url.Provider) RepositoryInfo { return RepositoryInfo{ ID: repo.ID, Path: repo.Path, - UID: repo.UID, + Identifier: repo.Identifier, DefaultBranch: repo.DefaultBranch, GitURL: urlProvider.GenerateGITCloneURL(repo.Path), } diff --git a/app/store/database.go b/app/store/database.go index 43543cd28..af32afb60 100644 --- a/app/store/database.go +++ b/app/store/database.go @@ -242,8 +242,8 @@ type ( // Find finds the token by id Find(ctx context.Context, id int64) (*types.Token, error) - // FindByUID finds the token by principalId and tokenUID - FindByUID(ctx context.Context, principalID int64, tokenUID string) (*types.Token, error) + // FindByIdentifier finds the token by principalId and token identifier. + FindByIdentifier(ctx context.Context, principalID int64, identifier string) (*types.Token, error) // Create saves the token details. Create(ctx context.Context, token *types.Token) error @@ -395,8 +395,8 @@ type ( // Find finds a protection rule by ID. Find(ctx context.Context, id int64) (*types.Rule, error) - // FindByUID finds a protection rule by parent ID and UID. - FindByUID(ctx context.Context, spaceID, repoID *int64, uid string) (*types.Rule, error) + // FindByIdentifier finds a protection rule by parent ID and identifier. + FindByIdentifier(ctx context.Context, spaceID, repoID *int64, identifier string) (*types.Rule, error) // Create inserts a new protection rule. Create(ctx context.Context, rule *types.Rule) error @@ -407,8 +407,8 @@ type ( // Delete removes a protection rule by its ID. Delete(ctx context.Context, id int64) error - // DeleteByUID removes a protection rule by its UID. - DeleteByUID(ctx context.Context, spaceID, repoID *int64, uid string) error + // DeleteByIdentifier removes a protection rule by its identifier. + DeleteByIdentifier(ctx context.Context, spaceID, repoID *int64, identifier string) error // Count returns count of protection rules matching the provided criteria. Count(ctx context.Context, spaceID, repoID *int64, filter *types.RuleFilter) (int64, error) @@ -425,8 +425,13 @@ type ( // Find finds the webhook by id. Find(ctx context.Context, id int64) (*types.Webhook, error) - // FindByUID finds the webhook with the given UID for the given parent. - FindByUID(ctx context.Context, parentType enum.WebhookParent, parentID int64, uid string) (*types.Webhook, error) + // FindByIdentifier finds the webhook with the given Identifier for the given parent. + FindByIdentifier( + ctx context.Context, + parentType enum.WebhookParent, + parentID int64, + identifier string, + ) (*types.Webhook, error) // Create creates a new webhook. Create(ctx context.Context, hook *types.Webhook) error @@ -441,8 +446,8 @@ type ( // Delete deletes the webhook for the given id. Delete(ctx context.Context, id int64) error - // DeleteByUID deletes the webhook with the given UID for the given parent. - DeleteByUID(ctx context.Context, parentType enum.WebhookParent, parentID int64, uid string) error + // DeleteByIdentifier deletes the webhook with the given identifier for the given parent. + DeleteByIdentifier(ctx context.Context, parentType enum.WebhookParent, parentID int64, identifier string) error // Count counts the webhooks for a given parent type and id. Count(ctx context.Context, parentType enum.WebhookParent, parentID int64, @@ -473,8 +478,8 @@ type ( } CheckStore interface { - // Find returns status check result for given unique key. - Find(ctx context.Context, repoID int64, commitSHA string, uid string) (types.Check, error) + // FindByIdentifier returns status check result for given unique key. + FindByIdentifier(ctx context.Context, repoID int64, commitSHA string, identifier string) (types.Check, error) // Upsert creates new or updates an existing status check result. Upsert(ctx context.Context, check *types.Check) error @@ -492,22 +497,12 @@ type ( ListResults(ctx context.Context, repoID int64, commitSHA string) ([]types.CheckResult, error) } - ReqCheckStore interface { - // Create creates new required status check. - Create(ctx context.Context, reqCheck *types.ReqCheck) error - - // List returns a list of required status checks for a repo. - List(ctx context.Context, repoID int64) ([]*types.ReqCheck, error) - - // Delete removes a required status checks for a repo. - Delete(ctx context.Context, repoID, reqCheckID int64) error - } PipelineStore interface { // Find returns a pipeline given a pipeline ID from the datastore. Find(ctx context.Context, id int64) (*types.Pipeline, error) - // FindByUID returns a pipeline with a given UID in a space - FindByUID(ctx context.Context, id int64, uid string) (*types.Pipeline, error) + // FindByIdentifier returns a pipeline with a given Identifier in a space + FindByIdentifier(ctx context.Context, id int64, identifier string) (*types.Pipeline, error) // Create creates a new pipeline in the datastore. Create(ctx context.Context, pipeline *types.Pipeline) error @@ -532,8 +527,8 @@ type ( // Count the number of pipelines in a repository matching the given filter. Count(ctx context.Context, repoID int64, filter types.ListQueryFilter) (int64, error) - // DeleteByUID deletes a pipeline with a given UID under a repo. - DeleteByUID(ctx context.Context, repoID int64, uid string) error + // DeleteByIdentifier deletes a pipeline with a given identifier under a repo. + DeleteByIdentifier(ctx context.Context, repoID int64, identifier string) error // IncrementSeqNum increments the sequence number of the pipeline IncrementSeqNum(ctx context.Context, pipeline *types.Pipeline) (*types.Pipeline, error) @@ -543,8 +538,8 @@ type ( // Find returns a secret given an ID Find(ctx context.Context, id int64) (*types.Secret, error) - // FindByUID returns a secret given a space ID and a UID - FindByUID(ctx context.Context, spaceID int64, uid string) (*types.Secret, error) + // FindByIdentifier returns a secret given a space ID and a identifier + FindByIdentifier(ctx context.Context, spaceID int64, identifier string) (*types.Secret, error) // Create creates a new secret Create(ctx context.Context, secret *types.Secret) error @@ -562,8 +557,8 @@ type ( // Delete deletes a secret given an ID. Delete(ctx context.Context, id int64) error - // DeleteByUID deletes a secret given a space ID and a uid. - DeleteByUID(ctx context.Context, spaceID int64, uid string) error + // DeleteByIdentifier deletes a secret given a space ID and a identifier. + DeleteByIdentifier(ctx context.Context, spaceID int64, identifier string) error // List lists the secrets in a given space. List(ctx context.Context, spaceID int64, filter types.ListQueryFilter) ([]*types.Secret, error) @@ -637,8 +632,8 @@ type ( // Find returns a connector given an ID. Find(ctx context.Context, id int64) (*types.Connector, error) - // FindByUID returns a connector given a space ID and a UID. - FindByUID(ctx context.Context, spaceID int64, uid string) (*types.Connector, error) + // FindByIdentifier returns a connector given a space ID and a identifier. + FindByIdentifier(ctx context.Context, spaceID int64, identifier string) (*types.Connector, error) // Create creates a new connector. Create(ctx context.Context, connector *types.Connector) error @@ -656,8 +651,8 @@ type ( // Delete deletes a connector given an ID. Delete(ctx context.Context, id int64) error - // DeleteByUID deletes a connector given a space ID and a uid. - DeleteByUID(ctx context.Context, spaceID int64, uid string) error + // DeleteByIdentifier deletes a connector given a space ID and an identifier. + DeleteByIdentifier(ctx context.Context, spaceID int64, identifier string) error // List lists the connectors in a given space. List(ctx context.Context, spaceID int64, filter types.ListQueryFilter) ([]*types.Connector, error) @@ -667,9 +662,9 @@ type ( // Find returns a template given an ID. Find(ctx context.Context, id int64) (*types.Template, error) - // FindByUIDAndType returns a template given a space ID, UID and a type - FindByUIDAndType(ctx context.Context, spaceID int64, - uid string, resolverType enum.ResolverType) (*types.Template, error) + // FindByIdentifierAndType returns a template given a space ID, identifier and a type + FindByIdentifierAndType(ctx context.Context, spaceID int64, + identifier string, resolverType enum.ResolverType) (*types.Template, error) // Create creates a new template. Create(ctx context.Context, template *types.Template) error @@ -687,16 +682,16 @@ type ( // Delete deletes a template given an ID. Delete(ctx context.Context, id int64) error - // DeleteByUIDAndType deletes a template given a space ID, uid and a type. - DeleteByUIDAndType(ctx context.Context, spaceID int64, uid string, resolverType enum.ResolverType) error + // DeleteByIdentifierAndType deletes a template given a space ID, identifier and a type. + DeleteByIdentifierAndType(ctx context.Context, spaceID int64, identifier string, resolverType enum.ResolverType) error // List lists the templates in a given space. List(ctx context.Context, spaceID int64, filter types.ListQueryFilter) ([]*types.Template, error) } TriggerStore interface { - // FindByUID returns a trigger given a pipeline and a trigger UID. - FindByUID(ctx context.Context, pipelineID int64, uid string) (*types.Trigger, error) + // FindByIdentifier returns a trigger given a pipeline and a trigger identifier. + FindByIdentifier(ctx context.Context, pipelineID int64, identifier string) (*types.Trigger, error) // Create creates a new trigger in the datastore. Create(ctx context.Context, trigger *types.Trigger) error @@ -711,8 +706,8 @@ type ( // List lists the triggers for a given pipeline ID. List(ctx context.Context, pipelineID int64, filter types.ListQueryFilter) ([]*types.Trigger, error) - // Delete deletes an trigger given a pipeline ID and a trigger UID. - DeleteByUID(ctx context.Context, pipelineID int64, uid string) error + // Delete deletes an trigger given a pipeline ID and a trigger identifier. + DeleteByIdentifier(ctx context.Context, pipelineID int64, identifier string) error // Count the number of triggers in a pipeline. Count(ctx context.Context, pipelineID int64, filter types.ListQueryFilter) (int64, error) @@ -744,7 +739,7 @@ type ( } UserGroupStore interface { - // Find returns a types.UserGroup given a space ID and uid. - Find(ctx context.Context, spaceID int64, uid string) (*types.UserGroup, error) + // FindByIdentifier returns a types.UserGroup given a space ID and identifier. + FindByIdentifier(ctx context.Context, spaceID int64, identifier string) (*types.UserGroup, error) } ) diff --git a/app/store/database/check.go b/app/store/database/check.go index 9e2f9090e..046a951da 100644 --- a/app/store/database/check.go +++ b/app/store/database/check.go @@ -82,7 +82,7 @@ type check struct { Updated int64 `db:"check_updated"` RepoID int64 `db:"check_repo_id"` CommitSHA string `db:"check_commit_sha"` - UID string `db:"check_uid"` + Identifier string `db:"check_uid"` Status enum.CheckStatus `db:"check_status"` Summary string `db:"check_summary"` Link string `db:"check_link"` @@ -94,15 +94,20 @@ type check struct { Ended int64 `db:"check_ended"` } -// Find returns status check result for given unique key. -func (s *CheckStore) Find(ctx context.Context, repoID int64, commitSHA string, uid string) (types.Check, error) { +// FindByIdentifier returns status check result for given unique key. +func (s *CheckStore) FindByIdentifier( + ctx context.Context, + repoID int64, + commitSHA string, + identifier string, +) (types.Check, error) { const sqlQuery = checkSelectBase + ` WHERE check_repo_id = $1 AND check_uid = $2 AND check_commit_sha = $3` db := dbtx.GetAccessor(ctx, s.db) dst := new(check) - if err := db.GetContext(ctx, dst, sqlQuery, repoID, uid, commitSHA); err != nil { + if err := db.GetContext(ctx, dst, sqlQuery, repoID, identifier, commitSHA); err != nil { return types.Check{}, database.ProcessSQLErrorf(err, "Failed to find check") } @@ -318,7 +323,7 @@ func mapInternalCheck(c *types.Check) *check { Updated: c.Updated, RepoID: c.RepoID, CommitSHA: c.CommitSHA, - UID: c.UID, + Identifier: c.Identifier, Status: c.Status, Summary: c.Summary, Link: c.Link, @@ -335,17 +340,17 @@ func mapInternalCheck(c *types.Check) *check { func mapCheck(c *check) types.Check { return types.Check{ - ID: c.ID, - CreatedBy: c.CreatedBy, - Created: c.Created, - Updated: c.Updated, - RepoID: c.RepoID, - CommitSHA: c.CommitSHA, - UID: c.UID, - Status: c.Status, - Summary: c.Summary, - Link: c.Link, - Metadata: c.Metadata, + ID: c.ID, + CreatedBy: c.CreatedBy, + Created: c.Created, + Updated: c.Updated, + RepoID: c.RepoID, + CommitSHA: c.CommitSHA, + Identifier: c.Identifier, + Status: c.Status, + Summary: c.Summary, + Link: c.Link, + Metadata: c.Metadata, Payload: types.CheckPayload{ Version: c.PayloadVersion, Kind: c.PayloadKind, diff --git a/app/store/database/check_req.go b/app/store/database/check_req.go deleted file mode 100644 index 09d883c49..000000000 --- a/app/store/database/check_req.go +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2023 Harness, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package database - -import ( - "context" - "fmt" - - "github.com/harness/gitness/app/store" - "github.com/harness/gitness/store/database" - "github.com/harness/gitness/store/database/dbtx" - "github.com/harness/gitness/types" - - "github.com/jmoiron/sqlx" - "github.com/pkg/errors" -) - -var _ store.ReqCheckStore = (*ReqCheckStore)(nil) - -// NewReqCheckStore returns a new CheckStore. -func NewReqCheckStore( - db *sqlx.DB, - pCache store.PrincipalInfoCache, -) *ReqCheckStore { - return &ReqCheckStore{ - db: db, - pCache: pCache, - } -} - -// ReqCheckStore implements store.CheckStore backed by a relational database. -type ReqCheckStore struct { - db *sqlx.DB - pCache store.PrincipalInfoCache -} - -const ( - reqCheckColumns = ` - reqcheck_id - ,reqcheck_created_by - ,reqcheck_created - ,reqcheck_repo_id - ,reqcheck_branch_pattern - ,reqcheck_check_uid` -) - -// reqCheck is used to fetch required status check data from the database. -// The object should be later re-packed into a different struct to return it as an API response. -type reqCheck struct { - ID int64 `db:"reqcheck_id"` - CreatedBy int64 `db:"reqcheck_created_by"` - Created int64 `db:"reqcheck_created"` - RepoID int64 `db:"reqcheck_repo_id"` - BranchPattern string `db:"reqcheck_branch_pattern"` - CheckUID string `db:"reqcheck_check_uid"` -} - -// Create creates new required status check. -func (s *ReqCheckStore) Create(ctx context.Context, reqCheck *types.ReqCheck) error { - const sqlQuery = ` - INSERT INTO reqchecks ( - reqcheck_created_by - ,reqcheck_created - ,reqcheck_repo_id - ,reqcheck_branch_pattern - ,reqcheck_check_uid - ) VALUES ( - :reqcheck_created_by - ,:reqcheck_created - ,:reqcheck_repo_id - ,:reqcheck_branch_pattern - ,:reqcheck_check_uid - ) - RETURNING reqcheck_id` - - db := dbtx.GetAccessor(ctx, s.db) - - query, arg, err := db.BindNamed(sqlQuery, mapInternalReqCheck(reqCheck)) - if err != nil { - return database.ProcessSQLErrorf(err, "Failed to bind required status check object") - } - - if err = db.QueryRowContext(ctx, query, arg...).Scan(&reqCheck.ID); err != nil { - return database.ProcessSQLErrorf(err, "Insert query failed") - } - - return nil -} - -// List returns a list of required status checks for a repo. -func (s *ReqCheckStore) List(ctx context.Context, repoID int64) ([]*types.ReqCheck, error) { - stmt := database.Builder. - Select(reqCheckColumns). - From("reqchecks"). - Where("reqcheck_repo_id = ?", repoID). - OrderBy("reqcheck_check_uid") - - sql, args, err := stmt.ToSql() - if err != nil { - return nil, errors.Wrap(err, "Failed to convert query to sql") - } - - dst := make([]*reqCheck, 0) - - db := dbtx.GetAccessor(ctx, s.db) - - if err = db.SelectContext(ctx, &dst, sql, args...); err != nil { - return nil, database.ProcessSQLErrorf(err, "Failed to execute list required status checks query") - } - - result, err := s.mapSliceReqCheck(ctx, dst) - if err != nil { - return nil, err - } - - return result, nil -} - -// Delete removes a required status checks for a repo. -func (s *ReqCheckStore) Delete(ctx context.Context, repoID, reqCheckID int64) error { - stmt := database.Builder. - Delete("reqchecks"). - Where("reqcheck_repo_id = ?", repoID). - Where("reqcheck_id = ?", reqCheckID) - - sql, args, err := stmt.ToSql() - if err != nil { - return errors.Wrap(err, "Failed to convert query to sql") - } - - db := dbtx.GetAccessor(ctx, s.db) - - _, err = db.ExecContext(ctx, sql, args...) - if err != nil { - return database.ProcessSQLErrorf(err, "Failed to execute delete required status check query") - } - - return nil -} - -func mapReqCheck(req *reqCheck) *types.ReqCheck { - return &types.ReqCheck{ - ID: req.ID, - CreatedBy: req.CreatedBy, - Created: req.Created, - RepoID: req.RepoID, - BranchPattern: req.BranchPattern, - CheckUID: req.CheckUID, - AddedBy: types.PrincipalInfo{}, - } -} - -func mapInternalReqCheck(req *types.ReqCheck) *reqCheck { - m := &reqCheck{ - ID: req.ID, - CreatedBy: req.CreatedBy, - Created: req.Created, - RepoID: req.RepoID, - BranchPattern: req.BranchPattern, - CheckUID: req.CheckUID, - } - - return m -} - -func (s *ReqCheckStore) mapSliceReqCheck(ctx context.Context, reqChecks []*reqCheck) ([]*types.ReqCheck, error) { - // collect all principal IDs - ids := make([]int64, len(reqChecks)) - for i, req := range reqChecks { - ids[i] = req.CreatedBy - } - - // pull principal infos from cache - infoMap, err := s.pCache.Map(ctx, ids) - if err != nil { - return nil, fmt.Errorf("failed to load required status check principal infos: %w", err) - } - - // attach the principal infos back to the slice items - m := make([]*types.ReqCheck, len(reqChecks)) - for i, req := range reqChecks { - m[i] = mapReqCheck(req) - if author, ok := infoMap[req.CreatedBy]; ok { - m[i].AddedBy = *author - } - } - - return m, nil -} diff --git a/app/store/database/connector.go b/app/store/database/connector.go index 9fb0a6348..9d0b77472 100644 --- a/app/store/database/connector.go +++ b/app/store/database/connector.go @@ -74,14 +74,18 @@ func (s *connectorStore) Find(ctx context.Context, id int64) (*types.Connector, return dst, nil } -// FindByUID returns a connector in a given space with a given UID. -func (s *connectorStore) FindByUID(ctx context.Context, spaceID int64, uid string) (*types.Connector, error) { +// FindByIdentifier returns a connector in a given space with a given identifier. +func (s *connectorStore) FindByIdentifier( + ctx context.Context, + spaceID int64, + identifier string, +) (*types.Connector, error) { const findQueryStmt = connectorQueryBase + ` WHERE connector_space_id = $1 AND connector_uid = $2` db := dbtx.GetAccessor(ctx, s.db) dst := new(types.Connector) - if err := db.GetContext(ctx, dst, findQueryStmt, spaceID, uid); err != nil { + if err := db.GetContext(ctx, dst, findQueryStmt, spaceID, identifier); err != nil { return nil, database.ProcessSQLErrorf(err, "Failed to find connector") } return dst, nil @@ -241,15 +245,15 @@ func (s *connectorStore) Delete(ctx context.Context, id int64) error { return nil } -// DeleteByUID deletes a connector with a given UID in a space. -func (s *connectorStore) DeleteByUID(ctx context.Context, spaceID int64, uid string) error { +// DeleteByIdentifier deletes a connector with a given identifier in a space. +func (s *connectorStore) DeleteByIdentifier(ctx context.Context, spaceID int64, identifier string) error { const connectorDeleteStmt = ` DELETE FROM connectors WHERE connector_space_id = $1 AND connector_uid = $2` db := dbtx.GetAccessor(ctx, s.db) - if _, err := db.ExecContext(ctx, connectorDeleteStmt, spaceID, uid); err != nil { + if _, err := db.ExecContext(ctx, connectorDeleteStmt, spaceID, identifier); err != nil { return database.ProcessSQLErrorf(err, "Could not delete connector") } diff --git a/app/store/database/membership.go b/app/store/database/membership.go index 93e37cc06..ca00ff909 100644 --- a/app/store/database/membership.go +++ b/app/store/database/membership.go @@ -336,7 +336,8 @@ func (s *MembershipStore) ListSpaces(ctx context.Context, } switch filter.Sort { - case enum.MembershipSpaceSortUID: + // TODO [CODE-1363]: remove after identifier migration. + case enum.MembershipSpaceSortUID, enum.MembershipSpaceSortIdentifier: stmt = stmt.OrderBy("space_uid " + order.String()) case enum.MembershipSpaceSortCreated: stmt = stmt.OrderBy("membership_created " + order.String()) diff --git a/app/store/database/migrate/migrate.go b/app/store/database/migrate/migrate.go index 9b4474a4e..f4bb363a7 100644 --- a/app/store/database/migrate/migrate.go +++ b/app/store/database/migrate/migrate.go @@ -124,11 +124,14 @@ func getMigrator(db *sqlx.DB) (migrate.Options, error) { log.Info().Msg("[START]") defer log.Info().Msg("[DONE]") - if version == "0039_alter_table_webhooks_uid" { + switch version { + case "0039_alter_table_webhooks_uid": return migrateAfter_0039_alter_table_webhooks_uid(ctx, dbtx) + case "0042_alter_table_rules": + return migrateAfter_0042_alter_table_rules(ctx, dbtx) + default: + return nil } - - return nil } opts := migrate.Options{ diff --git a/app/store/database/migrate/migrate_0039_alter_table_webhooks_uid.go b/app/store/database/migrate/migrate_0039_alter_table_webhooks_uid.go index ccdf35aca..add6404f7 100644 --- a/app/store/database/migrate/migrate_0039_alter_table_webhooks_uid.go +++ b/app/store/database/migrate/migrate_0039_alter_table_webhooks_uid.go @@ -42,7 +42,7 @@ func migrateAfter_0039_alter_table_webhooks_uid(ctx context.Context, dbtx *sql.T id int64 spaceID null.Int repoID null.Int - uid null.String + identifier null.String displayName string } @@ -72,7 +72,7 @@ func migrateAfter_0039_alter_table_webhooks_uid(ctx context.Context, dbtx *sql.T c := 0 for rows.Next() { - err = rows.Scan(&buffer[c].id, &buffer[c].displayName, &buffer[c].repoID, &buffer[c].spaceID, &buffer[c].uid) + err = rows.Scan(&buffer[c].id, &buffer[c].displayName, &buffer[c].repoID, &buffer[c].spaceID, &buffer[c].identifier) if err != nil { return 0, database.ProcessSQLErrorf(err, "failed scanning next row") } @@ -88,9 +88,9 @@ func migrateAfter_0039_alter_table_webhooks_uid(ctx context.Context, dbtx *sql.T return c, nil } - // keep track of unique UIDs for a given parent in memory (ASSUMPTION: limited number of webhooks per repo) + // keep track of unique identifiers for a given parent in memory (ASSUMPTION: limited number of webhooks per repo) parentID := "" - parentChildUIDs := map[string]bool{} + parentChildIdentifiers := map[string]bool{} for { n, err := nextPage() @@ -108,49 +108,49 @@ func migrateAfter_0039_alter_table_webhooks_uid(ctx context.Context, dbtx *sql.T // concatinate repoID + spaceID to get unique parent id (only used to identify same parents) newParentID := fmt.Sprintf("%d_%d", wh.repoID.ValueOrZero(), wh.spaceID.ValueOrZero()) if newParentID != parentID { - // new parent? reset child UIDs - parentChildUIDs = map[string]bool{} + // new parent? reset child identifiers + parentChildIdentifiers = map[string]bool{} parentID = newParentID } - // in case of down migration we already have uids for webhooks - if len(wh.uid.ValueOrZero()) > 0 { - parentChildUIDs[strings.ToLower(wh.uid.String)] = true + // in case of down migration we already have identifiers for webhooks + if len(wh.identifier.ValueOrZero()) > 0 { + parentChildIdentifiers[strings.ToLower(wh.identifier.String)] = true log.Info().Msgf( - "skip migration of webhook %d with displayname %q as it has a non-empty uid %q", + "skip migration of webhook %d with displayname %q as it has a non-empty identifier %q", wh.id, wh.displayName, - wh.uid.String, + wh.identifier.String, ) continue } - // try to generate unique id (adds random suffix if deterministic uid derived from display name isn't unique) + // try to generate unique id (adds random suffix if deterministic identifier derived from display name isn't unique) for try := 0; try < 5; try++ { randomize := try > 0 - newUID, err := WebhookDisplayNameToUID(wh.displayName, randomize) + newIdentifier, err := WebhookDisplayNameToIdentifier(wh.displayName, randomize) if err != nil { return fmt.Errorf("failed to migrate displayname: %w", err) } - newUIDLower := strings.ToLower(newUID) - if !parentChildUIDs[newUIDLower] { - parentChildUIDs[newUIDLower] = true - wh.uid = null.StringFrom(newUID) + newIdentifierLower := strings.ToLower(newIdentifier) + if !parentChildIdentifiers[newIdentifierLower] { + parentChildIdentifiers[newIdentifierLower] = true + wh.identifier = null.StringFrom(newIdentifier) break } } - if len(wh.uid.ValueOrZero()) == 0 { - return fmt.Errorf("failed to find a unique uid for webhook %d with displayname %q", wh.id, wh.displayName) + if len(wh.identifier.ValueOrZero()) == 0 { + return fmt.Errorf("failed to find a unique identifier for webhook %d with displayname %q", wh.id, wh.displayName) } log.Info().Msgf( - "[%s] migrate webhook %d with displayname %q to uid %q", + "[%s] migrate webhook %d with displayname %q to identifier %q", parentID, wh.id, wh.displayName, - wh.uid.String, + wh.identifier.String, ) const updateQuery = ` @@ -160,7 +160,7 @@ func migrateAfter_0039_alter_table_webhooks_uid(ctx context.Context, dbtx *sql.T WHERE webhook_id = $2` - result, err := dbtx.ExecContext(ctx, updateQuery, wh.uid.String, wh.id) + result, err := dbtx.ExecContext(ctx, updateQuery, wh.identifier.String, wh.id) if err != nil { return database.ProcessSQLErrorf(err, "failed to update webhook") } @@ -171,7 +171,7 @@ func migrateAfter_0039_alter_table_webhooks_uid(ctx context.Context, dbtx *sql.T } if count == 0 { - return fmt.Errorf("failed to update webhook uid - no rows were updated") + return fmt.Errorf("failed to update webhook identifier - no rows were updated") } } } @@ -179,16 +179,16 @@ func migrateAfter_0039_alter_table_webhooks_uid(ctx context.Context, dbtx *sql.T return nil } -// WebhookDisplayNameToUID migrates the provided displayname to a webhook uid. -// If randomize is true, a random suffix is added to randomize the uid. +// WebhookDisplayNameToIdentifier migrates the provided displayname to a webhook identifier. +// If randomize is true, a random suffix is added to randomize the identifier. // //nolint:gocognit -func WebhookDisplayNameToUID(displayName string, randomize bool) (string, error) { +func WebhookDisplayNameToIdentifier(displayName string, randomize bool) (string, error) { const placeholder = '_' const specialChars = ".-_" // remove / replace any illegal characters - // UID Regex: ^[a-zA-Z_][a-zA-Z0-9-_.]*$ - uid := strings.Map(func(r rune) rune { + // Identifier Regex: ^[a-zA-Z0-9-_.]*$ + identifier := strings.Map(func(r rune) rune { switch { // drop any control characters or empty characters case r < 32 || r == 127: @@ -208,32 +208,32 @@ func WebhookDisplayNameToUID(displayName string, randomize bool) (string, error) }, displayName) // remove any leading/trailing special characters - uid = strings.Trim(uid, specialChars) + identifier = strings.Trim(identifier, specialChars) // ensure string doesn't start with numbers (leading '_' is valid) - if len(uid) > 0 && uid[0] >= '0' && uid[0] <= '9' { - uid = string(placeholder) + uid + if len(identifier) > 0 && identifier[0] >= '0' && identifier[0] <= '9' { + identifier = string(placeholder) + identifier } // remove consecutive special characters - uid = santizeConsecutiveChars(uid, specialChars) + identifier = santizeConsecutiveChars(identifier, specialChars) // ensure length restrictions - if len(uid) > check.MaxUIDLength { - uid = uid[0:check.MaxUIDLength] + if len(identifier) > check.MaxIdentifierLength { + identifier = identifier[0:check.MaxIdentifierLength] } - // backfill randomized uid if sanitization ends up with empty uid - if len(uid) == 0 { - uid = "webhook" + // backfill randomized identifier if sanitization ends up with empty identifier + if len(identifier) == 0 { + identifier = "webhook" randomize = true } if randomize { - return randomizeUID(uid) + return randomizeIdentifier(identifier) } - return uid, nil + return identifier, nil } func santizeConsecutiveChars(in string, charSet string) string { @@ -257,18 +257,18 @@ func santizeConsecutiveChars(in string, charSet string) string { return out.String() } -func randomizeUID(uid string) (string, error) { +func randomizeIdentifier(identifier string) (string, error) { const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789" const length = 4 - const maxLength = check.MaxUIDLength - length - 1 // max length of uid to fit random suffix + const maxLength = check.MaxIdentifierLength - length - 1 // max length of identifier to fit random suffix - if len(uid) > maxLength { - uid = uid[0:maxLength] + if len(identifier) > maxLength { + identifier = identifier[0:maxLength] } suffix, err := gonanoid.Generate(alphabet, length) if err != nil { return "", fmt.Errorf("failed to generate gonanoid: %w", err) } - return uid + "_" + suffix, nil + return identifier + "_" + suffix, nil } diff --git a/app/store/database/migrate/migrate_0039_alter_table_webhooks_uid_test.go b/app/store/database/migrate/migrate_0039_alter_table_webhooks_uid_test.go index 97181abd2..e6663b419 100644 --- a/app/store/database/migrate/migrate_0039_alter_table_webhooks_uid_test.go +++ b/app/store/database/migrate/migrate_0039_alter_table_webhooks_uid_test.go @@ -22,11 +22,11 @@ import ( "github.com/stretchr/testify/assert" ) -func TestWebhookDisplayNameToUID(t *testing.T) { +func TestWebhookDisplayNameToIdentifier(t *testing.T) { var tests = []struct { displayName string randomize bool - expectedUID string + expectedIdentifier string expectedRandomized bool }{ // ensure only allowed characters get through @@ -47,7 +47,7 @@ func TestWebhookDisplayNameToUID(t *testing.T) { {strings.Repeat("a", 101), false, strings.Repeat("a", 100), false}, {" " + strings.Repeat("a", 100) + " ", false, strings.Repeat("a", 100), false}, - // empty uid after sanitization + // empty identifier after sanitization {"", false, "webhook", true}, {string(rune(21)), false, "webhook", true}, {" .-_-. ", false, "webhook", true}, @@ -65,19 +65,19 @@ func TestWebhookDisplayNameToUID(t *testing.T) { rndSuffixRegex := regexp.MustCompile("^_[a-z0-9]{4}$") for i, test := range tests { - uid, err := WebhookDisplayNameToUID(test.displayName, test.randomize) + identifier, err := WebhookDisplayNameToIdentifier(test.displayName, test.randomize) assert.NoError(t, err, "test case %d - migration ended in error (unexpected)") // no errors expected if test.expectedRandomized { - assert.True(t, len(uid) >= 5, "test case %d - uid length doesn't indicate random suffix", i) + assert.True(t, len(identifier) >= 5, "test case %d - identifier length doesn't indicate random suffix", i) - rndSuffix := uid[len(uid)-5:] - uid = uid[:len(uid)-5] + rndSuffix := identifier[len(identifier)-5:] + identifier = identifier[:len(identifier)-5] matched := rndSuffixRegex.Match([]byte(rndSuffix)) - assert.True(t, matched, "test case %d - uid doesn't contain expected random suffix", i) + assert.True(t, matched, "test case %d - identifier doesn't contain expected random suffix", i) } - assert.Equal(t, test.expectedUID, uid, "test case %d doesn't match the expected uid'", i) + assert.Equal(t, test.expectedIdentifier, identifier, "test case %d doesn't match the expected identifier'", i) } } diff --git a/app/store/database/migrate/migrate_0042_alter_table_rules.go b/app/store/database/migrate/migrate_0042_alter_table_rules.go new file mode 100644 index 000000000..e66ba8a37 --- /dev/null +++ b/app/store/database/migrate/migrate_0042_alter_table_rules.go @@ -0,0 +1,154 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package migrate + +import ( + "context" + "database/sql" + "encoding/json" + "fmt" + + "github.com/harness/gitness/app/services/protection" + "github.com/harness/gitness/store/database" + + "github.com/rs/zerolog/log" +) + +//nolint:gocognit,stylecheck,revive // have naming match migration version +func migrateAfter_0042_alter_table_rules( + ctx context.Context, + dbtx *sql.Tx, +) error { + log := log.Ctx(ctx) + + log.Info().Msg("migrate all branch rules from uid to identifier") + + // Unfortunately we have to process page by page in memory and can't process as we read: + // - lib/pq doesn't support updating rule while select statement is ongoing + // https://github.com/lib/pq/issues/635 + // - sqlite3 doesn't support DECLARE CURSOR functionality + type rule struct { + id int64 + uid string + definition string + } + + const pageSize = 1000 + buffer := make([]rule, pageSize) + page := 0 + nextPage := func() (int, error) { + const selectQuery = ` + SELECT rule_id, rule_uid, rule_definition + FROM rules + WHERE rule_type = 'branch' + LIMIT $1 + OFFSET $2 + ` + rows, err := dbtx.QueryContext(ctx, selectQuery, pageSize, page*pageSize) + if rows != nil { + defer func() { + err := rows.Close() + if err != nil { + log.Warn().Err(err).Msg("failed to close result rows") + } + }() + } + if err != nil { + return 0, database.ProcessSQLErrorf(err, "failed batch select query") + } + + c := 0 + for rows.Next() { + err = rows.Scan(&buffer[c].id, &buffer[c].uid, &buffer[c].definition) + if err != nil { + return 0, database.ProcessSQLErrorf(err, "failed scanning next row") + } + c++ + } + + if rows.Err() != nil { + return 0, database.ProcessSQLErrorf(err, "failed reading all rows") + } + + page++ + + return c, nil + } + + for { + n, err := nextPage() + if err != nil { + return fmt.Errorf("failed to read next batch of rules: %w", err) + } + + if n == 0 { + break + } + + for i := 0; i < n; i++ { + r := buffer[i] + + log.Info().Msgf( + "migrate rule %d with identifier %q", + r.id, + r.uid, + ) + + branchDefinition := protection.Branch{} + + // unmarshaling the json will deserialize require_uids into require_uids and require_identifiers. + // NOTE: could be done with existing SanitizeJSON method, but that would require dependencies. + err = json.Unmarshal(json.RawMessage(r.definition), &branchDefinition) + if err != nil { + return fmt.Errorf("failed to unmarshal branch definition: %w", err) + } + + updatedDefinitionRaw, err := protection.ToJSON(&branchDefinition) + if err != nil { + return fmt.Errorf("failed to marshal branch definition: %w", err) + } + + // skip updating DB in case there's no change (e.g. no required checks are configured or migration re-runs) + updatedDefinitionString := string(updatedDefinitionRaw) + if updatedDefinitionString == r.definition { + log.Info().Msg("skip updating rule as there's no change in definition") + continue + } + + const updateQuery = ` + UPDATE rules + SET + rule_definition = $1 + WHERE + rule_id = $2` + + result, err := dbtx.ExecContext(ctx, updateQuery, updatedDefinitionString, r.id) + if err != nil { + return database.ProcessSQLErrorf(err, "failed to update rule") + } + + count, err := result.RowsAffected() + if err != nil { + return database.ProcessSQLErrorf(err, "failed to get number of updated rows") + } + + if count == 0 { + return fmt.Errorf("failed to update branch rule definition - no rows were updated") + } + } + } + + return nil +} diff --git a/app/store/database/migrate/postgres/0042_drop_table_reqchecks.down.sql b/app/store/database/migrate/postgres/0042_drop_table_reqchecks.down.sql new file mode 100644 index 000000000..e29ffc542 --- /dev/null +++ b/app/store/database/migrate/postgres/0042_drop_table_reqchecks.down.sql @@ -0,0 +1 @@ +-- Table was never used, keep deleted. \ No newline at end of file diff --git a/app/store/database/migrate/postgres/0042_drop_table_reqchecks.up.sql b/app/store/database/migrate/postgres/0042_drop_table_reqchecks.up.sql new file mode 100644 index 000000000..59472f15c --- /dev/null +++ b/app/store/database/migrate/postgres/0042_drop_table_reqchecks.up.sql @@ -0,0 +1,2 @@ +-- use 'IF EXISTS' as we don't recreate on down migration. +DROP TABLE IF EXISTS reqchecks; \ No newline at end of file diff --git a/app/store/database/migrate/postgres/0043_alter_table_rules.down.sql b/app/store/database/migrate/postgres/0043_alter_table_rules.down.sql new file mode 100644 index 000000000..94da8eaed --- /dev/null +++ b/app/store/database/migrate/postgres/0043_alter_table_rules.down.sql @@ -0,0 +1 @@ +-- data is backwards compatible. \ No newline at end of file diff --git a/app/store/database/migrate/postgres/0043_alter_table_rules.up.sql b/app/store/database/migrate/postgres/0043_alter_table_rules.up.sql new file mode 100644 index 000000000..bf9ba2449 --- /dev/null +++ b/app/store/database/migrate/postgres/0043_alter_table_rules.up.sql @@ -0,0 +1 @@ +-- data is migrated in code. \ No newline at end of file diff --git a/app/store/database/migrate/postgres/0044_alter_table_tokens.down.sql b/app/store/database/migrate/postgres/0044_alter_table_tokens.down.sql new file mode 100644 index 000000000..073cf80fa --- /dev/null +++ b/app/store/database/migrate/postgres/0044_alter_table_tokens.down.sql @@ -0,0 +1,8 @@ +-- drop new index +DROP INDEX tokens_principal_id_uid; + +-- recreate unique constraint +ALTER TABLE tokens ADD CONSTRAINT tokens_token_principal_id_token_uid_key UNIQUE (token_principal_id, token_uid); + +-- recreate original indices +CREATE INDEX tokens_principal_id ON tokens(token_principal_id); \ No newline at end of file diff --git a/app/store/database/migrate/postgres/0044_alter_table_tokens.up.sql b/app/store/database/migrate/postgres/0044_alter_table_tokens.up.sql new file mode 100644 index 000000000..d7e6f8fb1 --- /dev/null +++ b/app/store/database/migrate/postgres/0044_alter_table_tokens.up.sql @@ -0,0 +1,16 @@ +-- delete old unique constraint +ALTER TABLE tokens DROP CONSTRAINT tokens_token_principal_id_token_uid_key; + +-- delete unnecessary index +DROP INDEX tokens_principal_id; + +-- delete all duplicates tokens by keeping newest one (worst case user can recreate their old tokens) +DELETE FROM + tokens t1 +USING tokens t2 +WHERE + t1.token_id < t2.token_id + AND t1.token_principal_id = t2.token_principal_id AND LOWER(t1.token_uid) = LOWER(t2.token_uid); + +-- create explicit unique index with case insensitivity +CREATE UNIQUE INDEX tokens_principal_id_uid ON tokens(token_principal_id, LOWER(token_uid)); diff --git a/app/store/database/migrate/sqlite/0042_drop_table_reqchecks.down.sql b/app/store/database/migrate/sqlite/0042_drop_table_reqchecks.down.sql new file mode 100644 index 000000000..e29ffc542 --- /dev/null +++ b/app/store/database/migrate/sqlite/0042_drop_table_reqchecks.down.sql @@ -0,0 +1 @@ +-- Table was never used, keep deleted. \ No newline at end of file diff --git a/app/store/database/migrate/sqlite/0042_drop_table_reqchecks.up.sql b/app/store/database/migrate/sqlite/0042_drop_table_reqchecks.up.sql new file mode 100644 index 000000000..59472f15c --- /dev/null +++ b/app/store/database/migrate/sqlite/0042_drop_table_reqchecks.up.sql @@ -0,0 +1,2 @@ +-- use 'IF EXISTS' as we don't recreate on down migration. +DROP TABLE IF EXISTS reqchecks; \ No newline at end of file diff --git a/app/store/database/migrate/sqlite/0043_alter_table_rules.down.sql b/app/store/database/migrate/sqlite/0043_alter_table_rules.down.sql new file mode 100644 index 000000000..94da8eaed --- /dev/null +++ b/app/store/database/migrate/sqlite/0043_alter_table_rules.down.sql @@ -0,0 +1 @@ +-- data is backwards compatible. \ No newline at end of file diff --git a/app/store/database/migrate/sqlite/0043_alter_table_rules.up.sql b/app/store/database/migrate/sqlite/0043_alter_table_rules.up.sql new file mode 100644 index 000000000..bf9ba2449 --- /dev/null +++ b/app/store/database/migrate/sqlite/0043_alter_table_rules.up.sql @@ -0,0 +1 @@ +-- data is migrated in code. \ No newline at end of file diff --git a/app/store/database/migrate/sqlite/0044_alter_table_tokens.down.sql b/app/store/database/migrate/sqlite/0044_alter_table_tokens.down.sql new file mode 100644 index 000000000..ad266d5b5 --- /dev/null +++ b/app/store/database/migrate/sqlite/0044_alter_table_tokens.down.sql @@ -0,0 +1,47 @@ +-- recreate original table with UNIQUE +CREATE TABLE tokens_new ( + token_id INTEGER PRIMARY KEY AUTOINCREMENT +,token_type TEXT COLLATE NOCASE +,token_uid TEXT COLLATE NOCASE +,token_principal_id INTEGER +,token_expires_at BIGINT +,token_issued_at BIGINT +,token_created_by INTEGER +,UNIQUE(token_principal_id, token_uid COLLATE NOCASE) + +,CONSTRAINT fk_token_principal_id FOREIGN KEY (token_principal_id) + REFERENCES principals (principal_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE CASCADE +); + +-- copy over data +INSERT INTO tokens_new( + token_id + ,token_type + ,token_uid + ,token_principal_id + ,token_expires_at + ,token_issued_at + ,token_created_by +) +SELECT + token_id + ,token_type + ,token_uid + ,token_principal_id + ,token_expires_at + ,token_issued_at + ,token_created_by +FROM tokens; + +-- delete old table (also deletes all indices) +DROP TABLE tokens; + +-- rename table +ALTER TABLE tokens_new RENAME TO tokens; + +-- recreate all previous indices +CREATE INDEX tokens_principal_id ON tokens(token_principal_id); +CREATE INDEX tokens_type_expires_at ON tokens(token_type, token_expires_at); + diff --git a/app/store/database/migrate/sqlite/0044_alter_table_tokens.up.sql b/app/store/database/migrate/sqlite/0044_alter_table_tokens.up.sql new file mode 100644 index 000000000..0a088fe47 --- /dev/null +++ b/app/store/database/migrate/sqlite/0044_alter_table_tokens.up.sql @@ -0,0 +1,48 @@ +-- recreate table without index +CREATE TABLE tokens_new ( + token_id INTEGER PRIMARY KEY AUTOINCREMENT +,token_type TEXT +,token_uid TEXT +,token_principal_id INTEGER +,token_expires_at BIGINT +,token_issued_at BIGINT +,token_created_by INTEGER + +,CONSTRAINT fk_token_principal_id FOREIGN KEY (token_principal_id) + REFERENCES principals (principal_id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE CASCADE +); + +-- copy over data +INSERT INTO tokens_new( + token_id + ,token_type + ,token_uid + ,token_principal_id + ,token_expires_at + ,token_issued_at + ,token_created_by +) +SELECT + token_id + ,token_type + ,token_uid + ,token_principal_id + ,token_expires_at + ,token_issued_at + ,token_created_by +FROM tokens; + +-- delete old table (also deletes all indices) +DROP TABLE tokens; + +-- rename table +ALTER TABLE tokens_new RENAME TO tokens; + +-- create explicit unique index with case insensitivity +CREATE UNIQUE INDEX tokens_principal_id_uid ON tokens(token_principal_id, LOWER(token_uid)); + +-- recreate old indices if needed (principal_id can be ignored since above index includes it) +CREATE INDEX tokens_type_expires_at ON tokens(token_type, token_expires_at); + diff --git a/app/store/database/pipeline.go b/app/store/database/pipeline.go index 956356f00..df06c672f 100644 --- a/app/store/database/pipeline.go +++ b/app/store/database/pipeline.go @@ -78,14 +78,18 @@ func (s *pipelineStore) Find(ctx context.Context, id int64) (*types.Pipeline, er return dst, nil } -// FindByUID returns a pipeline for a given repo with a given UID. -func (s *pipelineStore) FindByUID(ctx context.Context, repoID int64, uid string) (*types.Pipeline, error) { +// FindByIdentifier returns a pipeline for a given repo with a given Identifier. +func (s *pipelineStore) FindByIdentifier( + ctx context.Context, + repoID int64, + identifier string, +) (*types.Pipeline, error) { const findQueryStmt = pipelineQueryBase + ` WHERE pipeline_repo_id = $1 AND pipeline_uid = $2` db := dbtx.GetAccessor(ctx, s.db) dst := new(types.Pipeline) - if err := db.GetContext(ctx, dst, findQueryStmt, repoID, uid); err != nil { + if err := db.GetContext(ctx, dst, findQueryStmt, repoID, identifier); err != nil { return nil, database.ProcessSQLErrorf(err, "Failed to find pipeline") } return dst, nil @@ -357,15 +361,15 @@ func (s *pipelineStore) Delete(ctx context.Context, id int64) error { return nil } -// DeleteByUID deletes a pipeline with a given UID under a given repo. -func (s *pipelineStore) DeleteByUID(ctx context.Context, repoID int64, uid string) error { +// DeleteByIdentifier deletes a pipeline with a given Identifier under a given repo. +func (s *pipelineStore) DeleteByIdentifier(ctx context.Context, repoID int64, identifier string) error { const pipelineDeleteStmt = ` DELETE FROM pipelines WHERE pipeline_repo_id = $1 AND pipeline_uid = $2` db := dbtx.GetAccessor(ctx, s.db) - if _, err := db.ExecContext(ctx, pipelineDeleteStmt, repoID, uid); err != nil { + if _, err := db.ExecContext(ctx, pipelineDeleteStmt, repoID, identifier); err != nil { return database.ProcessSQLErrorf(err, "Could not delete pipeline") } diff --git a/app/store/database/plugin.go b/app/store/database/plugin.go index c1b951a75..277590de6 100644 --- a/app/store/database/plugin.go +++ b/app/store/database/plugin.go @@ -78,7 +78,7 @@ func (s *pluginStore) Create(ctx context.Context, plugin *types.Plugin) error { return database.ProcessSQLErrorf(err, "Failed to bind plugin object") } - if err = db.QueryRowContext(ctx, query, arg...).Scan(&plugin.UID); err != nil { + if err = db.QueryRowContext(ctx, query, arg...).Scan(&plugin.Identifier); err != nil { return database.ProcessSQLErrorf(err, "plugin query failed") } diff --git a/app/store/database/repo.go b/app/store/database/repo.go index 9c78f244d..f51a8aeed 100644 --- a/app/store/database/repo.go +++ b/app/store/database/repo.go @@ -60,7 +60,7 @@ type repository struct { ID int64 `db:"repo_id"` Version int64 `db:"repo_version"` ParentID int64 `db:"repo_parent_id"` - UID string `db:"repo_uid"` + Identifier string `db:"repo_uid"` Description string `db:"repo_description"` IsPublic bool `db:"repo_is_public"` CreatedBy int64 `db:"repo_created_by"` @@ -128,15 +128,19 @@ func (s *RepoStore) Find(ctx context.Context, id int64) (*types.Repository, erro return s.mapToRepo(ctx, dst) } -// Find finds the repo with the given UID in the given space ID. -func (s *RepoStore) FindByUID(ctx context.Context, spaceID int64, uid string) (*types.Repository, error) { +// Find finds the repo with the given identifier in the given space ID. +func (s *RepoStore) FindByIdentifier( + ctx context.Context, + spaceID int64, + identifier string, +) (*types.Repository, error) { const sqlQuery = repoSelectBase + ` WHERE repo_parent_id = $1 AND LOWER(repo_uid) = $2` db := dbtx.GetAccessor(ctx, s.db) dst := new(repository) - if err := db.GetContext(ctx, dst, sqlQuery, spaceID, strings.ToLower(uid)); err != nil { + if err := db.GetContext(ctx, dst, sqlQuery, spaceID, strings.ToLower(identifier)); err != nil { return nil, database.ProcessSQLErrorf(err, "Failed to find repo") } @@ -148,7 +152,7 @@ func (s *RepoStore) FindByRef(ctx context.Context, repoRef string) (*types.Repos // ASSUMPTION: digits only is not a valid repo path id, err := strconv.ParseInt(repoRef, 10, 64) if err != nil { - spacePath, repoUID, err := paths.DisectLeaf(repoRef) + spacePath, repoIdentifier, err := paths.DisectLeaf(repoRef) if err != nil { return nil, fmt.Errorf("failed to disect leaf for path '%s': %w", repoRef, err) } @@ -157,7 +161,7 @@ func (s *RepoStore) FindByRef(ctx context.Context, repoRef string) (*types.Repos return nil, fmt.Errorf("failed to get space path: %w", err) } - return s.FindByUID(ctx, pathObject.SpaceID, repoUID) + return s.FindByIdentifier(ctx, pathObject.SpaceID, repoIdentifier) } return s.Find(ctx, id) @@ -222,7 +226,7 @@ func (s *RepoStore) Create(ctx context.Context, repo *types.Repository) error { return database.ProcessSQLErrorf(err, "Insert query failed") } - repo.Path, err = s.getRepoPath(ctx, repo.ParentID, repo.UID) + repo.Path, err = s.getRepoPath(ctx, repo.ParentID, repo.Identifier) if err != nil { return err } @@ -282,8 +286,8 @@ func (s *RepoStore) Update(ctx context.Context, repo *types.Repository) error { repo.Version = dbRepo.Version repo.Updated = dbRepo.Updated - // update path in case parent/uid changed (its most likely cached anyway) - repo.Path, err = s.getRepoPath(ctx, repo.ParentID, repo.UID) + // update path in case parent/identifier changed (its most likely cached anyway) + repo.Path, err = s.getRepoPath(ctx, repo.ParentID, repo.Identifier) if err != nil { return err } @@ -458,7 +462,8 @@ func (s *RepoStore) List(ctx context.Context, parentID int64, opts *types.RepoFi stmt = stmt.Offset(database.Offset(opts.Page, opts.Size)) switch opts.Sort { - case enum.RepoAttrUID, enum.RepoAttrNone: + // TODO [CODE-1363]: remove after identifier migration. + case enum.RepoAttrUID, enum.RepoAttrIdentifier, enum.RepoAttrNone: // NOTE: string concatenation is safe because the // order attribute is an enum and is not user-defined, // and is therefore not subject to injection attacks. @@ -520,7 +525,7 @@ func (s *RepoStore) mapToRepo( ID: in.ID, Version: in.Version, ParentID: in.ParentID, - UID: in.UID, + Identifier: in.Identifier, Description: in.Description, IsPublic: in.IsPublic, Created: in.Created, @@ -541,7 +546,7 @@ func (s *RepoStore) mapToRepo( // Path: is set below } - res.Path, err = s.getRepoPath(ctx, in.ParentID, in.UID) + res.Path, err = s.getRepoPath(ctx, in.ParentID, in.Identifier) if err != nil { return nil, err } @@ -549,12 +554,12 @@ func (s *RepoStore) mapToRepo( return res, nil } -func (s *RepoStore) getRepoPath(ctx context.Context, parentID int64, repoUID string) (string, error) { +func (s *RepoStore) getRepoPath(ctx context.Context, parentID int64, repoIdentifier string) (string, error) { spacePath, err := s.spacePathStore.FindPrimaryBySpaceID(ctx, parentID) if err != nil { return "", fmt.Errorf("failed to get primary path for space %d: %w", parentID, err) } - return paths.Concatinate(spacePath.Value, repoUID), nil + return paths.Concatinate(spacePath.Value, repoIdentifier), nil } func (s *RepoStore) mapToRepos( @@ -598,7 +603,7 @@ func mapToInternalRepo(in *types.Repository) *repository { ID: in.ID, Version: in.Version, ParentID: in.ParentID, - UID: in.UID, + Identifier: in.Identifier, Description: in.Description, IsPublic: in.IsPublic, Created: in.Created, diff --git a/app/store/database/repo_test.go b/app/store/database/repo_test.go index ec62e865c..690ebd1f6 100644 --- a/app/store/database/repo_test.go +++ b/app/store/database/repo_test.go @@ -120,8 +120,8 @@ func createRepo( ) { t.Helper() - uid := "repo_" + strconv.FormatInt(id, 10) - repo := types.Repository{UID: uid, ID: id, ParentID: spaceID, GitUID: uid, Size: size} + identifier := "repo_" + strconv.FormatInt(id, 10) + repo := types.Repository{Identifier: identifier, ID: id, ParentID: spaceID, GitUID: identifier, Size: size} if err := repoStore.Create(*ctx, &repo); err != nil { t.Fatalf("failed to create repo %v", err) } diff --git a/app/store/database/rule.go b/app/store/database/rule.go index 709b0a350..e40693e82 100644 --- a/app/store/database/rule.go +++ b/app/store/database/rule.go @@ -64,7 +64,7 @@ type rule struct { SpaceID null.Int `db:"rule_space_id"` RepoID null.Int `db:"rule_repo_id"` - UID string `db:"rule_uid"` + Identifier string `db:"rule_uid"` Description string `db:"rule_description"` Type types.RuleType `db:"rule_type"` @@ -112,23 +112,28 @@ func (s *RuleStore) Find(ctx context.Context, id int64) (*types.Rule, error) { return &r, nil } -func (s *RuleStore) FindByUID(ctx context.Context, spaceID, repoID *int64, uid string) (*types.Rule, error) { +func (s *RuleStore) FindByIdentifier( + ctx context.Context, + spaceID *int64, + repoID *int64, + identifier string, +) (*types.Rule, error) { stmt := database.Builder. Select(ruleColumns). From("rules"). - Where("LOWER(rule_uid) = ?", strings.ToLower(uid)) + Where("LOWER(rule_uid) = ?", strings.ToLower(identifier)) stmt = s.applyParentID(stmt, spaceID, repoID) sql, args, err := stmt.ToSql() if err != nil { - return nil, fmt.Errorf("failed to convert find rule by UID to sql: %w", err) + return nil, fmt.Errorf("failed to convert find rule by Identifier to sql: %w", err) } db := dbtx.GetAccessor(ctx, s.db) dst := &rule{} if err = db.GetContext(ctx, dst, sql, args...); err != nil { - return nil, database.ProcessSQLErrorf(err, "Failed executing find rule by uid query") + return nil, database.ProcessSQLErrorf(err, "Failed executing find rule by identifier query") } r := s.mapToRule(ctx, dst) @@ -247,10 +252,10 @@ func (s *RuleStore) Delete(ctx context.Context, id int64) error { return nil } -func (s *RuleStore) DeleteByUID(ctx context.Context, spaceID, repoID *int64, uid string) error { +func (s *RuleStore) DeleteByIdentifier(ctx context.Context, spaceID, repoID *int64, identifier string) error { stmt := database.Builder. Delete("rules"). - Where("LOWER(rule_uid) = ?", strings.ToLower(uid)) + Where("LOWER(rule_uid) = ?", strings.ToLower(identifier)) if spaceID != nil { stmt = stmt.Where("rule_space_id = ?", *spaceID) @@ -262,13 +267,13 @@ func (s *RuleStore) DeleteByUID(ctx context.Context, spaceID, repoID *int64, uid sql, args, err := stmt.ToSql() if err != nil { - return fmt.Errorf("failed to convert delete rule by UID to sql: %w", err) + return fmt.Errorf("failed to convert delete rule by identifier to sql: %w", err) } db := dbtx.GetAccessor(ctx, s.db) if _, err = db.ExecContext(ctx, sql, args...); err != nil { - return database.ProcessSQLErrorf(err, "Failed executing delete rule by uid query") + return database.ProcessSQLErrorf(err, "Failed executing delete rule by identifier query") } return nil @@ -322,7 +327,8 @@ func (s *RuleStore) List(ctx context.Context, spaceID, repoID *int64, filter *ty stmt = stmt.OrderBy("rule_created " + order.String()) case enum.RuleSortUpdated: stmt = stmt.OrderBy("rule_updated " + order.String()) - case enum.RuleSortUID: + // TODO [CODE-1363]: remove after identifier migration. + case enum.RuleSortUID, enum.RuleSortIdentifier: stmt = stmt.OrderBy("LOWER(rule_uid) " + order.String()) } @@ -345,7 +351,7 @@ type ruleInfo struct { SpacePath string `db:"space_path"` RepoPath string `db:"repo_path"` ID int64 `db:"rule_id"` - UID string `db:"rule_uid"` + Identifier string `db:"rule_uid"` Type types.RuleType `db:"rule_type"` State enum.RuleState `db:"rule_state"` Pattern string `db:"rule_pattern"` @@ -465,7 +471,7 @@ func (s *RuleStore) mapToRule( Updated: in.Updated, SpaceID: in.SpaceID.Ptr(), RepoID: in.RepoID.Ptr(), - UID: in.UID, + Identifier: in.Identifier, Description: in.Description, Type: in.Type, State: in.State, @@ -505,7 +511,7 @@ func mapToInternalRule(in *types.Rule) rule { Updated: in.Updated, SpaceID: null.IntFromPtr(in.SpaceID), RepoID: null.IntFromPtr(in.RepoID), - UID: in.UID, + Identifier: in.Identifier, Description: in.Description, Type: in.Type, State: in.State, @@ -517,12 +523,12 @@ func mapToInternalRule(in *types.Rule) rule { func (*RuleStore) mapToRuleInfo(in *ruleInfo) types.RuleInfoInternal { return types.RuleInfoInternal{ RuleInfo: types.RuleInfo{ - SpacePath: in.SpacePath, - RepoPath: in.RepoPath, - ID: in.ID, - UID: in.UID, - Type: in.Type, - State: in.State, + SpacePath: in.SpacePath, + RepoPath: in.RepoPath, + ID: in.ID, + Identifier: in.Identifier, + Type: in.Type, + State: in.State, }, Pattern: json.RawMessage(in.Pattern), Definition: json.RawMessage(in.Definition), diff --git a/app/store/database/secret.go b/app/store/database/secret.go index 0cc229ce1..a00bc73d1 100644 --- a/app/store/database/secret.go +++ b/app/store/database/secret.go @@ -75,14 +75,14 @@ func (s *secretStore) Find(ctx context.Context, id int64) (*types.Secret, error) return dst, nil } -// FindByUID returns a secret in a given space with a given UID. -func (s *secretStore) FindByUID(ctx context.Context, spaceID int64, uid string) (*types.Secret, error) { +// FindByIdentifier returns a secret in a given space with a given identifier. +func (s *secretStore) FindByIdentifier(ctx context.Context, spaceID int64, identifier string) (*types.Secret, error) { const findQueryStmt = secretQueryBase + ` WHERE secret_space_id = $1 AND secret_uid = $2` db := dbtx.GetAccessor(ctx, s.db) dst := new(types.Secret) - if err := db.GetContext(ctx, dst, findQueryStmt, spaceID, uid); err != nil { + if err := db.GetContext(ctx, dst, findQueryStmt, spaceID, identifier); err != nil { return nil, database.ProcessSQLErrorf(err, "Failed to find secret") } return dst, nil @@ -262,8 +262,8 @@ func (s *secretStore) Delete(ctx context.Context, id int64) error { return nil } -// DeleteByUID deletes a secret with a given UID in a space. -func (s *secretStore) DeleteByUID(ctx context.Context, spaceID int64, uid string) error { +// DeleteByIdentifier deletes a secret with a given identifier in a space. +func (s *secretStore) DeleteByIdentifier(ctx context.Context, spaceID int64, identifier string) error { //nolint:gosec // wrong flagging const secretDeleteStmt = ` DELETE FROM secrets @@ -271,7 +271,7 @@ func (s *secretStore) DeleteByUID(ctx context.Context, spaceID int64, uid string db := dbtx.GetAccessor(ctx, s.db) - if _, err := db.ExecContext(ctx, secretDeleteStmt, spaceID, uid); err != nil { + if _, err := db.ExecContext(ctx, secretDeleteStmt, spaceID, identifier); err != nil { return database.ProcessSQLErrorf(err, "Could not delete secret") } diff --git a/app/store/database/setup_test.go b/app/store/database/setup_test.go index b43720dab..671282810 100644 --- a/app/store/database/setup_test.go +++ b/app/store/database/setup_test.go @@ -109,15 +109,15 @@ func createSpace( ) { t.Helper() - uid := "space_" + strconv.FormatInt(spaceID, 10) + identifier := "space_" + strconv.FormatInt(spaceID, 10) - space := types.Space{ID: spaceID, UID: uid, CreatedBy: userID, ParentID: parentID} + space := types.Space{ID: spaceID, Identifier: identifier, CreatedBy: userID, ParentID: parentID} if err := spaceStore.Create(*ctx, &space); err != nil { t.Fatalf("failed to create space %v", err) } if err := spacePathStore.InsertSegment(*ctx, &types.SpacePathSegment{ - ID: space.ID, UID: uid, CreatedBy: userID, SpaceID: spaceID, IsPrimary: true, + ID: space.ID, Identifier: identifier, CreatedBy: userID, SpaceID: spaceID, IsPrimary: true, }); err != nil { t.Fatalf("failed to insert segment %v", err) } diff --git a/app/store/database/space.go b/app/store/database/space.go index bef3c9d22..b80087fda 100644 --- a/app/store/database/space.go +++ b/app/store/database/space.go @@ -61,7 +61,7 @@ type space struct { Version int64 `db:"space_version"` // IMPORTANT: We need to make parentID optional for spaces to allow it to be a foreign key. ParentID null.Int `db:"space_parent_id"` - UID string `db:"space_uid"` + Identifier string `db:"space_uid"` Description string `db:"space_description"` IsPublic bool `db:"space_is_public"` CreatedBy int64 `db:"space_created_by"` @@ -233,7 +233,7 @@ func (s *SpaceStore) Update(ctx context.Context, space *types.Space) error { space.Version = dbSpace.Version space.Updated = dbSpace.Updated - // update path in case parent/uid changed + // update path in case parent/identifier changed space.Path, err = getSpacePath(ctx, s.spacePathStore, space.ID) if err != nil { return err @@ -327,7 +327,7 @@ func (s *SpaceStore) List(ctx context.Context, id int64, opts *types.SpaceFilter } switch opts.Sort { - case enum.SpaceAttrUID, enum.SpaceAttrNone: + case enum.SpaceAttrUID, enum.SpaceAttrIdentifier, enum.SpaceAttrNone: // NOTE: string concatenation is safe because the // order attribute is an enum and is not user-defined, // and is therefore not subject to injection attacks. @@ -364,7 +364,7 @@ func mapToSpace( res := &types.Space{ ID: in.ID, Version: in.Version, - UID: in.UID, + Identifier: in.Identifier, Description: in.Description, IsPublic: in.IsPublic, Created: in.Created, @@ -418,7 +418,7 @@ func mapToInternalSpace(s *types.Space) *space { res := &space{ ID: s.ID, Version: s.Version, - UID: s.UID, + Identifier: s.Identifier, Description: s.Description, IsPublic: s.IsPublic, Created: s.Created, diff --git a/app/store/database/space_path.go b/app/store/database/space_path.go index fa9f2da42..3230f4887 100644 --- a/app/store/database/space_path.go +++ b/app/store/database/space_path.go @@ -47,10 +47,10 @@ type SpacePathStore struct { // spacePathSegment is an internal representation of a segment of a space path. type spacePathSegment struct { ID int64 `db:"space_path_id"` - // UID is the original uid that was provided - UID string `db:"space_path_uid"` - // UIDUnique is a transformed version of UID which is used to ensure uniqueness guarantees - UIDUnique string `db:"space_path_uid_unique"` + // Identifier is the original identifier that was provided + Identifier string `db:"space_path_uid"` + // IdentifierUnique is a transformed version of Identifier which is used to ensure uniqueness guarantees + IdentifierUnique string `db:"space_path_uid_unique"` // IsPrimary indicates whether the path is the primary path of the space // IMPORTANT: to allow DB enforcement of at most one primary path per repo/space // we have a unique index on spaceID + IsPrimary and set IsPrimary to true @@ -132,7 +132,7 @@ func (s *SpacePathStore) FindPrimaryBySpaceID(ctx context.Context, spaceID int64 return nil, database.ProcessSQLErrorf(err, "Failed to find primary segment for %d", nextSpaceID.Int64) } - path = paths.Concatinate(dst.UID, path) + path = paths.Concatinate(dst.Identifier, path) nextSpaceID = dst.ParentID } @@ -149,8 +149,8 @@ func (s *SpacePathStore) FindByPath(ctx context.Context, path string) (*types.Sp db := dbtx.GetAccessor(ctx, s.db) segment := new(spacePathSegment) - segmentUIDs := paths.Segments(path) - if len(segmentUIDs) == 0 { + segmentIdentifiers := paths.Segments(path) + if len(segmentIdentifiers) == 0 { return nil, fmt.Errorf("path with no segments was passed '%s'", path) } @@ -158,19 +158,19 @@ func (s *SpacePathStore) FindByPath(ctx context.Context, path string) (*types.Sp var parentID int64 originalPath := "" isPrimary := true - for i, segmentUID := range segmentUIDs { - uniqueSegmentUID := s.spacePathTransformation(segmentUID, i == 0) + for i, segmentIdentifier := range segmentIdentifiers { + uniqueSegmentIdentifier := s.spacePathTransformation(segmentIdentifier, i == 0) if parentID == 0 { - err = db.GetContext(ctx, segment, sqlQueryNoParent, uniqueSegmentUID) + err = db.GetContext(ctx, segment, sqlQueryNoParent, uniqueSegmentIdentifier) } else { - err = db.GetContext(ctx, segment, sqlQueryParent, uniqueSegmentUID, parentID) + err = db.GetContext(ctx, segment, sqlQueryParent, uniqueSegmentIdentifier, parentID) } if err != nil { - return nil, database.ProcessSQLErrorf(err, "Failed to find segment for '%s' in '%s'", uniqueSegmentUID, path) + return nil, database.ProcessSQLErrorf(err, "Failed to find segment for '%s' in '%s'", uniqueSegmentIdentifier, path) } - originalPath = paths.Concatinate(originalPath, segment.UID) + originalPath = paths.Concatinate(originalPath, segment.Identifier) parentID = segment.SpaceID isPrimary = isPrimary && segment.IsPrimary.ValueOrZero() } @@ -199,13 +199,13 @@ func (s *SpacePathStore) DeletePrimarySegment(ctx context.Context, spaceID int64 func (s *SpacePathStore) mapToInternalSpacePathSegment(p *types.SpacePathSegment) *spacePathSegment { res := &spacePathSegment{ - ID: p.ID, - UID: p.UID, - UIDUnique: s.spacePathTransformation(p.UID, p.ParentID == 0), - SpaceID: p.SpaceID, - Created: p.Created, - CreatedBy: p.CreatedBy, - Updated: p.Updated, + ID: p.ID, + Identifier: p.Identifier, + IdentifierUnique: s.spacePathTransformation(p.Identifier, p.ParentID == 0), + SpaceID: p.SpaceID, + Created: p.Created, + CreatedBy: p.CreatedBy, + Updated: p.Updated, // ParentID: is set below // IsPrimary: is set below diff --git a/app/store/database/template.go b/app/store/database/template.go index 796e91c10..1682f341e 100644 --- a/app/store/database/template.go +++ b/app/store/database/template.go @@ -75,18 +75,25 @@ func (s *templateStore) Find(ctx context.Context, id int64) (*types.Template, er return dst, nil } -// FindByUIDAndType returns a template in a space with a given UID and a given type. -func (s *templateStore) FindByUIDAndType( +// FindByIdentifierAndType returns a template in a space with a given identifier and a given type. +func (s *templateStore) FindByIdentifierAndType( ctx context.Context, spaceID int64, - uid string, + identifier string, resolverType enum.ResolverType) (*types.Template, error) { const findQueryStmt = templateQueryBase + ` WHERE template_space_id = $1 AND template_uid = $2 AND template_type = $3` db := dbtx.GetAccessor(ctx, s.db) dst := new(types.Template) - if err := db.GetContext(ctx, dst, findQueryStmt, spaceID, uid, resolverType.String()); err != nil { + if err := db.GetContext( + ctx, + dst, + findQueryStmt, + spaceID, + identifier, + resolverType.String(), + ); err != nil { return nil, database.ProcessSQLErrorf(err, "Failed to find template") } return dst, nil @@ -247,11 +254,11 @@ func (s *templateStore) Delete(ctx context.Context, id int64) error { return nil } -// DeleteByUID deletes a template with a given UID in a space. -func (s *templateStore) DeleteByUIDAndType( +// DeleteByIdentifierAndType deletes a template with a given identifier in a space. +func (s *templateStore) DeleteByIdentifierAndType( ctx context.Context, spaceID int64, - uid string, + identifier string, resolverType enum.ResolverType, ) error { const templateDeleteStmt = ` @@ -260,7 +267,7 @@ func (s *templateStore) DeleteByUIDAndType( db := dbtx.GetAccessor(ctx, s.db) - if _, err := db.ExecContext(ctx, templateDeleteStmt, spaceID, uid, resolverType.String()); err != nil { + if _, err := db.ExecContext(ctx, templateDeleteStmt, spaceID, identifier, resolverType.String()); err != nil { return database.ProcessSQLErrorf(err, "Could not delete template") } diff --git a/app/store/database/token.go b/app/store/database/token.go index 12ef657b6..6abb2e6c3 100644 --- a/app/store/database/token.go +++ b/app/store/database/token.go @@ -17,6 +17,7 @@ package database import ( "context" "fmt" + "strings" "time" "github.com/harness/gitness/app/store" @@ -53,13 +54,19 @@ func (s *TokenStore) Find(ctx context.Context, id int64) (*types.Token, error) { return dst, nil } -// FindByUID finds the token by principalId and tokenUID. -func (s *TokenStore) FindByUID(ctx context.Context, principalID int64, tokenUID string) (*types.Token, error) { +// FindByIdentifier finds the token by principalId and token identifier. +func (s *TokenStore) FindByIdentifier(ctx context.Context, principalID int64, identifier string) (*types.Token, error) { db := dbtx.GetAccessor(ctx, s.db) dst := new(types.Token) - if err := db.GetContext(ctx, dst, TokenSelectByPrincipalIDAndUID, principalID, tokenUID); err != nil { - return nil, database.ProcessSQLErrorf(err, "Failed to find token by UID") + if err := db.GetContext( + ctx, + dst, + TokenSelectByPrincipalIDAndIdentifier, + principalID, + strings.ToLower(identifier), + ); err != nil { + return nil, database.ProcessSQLErrorf(err, "Failed to find token by identifier") } return dst, nil @@ -184,8 +191,8 @@ const TokenSelectByID = tokenSelectBase + ` WHERE token_id = $1 ` -const TokenSelectByPrincipalIDAndUID = tokenSelectBase + ` -WHERE token_principal_id = $1 AND token_uid = $2 +const TokenSelectByPrincipalIDAndIdentifier = tokenSelectBase + ` +WHERE token_principal_id = $1 AND LOWER(token_uid) = $2 ` const tokenDelete = ` diff --git a/app/store/database/trigger.go b/app/store/database/trigger.go index f0378e544..b59f23eae 100644 --- a/app/store/database/trigger.go +++ b/app/store/database/trigger.go @@ -37,7 +37,7 @@ var _ store.TriggerStore = (*triggerStore)(nil) type trigger struct { ID int64 `db:"trigger_id"` - UID string `db:"trigger_uid"` + Identifier string `db:"trigger_uid"` Description string `db:"trigger_description"` Type string `db:"trigger_type"` Secret string `db:"trigger_secret"` @@ -68,7 +68,7 @@ func mapInternalToTrigger(trigger *trigger) (*types.Trigger, error) { CreatedBy: trigger.CreatedBy, Disabled: trigger.Disabled, Actions: actions, - UID: trigger.UID, + Identifier: trigger.Identifier, Created: trigger.Created, Updated: trigger.Updated, Version: trigger.Version, @@ -90,7 +90,7 @@ func mapInternalToTriggerList(triggers []*trigger) ([]*types.Trigger, error) { func mapTriggerToInternal(t *types.Trigger) *trigger { return &trigger{ ID: t.ID, - UID: t.UID, + Identifier: t.Identifier, Description: t.Description, Type: t.Type, PipelineID: t.PipelineID, @@ -130,8 +130,12 @@ const ( ` ) -// Find returns an trigger given a pipeline ID and a trigger UID. -func (s *triggerStore) FindByUID(ctx context.Context, pipelineID int64, uid string) (*types.Trigger, error) { +// Find returns an trigger given a pipeline ID and a trigger identifier. +func (s *triggerStore) FindByIdentifier( + ctx context.Context, + pipelineID int64, + identifier string, +) (*types.Trigger, error) { const findQueryStmt = ` SELECT` + triggerColumns + ` FROM triggers @@ -139,7 +143,7 @@ func (s *triggerStore) FindByUID(ctx context.Context, pipelineID int64, uid stri db := dbtx.GetAccessor(ctx, s.db) dst := new(trigger) - if err := db.GetContext(ctx, dst, findQueryStmt, pipelineID, uid); err != nil { + if err := db.GetContext(ctx, dst, findQueryStmt, pipelineID, identifier); err != nil { return nil, database.ProcessSQLErrorf(err, "Failed to find trigger") } return mapInternalToTrigger(dst) @@ -254,7 +258,7 @@ func (s *triggerStore) UpdateOptLock(ctx context.Context, return nil, err } - trigger, err = s.FindByUID(ctx, trigger.PipelineID, trigger.UID) + trigger, err = s.FindByIdentifier(ctx, trigger.PipelineID, trigger.Identifier) if err != nil { return nil, err } @@ -345,15 +349,15 @@ func (s *triggerStore) Count(ctx context.Context, pipelineID int64, filter types return count, nil } -// Delete deletes an trigger given a pipeline ID and a trigger UID. -func (s *triggerStore) DeleteByUID(ctx context.Context, pipelineID int64, uid string) error { +// Delete deletes an trigger given a pipeline ID and a trigger identifier. +func (s *triggerStore) DeleteByIdentifier(ctx context.Context, pipelineID int64, identifier string) error { const triggerDeleteStmt = ` DELETE FROM triggers WHERE trigger_pipeline_id = $1 AND trigger_uid = $2` db := dbtx.GetAccessor(ctx, s.db) - if _, err := db.ExecContext(ctx, triggerDeleteStmt, pipelineID, uid); err != nil { + if _, err := db.ExecContext(ctx, triggerDeleteStmt, pipelineID, identifier); err != nil { return database.ProcessSQLErrorf(err, "Could not delete trigger") } diff --git a/app/store/database/usergroup.go b/app/store/database/usergroup.go index ca6390312..f7d39809e 100644 --- a/app/store/database/usergroup.go +++ b/app/store/database/usergroup.go @@ -28,7 +28,7 @@ type UserGroupStore struct { } // Find Dummy Method: to be implemented later. -func (s *UserGroupStore) Find(_ context.Context, _ int64, _ string) (*types.UserGroup, error) { +func (s *UserGroupStore) FindByIdentifier(_ context.Context, _ int64, _ string) (*types.UserGroup, error) { //nolint: nilnil return nil, store.ErrResourceNotFound } diff --git a/app/store/database/webhook.go b/app/store/database/webhook.go index b93954e77..e5785e0a0 100644 --- a/app/store/database/webhook.go +++ b/app/store/database/webhook.go @@ -57,8 +57,8 @@ type webhook struct { Updated int64 `db:"webhook_updated"` Internal bool `db:"webhook_internal"` - UID string `db:"webhook_uid"` - // TODO: Remove once UID migration is completed. + Identifier string `db:"webhook_uid"` + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. DisplayName string `db:"webhook_display_name"` Description string `db:"webhook_description"` URL string `db:"webhook_url"` @@ -114,17 +114,17 @@ func (s *WebhookStore) Find(ctx context.Context, id int64) (*types.Webhook, erro return res, nil } -// FindByUID finds the webhook with the given UID for the given parent. -func (s *WebhookStore) FindByUID( +// FindByIdentifier finds the webhook with the given Identifier for the given parent. +func (s *WebhookStore) FindByIdentifier( ctx context.Context, parentType enum.WebhookParent, parentID int64, - uid string, + identifier string, ) (*types.Webhook, error) { stmt := database.Builder. Select(webhookColumns). From("webhooks"). - Where("LOWER(webhook_uid) = ?", strings.ToLower(uid)) + Where("LOWER(webhook_uid) = ?", strings.ToLower(identifier)) switch parentType { case enum.WebhookParentRepo: @@ -307,16 +307,16 @@ func (s *WebhookStore) Delete(ctx context.Context, id int64) error { return nil } -// DeleteByUID deletes the webhook with the given UID for the given parent. -func (s *WebhookStore) DeleteByUID( +// DeleteByIdentifier deletes the webhook with the given Identifier for the given parent. +func (s *WebhookStore) DeleteByIdentifier( ctx context.Context, parentType enum.WebhookParent, parentID int64, - uid string, + identifier string, ) error { stmt := database.Builder. Delete("webhooks"). - Where("LOWER(webhook_uid) = ?", strings.ToLower(uid)) + Where("LOWER(webhook_uid) = ?", strings.ToLower(identifier)) switch parentType { case enum.WebhookParentRepo: @@ -405,13 +405,17 @@ func (s *WebhookStore) List(ctx context.Context, parentType enum.WebhookParent, stmt = stmt.Offset(database.Offset(opts.Page, opts.Size)) switch opts.Sort { + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed case enum.WebhookAttrID, enum.WebhookAttrNone: // NOTE: string concatenation is safe because the // order attribute is an enum and is not user-defined, // and is therefore not subject to injection attacks. stmt = stmt.OrderBy("webhook_id " + opts.Order.String()) - case enum.WebhookAttrUID: + + // TODO [CODE-1363]: remove after identifier migration. + case enum.WebhookAttrUID, enum.WebhookAttrIdentifier: stmt = stmt.OrderBy("LOWER(webhook_uid) " + opts.Order.String()) + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed case enum.WebhookAttrDisplayName: stmt = stmt.OrderBy("webhook_display_name " + opts.Order.String()) //TODO: Postgres does not support COLLATE NOCASE for UTF8 @@ -443,12 +447,13 @@ func (s *WebhookStore) List(ctx context.Context, parentType enum.WebhookParent, func mapToWebhook(hook *webhook) (*types.Webhook, error) { res := &types.Webhook{ - ID: hook.ID, - Version: hook.Version, - CreatedBy: hook.CreatedBy, - Created: hook.Created, - Updated: hook.Updated, - UID: hook.UID, + ID: hook.ID, + Version: hook.Version, + CreatedBy: hook.CreatedBy, + Created: hook.Created, + Updated: hook.Updated, + Identifier: hook.Identifier, + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed DisplayName: hook.DisplayName, Description: hook.Description, URL: hook.URL, @@ -478,12 +483,13 @@ func mapToWebhook(hook *webhook) (*types.Webhook, error) { func mapToInternalWebhook(hook *types.Webhook) (*webhook, error) { res := &webhook{ - ID: hook.ID, - Version: hook.Version, - CreatedBy: hook.CreatedBy, - Created: hook.Created, - Updated: hook.Updated, - UID: hook.UID, + ID: hook.ID, + Version: hook.Version, + CreatedBy: hook.CreatedBy, + Created: hook.Created, + Updated: hook.Updated, + Identifier: hook.Identifier, + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed DisplayName: hook.DisplayName, Description: hook.Description, URL: hook.URL, diff --git a/app/store/database/wire.go b/app/store/database/wire.go index 72008f388..cf5c3d1b2 100644 --- a/app/store/database/wire.go +++ b/app/store/database/wire.go @@ -53,7 +53,6 @@ var WireSet = wire.NewSet( ProvideWebhookStore, ProvideWebhookExecutionStore, ProvideCheckStore, - ProvideReqCheckStore, ProvideConnectorStore, ProvideTemplateStore, ProvideTriggerStore, @@ -240,10 +239,3 @@ func ProvideCheckStore(db *sqlx.DB, ) store.CheckStore { return NewCheckStore(db, principalInfoCache) } - -// ProvideReqCheckStore provides a required status check store. -func ProvideReqCheckStore(db *sqlx.DB, - principalInfoCache store.PrincipalInfoCache, -) store.ReqCheckStore { - return NewReqCheckStore(db, principalInfoCache) -} diff --git a/app/token/token.go b/app/token/token.go index c822252a0..0b7ce4b13 100644 --- a/app/token/token.go +++ b/app/token/token.go @@ -37,7 +37,7 @@ func CreateUserSession( ctx context.Context, tokenStore store.TokenStore, user *types.User, - uid string, + identifier string, ) (*types.Token, string, error) { principal := user.ToPrincipal() return create( @@ -46,7 +46,7 @@ func CreateUserSession( enum.TokenTypeSession, principal, principal, - uid, + identifier, ptr.Duration(userSessionTokenLifeTime), ) } @@ -56,7 +56,7 @@ func CreatePAT( tokenStore store.TokenStore, createdBy *types.Principal, createdFor *types.User, - uid string, + identifier string, lifetime *time.Duration, ) (*types.Token, string, error) { return create( @@ -65,7 +65,7 @@ func CreatePAT( enum.TokenTypePAT, createdBy, createdFor.ToPrincipal(), - uid, + identifier, lifetime, ) } @@ -75,7 +75,7 @@ func CreateSAT( tokenStore store.TokenStore, createdBy *types.Principal, createdFor *types.ServiceAccount, - uid string, + identifier string, lifetime *time.Duration, ) (*types.Token, string, error) { return create( @@ -84,7 +84,7 @@ func CreateSAT( enum.TokenTypeSAT, createdBy, createdFor.ToPrincipal(), - uid, + identifier, lifetime, ) } @@ -95,7 +95,7 @@ func create( tokenType enum.TokenType, createdBy *types.Principal, createdFor *types.Principal, - uid string, + identifier string, lifetime *time.Duration, ) (*types.Token, string, error) { issuedAt := time.Now() @@ -108,7 +108,7 @@ func create( // create db entry first so we get the id. token := types.Token{ Type: tokenType, - UID: uid, + Identifier: identifier, PrincipalID: createdFor.ID, IssuedAt: issuedAt.UnixMilli(), ExpiresAt: expiresAt, diff --git a/app/url/provider.go b/app/url/provider.go index b8df1954f..f94bd2364 100644 --- a/app/url/provider.go +++ b/app/url/provider.go @@ -61,7 +61,7 @@ type Provider interface { GetAPIHostname() string // GenerateUIBuildURL returns the endpoint to use for viewing build executions. - GenerateUIBuildURL(repoPath, pipelineUID string, seqNumber int64) string + GenerateUIBuildURL(repoPath, pipelineIdentifier string, seqNumber int64) string // GetGITHostname returns the host for the git endpoint. GetGITHostname() string @@ -161,9 +161,9 @@ func (p *provider) GenerateGITCloneURL(repoPath string) string { return p.gitURL.JoinPath(repoPath).String() } -func (p *provider) GenerateUIBuildURL(repoPath, pipelineUID string, seqNumber int64) string { +func (p *provider) GenerateUIBuildURL(repoPath, pipelineIdentifier string, seqNumber int64) string { return p.uiURL.JoinPath(repoPath, "pipelines", - pipelineUID, "execution", strconv.Itoa(int(seqNumber))).String() + pipelineIdentifier, "execution", strconv.Itoa(int(seqNumber))).String() } func (p *provider) GenerateUIRepoURL(repoPath string) string { diff --git a/cli/operations/user/create_pat.go b/cli/operations/user/create_pat.go index cd00fa423..84ec10c05 100644 --- a/cli/operations/user/create_pat.go +++ b/cli/operations/user/create_pat.go @@ -31,13 +31,13 @@ import ( const tokenTmpl = ` principalID: {{ .Token.PrincipalID }} -uid: {{ .Token.UID }} +identifier: {{ .Token.Identifier }} expiresAt: {{ .Token.ExpiresAt }} token: {{ .AccessToken }} ` //#nosec G101 type createPATCommand struct { - uid string + identifier string lifetimeInS int64 json bool @@ -54,8 +54,8 @@ func (c *createPATCommand) run(*kingpin.ParseContext) error { } in := user.CreateTokenInput{ - UID: c.uid, - Lifetime: lifeTime, + Identifier: c.identifier, + Lifetime: lifeTime, } tokenResp, err := provide.Client().UserCreatePAT(ctx, in) @@ -81,8 +81,8 @@ func registerCreatePAT(app *kingpin.CmdClause) { cmd := app.Command("pat", "create personal access token"). Action(c.run) - cmd.Arg("uid", "the uid of the token"). - Required().StringVar(&c.uid) + cmd.Arg("identifier", "the identifier of the token"). + Required().StringVar(&c.identifier) cmd.Arg("lifetime", "the lifetime of the token in seconds"). Int64Var(&c.lifetimeInS) diff --git a/cmd/gitness/wire_gen.go b/cmd/gitness/wire_gen.go index fc9e674c3..189eabb9c 100644 --- a/cmd/gitness/wire_gen.go +++ b/cmd/gitness/wire_gen.go @@ -121,7 +121,6 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro if err != nil { return nil, err } - pathUID := check.ProvidePathUIDCheck() repoStore := database.ProvideRepoStore(db, spacePathCache, spacePathStore) pipelineStore := database.ProvidePipelineStore(db) ruleStore := database.ProvideRuleStore(db, principalInfoCache) @@ -187,7 +186,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro if err != nil { return nil, err } - repoController := repo.ProvideController(config, transactor, provider, pathUID, authorizer, repoStore, spaceStore, pipelineStore, principalStore, ruleStore, principalInfoCache, protectionManager, gitInterface, repository, codeownersService, reporter, indexer, resourceLimiter, mutexManager) + repoController := repo.ProvideController(config, transactor, provider, authorizer, repoStore, spaceStore, pipelineStore, principalStore, ruleStore, principalInfoCache, protectionManager, gitInterface, repository, codeownersService, reporter, indexer, resourceLimiter, mutexManager) executionStore := database.ProvideExecutionStore(db) checkStore := database.ProvideCheckStore(db, principalInfoCache) stageStore := database.ProvideStageStore(db) @@ -207,18 +206,19 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro logStore := logs.ProvideLogStore(db, config) logStream := livelog.ProvideLogStream() logsController := logs2.ProvideController(authorizer, executionStore, repoStore, pipelineStore, stageStore, stepStore, logStore, logStream) + spaceIdentifier := check.ProvideSpaceIdentifierCheck() secretStore := database.ProvideSecretStore(db) connectorStore := database.ProvideConnectorStore(db) exporterRepository, err := exporter.ProvideSpaceExporter(provider, gitInterface, repoStore, jobScheduler, executor, encrypter, streamer) if err != nil { return nil, err } - spaceController := space.ProvideController(config, transactor, provider, streamer, pathUID, authorizer, spacePathStore, pipelineStore, secretStore, connectorStore, templateStore, spaceStore, repoStore, principalStore, repoController, membershipStore, repository, exporterRepository, resourceLimiter) - pipelineController := pipeline.ProvideController(pathUID, repoStore, triggerStore, authorizer, pipelineStore) - secretController := secret.ProvideController(pathUID, encrypter, secretStore, authorizer, spaceStore) - triggerController := trigger.ProvideController(authorizer, triggerStore, pathUID, pipelineStore, repoStore) - connectorController := connector.ProvideController(pathUID, connectorStore, authorizer, spaceStore) - templateController := template.ProvideController(pathUID, templateStore, authorizer, spaceStore) + spaceController := space.ProvideController(config, transactor, provider, streamer, spaceIdentifier, authorizer, spacePathStore, pipelineStore, secretStore, connectorStore, templateStore, spaceStore, repoStore, principalStore, repoController, membershipStore, repository, exporterRepository, resourceLimiter) + pipelineController := pipeline.ProvideController(repoStore, triggerStore, authorizer, pipelineStore) + secretController := secret.ProvideController(encrypter, secretStore, authorizer, spaceStore) + triggerController := trigger.ProvideController(authorizer, triggerStore, pipelineStore, repoStore) + connectorController := connector.ProvideController(connectorStore, authorizer, spaceStore) + templateController := template.ProvideController(templateStore, authorizer, spaceStore) pluginController := plugin.ProvideController(pluginStore) pullReqStore := database.ProvidePullReqStore(db, principalInfoCache) pullReqActivityStore := database.ProvidePullReqActivityStore(db, principalInfoCache) diff --git a/types/authz.go b/types/authz.go index b1066ab17..2fbd464d5 100644 --- a/types/authz.go +++ b/types/authz.go @@ -26,8 +26,8 @@ type PermissionCheck struct { // Resource represents the resource of a permission check. // Note: Keep the name empty in case access is requested for all resources of that type. type Resource struct { - Type enum.ResourceType - Name string + Type enum.ResourceType + Identifier string } // Scope represents the scope of a permission check diff --git a/types/check.go b/types/check.go index 783c1734d..873cc46b9 100644 --- a/types/check.go +++ b/types/check.go @@ -21,27 +21,53 @@ import ( ) type Check struct { - ID int64 `json:"id"` - CreatedBy int64 `json:"-"` // clients will use "reported_by" - Created int64 `json:"created"` - Updated int64 `json:"updated"` - RepoID int64 `json:"-"` // status checks are always returned for a commit in a repository - CommitSHA string `json:"-"` // status checks are always returned for a commit in a repository - UID string `json:"uid"` - Status enum.CheckStatus `json:"status"` - Summary string `json:"summary"` - Link string `json:"link"` - Metadata json.RawMessage `json:"metadata"` - Started int64 `json:"started"` - Ended int64 `json:"ended"` + ID int64 `json:"id"` + CreatedBy int64 `json:"-"` // clients will use "reported_by" + Created int64 `json:"created"` + Updated int64 `json:"updated"` + RepoID int64 `json:"-"` // status checks are always returned for a commit in a repository + CommitSHA string `json:"-"` // status checks are always returned for a commit in a repository + Identifier string `json:"identifier"` + Status enum.CheckStatus `json:"status"` + Summary string `json:"summary"` + Link string `json:"link"` + Metadata json.RawMessage `json:"metadata"` + Started int64 `json:"started"` + Ended int64 `json:"ended"` Payload CheckPayload `json:"payload"` ReportedBy PrincipalInfo `json:"reported_by"` } +// TODO [CODE-1363]: remove after identifier migration. +func (c Check) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Check + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(c), + UID: c.Identifier, + }) +} + type CheckResult struct { - UID string `json:"uid" db:"check_uid"` - Status enum.CheckStatus `json:"status" db:"check_status"` + Identifier string `json:"identifier" db:"check_uid"` + Status enum.CheckStatus `json:"status" db:"check_status"` +} + +// TODO [CODE-1363]: remove after identifier migration. +func (s CheckResult) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias CheckResult + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(s), + UID: s.Identifier, + }) } type CheckPayload struct { @@ -61,17 +87,6 @@ type CheckRecentOptions struct { Since int64 } -type ReqCheck struct { - ID int64 `json:"id"` - CreatedBy int64 `json:"-"` // clients will use "added_by" - Created int64 `json:"created"` - RepoID int64 `json:"-"` // required status checks are always returned for a single repository - BranchPattern string `json:"branch_pattern"` - CheckUID string `json:"check_uid"` - - AddedBy PrincipalInfo `json:"added_by"` -} - type CheckPayloadText struct { Details string `json:"details"` } diff --git a/types/check/common.go b/types/check/common.go index 80d4d1c87..8ae35997f 100644 --- a/types/check/common.go +++ b/types/check/common.go @@ -24,9 +24,10 @@ const ( minDisplayNameLength = 1 maxDisplayNameLength = 256 - minUIDLength = 1 - MaxUIDLength = 100 - uidRegex = "^[a-zA-Z_][a-zA-Z0-9-_.]*$" + minIdentifierLength = 1 + MaxIdentifierLength = 100 + identifierRegex = "^[a-zA-Z0-9-_.]*$" + illegalRepoSpaceIdentifierSuffix = ".git" minEmailLength = 1 maxEmailLength = 250 @@ -35,9 +36,9 @@ const ( ) var ( - // illegalRootSpaceUIDs is the list of space UIDs we are blocking for root spaces + // illegalRootSpaceIdentifiers is the list of space identifier we are blocking for root spaces // as they might cause issues with routing. - illegalRootSpaceUIDs = []string{"api", "git"} + illegalRootSpaceIdentifiers = []string{"api", "git"} ) var ( @@ -49,12 +50,15 @@ var ( fmt.Sprintf("Description can be at most %d in length.", maxDescriptionLength), } - ErrUIDLength = &ValidationError{ - fmt.Sprintf("UID has to be between %d and %d in length.", - minUIDLength, MaxUIDLength), + ErrIdentifierLength = &ValidationError{ + fmt.Sprintf( + "Identifier has to be between %d and %d in length.", + minIdentifierLength, + MaxIdentifierLength, + ), } - ErrUIDRegex = &ValidationError{ - "UID has to start with a letter (or _) and only contain the following characters [a-zA-Z0-9-_.].", + ErrIdentifierRegex = &ValidationError{ + "Identifier can only contain the following characters [a-zA-Z0-9-_.].", } ErrEmailLen = &ValidationError{ @@ -63,8 +67,12 @@ var ( ErrInvalidCharacters = &ValidationError{"Input contains invalid characters."} - ErrIllegalRootSpaceUID = &ValidationError{ - fmt.Sprintf("The following names are not allowed for a root space: %v", illegalRootSpaceUIDs), + ErrIllegalRootSpaceIdentifier = &ValidationError{ + fmt.Sprintf("The following identifiers are not allowed for a root space: %v", illegalRootSpaceIdentifiers), + } + + ErrIllegalRepoSpaceIdentifierSuffix = &ValidationError{ + fmt.Sprintf("Space and repository identifiers cannot end with %q.", illegalRepoSpaceIdentifierSuffix), } ) @@ -99,15 +107,29 @@ func ForControlCharacters(s string) error { return nil } -// UID checks the provided uid and returns an error if it isn't valid. -func UID(uid string) error { - l := len(uid) - if l < minUIDLength || l > MaxUIDLength { - return ErrUIDLength +// Identifier checks the provided identifier and returns an error if it isn't valid. +func Identifier(identifier string) error { + l := len(identifier) + if l < minIdentifierLength || l > MaxIdentifierLength { + return ErrIdentifierLength } - if ok, _ := regexp.Match(uidRegex, []byte(uid)); !ok { - return ErrUIDRegex + if ok, _ := regexp.Match(identifierRegex, []byte(identifier)); !ok { + return ErrIdentifierRegex + } + + return nil +} + +// RepoIdentifier performs the default Identifier check and also blocks illegal repo identifiers. +func RepoIdentifier(identifier string) error { + if err := Identifier(identifier); err != nil { + return err + } + + identifierLower := strings.ToLower(identifier) + if strings.HasSuffix(identifierLower, illegalRepoSpaceIdentifierSuffix) { + return ErrIllegalRepoSpaceIdentifierSuffix } return nil @@ -119,25 +141,29 @@ type PrincipalUID func(uid string) error // PrincipalUIDDefault performs the default Principal UID check. func PrincipalUIDDefault(uid string) error { - return UID(uid) + return Identifier(uid) } -// PathUID is an abstraction of a validation method that returns true -// iff the UID is valid to be used in a resource path for repo/space. +// SpaceIdentifier is an abstraction of a validation method that returns true +// iff the Identifier is valid to be used in a resource path for repo/space. // NOTE: Enables support for different path formats. -type PathUID func(uid string, isRoot bool) error +type SpaceIdentifier func(identifier string, isRoot bool) error -// PathUIDDefault performs the default UID check and also blocks illegal root space UIDs. -func PathUIDDefault(uid string, isRoot bool) error { - if err := UID(uid); err != nil { +// SpaceIdentifierDefault performs the default Identifier check and also blocks illegal root space Identifiers. +func SpaceIdentifierDefault(identifier string, isRoot bool) error { + if err := Identifier(identifier); err != nil { return err } + identifierLower := strings.ToLower(identifier) + if strings.HasSuffix(identifierLower, illegalRepoSpaceIdentifierSuffix) { + return ErrIllegalRepoSpaceIdentifierSuffix + } + if isRoot { - uidLower := strings.ToLower(uid) - for _, p := range illegalRootSpaceUIDs { - if p == uidLower { - return ErrIllegalRootSpaceUID + for _, p := range illegalRootSpaceIdentifiers { + if p == identifierLower { + return ErrIllegalRootSpaceIdentifier } } } diff --git a/types/check/path.go b/types/check/path.go index ad79a4b13..93c983423 100644 --- a/types/check/path.go +++ b/types/check/path.go @@ -43,7 +43,7 @@ var ( ) // Path checks the provided path and returns an error in it isn't valid. -func Path(path string, isSpace bool, uidCheck PathUID) error { +func Path(path string, isSpace bool, identifierCheck SpaceIdentifier) error { if path == "" { return ErrPathEmpty } @@ -58,12 +58,12 @@ func Path(path string, isSpace bool, uidCheck PathUID) error { return err } - // ensure all segments of the path are valid uids + // ensure all segments of the path are valid identifiers segments := strings.Split(path, types.PathSeparator) for i, s := range segments { if s == "" { return ErrEmptyPathSegment - } else if err := uidCheck(s, i == 0); err != nil { + } else if err := identifierCheck(s, i == 0); err != nil { return fmt.Errorf("invalid segment '%s': %w", s, err) } } diff --git a/types/check/wire.go b/types/check/wire.go index dae0f66fa..a6c251427 100644 --- a/types/check/wire.go +++ b/types/check/wire.go @@ -21,11 +21,11 @@ import ( // WireSet provides a wire set for this package. var WireSet = wire.NewSet( ProvidePrincipalUIDCheck, - ProvidePathUIDCheck, + ProvideSpaceIdentifierCheck, ) -func ProvidePathUIDCheck() PathUID { - return PathUIDDefault +func ProvideSpaceIdentifierCheck() SpaceIdentifier { + return SpaceIdentifierDefault } func ProvidePrincipalUIDCheck() PrincipalUID { diff --git a/types/connector.go b/types/connector.go index 30c7cccf4..51fa07a20 100644 --- a/types/connector.go +++ b/types/connector.go @@ -14,14 +14,29 @@ package types +import "encoding/json" + type Connector struct { - ID int64 `db:"connector_id" json:"id"` + ID int64 `db:"connector_id" json:"-"` Description string `db:"connector_description" json:"description"` SpaceID int64 `db:"connector_space_id" json:"space_id"` - UID string `db:"connector_uid" json:"uid"` + Identifier string `db:"connector_uid" json:"identifier"` Type string `db:"connector_type" json:"type"` Data string `db:"connector_data" json:"data"` Created int64 `db:"connector_created" json:"created"` Updated int64 `db:"connector_updated" json:"updated"` Version int64 `db:"connector_version" json:"-"` } + +// TODO [CODE-1363]: remove after identifier migration. +func (s Connector) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Connector + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(s), + UID: s.Identifier, + }) +} diff --git a/types/enum/common.go b/types/enum/common.go index 26d1c0473..e89215f4f 100644 --- a/types/enum/common.go +++ b/types/enum/common.go @@ -33,8 +33,10 @@ func Sanitize[E constraints.Ordered](element E, all func() ([]E, E)) (E, bool) { } const ( - id = "id" + id = "id" + // TODO [CODE-1363]: remove after identifier migration. uid = "uid" + identifier = "identifier" path = "path" name = "name" email = "email" diff --git a/types/enum/membership.go b/types/enum/membership.go index e39ac8d97..387dfd212 100644 --- a/types/enum/membership.go +++ b/types/enum/membership.go @@ -70,12 +70,16 @@ type MembershipSpaceSort string // MembershipSpaceSort enumeration. const ( - MembershipSpaceSortUID MembershipSpaceSort = uid - MembershipSpaceSortCreated MembershipSpaceSort = created + // TODO [CODE-1363]: remove after identifier migration. + MembershipSpaceSortUID MembershipSpaceSort = uid + MembershipSpaceSortIdentifier MembershipSpaceSort = identifier + MembershipSpaceSortCreated MembershipSpaceSort = created ) var membershipSpaceSorts = sortEnum([]MembershipSpaceSort{ + // TODO [CODE-1363]: remove after identifier migration. MembershipSpaceSortUID, + MembershipSpaceSortIdentifier, MembershipSpaceSortCreated, }) @@ -84,27 +88,34 @@ func (s MembershipSpaceSort) Sanitize() (MembershipSpaceSort, bool) { return Sanitize(s, GetAllMembershipSpaceSorts) } func GetAllMembershipSpaceSorts() ([]MembershipSpaceSort, MembershipSpaceSort) { - return membershipSpaceSorts, MembershipSpaceSortUID + // TODO [CODE-1363]: remove after identifier migration. + return membershipSpaceSorts, MembershipSpaceSortIdentifier } // ParseMembershipSpaceSort parses the membership space sort attribute string // and returns the equivalent enumeration. func ParseMembershipSpaceSort(s string) MembershipSpaceSort { switch strings.ToLower(s) { - case name: + case name, identifier: + return MembershipSpaceSortIdentifier + // TODO [CODE-1363]: remove after identifier migration. + case uid: return MembershipSpaceSortUID case created, createdAt: return MembershipSpaceSortCreated default: - return MembershipSpaceSortUID + return MembershipSpaceSortIdentifier } } // String returns the string representation of the attribute. func (s MembershipSpaceSort) String() string { switch s { + // TODO [CODE-1363]: remove after identifier migration. case MembershipSpaceSortUID: return uid + case MembershipSpaceSortIdentifier: + return identifier case MembershipSpaceSortCreated: return created default: diff --git a/types/enum/repo.go b/types/enum/repo.go index c6c3ea00a..1259cba64 100644 --- a/types/enum/repo.go +++ b/types/enum/repo.go @@ -24,7 +24,9 @@ type RepoAttr int // Order enumeration. const ( RepoAttrNone RepoAttr = iota + // TODO [CODE-1363]: remove after identifier migration. RepoAttrUID + RepoAttrIdentifier RepoAttrCreated RepoAttrUpdated ) @@ -33,8 +35,11 @@ const ( // and returns the equivalent enumeration. func ParseRepoAttr(s string) RepoAttr { switch strings.ToLower(s) { + // TODO [CODE-1363]: remove after identifier migration. case uid: return RepoAttrUID + case identifier: + return RepoAttrIdentifier case created, createdAt: return RepoAttrCreated case updated, updatedAt: @@ -47,8 +52,11 @@ func ParseRepoAttr(s string) RepoAttr { // String returns the string representation of the attribute. func (a RepoAttr) String() string { switch a { + // TODO [CODE-1363]: remove after identifier migration. case RepoAttrUID: return uid + case RepoAttrIdentifier: + return identifier case RepoAttrCreated: return created case RepoAttrUpdated: diff --git a/types/enum/rule.go b/types/enum/rule.go index 5a59a3742..0c54def56 100644 --- a/types/enum/rule.go +++ b/types/enum/rule.go @@ -46,13 +46,17 @@ func GetAllRuleStates() ([]RuleState, RuleState) { type RuleSort string const ( - RuleSortUID RuleSort = uid - RuleSortCreated RuleSort = createdAt - RuleSortUpdated RuleSort = updatedAt + // TODO [CODE-1363]: remove after identifier migration. + RuleSortUID RuleSort = uid + RuleSortIdentifier RuleSort = identifier + RuleSortCreated RuleSort = createdAt + RuleSortUpdated RuleSort = updatedAt ) var ruleSorts = sortEnum([]RuleSort{ + // TODO [CODE-1363]: remove after identifier migration. RuleSortUID, + RuleSortIdentifier, RuleSortCreated, RuleSortUpdated, }) @@ -68,11 +72,14 @@ func GetAllRuleSorts() ([]RuleSort, RuleSort) { // ParseRuleSortAttr parses the protection rule sorting option. func ParseRuleSortAttr(s string) RuleSort { switch strings.ToLower(s) { + // TODO [CODE-1363]: remove after identifier migration. + case uid: + return RuleSortUID case created, createdAt: return RuleSortCreated case updated, updatedAt: return RuleSortUpdated } - return RuleSortUID + return RuleSortIdentifier } diff --git a/types/enum/space.go b/types/enum/space.go index a3d9b2a67..ad90f6a24 100644 --- a/types/enum/space.go +++ b/types/enum/space.go @@ -22,7 +22,9 @@ type SpaceAttr int // Order enumeration. const ( SpaceAttrNone SpaceAttr = iota + // TODO [CODE-1363]: remove after identifier migration. SpaceAttrUID + SpaceAttrIdentifier SpaceAttrCreated SpaceAttrUpdated ) @@ -31,8 +33,11 @@ const ( // and returns the equivalent enumeration. func ParseSpaceAttr(s string) SpaceAttr { switch strings.ToLower(s) { + // TODO [CODE-1363]: remove after identifier migration. case uid: return SpaceAttrUID + case identifier: + return SpaceAttrIdentifier case created, createdAt: return SpaceAttrCreated case updated, updatedAt: @@ -45,8 +50,11 @@ func ParseSpaceAttr(s string) SpaceAttr { // String returns the string representation of the attribute. func (a SpaceAttr) String() string { switch a { + // TODO [CODE-1363]: remove after identifier migration. case SpaceAttrUID: return uid + case SpaceAttrIdentifier: + return identifier case SpaceAttrCreated: return created case SpaceAttrUpdated: diff --git a/types/enum/webhook.go b/types/enum/webhook.go index c886e0f8c..c9cda11a2 100644 --- a/types/enum/webhook.go +++ b/types/enum/webhook.go @@ -21,8 +21,12 @@ type WebhookAttr int const ( WebhookAttrNone WebhookAttr = iota + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. WebhookAttrID + // TODO [CODE-1363]: remove after identifier migration. WebhookAttrUID + WebhookAttrIdentifier + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. WebhookAttrDisplayName WebhookAttrCreated WebhookAttrUpdated @@ -32,10 +36,15 @@ const ( // and returns the equivalent enumeration. func ParseWebhookAttr(s string) WebhookAttr { switch strings.ToLower(s) { + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. case id: return WebhookAttrID + // TODO [CODE-1363]: remove after identifier migration. case uid: return WebhookAttrUID + case identifier: + return WebhookAttrIdentifier + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. case displayName: return WebhookAttrDisplayName case created, createdAt: @@ -50,10 +59,15 @@ func ParseWebhookAttr(s string) WebhookAttr { // String returns the string representation of the attribute. func (a WebhookAttr) String() string { switch a { + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. case WebhookAttrID: return id + // TODO [CODE-1363]: remove after identifier migration. case WebhookAttrUID: return uid + case WebhookAttrIdentifier: + return identifier + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. case WebhookAttrDisplayName: return displayName case WebhookAttrCreated: diff --git a/types/path.go b/types/path.go index 95b9878bc..e133a7224 100644 --- a/types/path.go +++ b/types/path.go @@ -14,6 +14,8 @@ package types +import "encoding/json" + const ( PathSeparator = "/" ) @@ -28,12 +30,25 @@ type SpacePath struct { // SpacePathSegment represents a segment of a path to a space. type SpacePathSegment struct { // TODO: int64 ID doesn't match DB - ID int64 `json:"id"` - UID string `json:"uid"` - IsPrimary bool `json:"is_primary"` - SpaceID int64 `json:"space_id"` - ParentID int64 `json:"parent_id"` - CreatedBy int64 `json:"created_by"` - Created int64 `json:"created"` - Updated int64 `json:"updated"` + ID int64 `json:"-"` + Identifier string `json:"identifier"` + IsPrimary bool `json:"is_primary"` + SpaceID int64 `json:"space_id"` + ParentID int64 `json:"parent_id"` + CreatedBy int64 `json:"created_by"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` +} + +// TODO [CODE-1363]: remove after identifier migration. +func (s SpacePathSegment) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias SpacePathSegment + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(s), + UID: s.Identifier, + }) } diff --git a/types/pipeline.go b/types/pipeline.go index a1746c1c8..edd7fc075 100644 --- a/types/pipeline.go +++ b/types/pipeline.go @@ -14,10 +14,12 @@ package types +import "encoding/json" + type Pipeline struct { - ID int64 `db:"pipeline_id" json:"id"` + ID int64 `db:"pipeline_id" json:"-"` Description string `db:"pipeline_description" json:"description"` - UID string `db:"pipeline_uid" json:"uid"` + Identifier string `db:"pipeline_uid" json:"identifier"` Disabled bool `db:"pipeline_disabled" json:"disabled"` CreatedBy int64 `db:"pipeline_created_by" json:"created_by"` // Seq is the last execution number for this pipeline @@ -31,3 +33,16 @@ type Pipeline struct { Updated int64 `db:"pipeline_updated" json:"updated"` Version int64 `db:"pipeline_version" json:"-"` } + +// TODO [CODE-1363]: remove after identifier migration. +func (s Pipeline) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Pipeline + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(s), + UID: s.Identifier, + }) +} diff --git a/types/plugin.go b/types/plugin.go index 0efcaf1cb..163335fdb 100644 --- a/types/plugin.go +++ b/types/plugin.go @@ -14,11 +14,13 @@ package types +import "encoding/json" + // Plugin represents a Harness plugin. It has an associated template stored // in the spec field. The spec is used by the UI to provide a smart visual // editor for adding plugins to YAML schema. type Plugin struct { - UID string `db:"plugin_uid" json:"uid"` + Identifier string `db:"plugin_uid" json:"identifier"` Description string `db:"plugin_description" json:"description"` // Currently we only support step level plugins but more can be added in the future. Type string `db:"plugin_type" json:"type"` @@ -31,21 +33,34 @@ type Plugin struct { // Matches checks whether two plugins are identical. // We can use reflection here, this is just easier to add on to // when needed. -func (plugin *Plugin) Matches(v *Plugin) bool { - if plugin.UID != v.UID { +func (p *Plugin) Matches(v *Plugin) bool { + if p.Identifier != v.Identifier { return false } - if plugin.Description != v.Description { + if p.Description != v.Description { return false } - if plugin.Spec != v.Spec { + if p.Spec != v.Spec { return false } - if plugin.Version != v.Version { + if p.Version != v.Version { return false } - if plugin.Logo != v.Logo { + if p.Logo != v.Logo { return false } return true } + +// TODO [CODE-1363]: remove after identifier migration. +func (p Plugin) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Plugin + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(p), + UID: p.Identifier, + }) +} diff --git a/types/repo.go b/types/repo.go index 102fae9e5..ad333f224 100644 --- a/types/repo.go +++ b/types/repo.go @@ -15,6 +15,8 @@ package types import ( + "encoding/json" + "github.com/harness/gitness/types/enum" ) @@ -24,7 +26,7 @@ type Repository struct { ID int64 `json:"id"` Version int64 `json:"-"` ParentID int64 `json:"parent_id"` - UID string `json:"uid"` + Identifier string `json:"identifier"` Path string `json:"path"` Description string `json:"description"` IsPublic bool `json:"is_public"` @@ -52,6 +54,19 @@ type Repository struct { GitURL string `json:"git_url"` } +// TODO [CODE-1363]: remove after identifier migration. +func (r Repository) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Repository + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(r), + UID: r.Identifier, + }) +} + type RepositorySizeInfo struct { ID int64 `json:"id"` GitUID string `json:"git_uid"` diff --git a/types/rule.go b/types/rule.go index 63aa5c713..59ed81a85 100644 --- a/types/rule.go +++ b/types/rule.go @@ -32,7 +32,7 @@ type Rule struct { RepoID *int64 `json:"-"` SpaceID *int64 `json:"-"` - UID string `json:"uid"` + Identifier string `json:"identifier"` Description string `json:"description"` Type RuleType `json:"type"` @@ -46,6 +46,19 @@ type Rule struct { Users map[int64]*PrincipalInfo `json:"users"` } +// TODO [CODE-1363]: remove after identifier migration. +func (r Rule) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Rule + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(r), + UID: r.Identifier, + }) +} + type RuleType string type RuleFilter struct { @@ -95,10 +108,23 @@ type RuleInfo struct { SpacePath string `json:"space_path,omitempty"` RepoPath string `json:"repo_path,omitempty"` - ID int64 `json:"-"` - UID string `json:"uid"` - Type RuleType `json:"type"` - State enum.RuleState `json:"state"` + ID int64 `json:"-"` + Identifier string `json:"identifier"` + Type RuleType `json:"type"` + State enum.RuleState `json:"state"` +} + +// TODO [CODE-1363]: remove after identifier migration. +func (r RuleInfo) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias RuleInfo + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(r), + UID: r.Identifier, + }) } type RuleInfoInternal struct { diff --git a/types/secret.go b/types/secret.go index 8fcf124fc..3e3b9361c 100644 --- a/types/secret.go +++ b/types/secret.go @@ -14,24 +14,39 @@ package types +import "encoding/json" + type Secret struct { - ID int64 `db:"secret_id" json:"id"` + ID int64 `db:"secret_id" json:"-"` Description string `db:"secret_description" json:"description"` SpaceID int64 `db:"secret_space_id" json:"space_id"` CreatedBy int64 `db:"secret_created_by" json:"created_by"` - UID string `db:"secret_uid" json:"uid"` + Identifier string `db:"secret_uid" json:"identifier"` 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:"-"` } +// TODO [CODE-1363]: remove after identifier migration. +func (s Secret) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Secret + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(s), + UID: s.Identifier, + }) +} + // Copy makes a copy of the secret without the value. func (s *Secret) CopyWithoutData() *Secret { return &Secret{ ID: s.ID, Description: s.Description, - UID: s.UID, + Identifier: s.Identifier, SpaceID: s.SpaceID, Created: s.Created, Updated: s.Updated, diff --git a/types/space.go b/types/space.go index 987b4dd5a..b752a8fd3 100644 --- a/types/space.go +++ b/types/space.go @@ -15,6 +15,8 @@ package types import ( + "encoding/json" + "github.com/harness/gitness/types/enum" ) @@ -22,9 +24,9 @@ import ( Space represents a space. There isn't a one-solves-all hierarchical data structure for DBs, so for now we are using a mix of materialized paths and adjacency list. -Every space stores its parent, and a space's path is stored in a separate table. -PRO: Quick lookup of childs, quick lookup based on fqdn (apis) -CON: Changing a space uid requires changing all its ancestors' Paths. +Every space stores its parent, and a space's path (and aliases) is stored in a separate table. +PRO: Quick lookup of childs, quick lookup based on fqdn (apis). +CON: we require a separate table. Interesting reads: https://stackoverflow.com/questions/4048151/what-are-the-options-for-storing-hierarchical-data-in-a-relational-database @@ -35,7 +37,7 @@ type Space struct { Version int64 `json:"-"` ParentID int64 `json:"parent_id"` Path string `json:"path"` - UID string `json:"uid"` + Identifier string `json:"identifier"` Description string `json:"description"` IsPublic bool `json:"is_public"` CreatedBy int64 `json:"created_by"` @@ -43,6 +45,19 @@ type Space struct { Updated int64 `json:"updated"` } +// TODO [CODE-1363]: remove after identifier migration. +func (s Space) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Space + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(s), + UID: s.Identifier, + }) +} + // Stores spaces query parameters. type SpaceFilter struct { Page int `json:"page"` diff --git a/types/template.go b/types/template.go index bc5d40e7c..c2d825cf7 100644 --- a/types/template.go +++ b/types/template.go @@ -14,16 +14,33 @@ package types -import "github.com/harness/gitness/types/enum" +import ( + "encoding/json" + + "github.com/harness/gitness/types/enum" +) type Template struct { - ID int64 `db:"template_id" json:"id"` + ID int64 `db:"template_id" json:"-"` Description string `db:"template_description" json:"description"` Type enum.ResolverType `db:"template_type" json:"type"` SpaceID int64 `db:"template_space_id" json:"space_id"` - UID string `db:"template_uid" json:"uid"` + Identifier string `db:"template_uid" json:"identifier"` Data string `db:"template_data" json:"data"` Created int64 `db:"template_created" json:"created"` Updated int64 `db:"template_updated" json:"updated"` Version int64 `db:"template_version" json:"-"` } + +// TODO [CODE-1363]: remove after identifier migration. +func (t Template) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Template + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(t), + UID: t.Identifier, + }) +} diff --git a/types/token.go b/types/token.go index ef86156f4..1653c7750 100644 --- a/types/token.go +++ b/types/token.go @@ -15,6 +15,8 @@ package types import ( + "encoding/json" + "github.com/harness/gitness/types/enum" ) @@ -24,7 +26,7 @@ type Token struct { ID int64 `db:"token_id" json:"-"` PrincipalID int64 `db:"token_principal_id" json:"principal_id"` Type enum.TokenType `db:"token_type" json:"type"` - UID string `db:"token_uid" json:"uid"` + Identifier string `db:"token_uid" json:"identifier"` // ExpiresAt is an optional unix time that if specified restricts the validity of a token. ExpiresAt *int64 `db:"token_expires_at" json:"expires_at,omitempty"` // IssuedAt is the unix time at which the token was issued. @@ -32,6 +34,19 @@ type Token struct { CreatedBy int64 `db:"token_created_by" json:"created_by"` } +// TODO [CODE-1363]: remove after identifier migration. +func (t Token) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Token + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(t), + UID: t.Identifier, + }) +} + // TokenResponse is returned as part of token creation for PAT / SAT / User Session. type TokenResponse struct { AccessToken string `json:"access_token"` diff --git a/types/trigger.go b/types/trigger.go index b384a30a6..113c68740 100644 --- a/types/trigger.go +++ b/types/trigger.go @@ -14,10 +14,14 @@ package types -import "github.com/harness/gitness/types/enum" +import ( + "encoding/json" + + "github.com/harness/gitness/types/enum" +) type Trigger struct { - ID int64 `json:"id"` + ID int64 `json:"-"` Description string `json:"description"` Type string `json:"trigger_type"` PipelineID int64 `json:"pipeline_id"` @@ -26,8 +30,21 @@ type Trigger struct { CreatedBy int64 `json:"created_by"` Disabled bool `json:"disabled"` Actions []enum.TriggerAction `json:"actions"` - UID string `json:"uid"` + Identifier string `json:"identifier"` Created int64 `json:"created"` Updated int64 `json:"updated"` Version int64 `json:"-"` } + +// TODO [CODE-1363]: remove after identifier migration. +func (s Trigger) MarshalJSON() ([]byte, error) { + // alias allows us to embed the original object while avoiding an infinite loop of marshaling. + type alias Trigger + return json.Marshal(&struct { + alias + UID string `json:"uid"` + }{ + alias: (alias)(s), + UID: s.Identifier, + }) +} diff --git a/types/usergroup.go b/types/usergroup.go index edb9e8aa6..e6ba4f714 100644 --- a/types/usergroup.go +++ b/types/usergroup.go @@ -16,7 +16,7 @@ package types type UserGroup struct { - ID string `json:"id"` + Identifier string `json:"identifier"` Name string `json:"name"` Description string `json:"description"` Users []string diff --git a/types/webhook.go b/types/webhook.go index 2abf5d474..7e6c48d4a 100644 --- a/types/webhook.go +++ b/types/webhook.go @@ -22,6 +22,7 @@ import ( // Webhook represents a webhook. type Webhook struct { + // TODO [CODE-1364]: Hide once UID/Identifier migration is completed. ID int64 `json:"id"` Version int64 `json:"version"` ParentID int64 `json:"parent_id"` @@ -31,8 +32,8 @@ type Webhook struct { Updated int64 `json:"updated"` Internal bool `json:"-"` - UID string `json:"uid"` - // TODO: Remove once UID migration is completed. + Identifier string `json:"identifier"` + // TODO [CODE-1364]: Remove once UID/Identifier migration is completed. DisplayName string `json:"display_name"` Description string `json:"description"` URL string `json:"url"` @@ -55,9 +56,13 @@ func (w *Webhook) MarshalJSON() ([]byte, error) { return json.Marshal(&struct { *WebhookAlias HasSecret bool `json:"has_secret"` + // TODO [CODE-1363]: remove after identifier migration. + UID string `json:"uid"` }{ WebhookAlias: (*WebhookAlias)(w), HasSecret: w != nil && w.Secret != "", + // TODO [CODE-1363]: remove after identifier migration. + UID: w.Identifier, }) }