Merge remote-tracking branch 'upstream/main' into limit-repo-size

This commit is contained in:
DmitryFrolovTri
2022-12-14 05:27:36 +00:00
166 changed files with 2898 additions and 1090 deletions
+1 -1
View File
@@ -110,7 +110,7 @@ func determineAccessMode(ctx *Context) (perm.AccessMode, error) {
return accessMode, err
}
for _, t := range teams {
perm := t.UnitAccessModeCtx(ctx, unit.TypePackages)
perm := t.UnitAccessMode(ctx, unit.TypePackages)
if accessMode < perm {
accessMode = perm
}
+7 -7
View File
@@ -163,13 +163,13 @@ func (r *Repository) CanUseTimetracker(issue *issues_model.Issue, user *user_mod
// 1. Is timetracker enabled
// 2. Is the user a contributor, admin, poster or assignee and do the repository policies require this?
isAssigned, _ := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user)
return r.Repository.IsTimetrackerEnabled() && (!r.Repository.AllowOnlyContributorsToTrackTime() ||
return r.Repository.IsTimetrackerEnabled(db.DefaultContext) && (!r.Repository.AllowOnlyContributorsToTrackTime(db.DefaultContext) ||
r.Permission.CanWriteIssuesOrPulls(issue.IsPull) || issue.IsPoster(user.ID) || isAssigned)
}
// CanCreateIssueDependencies returns whether or not a user can create dependencies.
func (r *Repository) CanCreateIssueDependencies(user *user_model.User, isPull bool) bool {
return r.Repository.IsDependenciesEnabled() && r.Permission.CanWriteIssuesOrPulls(isPull)
return r.Repository.IsDependenciesEnabled(db.DefaultContext) && r.Permission.CanWriteIssuesOrPulls(isPull)
}
// GetCommitsCount returns cached commit count for current view
@@ -528,12 +528,12 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
unit, err := ctx.Repo.Repository.GetUnit(unit_model.TypeExternalTracker)
unit, err := ctx.Repo.Repository.GetUnit(ctx, unit_model.TypeExternalTracker)
if err == nil {
ctx.Data["RepoExternalIssuesLink"] = unit.ExternalTrackerConfig().ExternalTrackerURL
}
ctx.Data["NumTags"], err = repo_model.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{
ctx.Data["NumTags"], err = repo_model.GetReleaseCountByRepoID(ctx, ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{
IncludeDrafts: true,
IncludeTags: true,
HasSha1: util.OptionalBoolTrue, // only draft releases which are created with existing tags
@@ -542,7 +542,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
ctx.ServerError("GetReleaseCountByRepoID", err)
return
}
ctx.Data["NumReleases"], err = repo_model.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{})
ctx.Data["NumReleases"], err = repo_model.GetReleaseCountByRepoID(ctx, ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{})
if err != nil {
ctx.ServerError("GetReleaseCountByRepoID", err)
return
@@ -723,13 +723,13 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
if ctx.Repo.Repository.Status == repo_model.RepositoryPendingTransfer {
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx.Repo.Repository)
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository)
if err != nil {
ctx.ServerError("GetPendingRepositoryTransfer", err)
return
}
if err := repoTransfer.LoadAttributes(); err != nil {
if err := repoTransfer.LoadAttributes(ctx); err != nil {
ctx.ServerError("LoadRecipient", err)
return
}
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package convert
import (
repo_model "code.gitea.io/gitea/models/repo"
api "code.gitea.io/gitea/modules/structs"
)
// ToAttachment converts models.Attachment to api.Attachment
func ToAttachment(a *repo_model.Attachment) *api.Attachment {
return &api.Attachment{
ID: a.ID,
Name: a.Name,
Created: a.CreatedUnix.AsTime(),
DownloadCount: a.DownloadCount,
Size: a.Size,
UUID: a.UUID,
DownloadURL: a.DownloadURL(),
}
}
func ToAttachments(attachments []*repo_model.Attachment) []*api.Attachment {
converted := make([]*api.Attachment, 0, len(attachments))
for _, attachment := range attachments {
converted = append(converted, ToAttachment(attachment))
}
return converted
}
+15 -14
View File
@@ -37,20 +37,21 @@ func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
}
apiIssue := &api.Issue{
ID: issue.ID,
URL: issue.APIURL(),
HTMLURL: issue.HTMLURL(),
Index: issue.Index,
Poster: ToUser(issue.Poster, nil),
Title: issue.Title,
Body: issue.Content,
Ref: issue.Ref,
Labels: ToLabelList(issue.Labels, issue.Repo, issue.Repo.Owner),
State: issue.State(),
IsLocked: issue.IsLocked,
Comments: issue.NumComments,
Created: issue.CreatedUnix.AsTime(),
Updated: issue.UpdatedUnix.AsTime(),
ID: issue.ID,
URL: issue.APIURL(),
HTMLURL: issue.HTMLURL(),
Index: issue.Index,
Poster: ToUser(issue.Poster, nil),
Title: issue.Title,
Body: issue.Content,
Attachments: ToAttachments(issue.Attachments),
Ref: issue.Ref,
Labels: ToLabelList(issue.Labels, issue.Repo, issue.Repo.Owner),
State: issue.State(),
IsLocked: issue.IsLocked,
Comments: issue.NumComments,
Created: issue.CreatedUnix.AsTime(),
Updated: issue.UpdatedUnix.AsTime(),
}
apiIssue.Repo = &api.RepositoryMeta{
+10 -9
View File
@@ -16,14 +16,15 @@ import (
// ToComment converts a issues_model.Comment to the api.Comment format
func ToComment(c *issues_model.Comment) *api.Comment {
return &api.Comment{
ID: c.ID,
Poster: ToUser(c.Poster, nil),
HTMLURL: c.HTMLURL(),
IssueURL: c.IssueURL(),
PRURL: c.PRURL(),
Body: c.Content,
Created: c.CreatedUnix.AsTime(),
Updated: c.UpdatedUnix.AsTime(),
ID: c.ID,
Poster: ToUser(c.Poster, nil),
HTMLURL: c.HTMLURL(),
IssueURL: c.IssueURL(),
PRURL: c.PRURL(),
Body: c.Content,
Attachments: ToAttachments(c.Attachments),
Created: c.CreatedUnix.AsTime(),
Updated: c.UpdatedUnix.AsTime(),
}
}
@@ -148,7 +149,7 @@ func ToTimelineComment(ctx context.Context, c *issues_model.Comment, doer *user_
var err error
repo, err = repo_model.GetRepositoryByID(ctx, c.Label.RepoID)
if err != nil {
log.Error("GetRepositoryByIDCtx(%d): %v", c.Label.RepoID, err)
log.Error("GetRepositoryByID(%d): %v", c.Label.RepoID, err)
return nil
}
}
+1 -18
View File
@@ -10,10 +10,6 @@ import (
// ToRelease convert a repo_model.Release to api.Release
func ToRelease(r *repo_model.Release) *api.Release {
assets := make([]*api.Attachment, 0)
for _, att := range r.Attachments {
assets = append(assets, ToReleaseAttachment(att))
}
return &api.Release{
ID: r.ID,
TagName: r.TagName,
@@ -29,19 +25,6 @@ func ToRelease(r *repo_model.Release) *api.Release {
CreatedAt: r.CreatedUnix.AsTime(),
PublishedAt: r.CreatedUnix.AsTime(),
Publisher: ToUser(r.Publisher, nil),
Attachments: assets,
}
}
// ToReleaseAttachment converts models.Attachment to api.Attachment
func ToReleaseAttachment(a *repo_model.Attachment) *api.Attachment {
return &api.Attachment{
ID: a.ID,
Name: a.Name,
Created: a.CreatedUnix.AsTime(),
DownloadCount: a.DownloadCount,
Size: a.Size,
UUID: a.UUID,
DownloadURL: a.DownloadURL(),
Attachments: ToAttachments(r.Attachments),
}
}
+11 -12
View File
@@ -8,7 +8,6 @@ import (
"time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
unit_model "code.gitea.io/gitea/models/unit"
@@ -44,7 +43,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, mode perm.Acc
hasIssues := false
var externalTracker *api.ExternalTracker
var internalTracker *api.InternalTracker
if unit, err := repo.GetUnit(unit_model.TypeIssues); err == nil {
if unit, err := repo.GetUnit(ctx, unit_model.TypeIssues); err == nil {
config := unit.IssuesConfig()
hasIssues = true
internalTracker = &api.InternalTracker{
@@ -52,7 +51,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, mode perm.Acc
AllowOnlyContributorsToTrackTime: config.AllowOnlyContributorsToTrackTime,
EnableIssueDependencies: config.EnableDependencies,
}
} else if unit, err := repo.GetUnit(unit_model.TypeExternalTracker); err == nil {
} else if unit, err := repo.GetUnit(ctx, unit_model.TypeExternalTracker); err == nil {
config := unit.ExternalTrackerConfig()
hasIssues = true
externalTracker = &api.ExternalTracker{
@@ -64,9 +63,9 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, mode perm.Acc
}
hasWiki := false
var externalWiki *api.ExternalWiki
if _, err := repo.GetUnit(unit_model.TypeWiki); err == nil {
if _, err := repo.GetUnit(ctx, unit_model.TypeWiki); err == nil {
hasWiki = true
} else if unit, err := repo.GetUnit(unit_model.TypeExternalWiki); err == nil {
} else if unit, err := repo.GetUnit(ctx, unit_model.TypeExternalWiki); err == nil {
hasWiki = true
config := unit.ExternalWikiConfig()
externalWiki = &api.ExternalWiki{
@@ -82,7 +81,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, mode perm.Acc
allowRebaseUpdate := false
defaultDeleteBranchAfterMerge := false
defaultMergeStyle := repo_model.MergeStyleMerge
if unit, err := repo.GetUnit(unit_model.TypePullRequests); err == nil {
if unit, err := repo.GetUnit(ctx, unit_model.TypePullRequests); err == nil {
config := unit.PullRequestsConfig()
hasPullRequests = true
ignoreWhitespaceConflicts = config.IgnoreWhitespaceConflicts
@@ -95,21 +94,21 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, mode perm.Acc
defaultMergeStyle = config.GetDefaultMergeStyle()
}
hasProjects := false
if _, err := repo.GetUnit(unit_model.TypeProjects); err == nil {
if _, err := repo.GetUnit(ctx, unit_model.TypeProjects); err == nil {
hasProjects = true
}
if err := repo.GetOwner(db.DefaultContext); err != nil {
if err := repo.GetOwner(ctx); err != nil {
return nil
}
numReleases, _ := repo_model.GetReleaseCountByRepoID(repo.ID, repo_model.FindReleasesOptions{IncludeDrafts: false, IncludeTags: false})
numReleases, _ := repo_model.GetReleaseCountByRepoID(ctx, repo.ID, repo_model.FindReleasesOptions{IncludeDrafts: false, IncludeTags: false})
mirrorInterval := ""
var mirrorUpdated time.Time
if repo.IsMirror {
var err error
repo.Mirror, err = repo_model.GetMirrorByRepoID(db.DefaultContext, repo.ID)
repo.Mirror, err = repo_model.GetMirrorByRepoID(ctx, repo.ID)
if err == nil {
mirrorInterval = repo.Mirror.Interval.String()
mirrorUpdated = repo.Mirror.UpdatedUnix.AsTime()
@@ -118,11 +117,11 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, mode perm.Acc
var transfer *api.RepoTransfer
if repo.Status == repo_model.RepositoryPendingTransfer {
t, err := models.GetPendingRepositoryTransfer(repo)
t, err := models.GetPendingRepositoryTransfer(ctx, repo)
if err != nil && !models.IsErrNoPendingTransfer(err) {
log.Warn("GetPendingRepositoryTransfer: %v", err)
} else {
if err := t.LoadAttributes(); err != nil {
if err := t.LoadAttributes(ctx); err != nil {
log.Warn("LoadAttributes of RepoTransfer: %v", err)
} else {
transfer = ToRepoTransfer(t)
+8 -11
View File
@@ -305,18 +305,15 @@ func postProcess(ctx *RenderContext, procs []processor, input io.Reader, output
return err
}
res := bytes.NewBuffer(make([]byte, 0, len(rawHTML)+50))
// prepend "<html><body>"
_, _ = res.WriteString("<html><body>")
// Strip out nuls - they're always invalid
_, _ = res.Write(tagCleaner.ReplaceAll([]byte(nulCleaner.Replace(string(rawHTML))), []byte("&lt;$1")))
// close the tags
_, _ = res.WriteString("</body></html>")
// parse the HTML
node, err := html.Parse(res)
node, err := html.Parse(io.MultiReader(
// prepend "<html><body>"
strings.NewReader("<html><body>"),
// Strip out nuls - they're always invalid
bytes.NewReader(tagCleaner.ReplaceAll([]byte(nulCleaner.Replace(string(rawHTML))), []byte("&lt;$1"))),
// close the tags
strings.NewReader("</body></html>"),
))
if err != nil {
return &postProcessError{"invalid HTML", err}
}
+5
View File
@@ -314,6 +314,11 @@ func (m *webhookNotifier) NotifyNewPullRequest(ctx context.Context, pull *issues
}
func (m *webhookNotifier) NotifyIssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldContent string) {
if err := issue.LoadRepo(ctx); err != nil {
log.Error("LoadRepo: %v", err)
return
}
mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
var err error
if issue.IsPull {
+17 -22
View File
@@ -13,30 +13,25 @@ import (
user_model "code.gitea.io/gitea/models/user"
)
func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error {
collaboration := &repo_model.Collaboration{
RepoID: repo.ID,
UserID: u.ID,
}
func AddCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error {
return db.AutoTx(ctx, func(ctx context.Context) error {
collaboration := &repo_model.Collaboration{
RepoID: repo.ID,
UserID: u.ID,
}
has, err := db.GetByBean(ctx, collaboration)
if err != nil {
return err
} else if has {
return nil
}
collaboration.Mode = perm.AccessModeWrite
has, err := db.GetByBean(ctx, collaboration)
if err != nil {
return err
} else if has {
return nil
}
collaboration.Mode = perm.AccessModeWrite
if err = db.Insert(ctx, collaboration); err != nil {
return err
}
if err = db.Insert(ctx, collaboration); err != nil {
return err
}
return access_model.RecalculateUserAccess(ctx, repo, u.ID)
}
// AddCollaborator adds new collaboration to a repository with default access mode.
func AddCollaborator(repo *repo_model.Repository, u *user_model.User) error {
return db.WithTx(db.DefaultContext, func(ctx context.Context) error {
return addCollaborator(ctx, repo, u)
return access_model.RecalculateUserAccess(ctx, repo, u.ID)
})
}
+8 -8
View File
@@ -25,7 +25,7 @@ func TestRepository_AddCollaborator(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
assert.NoError(t, repo.GetOwner(db.DefaultContext))
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
assert.NoError(t, AddCollaborator(repo, user))
assert.NoError(t, AddCollaborator(db.DefaultContext, repo, user))
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}, &user_model.User{ID: userID})
}
testSuccess(1, 4)
@@ -50,7 +50,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
}
// change to collaborator
assert.NoError(t, AddCollaborator(repo, user))
assert.NoError(t, AddCollaborator(db.DefaultContext, repo, user))
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -103,7 +103,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
}
// change to collaborator to default write access
assert.NoError(t, AddCollaborator(repo, user))
assert.NoError(t, AddCollaborator(db.DefaultContext, repo, user))
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -111,7 +111,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
assert.True(t, perm.CanWrite(unit.Type))
}
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, user.ID, perm_model.AccessModeRead))
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -155,7 +155,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
}
// change to collaborator to default write access
assert.NoError(t, AddCollaborator(repo, user))
assert.NoError(t, AddCollaborator(db.DefaultContext, repo, user))
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -163,7 +163,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
assert.True(t, perm.CanWrite(unit.Type))
}
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, user.ID, perm_model.AccessModeRead))
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -217,7 +217,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
}
// change to collaborator to default write access
assert.NoError(t, AddCollaborator(repo, user))
assert.NoError(t, AddCollaborator(db.DefaultContext, repo, user))
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -225,7 +225,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
assert.True(t, perm.CanWrite(unit.Type))
}
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, user.ID, perm_model.AccessModeRead))
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
+3 -3
View File
@@ -125,10 +125,10 @@ func CreateRepositoryByExample(ctx context.Context, doer, u *user_model.User, re
return fmt.Errorf("IsUserRepoAdmin: %w", err)
} else if !isAdmin {
// Make creator repo admin if it wasn't assigned automatically
if err = addCollaborator(ctx, repo, doer); err != nil {
return fmt.Errorf("addCollaborator: %w", err)
if err = AddCollaborator(ctx, repo, doer); err != nil {
return fmt.Errorf("AddCollaborator: %w", err)
}
if err = repo_model.ChangeCollaborationAccessModeCtx(ctx, repo, doer.ID, perm.AccessModeAdmin); err != nil {
if err = repo_model.ChangeCollaborationAccessMode(ctx, repo, doer.ID, perm.AccessModeAdmin); err != nil {
return fmt.Errorf("ChangeCollaborationAccessModeCtx: %w", err)
}
}
+13 -12
View File
@@ -41,18 +41,19 @@ type RepositoryMeta struct {
// Issue represents an issue in a repository
// swagger:model
type Issue struct {
ID int64 `json:"id"`
URL string `json:"url"`
HTMLURL string `json:"html_url"`
Index int64 `json:"number"`
Poster *User `json:"user"`
OriginalAuthor string `json:"original_author"`
OriginalAuthorID int64 `json:"original_author_id"`
Title string `json:"title"`
Body string `json:"body"`
Ref string `json:"ref"`
Labels []*Label `json:"labels"`
Milestone *Milestone `json:"milestone"`
ID int64 `json:"id"`
URL string `json:"url"`
HTMLURL string `json:"html_url"`
Index int64 `json:"number"`
Poster *User `json:"user"`
OriginalAuthor string `json:"original_author"`
OriginalAuthorID int64 `json:"original_author_id"`
Title string `json:"title"`
Body string `json:"body"`
Ref string `json:"ref"`
Attachments []*Attachment `json:"assets"`
Labels []*Label `json:"labels"`
Milestone *Milestone `json:"milestone"`
// deprecated
Assignee *User `json:"assignee"`
Assignees []*User `json:"assignees"`
+9 -8
View File
@@ -9,14 +9,15 @@ import (
// Comment represents a comment on a commit or issue
type Comment struct {
ID int64 `json:"id"`
HTMLURL string `json:"html_url"`
PRURL string `json:"pull_request_url"`
IssueURL string `json:"issue_url"`
Poster *User `json:"user"`
OriginalAuthor string `json:"original_author"`
OriginalAuthorID int64 `json:"original_author_id"`
Body string `json:"body"`
ID int64 `json:"id"`
HTMLURL string `json:"html_url"`
PRURL string `json:"pull_request_url"`
IssueURL string `json:"issue_url"`
Poster *User `json:"user"`
OriginalAuthor string `json:"original_author"`
OriginalAuthorID int64 `json:"original_author_id"`
Body string `json:"body"`
Attachments []*Attachment `json:"assets"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
// swagger:strfmt date-time
+2 -10
View File
@@ -7,7 +7,6 @@ import (
goctx "context"
"fmt"
"net/http"
"reflect"
"strings"
"code.gitea.io/gitea/modules/context"
@@ -18,16 +17,9 @@ import (
)
// Bind binding an obj to a handler
func Bind(obj interface{}) http.HandlerFunc {
tp := reflect.TypeOf(obj)
if tp.Kind() == reflect.Ptr {
tp = tp.Elem()
}
if tp.Kind() != reflect.Struct {
panic("Only structs are allowed to bind")
}
func Bind[T any](obj T) http.HandlerFunc {
return Wrap(func(ctx *context.Context) {
theObj := reflect.New(tp).Interface() // create a new form obj for every request but not use obj directly
theObj := new(T) // create a new form obj for every request but not use obj directly
binding.Bind(ctx.Req, theObj)
SetForm(ctx, theObj)
middleware.AssignForm(theObj, ctx.Data)