diff options
author | Anthony Wang | 2023-03-04 00:03:38 +0000 |
---|---|---|
committer | Anthony Wang | 2023-03-04 00:03:38 +0000 |
commit | b4640101f3c8938ed689743606a79601201141ca (patch) | |
tree | 8469fc5ef817560db646837b41417d50e2f8ebfc /services | |
parent | dc20c2832871f6462990751ea802e14b02bf41b0 (diff) | |
parent | 8540fc45b11eff9a73753ca139f8ea5c38509bf5 (diff) |
Merge remote-tracking branch 'origin/main' into forgejo-federation
Diffstat (limited to 'services')
-rw-r--r-- | services/actions/notifier_helper.go | 48 | ||||
-rw-r--r-- | services/auth/source/oauth2/jwtsigningkey.go | 2 | ||||
-rw-r--r-- | services/automerge/automerge.go | 2 | ||||
-rw-r--r-- | services/convert/mirror.go | 1 | ||||
-rw-r--r-- | services/forms/repo_form.go | 3 | ||||
-rw-r--r-- | services/lfs/server.go | 2 | ||||
-rw-r--r-- | services/mailer/token/token.go | 3 | ||||
-rw-r--r-- | services/pull/check.go | 37 | ||||
-rw-r--r-- | services/pull/merge.go | 4 | ||||
-rw-r--r-- | services/repository/files/tree.go | 5 | ||||
-rw-r--r-- | services/webhook/deliver.go | 2 | ||||
-rw-r--r-- | services/webhook/notifier.go | 7 |
12 files changed, 94 insertions, 22 deletions
diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index df67d2fa1..ef63b8cf9 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -153,7 +153,7 @@ func notify(ctx context.Context, input *notifyInput) error { } for id, content := range workflows { - run := actions_model.ActionRun{ + run := &actions_model.ActionRun{ Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0], RepoID: input.Repo.ID, OwnerID: input.Repo.OwnerID, @@ -166,12 +166,19 @@ func notify(ctx context.Context, input *notifyInput) error { EventPayload: string(p), Status: actions_model.StatusWaiting, } + if need, err := ifNeedApproval(ctx, run, input.Repo, input.Doer); err != nil { + log.Error("check if need approval for repo %d with user %d: %v", input.Repo.ID, input.Doer.ID, err) + continue + } else { + run.NeedApproval = need + } + jobs, err := jobparser.Parse(content) if err != nil { log.Error("jobparser.Parse: %v", err) continue } - if err := actions_model.InsertRun(ctx, &run, jobs); err != nil { + if err := actions_model.InsertRun(ctx, run, jobs); err != nil { log.Error("InsertRun: %v", err) continue } @@ -234,3 +241,40 @@ func notifyPackage(ctx context.Context, sender *user_model.User, pd *packages_mo }). Notify(ctx) } + +func ifNeedApproval(ctx context.Context, run *actions_model.ActionRun, repo *repo_model.Repository, user *user_model.User) (bool, error) { + // don't need approval if it's not a fork PR + if !run.IsForkPullRequest { + return false, nil + } + + // always need approval if the user is restricted + if user.IsRestricted { + log.Trace("need approval because user %d is restricted", user.ID) + return true, nil + } + + // don't need approval if the user can write + if perm, err := access_model.GetUserRepoPermission(ctx, repo, user); err != nil { + return false, fmt.Errorf("GetUserRepoPermission: %w", err) + } else if perm.CanWrite(unit_model.TypeActions) { + log.Trace("do not need approval because user %d can write", user.ID) + return false, nil + } + + // don't need approval if the user has been approved before + if count, err := actions_model.CountRuns(ctx, actions_model.FindRunOptions{ + RepoID: repo.ID, + TriggerUserID: user.ID, + Approved: true, + }); err != nil { + return false, fmt.Errorf("CountRuns: %w", err) + } else if count > 0 { + log.Trace("do not need approval because user %d has been approved before", user.ID) + return false, nil + } + + // otherwise, need approval + log.Trace("need approval because it's the first time user %d triggered actions", user.ID) + return true, nil +} diff --git a/services/auth/source/oauth2/jwtsigningkey.go b/services/auth/source/oauth2/jwtsigningkey.go index 93c157437..94feddbf6 100644 --- a/services/auth/source/oauth2/jwtsigningkey.go +++ b/services/auth/source/oauth2/jwtsigningkey.go @@ -9,7 +9,6 @@ import ( "crypto/elliptic" "crypto/rand" "crypto/rsa" - "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" @@ -25,6 +24,7 @@ import ( "code.gitea.io/gitea/modules/util" "github.com/golang-jwt/jwt/v4" + "github.com/minio/sha256-simd" ini "gopkg.in/ini.v1" ) diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go index 74cfb8da8..994604764 100644 --- a/services/automerge/automerge.go +++ b/services/automerge/automerge.go @@ -230,7 +230,7 @@ func handlePull(pullID int64, sha string) { return } - if err := pull_service.CheckPullMergable(ctx, doer, &perm, pr, false, false); err != nil { + if err := pull_service.CheckPullMergable(ctx, doer, &perm, pr, pull_service.MergeCheckTypeGeneral, false); err != nil { if errors.Is(pull_service.ErrUserNotAllowedToMerge, err) { log.Info("%-v was scheduled to automerge by an unauthorized user", pr) return diff --git a/services/convert/mirror.go b/services/convert/mirror.go index 1dcfc9b64..f7a8e17fd 100644 --- a/services/convert/mirror.go +++ b/services/convert/mirror.go @@ -24,6 +24,7 @@ func ToPushMirror(pm *repo_model.PushMirror) (*api.PushMirror, error) { LastUpdateUnix: pm.LastUpdateUnix.FormatLong(), LastError: pm.LastError, Interval: pm.Interval.String(), + SyncOnCommit: pm.SyncOnCommit, }, nil } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index ff0916f8e..e9645b5ab 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -190,6 +190,7 @@ func (f *RepoSettingForm) Validate(req *http.Request, errs binding.Errors) bindi // ProtectBranchForm form for changing protected branch settings type ProtectBranchForm struct { RuleName string `binding:"Required"` + RuleID int64 EnablePush string WhitelistUsers string WhitelistTeams string @@ -603,7 +604,7 @@ type MergePullRequestForm struct { MergeMessageField string MergeCommitID string // only used for manually-merged HeadCommitID string `json:"head_commit_id,omitempty"` - ForceMerge *bool `json:"force_merge,omitempty"` + ForceMerge bool `json:"force_merge,omitempty"` MergeWhenChecksSucceed bool `json:"merge_when_checks_succeed,omitempty"` DeleteBranchAfterMerge bool `json:"delete_branch_after_merge,omitempty"` } diff --git a/services/lfs/server.go b/services/lfs/server.go index 320c8e728..217d45124 100644 --- a/services/lfs/server.go +++ b/services/lfs/server.go @@ -5,7 +5,6 @@ package lfs import ( stdCtx "context" - "crypto/sha256" "encoding/base64" "encoding/hex" "errors" @@ -32,6 +31,7 @@ import ( "code.gitea.io/gitea/modules/storage" "github.com/golang-jwt/jwt/v4" + "github.com/minio/sha256-simd" ) // requestContext contain variables from the HTTP request. diff --git a/services/mailer/token/token.go b/services/mailer/token/token.go index 8a5a762d6..aa7b56718 100644 --- a/services/mailer/token/token.go +++ b/services/mailer/token/token.go @@ -6,13 +6,14 @@ package token import ( "context" crypto_hmac "crypto/hmac" - "crypto/sha256" "encoding/base32" "fmt" "time" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/util" + + "github.com/minio/sha256-simd" ) // A token is a verifiable container describing an action. diff --git a/services/pull/check.go b/services/pull/check.go index 310ea2e71..02d901541 100644 --- a/services/pull/check.go +++ b/services/pull/check.go @@ -59,8 +59,16 @@ func AddToTaskQueue(pr *issues_model.PullRequest) { } } +type MergeCheckType int + +const ( + MergeCheckTypeGeneral MergeCheckType = iota // general merge checks for "merge", "rebase", "squash", etc + MergeCheckTypeManually // Manually Merged button (mark a PR as merged manually) + MergeCheckTypeAuto // Auto Merge (Scheduled Merge) After Checks Succeed +) + // CheckPullMergable check if the pull mergable based on all conditions (branch protection, merge options, ...) -func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, manuallMerge, force bool) error { +func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, mergeCheckType MergeCheckType, adminSkipProtectionCheck bool) error { return db.WithTx(stdCtx, func(ctx context.Context) error { if pr.HasMerged { return ErrHasMerged @@ -80,8 +88,8 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce return ErrUserNotAllowedToMerge } - if manuallMerge { - // don't check rules to "auto merge", doer is going to mark this pull as merged manually + if mergeCheckType == MergeCheckTypeManually { + // if doer is doing "manually merge" (mark as merged manually), do not check anything return nil } @@ -103,14 +111,25 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce return err } - if !force { - return err + // Now the branch protection check failed, check whether the failure could be skipped (skip by setting err = nil) + + // * when doing Auto Merge (Scheduled Merge After Checks Succeed), skip the branch protection check + if mergeCheckType == MergeCheckTypeAuto { + err = nil + } + + // * if the doer is admin, they could skip the branch protection check + if adminSkipProtectionCheck { + if isRepoAdmin, errCheckAdmin := access_model.IsUserRepoAdmin(ctx, pr.BaseRepo, doer); errCheckAdmin != nil { + log.Error("Unable to check if %-v is a repo admin in %-v: %v", doer, pr.BaseRepo, errCheckAdmin) + return errCheckAdmin + } else if isRepoAdmin { + err = nil // repo admin can skip the check, so clear the error + } } - if isRepoAdmin, err2 := access_model.IsUserRepoAdmin(ctx, pr.BaseRepo, doer); err2 != nil { - log.Error("Unable to check if %-v is a repo admin in %-v: %v", doer, pr.BaseRepo, err2) - return err2 - } else if !isRepoAdmin { + // If there is still a branch protection check error, return it + if err != nil { return err } } diff --git a/services/pull/merge.go b/services/pull/merge.go index 3ac67d91b..ad428427c 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -533,7 +533,7 @@ func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_mode if err := git.NewCommand(ctx, "commit"). AddArguments(signArgs...). AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email). - AddOptionValues("-m", message). + AddOptionFormat("--message=%s", message). Run(&git.RunOpts{ Env: env, Dir: tmpBasePath, @@ -641,7 +641,7 @@ func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_mode func commitAndSignNoAuthor(ctx context.Context, pr *issues_model.PullRequest, message string, signArgs git.TrustedCmdArgs, tmpBasePath string, env []string) error { var outbuf, errbuf strings.Builder - if err := git.NewCommand(ctx, "commit").AddArguments(signArgs...).AddOptionValues("-m", message). + if err := git.NewCommand(ctx, "commit").AddArguments(signArgs...).AddOptionFormat("--message=%s", message). Run(&git.RunOpts{ Env: env, Dir: tmpBasePath, diff --git a/services/repository/files/tree.go b/services/repository/files/tree.go index f4304ea63..0b1d30484 100644 --- a/services/repository/files/tree.go +++ b/services/repository/files/tree.go @@ -85,6 +85,11 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git if entries[e].IsDir() { copy(treeURL[copyPos:], entries[e].ID.String()) tree.Entries[i].URL = string(treeURL) + } else if entries[e].IsSubModule() { + // In Github Rest API Version=2022-11-28, if a tree entry is a submodule, + // its url will be returned as an empty string. + // So the URL will be set to "" here. + tree.Entries[i].URL = "" } else { copy(blobURL[copyPos:], entries[e].ID.String()) tree.Entries[i].URL = string(blobURL) diff --git a/services/webhook/deliver.go b/services/webhook/deliver.go index effbe45e5..e389b1f9f 100644 --- a/services/webhook/deliver.go +++ b/services/webhook/deliver.go @@ -7,7 +7,6 @@ import ( "context" "crypto/hmac" "crypto/sha1" - "crypto/sha256" "crypto/tls" "encoding/hex" "fmt" @@ -29,6 +28,7 @@ import ( webhook_module "code.gitea.io/gitea/modules/webhook" "github.com/gobwas/glob" + "github.com/minio/sha256-simd" ) // Deliver deliver hook task diff --git a/services/webhook/notifier.go b/services/webhook/notifier.go index ba6d968db..b023717cd 100644 --- a/services/webhook/notifier.go +++ b/services/webhook/notifier.go @@ -150,7 +150,6 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(ctx context.Context, doer *u log.Error("LoadPullRequest failed: %v", err) return } - issue.PullRequest.Issue = issue apiPullRequest := &api.PullRequestPayload{ Index: issue.Index, PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), @@ -196,7 +195,6 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(ctx context.Context, doer *user log.Error("LoadPullRequest failed: %v", err) return } - issue.PullRequest.Issue = issue err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{ Action: api.HookIssueEdited, Index: issue.Index, @@ -328,7 +326,10 @@ func (m *webhookNotifier) NotifyIssueChangeContent(ctx context.Context, doer *us mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo) var err error if issue.IsPull { - issue.PullRequest.Issue = issue + if err := issue.LoadPullRequest(ctx); err != nil { + log.Error("LoadPullRequest: %v", err) + return + } err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{ Action: api.HookIssueEdited, Index: issue.Index, |