Skip to content

Commit

Permalink
Merge remote-tracking branch 'giteaofficial/main'
Browse files Browse the repository at this point in the history
* giteaofficial/main:
  Abstract hash function usage (go-gitea#28138)
  Add endpoint for not implemented Docker auth (go-gitea#28457)
  docs: Update group membership fields to match application. (go-gitea#28175)
  • Loading branch information
zjjhot committed Dec 14, 2023
2 parents b4a4443 + cbf923e commit cb0c502
Show file tree
Hide file tree
Showing 125 changed files with 969 additions and 602 deletions.
7 changes: 5 additions & 2 deletions cmd/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,9 @@ Gitea or set your environment appropriately.`, "")
oldCommitIDs[count] = string(fields[0])
newCommitIDs[count] = string(fields[1])
refFullNames[count] = git.RefName(fields[2])
if refFullNames[count] == git.BranchPrefix+"master" && newCommitIDs[count] != git.EmptySHA && count == total {

commitID, _ := git.IDFromString(newCommitIDs[count])
if refFullNames[count] == git.BranchPrefix+"master" && !commitID.IsZero() && count == total {
masterPushed = true
}
count++
Expand Down Expand Up @@ -669,7 +671,8 @@ Gitea or set your environment appropriately.`, "")
if err != nil {
return err
}
if rs.OldOID != git.EmptySHA {
commitID, _ := git.IDFromString(rs.OldOID)
if !commitID.IsZero() {
err = writeDataPktLine(ctx, os.Stdout, []byte("option old-oid "+rs.OldOID))
if err != nil {
return err
Expand Down
18 changes: 9 additions & 9 deletions docs/content/usage/authentication.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,25 +145,25 @@ Adds the following fields:

Uses the following fields:

- Group Search Base (optional)
- Group Search Base DN (optional)

- The LDAP DN used for groups.
- Example: `ou=group,dc=mydomain,dc=com`

- Group Name Filter (optional)

- An LDAP filter declaring how to find valid groups in the above DN.
- Example: `(|(cn=gitea_users)(cn=admins))`
- Group Attribute Containing List Of Users (optional)
- The attribute of the group object that lists/contains the group members.
- Example: `memberUid` or `member`

- User Attribute in Group (optional)
- User Attribute Listed in Group (optional)

- The user attribute that is used to reference a user in the group object.
- Example: `uid` if the group objects contains a `member: bender` and the user object contains a `uid: bender`.
- Example: `dn` if the group object contains a `member: uid=bender,ou=users,dc=planetexpress,dc=com`.

- Group Attribute for User (optional)
- The attribute of the group object that lists/contains the group members.
- Example: `memberUid` or `member`
- Verify group membership in LDAP (optional)

- An LDAP filter declaring how to find valid groups in the above DN.
- Example: `(|(cn=gitea_users)(cn=admins))`

## PAM (Pluggable Authentication Module)

Expand Down
2 changes: 1 addition & 1 deletion models/git/branch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestAddDeletedBranch(t *testing.T) {
assert.True(t, secondBranch.IsDeleted)

commit := &git.Commit{
ID: git.MustIDFromString(secondBranch.CommitID),
ID: repo.ObjectFormat.MustIDFromString(secondBranch.CommitID),
CommitMessage: secondBranch.CommitMessage,
Committer: &git.Signature{
When: secondBranch.CommitTime.AsLocalTime(),
Expand Down
13 changes: 5 additions & 8 deletions models/git/commit_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ WHEN NOT MATCHED

// GetNextCommitStatusIndex retried 3 times to generate a resource index
func GetNextCommitStatusIndex(ctx context.Context, repoID int64, sha string) (int64, error) {
if !git.IsValidSHAPattern(sha) {
_, err := git.IDFromString(sha)
if err != nil {
return 0, git.ErrInvalidSHA{SHA: sha}
}

Expand Down Expand Up @@ -425,7 +426,7 @@ func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, befor
type NewCommitStatusOptions struct {
Repo *repo_model.Repository
Creator *user_model.User
SHA string
SHA git.ObjectID
CommitStatus *CommitStatus
}

Expand All @@ -440,26 +441,22 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error {
return fmt.Errorf("NewCommitStatus[%s, %s]: no user specified", repoPath, opts.SHA)
}

if _, err := git.NewIDFromString(opts.SHA); err != nil {
return fmt.Errorf("NewCommitStatus[%s, %s]: invalid sha: %w", repoPath, opts.SHA, err)
}

ctx, committer, err := db.TxContext(ctx)
if err != nil {
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", opts.Repo.ID, opts.Creator.ID, opts.SHA, err)
}
defer committer.Close()

// Get the next Status Index
idx, err := GetNextCommitStatusIndex(ctx, opts.Repo.ID, opts.SHA)
idx, err := GetNextCommitStatusIndex(ctx, opts.Repo.ID, opts.SHA.String())
if err != nil {
return fmt.Errorf("generate commit status index failed: %w", err)
}

opts.CommitStatus.Description = strings.TrimSpace(opts.CommitStatus.Description)
opts.CommitStatus.Context = strings.TrimSpace(opts.CommitStatus.Context)
opts.CommitStatus.TargetURL = strings.TrimSpace(opts.CommitStatus.TargetURL)
opts.CommitStatus.SHA = opts.SHA
opts.CommitStatus.SHA = opts.SHA.String()
opts.CommitStatus.CreatorID = opts.Creator.ID
opts.CommitStatus.RepoID = opts.Repo.ID
opts.CommitStatus.Index = idx
Expand Down
6 changes: 5 additions & 1 deletion models/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
Expand Down Expand Up @@ -179,6 +180,7 @@ type Repository struct {
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"`
Topics []string `xorm:"TEXT JSON"`
ObjectFormat git.ObjectFormat `xorm:"-"`

TrustModel TrustModelType

Expand Down Expand Up @@ -274,6 +276,8 @@ func (repo *Repository) AfterLoad() {
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns

repo.ObjectFormat = git.ObjectFormatFromID(git.Sha1)
}

// LoadAttributes loads attributes of the repository.
Expand Down Expand Up @@ -313,7 +317,7 @@ func (repo *Repository) HTMLURL() string {
// CommitLink make link to by commit full ID
// note: won't check whether it's an right id
func (repo *Repository) CommitLink(commitID string) (result string) {
if commitID == "" || commitID == "0000000000000000000000000000000000000000" {
if git.IsEmptyCommitID(commitID) {
result = ""
} else {
result = repo.Link() + "/commit/" + url.PathEscape(commitID)
Expand Down
9 changes: 7 additions & 2 deletions modules/context/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,12 @@ func RepoRefForAPI(next http.Handler) http.Handler {
return
}

objectFormat, err := ctx.Repo.GitRepo.GetObjectFormat()
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
return
}

if ref := ctx.FormTrim("ref"); len(ref) > 0 {
commit, err := ctx.Repo.GitRepo.GetCommit(ref)
if err != nil {
Expand All @@ -325,7 +331,6 @@ func RepoRefForAPI(next http.Handler) http.Handler {
return
}

var err error
refName := getRefName(ctx.Base, ctx.Repo, RepoRefAny)

if ctx.Repo.GitRepo.IsBranchExist(refName) {
Expand All @@ -342,7 +347,7 @@ func RepoRefForAPI(next http.Handler) http.Handler {
return
}
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
} else if len(refName) == git.SHAFullLength {
} else if len(refName) == objectFormat.FullLength() {
ctx.Repo.CommitID = refName
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName)
if err != nil {
Expand Down
18 changes: 14 additions & 4 deletions modules/context/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,9 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
}
// For legacy and API support only full commit sha
parts := strings.Split(path, "/")
if len(parts) > 0 && len(parts[0]) == git.SHAFullLength {
objectFormat, _ := repo.GitRepo.GetObjectFormat()

if len(parts) > 0 && len(parts[0]) == objectFormat.FullLength() {
repo.TreePath = strings.Join(parts[1:], "/")
return parts[0]
}
Expand Down Expand Up @@ -869,7 +871,9 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
return getRefNameFromPath(ctx, repo, path, repo.GitRepo.IsTagExist)
case RepoRefCommit:
parts := strings.Split(path, "/")
if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= git.SHAFullLength {
objectFormat, _ := repo.GitRepo.GetObjectFormat()

if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= objectFormat.FullLength() {
repo.TreePath = strings.Join(parts[1:], "/")
return parts[0]
}
Expand Down Expand Up @@ -929,6 +933,12 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
}
}

objectFormat, err := ctx.Repo.GitRepo.GetObjectFormat()
if err != nil {
log.Error("Cannot determine objectFormat for repository: %w", err)
ctx.Repo.Repository.MarkAsBrokenEmpty()
}

// Get default branch.
if len(ctx.Params("*")) == 0 {
refName = ctx.Repo.Repository.DefaultBranch
Expand Down Expand Up @@ -995,7 +1005,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
return cancel
}
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
} else if len(refName) >= 7 && len(refName) <= git.SHAFullLength {
} else if len(refName) >= 7 && len(refName) <= objectFormat.FullLength() {
ctx.Repo.IsViewCommit = true
ctx.Repo.CommitID = refName

Expand All @@ -1005,7 +1015,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
return cancel
}
// If short commit ID add canonical link header
if len(refName) < git.SHAFullLength {
if len(refName) < objectFormat.FullLength() {
ctx.RespHeader().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"",
util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1))))
}
Expand Down
30 changes: 15 additions & 15 deletions modules/git/batch_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi
// ReadBatchLine reads the header line from cat-file --batch
// We expect:
// <sha> SP <type> SP <size> LF
// sha is a 40byte not 20byte here
// sha is a hex encoded here
func ReadBatchLine(rd *bufio.Reader) (sha []byte, typ string, size int64, err error) {
typ, err = rd.ReadString('\n')
if err != nil {
Expand Down Expand Up @@ -251,20 +251,19 @@ headerLoop:
}

// git tree files are a list:
// <mode-in-ascii> SP <fname> NUL <20-byte SHA>
// <mode-in-ascii> SP <fname> NUL <binary Hash>
//
// Unfortunately this 20-byte notation is somewhat in conflict to all other git tools
// Therefore we need some method to convert these 20-byte SHAs to a 40-byte SHA
// Therefore we need some method to convert these binary hashes to hex hashes

// constant hextable to help quickly convert between 20byte and 40byte hashes
// constant hextable to help quickly convert between binary and hex representation
const hextable = "0123456789abcdef"

// To40ByteSHA converts a 20-byte SHA into a 40-byte sha. Input and output can be the
// same 40 byte slice to support in place conversion without allocations.
// BinToHexHeash converts a binary Hash into a hex encoded one. Input and output can be the
// same byte slice to support in place conversion without allocations.
// This is at least 100x quicker that hex.EncodeToString
// NB This requires that out is a 40-byte slice
func To40ByteSHA(sha, out []byte) []byte {
for i := 19; i >= 0; i-- {
func BinToHex(objectFormat ObjectFormat, sha, out []byte) []byte {
for i := objectFormat.FullLength()/2 - 1; i >= 0; i-- {
v := sha[i]
vhi, vlo := v>>4, v&0x0f
shi, slo := hextable[vhi], hextable[vlo]
Expand All @@ -278,10 +277,10 @@ func To40ByteSHA(sha, out []byte) []byte {
// It is recommended therefore to pass in an fnameBuf large enough to avoid almost all allocations
//
// Each line is composed of:
// <mode-in-ascii-dropping-initial-zeros> SP <fname> NUL <20-byte SHA>
// <mode-in-ascii-dropping-initial-zeros> SP <fname> NUL <binary HASH>
//
// We don't attempt to convert the 20-byte SHA to 40-byte SHA to save a lot of time
func ParseTreeLine(rd *bufio.Reader, modeBuf, fnameBuf, shaBuf []byte) (mode, fname, sha []byte, n int, err error) {
// We don't attempt to convert the raw HASH to save a lot of time
func ParseTreeLine(objectFormat ObjectFormat, rd *bufio.Reader, modeBuf, fnameBuf, shaBuf []byte) (mode, fname, sha []byte, n int, err error) {
var readBytes []byte

// Read the Mode & fname
Expand Down Expand Up @@ -324,11 +323,12 @@ func ParseTreeLine(rd *bufio.Reader, modeBuf, fnameBuf, shaBuf []byte) (mode, fn
fnameBuf = fnameBuf[:len(fnameBuf)-1]
fname = fnameBuf

// Deal with the 20-byte SHA
// Deal with the binary hash
idx = 0
for idx < 20 {
len := objectFormat.FullLength() / 2
for idx < len {
var read int
read, err = rd.Read(shaBuf[idx:20])
read, err = rd.Read(shaBuf[idx:len])
n += read
if err != nil {
return mode, fname, sha, n, err
Expand Down
39 changes: 20 additions & 19 deletions modules/git/blame.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import (
"fmt"
"io"
"os"
"regexp"
"strings"

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
Expand All @@ -33,14 +31,13 @@ type BlameReader struct {
done chan error
lastSha *string
ignoreRevsFile *string
objectFormat ObjectFormat
}

func (r *BlameReader) UsesIgnoreRevs() bool {
return r.ignoreRevsFile != nil
}

var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})")

// NextPart returns next part of blame (sequential code lines with the same commit)
func (r *BlameReader) NextPart() (*BlamePart, error) {
var blamePart *BlamePart
Expand All @@ -52,6 +49,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
}
}

const previousHeader = "previous "
var lineBytes []byte
var isPrefix bool
var err error
Expand All @@ -67,21 +65,22 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
continue
}

line := string(lineBytes)

lines := shaLineRegex.FindStringSubmatch(line)
if lines != nil {
sha1 := lines[1]
var objectID string
objectFormatLength := r.objectFormat.FullLength()

if len(lineBytes) > objectFormatLength && lineBytes[objectFormatLength] == ' ' && r.objectFormat.IsValid(string(lineBytes[0:objectFormatLength])) {
objectID = string(lineBytes[0:objectFormatLength])
}
if len(objectID) > 0 {
if blamePart == nil {
blamePart = &BlamePart{
Sha: sha1,
Sha: objectID,
Lines: make([]string, 0),
}
}

if blamePart.Sha != sha1 {
r.lastSha = &sha1
if blamePart.Sha != objectID {
r.lastSha = &objectID
// need to munch to end of line...
for isPrefix {
_, isPrefix, err = r.bufferedReader.ReadLine()
Expand All @@ -91,12 +90,13 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
}
return blamePart, nil
}
} else if line[0] == '\t' {
blamePart.Lines = append(blamePart.Lines, line[1:])
} else if strings.HasPrefix(line, "previous ") {
parts := strings.SplitN(line[len("previous "):], " ", 2)
blamePart.PreviousSha = parts[0]
blamePart.PreviousPath = parts[1]
} else if lineBytes[0] == '\t' {
blamePart.Lines = append(blamePart.Lines, string(lineBytes[1:]))
} else if bytes.HasPrefix(lineBytes, []byte(previousHeader)) {
offset := len(previousHeader) // already includes a space
blamePart.PreviousSha = string(lineBytes[offset : offset+objectFormatLength])
offset += objectFormatLength + 1 // +1 for space
blamePart.PreviousPath = string(lineBytes[offset:])
}

// need to munch to end of line...
Expand Down Expand Up @@ -126,7 +126,7 @@ func (r *BlameReader) Close() error {
}

// CreateBlameReader creates reader for given repository, commit and file
func CreateBlameReader(ctx context.Context, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (*BlameReader, error) {
func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (*BlameReader, error) {
var ignoreRevsFile *string
if CheckGitVersionAtLeast("2.23") == nil && !bypassBlameIgnore {
ignoreRevsFile = tryCreateBlameIgnoreRevsFile(commit)
Expand Down Expand Up @@ -175,6 +175,7 @@ func CreateBlameReader(ctx context.Context, repoPath string, commit *Commit, fil
bufferedReader: bufferedReader,
done: done,
ignoreRevsFile: ignoreRevsFile,
objectFormat: objectFormat,
}, nil
}

Expand Down
Loading

0 comments on commit cb0c502

Please sign in to comment.