forked from forgejo/forgejo
Add require signed commit for protected branch (#9708)
* Add require signed commit for protected branch * Fix fmt * Make editor show if they will be signed * bugfix * Add basic merge check and better information for CRUD * linting comment * Add descriptors to merge signing * Slight refactor * Slight improvement to appearances * Handle Merge API * manage CRUD API * Move error to error.go * Remove fix to delete.go * prep for merge * need to tolerate \r\n in message * check protected branch before trying to load it * Apply suggestions from code review Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * fix commit-reader Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
This commit is contained in:
parent
6b1fa12359
commit
66ee9b87f9
29 changed files with 618 additions and 122 deletions
|
@ -97,7 +97,7 @@ func (c *Command) RunInDirTimeoutEnvFullPipeline(env []string, timeout time.Dura
|
|||
|
||||
// RunInDirTimeoutEnvFullPipelineFunc executes the command in given directory with given timeout,
|
||||
// it pipes stdout and stderr to given io.Writer and passes in an io.Reader as stdin. Between cmd.Start and cmd.Wait the passed in function is run.
|
||||
func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time.Duration, dir string, stdout, stderr io.Writer, stdin io.Reader, fn func(context.Context, context.CancelFunc)) error {
|
||||
func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time.Duration, dir string, stdout, stderr io.Writer, stdin io.Reader, fn func(context.Context, context.CancelFunc) error) error {
|
||||
|
||||
if timeout == -1 {
|
||||
timeout = DefaultCommandExecutionTimeout
|
||||
|
@ -135,7 +135,11 @@ func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time.
|
|||
defer process.GetManager().Remove(pid)
|
||||
|
||||
if fn != nil {
|
||||
fn(ctx, cancel)
|
||||
err := fn(ctx, cancel)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := cmd.Wait(); err != nil && ctx.Err() != context.DeadlineExceeded {
|
||||
|
|
|
@ -33,7 +33,7 @@ type Commit struct {
|
|||
CommitMessage string
|
||||
Signature *CommitGPGSignature
|
||||
|
||||
parents []SHA1 // SHA1 strings
|
||||
Parents []SHA1 // SHA1 strings
|
||||
submoduleCache *ObjectCache
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ func convertCommit(c *object.Commit) *Commit {
|
|||
Committer: &c.Committer,
|
||||
Author: &c.Author,
|
||||
Signature: convertPGPSignature(c),
|
||||
parents: c.ParentHashes,
|
||||
Parents: c.ParentHashes,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,10 +111,10 @@ func (c *Commit) Summary() string {
|
|||
// ParentID returns oid of n-th parent (0-based index).
|
||||
// It returns nil if no such parent exists.
|
||||
func (c *Commit) ParentID(n int) (SHA1, error) {
|
||||
if n >= len(c.parents) {
|
||||
if n >= len(c.Parents) {
|
||||
return SHA1{}, ErrNotExist{"", ""}
|
||||
}
|
||||
return c.parents[n], nil
|
||||
return c.Parents[n], nil
|
||||
}
|
||||
|
||||
// Parent returns n-th parent (0-based index) of the commit.
|
||||
|
@ -133,7 +133,7 @@ func (c *Commit) Parent(n int) (*Commit, error) {
|
|||
// ParentCount returns number of parents of the commit.
|
||||
// 0 if this is the root commit, otherwise 1,2, etc.
|
||||
func (c *Commit) ParentCount() int {
|
||||
return len(c.parents)
|
||||
return len(c.Parents)
|
||||
}
|
||||
|
||||
func isImageFile(data []byte) (string, bool) {
|
||||
|
|
108
modules/git/commit_reader.go
Normal file
108
modules/git/commit_reader.go
Normal file
|
@ -0,0 +1,108 @@
|
|||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package git
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
)
|
||||
|
||||
// CommitFromReader will generate a Commit from a provided reader
|
||||
// We will need this to interpret commits from cat-file
|
||||
func CommitFromReader(gitRepo *Repository, sha plumbing.Hash, reader io.Reader) (*Commit, error) {
|
||||
commit := &Commit{
|
||||
ID: sha,
|
||||
}
|
||||
|
||||
payloadSB := new(strings.Builder)
|
||||
signatureSB := new(strings.Builder)
|
||||
messageSB := new(strings.Builder)
|
||||
message := false
|
||||
pgpsig := false
|
||||
|
||||
scanner := bufio.NewScanner(reader)
|
||||
// Split by '\n' but include the '\n'
|
||||
scanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||
if atEOF && len(data) == 0 {
|
||||
return 0, nil, nil
|
||||
}
|
||||
if i := bytes.IndexByte(data, '\n'); i >= 0 {
|
||||
// We have a full newline-terminated line.
|
||||
return i + 1, data[0 : i+1], nil
|
||||
}
|
||||
// If we're at EOF, we have a final, non-terminated line. Return it.
|
||||
if atEOF {
|
||||
return len(data), data, nil
|
||||
}
|
||||
// Request more data.
|
||||
return 0, nil, nil
|
||||
})
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Bytes()
|
||||
if pgpsig {
|
||||
if len(line) > 0 && line[0] == ' ' {
|
||||
_, _ = signatureSB.Write(line[1:])
|
||||
continue
|
||||
} else {
|
||||
pgpsig = false
|
||||
}
|
||||
}
|
||||
|
||||
if !message {
|
||||
// This is probably not correct but is copied from go-gits interpretation...
|
||||
trimmed := bytes.TrimSpace(line)
|
||||
if len(trimmed) == 0 {
|
||||
message = true
|
||||
_, _ = payloadSB.Write(line)
|
||||
continue
|
||||
}
|
||||
|
||||
split := bytes.SplitN(trimmed, []byte{' '}, 2)
|
||||
var data []byte
|
||||
if len(split) > 1 {
|
||||
data = split[1]
|
||||
}
|
||||
|
||||
switch string(split[0]) {
|
||||
case "tree":
|
||||
commit.Tree = *NewTree(gitRepo, plumbing.NewHash(string(data)))
|
||||
_, _ = payloadSB.Write(line)
|
||||
case "parent":
|
||||
commit.Parents = append(commit.Parents, plumbing.NewHash(string(data)))
|
||||
_, _ = payloadSB.Write(line)
|
||||
case "author":
|
||||
commit.Author = &Signature{}
|
||||
commit.Author.Decode(data)
|
||||
_, _ = payloadSB.Write(line)
|
||||
case "committer":
|
||||
commit.Committer = &Signature{}
|
||||
commit.Committer.Decode(data)
|
||||
_, _ = payloadSB.Write(line)
|
||||
case "gpgsig":
|
||||
_, _ = signatureSB.Write(data)
|
||||
_ = signatureSB.WriteByte('\n')
|
||||
pgpsig = true
|
||||
}
|
||||
} else {
|
||||
_, _ = messageSB.Write(line)
|
||||
}
|
||||
}
|
||||
commit.CommitMessage = messageSB.String()
|
||||
_, _ = payloadSB.WriteString(commit.CommitMessage)
|
||||
commit.Signature = &CommitGPGSignature{
|
||||
Signature: signatureSB.String(),
|
||||
Payload: payloadSB.String(),
|
||||
}
|
||||
if len(commit.Signature.Signature) == 0 {
|
||||
commit.Signature = nil
|
||||
}
|
||||
|
||||
return commit, scanner.Err()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue