mirror of https://github.com/go-gitea/gitea
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>pull/9731/head^2
parent
6b1fa12359
commit
66ee9b87f9
@ -0,0 +1,18 @@ |
|||||||
|
// 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 migrations |
||||||
|
|
||||||
|
import ( |
||||||
|
"xorm.io/xorm" |
||||||
|
) |
||||||
|
|
||||||
|
func addRequireSignedCommits(x *xorm.Engine) error { |
||||||
|
|
||||||
|
type ProtectedBranch struct { |
||||||
|
RequireSignedCommits bool `xorm:"NOT NULL DEFAULT false"` |
||||||
|
} |
||||||
|
|
||||||
|
return x.Sync2(new(ProtectedBranch)) |
||||||
|
} |
@ -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…
Reference in new issue