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