c572fcfe04
Rename the Go module path from code.gitea.io/gitea to git.mokoconsulting.tech/MokoConsulting/MokoGitea across the entire codebase. Scope: - go.mod module declaration - 2,235 Go source files (import paths) - Dockerfile WORKDIR and COPY paths - Swagger API templates - golangci.yml linter config External dependencies (code.gitea.io/gitea-vet, code.gitea.io/sdk/gitea, gitea.com/gitea/act, etc.) are intentionally NOT renamed — they are separate upstream modules. Closes #132 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
92 lines
3.0 KiB
Go
92 lines
3.0 KiB
Go
// Copyright 2021 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package private
|
|
|
|
import (
|
|
"bufio"
|
|
"io"
|
|
|
|
"git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/git"
|
|
"git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/git/gitcmd"
|
|
"git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/log"
|
|
asymkey_service "git.mokoconsulting.tech/MokoConsulting/MokoGitea/services/asymkey"
|
|
)
|
|
|
|
// This file contains commit verification functions for refs passed across in hooks
|
|
|
|
func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env []string) error {
|
|
var command *gitcmd.Command
|
|
objectFormat, _ := repo.GetObjectFormat()
|
|
if oldCommitID == objectFormat.EmptyObjectID().String() {
|
|
// When creating a new branch, the oldCommitID is empty, by using "newCommitID --not --all":
|
|
// List commits that are reachable by following the newCommitID, exclude "all" existing heads/tags commits
|
|
// So, it only lists the new commits received, doesn't list the commits already present in the receiving repository
|
|
command = gitcmd.NewCommand("rev-list").AddDynamicArguments(newCommitID).AddArguments("--not", "--all")
|
|
} else {
|
|
command = gitcmd.NewCommand("rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID)
|
|
}
|
|
// This is safe as force pushes are already forbidden
|
|
stdoutReader, stdoutReaderClose := command.MakeStdoutPipe()
|
|
defer stdoutReaderClose()
|
|
|
|
err := command.WithEnv(env).
|
|
WithDir(repo.Path).
|
|
WithPipelineFunc(func(ctx gitcmd.Context) error {
|
|
err := readAndVerifyCommitsFromShaReader(stdoutReader, repo, env)
|
|
return ctx.CancelPipeline(err)
|
|
}).
|
|
Run(repo.Ctx)
|
|
if err != nil && !isErrUnverifiedCommit(err) {
|
|
log.Error("Unable to check commits from %s to %s in %s: %v", oldCommitID, newCommitID, repo.Path, err)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func readAndVerifyCommitsFromShaReader(input io.ReadCloser, repo *git.Repository, env []string) error {
|
|
scanner := bufio.NewScanner(input)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
err := readAndVerifyCommit(line, repo, env)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return scanner.Err()
|
|
}
|
|
|
|
func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
|
|
commitID := git.MustIDFromString(sha)
|
|
cmd := gitcmd.NewCommand("cat-file", "commit").AddDynamicArguments(sha)
|
|
stdoutReader, stdoutReaderClose := cmd.MakeStdoutPipe()
|
|
defer stdoutReaderClose()
|
|
|
|
return cmd.WithEnv(env).
|
|
WithDir(repo.Path).
|
|
WithPipelineFunc(func(ctx gitcmd.Context) error {
|
|
commit, err := git.CommitFromReader(repo, commitID, stdoutReader)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
verification := asymkey_service.ParseCommitWithSignature(ctx, commit)
|
|
if !verification.Verified {
|
|
return ctx.CancelPipeline(&errUnverifiedCommit{commit.ID.String()})
|
|
}
|
|
return nil
|
|
}).
|
|
Run(repo.Ctx)
|
|
}
|
|
|
|
type errUnverifiedCommit struct {
|
|
sha string
|
|
}
|
|
|
|
func (e *errUnverifiedCommit) Error() string {
|
|
return "Unverified commit: " + e.sha
|
|
}
|
|
|
|
func isErrUnverifiedCommit(err error) bool {
|
|
_, ok := err.(*errUnverifiedCommit)
|
|
return ok
|
|
}
|