1
1
mirror of https://github.com/go-gitea/gitea synced 2025-12-07 13:28:25 +00:00

Merge remote-tracking branch 'origin/main' into api-repo-actions

This commit is contained in:
chesterip
2023-08-30 11:31:23 -04:00
317 changed files with 3111 additions and 2686 deletions
+8 -13
View File
@@ -10,6 +10,7 @@ import (
actions_model "code.gitea.io/gitea/models/actions"
secret_model "code.gitea.io/gitea/models/secret"
actions_module "code.gitea.io/gitea/modules/actions"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
@@ -55,8 +56,12 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv
func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string {
secrets := map[string]string{}
secrets["GITHUB_TOKEN"] = task.Token
secrets["GITEA_TOKEN"] = task.Token
if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget {
// ignore secrets for fork pull request
// ignore secrets for fork pull request, except GITHUB_TOKEN and GITEA_TOKEN which are automatically generated.
// for the tasks triggered by pull_request_target event, they could access the secrets because they will run in the context of the base branch
// see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
return secrets
@@ -82,13 +87,6 @@ func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[s
}
}
if _, ok := secrets["GITHUB_TOKEN"]; !ok {
secrets["GITHUB_TOKEN"] = task.Token
}
if _, ok := secrets["GITEA_TOKEN"]; !ok {
secrets["GITEA_TOKEN"] = task.Token
}
return secrets
}
@@ -200,10 +198,7 @@ func findTaskNeeds(ctx context.Context, task *actions_model.ActionTask) (map[str
if len(task.Job.Needs) == 0 {
return nil, nil
}
needs := map[string]struct{}{}
for _, v := range task.Job.Needs {
needs[v] = struct{}{}
}
needs := container.SetOf(task.Job.Needs...)
jobs, _, err := actions_model.FindRunJobs(ctx, actions_model.FindRunJobOptions{RunID: task.Job.RunID})
if err != nil {
@@ -212,7 +207,7 @@ func findTaskNeeds(ctx context.Context, task *actions_model.ActionTask) (map[str
ret := make(map[string]*runnerv1.TaskNeed, len(needs))
for _, job := range jobs {
if _, ok := needs[job.JobID]; !ok {
if !needs.Contains(job.JobID) {
continue
}
if job.TaskID == 0 || !job.Status.IsDone() {
+3 -1
View File
@@ -16,6 +16,8 @@ import (
"code.gitea.io/gitea/modules/log"
packages_module "code.gitea.io/gitea/modules/packages"
cargo_module "code.gitea.io/gitea/modules/packages/cargo"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers/api/packages/helper"
"code.gitea.io/gitea/services/convert"
@@ -48,7 +50,7 @@ func apiError(ctx *context.Context, status int, obj any) {
// https://rust-lang.github.io/rfcs/2789-sparse-index.html
func RepositoryConfig(ctx *context.Context) {
ctx.JSON(http.StatusOK, cargo_service.BuildConfig(ctx.Package.Owner))
ctx.JSON(http.StatusOK, cargo_service.BuildConfig(ctx.Package.Owner, setting.Service.RequireSignInView || ctx.Package.Owner.Visibility != structs.VisibleTypePublic))
}
func EnumeratePackageVersions(ctx *context.Context) {
+7 -1
View File
@@ -933,6 +933,10 @@ func Routes() *web.Route {
m.Post("/accept", repo.AcceptTransfer)
m.Post("/reject", repo.RejectTransfer)
}, reqToken())
m.Group("/actions/secrets", func() {
m.Combo("/{secretname}").
Put(reqToken(), reqOwner(), bind(api.CreateOrUpdateSecretOption{}), repo.CreateOrUpdateSecret)
})
m.Group("/hooks/git", func() {
m.Combo("").Get(repo.ListGitHooks)
m.Group("/{id}", func() {
@@ -1303,7 +1307,9 @@ func Routes() *web.Route {
})
m.Group("/actions/secrets", func() {
m.Get("", reqToken(), reqOrgOwnership(), org.ListActionsSecrets)
m.Post("", reqToken(), reqOrgOwnership(), bind(api.CreateSecretOption{}), org.CreateOrgSecret)
m.Combo("/{secretname}").
Put(reqToken(), reqOrgOwnership(), bind(api.CreateOrUpdateSecretOption{}), org.CreateOrUpdateSecret).
Delete(reqToken(), reqOrgOwnership(), org.DeleteOrgSecret)
})
m.Group("/public_members", func() {
m.Get("", org.ListPublicMembers)
+67 -15
View File
@@ -12,7 +12,6 @@ import (
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/routers/web/shared/actions"
"code.gitea.io/gitea/services/convert"
)
// ListActionsSecrets list an organization's actions secrets
@@ -74,11 +73,11 @@ func listActionsSecrets(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, apiSecrets)
}
// CreateOrgSecret create one secret of the organization
func CreateOrgSecret(ctx *context.APIContext) {
// swagger:operation POST /orgs/{org}/actions/secrets organization createOrgSecret
// create or update one secret of the organization
func CreateOrUpdateSecret(ctx *context.APIContext) {
// swagger:operation PUT /orgs/{org}/actions/secrets/{secretname} organization updateOrgSecret
// ---
// summary: Create a secret in an organization
// summary: Create or Update a secret value in an organization
// consumes:
// - application/json
// produces:
@@ -89,27 +88,80 @@ func CreateOrgSecret(ctx *context.APIContext) {
// description: name of organization
// type: string
// required: true
// - name: secretname
// in: path
// description: name of the secret
// type: string
// required: true
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/CreateSecretOption"
// "$ref": "#/definitions/CreateOrUpdateSecretOption"
// responses:
// "201":
// "$ref": "#/responses/Secret"
// description: response when creating a secret
// "204":
// description: response when updating a secret
// "400":
// "$ref": "#/responses/error"
// "404":
// "$ref": "#/responses/notFound"
// "403":
// "$ref": "#/responses/forbidden"
opt := web.GetForm(ctx).(*api.CreateSecretOption)
s, err := secret_model.InsertEncryptedSecret(
ctx, ctx.Org.Organization.ID, 0, opt.Name, actions.ReserveLineBreakForTextarea(opt.Data),
)
secretName := ctx.Params(":secretname")
if err := actions.NameRegexMatch(secretName); err != nil {
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
return
}
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
isCreated, err := secret_model.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, secretName, opt.Data)
if err != nil {
ctx.Error(http.StatusInternalServerError, "InsertEncryptedSecret", err)
ctx.Error(http.StatusInternalServerError, "CreateOrUpdateSecret", err)
return
}
if isCreated {
ctx.Status(http.StatusCreated)
return
}
ctx.JSON(http.StatusCreated, convert.ToSecret(s))
ctx.Status(http.StatusNoContent)
}
// DeleteOrgSecret delete one secret of the organization
func DeleteOrgSecret(ctx *context.APIContext) {
// swagger:operation DELETE /orgs/{org}/actions/secrets/{secretname} organization deleteOrgSecret
// ---
// summary: Delete a secret in an organization
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: org
// in: path
// description: name of organization
// type: string
// required: true
// - name: secretname
// in: path
// description: name of the secret
// type: string
// required: true
// responses:
// "204":
// description: delete one secret of the organization
// "403":
// "$ref": "#/responses/forbidden"
secretName := ctx.Params(":secretname")
err := secret_model.DeleteSecret(
ctx, ctx.Org.Organization.ID, 0, secretName,
)
if secret_model.IsErrSecretNotFound(err) {
ctx.NotFound(err)
return
}
if err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteSecret", err)
return
}
ctx.Status(http.StatusNoContent)
}
+75
View File
@@ -0,0 +1,75 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repo
import (
"net/http"
secret_model "code.gitea.io/gitea/models/secret"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/web/shared/actions"
)
// create or update one secret of the repository
func CreateOrUpdateSecret(ctx *context.APIContext) {
// swagger:operation PUT /repos/{owner}/{repo}/actions/secrets/{secretname} repository updateRepoSecret
// ---
// summary: Create or Update a secret value in a repository
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repository
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repository
// type: string
// required: true
// - name: secretname
// in: path
// description: name of the secret
// type: string
// required: true
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/CreateOrUpdateSecretOption"
// responses:
// "201":
// description: response when creating a secret
// "204":
// description: response when updating a secret
// "400":
// "$ref": "#/responses/error"
// "403":
// "$ref": "#/responses/forbidden"
owner := ctx.Repo.Owner
repo := ctx.Repo.Repository
secretName := ctx.Params(":secretname")
if err := actions.NameRegexMatch(secretName); err != nil {
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
return
}
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
isCreated, err := secret_model.CreateOrUpdateSecret(ctx, owner.ID, repo.ID, secretName, opt.Data)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CreateOrUpdateSecret", err)
return
}
if isCreated {
ctx.Status(http.StatusCreated)
return
}
ctx.Status(http.StatusNoContent)
}
+2 -1
View File
@@ -768,7 +768,8 @@ func EditBranchProtection(ctx *context.APIContext) {
if form.EnableStatusCheck != nil {
protectBranch.EnableStatusCheck = *form.EnableStatusCheck
}
if protectBranch.EnableStatusCheck {
if form.StatusCheckContexts != nil {
protectBranch.StatusCheckContexts = form.StatusCheckContexts
}
+1 -2
View File
@@ -14,7 +14,6 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/context"
mirror_module "code.gitea.io/gitea/modules/mirror"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
@@ -70,7 +69,7 @@ func MirrorSync(ctx *context.APIContext) {
return
}
mirror_module.AddPullMirrorToQueue(repo.ID)
mirror_service.AddPullMirrorToQueue(repo.ID)
ctx.Status(http.StatusOK)
}
+7 -9
View File
@@ -326,11 +326,9 @@ func CreatePullRequest(ctx *context.APIContext) {
return
}
labelIDs = make([]int64, len(form.Labels))
orgLabelIDs := make([]int64, len(form.Labels))
for i := range labels {
labelIDs[i] = labels[i].ID
labelIDs = make([]int64, 0, len(labels))
for _, label := range labels {
labelIDs = append(labelIDs, label.ID)
}
if ctx.Repo.Owner.IsOrganization() {
@@ -340,12 +338,12 @@ func CreatePullRequest(ctx *context.APIContext) {
return
}
for i := range orgLabels {
orgLabelIDs[i] = orgLabels[i].ID
orgLabelIDs := make([]int64, 0, len(orgLabels))
for _, orgLabel := range orgLabels {
orgLabelIDs = append(orgLabelIDs, orgLabel.ID)
}
labelIDs = append(labelIDs, orgLabelIDs...)
}
labelIDs = append(labelIDs, orgLabelIDs...)
}
if form.Milestone > 0 {
+1 -1
View File
@@ -189,5 +189,5 @@ type swaggerParameterBodies struct {
UpdateRepoAvatarOptions api.UpdateRepoAvatarOption
// in:body
CreateSecretOption api.CreateSecretOption
CreateOrUpdateSecretOption api.CreateOrUpdateSecretOption
}
+2 -10
View File
@@ -60,17 +60,9 @@ func Contexter() func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
base, baseCleanUp := context.NewBaseContext(resp, req)
ctx := &context.Context{
Base: base,
Flash: &middleware.Flash{},
Render: rnd,
Session: session.GetSession(req),
}
defer baseCleanUp()
ctx.TemplateContext = context.NewTemplateContext(ctx)
ctx.TemplateContext["Locale"] = ctx.Locale
ctx := context.NewWebContext(base, rnd, session.GetSession(req))
ctx.AppendContextValue(context.WebContextKey, ctx)
ctx.Data.MergeFrom(middleware.CommonTemplateContextData())
ctx.Data.MergeFrom(middleware.ContextData{
@@ -189,7 +181,7 @@ func checkDatabase(ctx *context.Context, form *forms.InstallForm) bool {
if err = db.InitEngine(ctx); err != nil {
if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
ctx.Data["Err_DbType"] = true
ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://docs.gitea.io/en-us/install-from-binary/"), tplInstall, form)
ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://docs.gitea.com/installation/install-from-binary"), tplInstall, form)
} else {
ctx.Data["Err_DbSetting"] = true
ctx.RenderWithErr(ctx.Tr("install.invalid_db_setting", err), tplInstall, form)
+24 -16
View File
@@ -28,23 +28,31 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env []
_ = stdoutWriter.Close()
}()
var command *git.Command
if oldCommitID == git.EmptySHA {
// When creating a new branch, the oldCommitID is empty, by using "newCommitID --not --all":
// List commits that are reachable by following the newCommitID, exclude "all" existing heads/tags commits
// So, it only lists the new commits received, doesn't list the commits already present in the receiving repository
command = git.NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(newCommitID).AddArguments("--not", "--all")
} else {
command = git.NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID)
}
// This is safe as force pushes are already forbidden
err = git.NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID).
Run(&git.RunOpts{
Env: env,
Dir: repo.Path,
Stdout: stdoutWriter,
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
_ = stdoutWriter.Close()
err := readAndVerifyCommitsFromShaReader(stdoutReader, repo, env)
if err != nil {
log.Error("%v", err)
cancel()
}
_ = stdoutReader.Close()
return err
},
})
err = command.Run(&git.RunOpts{
Env: env,
Dir: repo.Path,
Stdout: stdoutWriter,
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
_ = stdoutWriter.Close()
err := readAndVerifyCommitsFromShaReader(stdoutReader, repo, env)
if err != nil {
log.Error("%v", err)
cancel()
}
_ = stdoutReader.Close()
return err
},
})
if err != nil && !isErrUnverifiedCommit(err) {
log.Error("Unable to check commits from %s to %s in %s: %v", oldCommitID, newCommitID, repo.Path, err)
}
+43
View File
@@ -0,0 +1,43 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package private
import (
"context"
"testing"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/git"
"github.com/stretchr/testify/assert"
)
var testReposDir = "tests/repos/"
func TestVerifyCommits(t *testing.T) {
unittest.PrepareTestEnv(t)
gitRepo, err := git.OpenRepository(context.Background(), testReposDir+"repo1_hook_verification")
defer gitRepo.Close()
assert.NoError(t, err)
testCases := []struct {
base, head string
verified bool
}{
{"72920278f2f999e3005801e5d5b8ab8139d3641c", "d766f2917716d45be24bfa968b8409544941be32", true},
{git.EmptySHA, "93eac826f6188f34646cea81bf426aa5ba7d3bfe", true}, // New branch with verified commit
{"9779d17a04f1e2640583d35703c62460b2d86e0a", "72920278f2f999e3005801e5d5b8ab8139d3641c", false},
{git.EmptySHA, "9ce3f779ae33f31fce17fac3c512047b75d7498b", false}, // New branch with unverified commit
}
for _, tc := range testCases {
err = verifyCommits(tc.base, tc.head, gitRepo, nil)
if tc.verified {
assert.NoError(t, err)
} else {
assert.Error(t, err)
}
}
}
+17
View File
@@ -0,0 +1,17 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package private
import (
"path/filepath"
"testing"
"code.gitea.io/gitea/models/unittest"
)
func TestMain(m *testing.M) {
unittest.MainTest(m, &unittest.TestOptions{
GiteaRootPath: filepath.Join("..", ".."),
})
}
@@ -0,0 +1 @@
ref: refs/heads/main
@@ -0,0 +1,6 @@
[core]
repositoryformatversion = 0
filemode = false
bare = true
symlinks = false
ignorecase = true
@@ -0,0 +1 @@
d766f2917716d45be24bfa968b8409544941be32 refs/heads/main
@@ -0,0 +1 @@
0000000000000000000000000000000000000000 d766f2917716d45be24bfa968b8409544941be32 Gitea <gitea@fake.local> 1693148474 +0800 push
@@ -0,0 +1 @@
0000000000000000000000000000000000000000 d766f2917716d45be24bfa968b8409544941be32 Gitea <gitea@fake.local> 1693148474 +0800 push
@@ -0,0 +1,2 @@
x•ŽK
1Ù ÒéüAÄS¸ï$Í"32 ooð®ŠWð òÞ{!žæ`–˜JC%¡.˜ $Ár]sѱe$ïmòâMƒ·)£÷±(O`ªbtlÐE[:;4–àHÐ1_û”rayýáþl“é’÷~“ÊE­L@cå€Xv…Mþã":µMÛƒG«_}À?Ý
@@ -0,0 +1,2 @@
x1
!ES{ŠéAwGGa 9EúQg W·Èí#¹AªÞû©ÕZ§/£‹€³Œ–p±ì(¤(ó®óBhÈÛ¼&áŸãÝ:pLY`ûÍãU†ð-µzŸÁ°ô†\µ×ZM:†ü¡¨Êå€óxJ/ûG}:µ3
@@ -0,0 +1,3 @@
x•ŽA
Â0E]ç³$™L“ ˆx•L2µ]´•
ÞÞê
@@ -0,0 +1,3 @@
x•’Ë®«FE3æ+zn%44æ!%QxƒÛ€s˜AÓ` 8Øæëã{£Ì2IM¶j•ª´¥Údèûf²Ìý2”‚"‡$§e‰¶
-(â ­Ä!´ÝJ"åaŲ@•BaîùHo3 ŸVØòå<$/)å$JøJDB¡•H¤§˜ü{¾ RRðûOù«nfšÿF†þOÀ‰
âq[°2„̇~ŒÍô¬Ô÷zjjðëÒLÛÅÀ·}prm¬Fqhþä `@Ø«¦ªš®ª¥Õ˜fî?3Ç[7г…ê¨Ð) ^™þuÿÖ¿,µÆl7©zÝÿr|&«Ou4Ø9Ó:µÎQjôû·êÕ1x±õå6ÍQ‡÷ƒÀ%Áåtû‰sò¸íV‰| ( V¿,aL,ù«G~²Ç¹‹‹r¥ùûî@·`·Àþ$[! XËŠep©Œæ[8 oýä(›« k£Z´Î³yóeÐ¹ÙÆÄ«Y²¿kÖd€¯6•3¾;3ÜÔ RÔi Þ‹dYÓDk91V]/Cê#º¾&ÿêpo´Fáb¯‹¶}§¹ô¦òuW&]+m xaqdÜIõX¯þ3
@@ -0,0 +1,3 @@
x•ŽA
Â0E]ç³$™L“ ˆx•L2µ]´•
ÞÞê
@@ -0,0 +1 @@
d766f2917716d45be24bfa968b8409544941be32
@@ -0,0 +1,127 @@
# GPG key for abcde@gitea.com
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
4akc
=OYIo
-----END PGP PUBLIC KEY BLOCK-----
-----BEGIN PGP PRIVATE KEY BLOCK-----
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
ZZtqph2TItCeV04HoaKHHc254akc
=PPG4
-----END PGP PRIVATE KEY BLOCK-----
+1 -1
View File
@@ -191,7 +191,7 @@ func List(ctx *context.Context) {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}
ctx.Data["Actors"] = repo.MakeSelfOnTop(ctx, actors)
ctx.Data["Actors"] = repo.MakeSelfOnTop(ctx.Doer, actors)
ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx)
+1 -4
View File
@@ -81,7 +81,6 @@ func Commits(ctx *context.Context) {
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
ctx.Data["CommitCount"] = commitsCount
ctx.Data["RefName"] = ctx.Repo.RefName
pager := context.NewPagination(int(commitsCount), pageSize, page, 5)
pager.SetDefaultParams(ctx)
@@ -157,7 +156,7 @@ func Graph(ctx *context.Context) {
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
ctx.Data["CommitCount"] = commitsCount
ctx.Data["RefName"] = ctx.Repo.RefName
paginator := context.NewPagination(int(graphCommitsCount), setting.UI.GraphMaxCommitNum, page, 5)
paginator.AddParam(ctx, "mode", "Mode")
paginator.AddParam(ctx, "hide-pr-refs", "HidePRRefs")
@@ -203,7 +202,6 @@ func SearchCommits(ctx *context.Context) {
}
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
ctx.Data["RefName"] = ctx.Repo.RefName
ctx.HTML(http.StatusOK, tplCommits)
}
@@ -247,7 +245,6 @@ func FileHistory(ctx *context.Context) {
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
ctx.Data["FileName"] = fileName
ctx.Data["CommitCount"] = commitsCount
ctx.Data["RefName"] = ctx.Repo.RefName
pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5)
pager.SetDefaultParams(ctx)
+1 -1
View File
@@ -460,7 +460,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
rootRepo.ID != ci.HeadRepo.ID &&
rootRepo.ID != baseRepo.ID {
canRead := access_model.CheckRepoUnitUser(ctx, rootRepo, ctx.Doer, unit.TypeCode)
if canRead && rootRepo.AllowsPulls() {
if canRead {
ctx.Data["RootRepo"] = rootRepo
if !fileOnly {
branches, tags, err := getBranchesAndTagsForRepo(ctx, rootRepo)
+3 -4
View File
@@ -7,16 +7,15 @@ import (
"sort"
"code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
)
func MakeSelfOnTop(ctx *context.Context, users []*user.User) []*user.User {
if ctx.Doer != nil {
func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User {
if doer != nil {
sort.Slice(users, func(i, j int) bool {
if users[i].ID == users[j].ID {
return false
}
return users[i].ID == ctx.Doer.ID // if users[i] is self, put it before others, so less=true
return users[i].ID == doer.ID // if users[i] is self, put it before others, so less=true
})
}
return users
+3 -4
View File
@@ -7,21 +7,20 @@ import (
"testing"
"code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
"github.com/stretchr/testify/assert"
)
func TestMakeSelfOnTop(t *testing.T) {
users := MakeSelfOnTop(&context.Context{}, []*user.User{{ID: 2}, {ID: 1}})
users := MakeSelfOnTop(nil, []*user.User{{ID: 2}, {ID: 1}})
assert.Len(t, users, 2)
assert.EqualValues(t, 2, users[0].ID)
users = MakeSelfOnTop(&context.Context{Doer: &user.User{ID: 1}}, []*user.User{{ID: 2}, {ID: 1}})
users = MakeSelfOnTop(&user.User{ID: 1}, []*user.User{{ID: 2}, {ID: 1}})
assert.Len(t, users, 2)
assert.EqualValues(t, 1, users[0].ID)
users = MakeSelfOnTop(&context.Context{Doer: &user.User{ID: 2}}, []*user.User{{ID: 2}, {ID: 1}})
users = MakeSelfOnTop(&user.User{ID: 2}, []*user.User{{ID: 2}, {ID: 1}})
assert.Len(t, users, 2)
assert.EqualValues(t, 2, users[0].ID)
}
+58 -35
View File
@@ -331,7 +331,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
ctx.ServerError("GetRepoAssignees", err)
return
}
ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
handleTeamMentions(ctx)
if ctx.Written() {
@@ -535,7 +535,7 @@ func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *repo_model.R
ctx.ServerError("GetRepoAssignees", err)
return
}
ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
handleTeamMentions(ctx)
}
@@ -1228,47 +1228,70 @@ func NewIssuePost(ctx *context.Context) {
}
}
// roleDescriptor returns the Role Descriptor for a comment in/with the given repo, poster and issue
// roleDescriptor returns the role descriptor for a comment in/with the given repo, poster and issue
func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *issues_model.Issue, hasOriginalAuthor bool) (issues_model.RoleDescriptor, error) {
roleDescriptor := issues_model.RoleDescriptor{}
if hasOriginalAuthor {
return issues_model.RoleDescriptorNone, nil
return roleDescriptor, nil
}
perm, err := access_model.GetUserRepoPermission(ctx, repo, poster)
if err != nil {
return issues_model.RoleDescriptorNone, err
}
// By default the poster has no roles on the comment.
roleDescriptor := issues_model.RoleDescriptorNone
// Check if the poster is owner of the repo.
if perm.IsOwner() {
// If the poster isn't a admin, enable the owner role.
if !poster.IsAdmin {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorOwner)
} else {
// Otherwise check if poster is the real repo admin.
ok, err := access_model.IsUserRealRepoAdmin(repo, poster)
if err != nil {
return issues_model.RoleDescriptorNone, err
}
if ok {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorOwner)
}
}
}
// Is the poster can write issues or pulls to the repo, enable the Writer role.
// Only enable this if the poster doesn't have the owner role already.
if !roleDescriptor.HasRole("Owner") && perm.CanWriteIssuesOrPulls(issue.IsPull) {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorWriter)
return roleDescriptor, err
}
// If the poster is the actual poster of the issue, enable Poster role.
if issue.IsPoster(poster.ID) {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorPoster)
roleDescriptor.IsPoster = issue.IsPoster(poster.ID)
// Check if the poster is owner of the repo.
if perm.IsOwner() {
// If the poster isn't an admin, enable the owner role.
if !poster.IsAdmin {
roleDescriptor.RoleInRepo = issues_model.RoleRepoOwner
return roleDescriptor, nil
}
// Otherwise check if poster is the real repo admin.
ok, err := access_model.IsUserRealRepoAdmin(repo, poster)
if err != nil {
return roleDescriptor, err
}
if ok {
roleDescriptor.RoleInRepo = issues_model.RoleRepoOwner
return roleDescriptor, nil
}
}
// If repo is organization, check Member role
if err := repo.LoadOwner(ctx); err != nil {
return roleDescriptor, err
}
if repo.Owner.IsOrganization() {
if isMember, err := organization.IsOrganizationMember(ctx, repo.Owner.ID, poster.ID); err != nil {
return roleDescriptor, err
} else if isMember {
roleDescriptor.RoleInRepo = issues_model.RoleRepoMember
return roleDescriptor, nil
}
}
// If the poster is the collaborator of the repo
if isCollaborator, err := repo_model.IsCollaborator(ctx, repo.ID, poster.ID); err != nil {
return roleDescriptor, err
} else if isCollaborator {
roleDescriptor.RoleInRepo = issues_model.RoleRepoCollaborator
return roleDescriptor, nil
}
hasMergedPR, err := issues_model.HasMergedPullRequestInRepo(ctx, repo.ID, poster.ID)
if err != nil {
return roleDescriptor, err
} else if hasMergedPR {
roleDescriptor.RoleInRepo = issues_model.RoleRepoContributor
} else {
// only display first time contributor in the first opening pull request
roleDescriptor.RoleInRepo = issues_model.RoleRepoFirstTimeContributor
}
return roleDescriptor, nil
@@ -3602,7 +3625,7 @@ func issuePosters(ctx *context.Context, isPullList bool) {
}
}
posters = MakeSelfOnTop(ctx, posters)
posters = MakeSelfOnTop(ctx.Doer, posters)
resp := &userSearchResponse{}
resp.Results = make([]*userSearchInfo, len(posters))
+1 -1
View File
@@ -956,7 +956,7 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
ctx.ServerError("GetRepoAssignees", err)
return
}
ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
handleTeamMentions(ctx)
if ctx.Written() {
+2 -2
View File
@@ -349,7 +349,7 @@ func NewRelease(ctx *context.Context) {
ctx.ServerError("GetRepoAssignees", err)
return
}
ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
upload.AddUploadContext(ctx, "release")
@@ -538,7 +538,7 @@ func EditRelease(ctx *context.Context) {
ctx.ServerError("GetRepoAssignees", err)
return
}
ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
ctx.HTML(http.StatusOK, tplReleaseNew)
}
+3 -4
View File
@@ -24,7 +24,6 @@ import (
"code.gitea.io/gitea/modules/indexer/stats"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log"
mirror_module "code.gitea.io/gitea/modules/mirror"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
@@ -277,7 +276,7 @@ func SettingsPost(ctx *context.Context) {
return
}
mirror_module.AddPullMirrorToQueue(repo.ID)
mirror_service.AddPullMirrorToQueue(repo.ID)
ctx.Flash.Info(ctx.Tr("repo.settings.mirror_sync_in_progress"))
ctx.Redirect(repo.Link() + "/settings")
@@ -294,7 +293,7 @@ func SettingsPost(ctx *context.Context) {
return
}
mirror_module.AddPushMirrorToQueue(m.ID)
mirror_service.AddPushMirrorToQueue(m.ID)
ctx.Flash.Info(ctx.Tr("repo.settings.mirror_sync_in_progress"))
ctx.Redirect(repo.Link() + "/settings")
@@ -332,7 +331,7 @@ func SettingsPost(ctx *context.Context) {
// If we observed its implementation in the context of `push-mirror-sync` where it
// is evident that pushing to the queue is necessary for updates.
// So, there are updates within the given interval, it is necessary to update the queue accordingly.
mirror_module.AddPushMirrorToQueue(m.ID)
mirror_service.AddPushMirrorToQueue(m.ID)
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
ctx.Redirect(repo.Link() + "/settings")
+1 -1
View File
@@ -44,7 +44,7 @@ func Webhooks(ctx *context.Context) {
ctx.Data["PageIsSettingsHooks"] = true
ctx.Data["BaseLink"] = ctx.Repo.RepoLink + "/settings/hooks"
ctx.Data["BaseLinkNew"] = ctx.Repo.RepoLink + "/settings/hooks"
ctx.Data["Description"] = ctx.Tr("repo.settings.hooks_desc", "https://docs.gitea.io/en-us/webhooks/")
ctx.Data["Description"] = ctx.Tr("repo.settings.hooks_desc", "https://docs.gitea.com/usage/webhooks")
ws, err := webhook.ListWebhooksByOpts(ctx, &webhook.ListWebhookOptions{RepoID: ctx.Repo.Repository.ID})
if err != nil {
+4 -7
View File
@@ -157,7 +157,7 @@ func Milestones(ctx *context.Context) {
}
repoOpts := repo_model.SearchRepoOptions{
Actor: ctxUser,
Actor: ctx.Doer,
OwnerID: ctxUser.ID,
Private: true,
AllPublic: false, // Include also all public repositories of users and public organisations
@@ -449,7 +449,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
// - Team has read permission to repository.
repoOpts := &repo_model.SearchRepoOptions{
Actor: ctx.Doer,
OwnerID: ctx.Doer.ID,
OwnerID: ctxUser.ID,
Private: true,
AllPublic: false,
AllLimited: false,
@@ -567,12 +567,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
// Remove repositories that should not be shown,
// which are repositories that have no issues and are not selected by the user.
selectedReposMap := make(map[int64]struct{}, len(selectedRepoIDs))
for _, repoID := range selectedRepoIDs {
selectedReposMap[repoID] = struct{}{}
}
selectedRepos := container.SetOf(selectedRepoIDs...)
for k, v := range issueCountByRepo {
if _, ok := selectedReposMap[k]; !ok && v == 0 {
if v == 0 && !selectedRepos.Contains(k) {
delete(issueCountByRepo, k)
}
}