drone/app/api/controller/githook/pre_receive_process.go

159 lines
4.3 KiB
Go

// 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 githook
import (
"context"
"fmt"
"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/git"
"github.com/harness/gitness/git/hook"
"github.com/harness/gitness/types"
"github.com/gotidy/ptr"
)
func (c *Controller) processObjects(
ctx context.Context,
repo *types.RepositoryCore,
principal *types.Principal,
refUpdates changedRefs,
in types.GithookPreReceiveInput,
output *hook.Output,
) error {
if refUpdates.hasOnlyDeletedBranches() {
return nil
}
var sizeLimit int64
var err error
sizeLimit, err = settings.RepoGet(
ctx,
c.settings,
repo.ID,
settings.KeyFileSizeLimit,
settings.DefaultFileSizeLimit,
)
if err != nil {
return fmt.Errorf("failed to check settings for file size limit: %w", err)
}
principalCommitterMatch, err := settings.RepoGet(
ctx,
c.settings,
repo.ID,
settings.KeyPrincipalCommitterMatch,
settings.DefaultPrincipalCommitterMatch,
)
if err != nil {
return fmt.Errorf("failed to check settings for principal committer match: %w", err)
}
gitLFSEnabled, err := settings.RepoGet(
ctx,
c.settings,
repo.ID,
settings.KeyGitLFSEnabled,
settings.DefaultGitLFSEnabled,
)
if err != nil {
return fmt.Errorf("failed to check settings for Git LFS enabled: %w", err)
}
if sizeLimit == 0 && !principalCommitterMatch && !gitLFSEnabled {
return nil
}
preReceiveObjsIn := git.ProcessPreReceiveObjectsParams{
ReadParams: git.ReadParams{
RepoUID: repo.GitUID,
AlternateObjectDirs: in.Environment.AlternateObjectDirs,
},
}
if sizeLimit > 0 {
preReceiveObjsIn.FindOversizeFilesParams = &git.FindOversizeFilesParams{
SizeLimit: sizeLimit,
}
}
if principalCommitterMatch && principal != nil {
preReceiveObjsIn.FindCommitterMismatchParams = &git.FindCommitterMismatchParams{
PrincipalEmail: principal.Email,
}
}
if gitLFSEnabled {
preReceiveObjsIn.FindLFSPointersParams = &git.FindLFSPointersParams{}
}
preReceiveObjsOut, err := c.git.ProcessPreReceiveObjects(
ctx,
preReceiveObjsIn,
)
if err != nil {
return fmt.Errorf("failed to process pre-receive objects: %w", err)
}
if preReceiveObjsOut.FindOversizeFilesOutput != nil &&
len(preReceiveObjsOut.FindOversizeFilesOutput.FileInfos) > 0 {
output.Error = ptr.String("Changes blocked by files exceeding the file size limit")
printOversizeFiles(
output,
preReceiveObjsOut.FindOversizeFilesOutput.FileInfos,
preReceiveObjsOut.FindOversizeFilesOutput.Total,
sizeLimit,
)
}
if preReceiveObjsOut.FindCommitterMismatchOutput != nil &&
len(preReceiveObjsOut.FindCommitterMismatchOutput.CommitInfos) > 0 {
output.Error = ptr.String("Committer verification failed: authenticated user and committer must match")
printCommitterMismatch(
output,
preReceiveObjsOut.FindCommitterMismatchOutput.CommitInfos,
preReceiveObjsIn.FindCommitterMismatchParams.PrincipalEmail,
preReceiveObjsOut.FindCommitterMismatchOutput.Total,
)
}
if preReceiveObjsOut.FindLFSPointersOutput != nil &&
len(preReceiveObjsOut.FindLFSPointersOutput.LFSInfos) > 0 {
objIDs := make([]string, len(preReceiveObjsOut.FindLFSPointersOutput.LFSInfos))
for i, info := range preReceiveObjsOut.FindLFSPointersOutput.LFSInfos {
objIDs[i] = info.ObjID
}
existingObjs, err := c.lfsStore.FindMany(ctx, in.RepoID, objIDs)
if err != nil {
return fmt.Errorf("failed to find lfs objects: %w", err)
}
//nolint:lll
if len(existingObjs) != len(objIDs) {
output.Error = ptr.String(
"Changes blocked by unknown Git LFS objects. Please try `git lfs push --all` or check if LFS is setup properly.")
printLFSPointers(
output,
preReceiveObjsOut.FindLFSPointersOutput.LFSInfos,
preReceiveObjsOut.FindLFSPointersOutput.Total,
)
}
}
return nil
}