Skip to content

Commit 17c691f

Browse files
6543techknowlogick
authored andcommitted
[Backport] [API] Allow only specific Colums to be updated on Issue (#9539) (#9580)
* Fix #9189 - API Allow only specific Colums to be updated on Issue (#9539) * dont insert "-1" in any case to issue.poster_id * Make sure API cant override importand fields * code format * add Test for IssueEdit * load milestone and return it on IssueEdit via API * extend Test for TestAPIEditIssue * fix TEST * make sure Poster is loaded * keep code format on backport as it is
1 parent cb3fe4c commit 17c691f

File tree

7 files changed

+116
-23
lines changed

7 files changed

+116
-23
lines changed

integrations/api_issue_test.go

+59
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"net/http"
1010
"testing"
11+
"time"
1112

1213
"code.gitea.io/gitea/models"
1314
api "code.gitea.io/gitea/modules/structs"
@@ -62,3 +63,61 @@ func TestAPICreateIssue(t *testing.T) {
6263
Title: title,
6364
})
6465
}
66+
67+
func TestAPIEditIssue(t *testing.T) {
68+
prepareTestEnv(t)
69+
70+
issueBefore := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 9}).(*models.Issue)
71+
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: issueBefore.RepoID}).(*models.Repository)
72+
owner := models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User)
73+
assert.NoError(t, issueBefore.LoadAttributes())
74+
assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix))
75+
assert.Equal(t, api.StateOpen, issueBefore.State())
76+
77+
session := loginUser(t, owner.Name)
78+
token := getTokenForLoggedInUser(t, session)
79+
80+
// update values of issue
81+
issueState := "closed"
82+
removeDeadline := time.Unix(0, 0)
83+
milestone := int64(4)
84+
body := "new content!"
85+
title := "new title from api set"
86+
87+
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d?token=%s", owner.Name, repo.Name, issueBefore.Index, token)
88+
req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{
89+
State: &issueState,
90+
Deadline: &removeDeadline,
91+
Milestone: &milestone,
92+
Body: &body,
93+
Title: title,
94+
95+
// ToDo change more
96+
})
97+
resp := session.MakeRequest(t, req, http.StatusCreated)
98+
var apiIssue api.Issue
99+
DecodeJSON(t, resp, &apiIssue)
100+
101+
issueAfter := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 9}).(*models.Issue)
102+
103+
// check deleted user
104+
assert.Equal(t, int64(500), issueAfter.PosterID)
105+
assert.NoError(t, issueAfter.LoadAttributes())
106+
assert.Equal(t, int64(-1), issueAfter.PosterID)
107+
assert.Equal(t, int64(-1), issueBefore.PosterID)
108+
assert.Equal(t, int64(-1), apiIssue.Poster.ID)
109+
110+
// API response
111+
assert.Equal(t, api.StateClosed, apiIssue.State)
112+
assert.Equal(t, milestone, apiIssue.Milestone.ID)
113+
assert.Equal(t, body, apiIssue.Body)
114+
assert.True(t, apiIssue.Deadline == nil)
115+
assert.Equal(t, title, apiIssue.Title)
116+
117+
// in database
118+
assert.Equal(t, api.StateClosed, issueAfter.State())
119+
assert.Equal(t, milestone, issueAfter.MilestoneID)
120+
assert.Equal(t, int64(0), int64(issueAfter.DeadlineUnix))
121+
assert.Equal(t, body, issueAfter.Content)
122+
assert.Equal(t, title, issueAfter.Title)
123+
}

models/fixtures/issue.yml

+14-1
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,17 @@
9696
is_closed: false
9797
is_pull: true
9898
created_unix: 946684820
99-
updated_unix: 978307180
99+
updated_unix: 978307180
100+
101+
-
102+
id: 9
103+
repo_id: 42
104+
index: 1
105+
poster_id: 500
106+
name: issue from deleted account
107+
content: content from deleted account
108+
is_closed: false
109+
is_pull: false
110+
created_unix: 946684830
111+
updated_unix: 999307200
112+
deadline_unix: 1019307200

models/fixtures/milestone.yml

+8
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,11 @@
2121
content: content3
2222
is_closed: true
2323
num_issues: 0
24+
25+
-
26+
id: 4
27+
repo_id: 42
28+
name: milestone of repo42
29+
content: content random
30+
is_closed: false
31+
num_issues: 0

models/fixtures/repository.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,8 @@
547547
is_private: false
548548
num_stars: 0
549549
num_forks: 0
550-
num_issues: 0
550+
num_issues: 1
551+
num_milestones: 1
551552
is_mirror: false
552553

553554
-

models/issue.go

+24-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// Copyright 2014 The Gogs Authors. All rights reserved.
2+
// Copyright 2020 The Gitea Authors. All rights reserved.
23
// Use of this source code is governed by a MIT-style
34
// license that can be found in the LICENSE file.
45

@@ -238,6 +239,16 @@ func (issue *Issue) loadReactions(e Engine) (err error) {
238239
return nil
239240
}
240241

242+
func (issue *Issue) loadMilestone(e Engine) (err error) {
243+
if issue.Milestone == nil && issue.MilestoneID > 0 {
244+
issue.Milestone, err = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
245+
if err != nil && !IsErrMilestoneNotExist(err) {
246+
return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err)
247+
}
248+
}
249+
return nil
250+
}
251+
241252
func (issue *Issue) loadAttributes(e Engine) (err error) {
242253
if err = issue.loadRepo(e); err != nil {
243254
return
@@ -251,11 +262,8 @@ func (issue *Issue) loadAttributes(e Engine) (err error) {
251262
return
252263
}
253264

254-
if issue.Milestone == nil && issue.MilestoneID > 0 {
255-
issue.Milestone, err = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
256-
if err != nil && !IsErrMilestoneNotExist(err) {
257-
return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err)
258-
}
265+
if err = issue.loadMilestone(e); err != nil {
266+
return
259267
}
260268

261269
if err = issue.loadAssignees(e); err != nil {
@@ -295,6 +303,11 @@ func (issue *Issue) LoadAttributes() error {
295303
return issue.loadAttributes(x)
296304
}
297305

306+
// LoadMilestone load milestone of this issue.
307+
func (issue *Issue) LoadMilestone() error {
308+
return issue.loadMilestone(x)
309+
}
310+
298311
// GetIsRead load the `IsRead` field of the issue
299312
func (issue *Issue) GetIsRead(userID int64) error {
300313
issueUser := &IssueUser{IssueID: issue.ID, UID: userID}
@@ -1730,22 +1743,17 @@ func SearchIssueIDsByKeyword(kw string, repoID int64, limit, start int) (int64,
17301743
return total, ids, nil
17311744
}
17321745

1733-
func updateIssue(e Engine, issue *Issue) error {
1734-
_, err := e.ID(issue.ID).AllCols().Update(issue)
1735-
if err != nil {
1736-
return err
1737-
}
1738-
return nil
1739-
}
1740-
1741-
// UpdateIssue updates all fields of given issue.
1742-
func UpdateIssue(issue *Issue) error {
1746+
// UpdateIssueByAPI updates all allowed fields of given issue.
1747+
func UpdateIssueByAPI(issue *Issue) error {
17431748
sess := x.NewSession()
17441749
defer sess.Close()
17451750
if err := sess.Begin(); err != nil {
17461751
return err
17471752
}
1748-
if err := updateIssue(sess, issue); err != nil {
1753+
if _, err := sess.ID(issue.ID).Cols(
1754+
"name", "is_closed", "content", "milestone_id", "priority",
1755+
"deadline_unix", "updated_unix", "closed_unix", "is_locked").
1756+
Update(issue); err != nil {
17491757
return err
17501758
}
17511759
if err := issue.neuterCrossReferences(sess); err != nil {

routers/api/v1/repo/issue.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
352352
}
353353
}
354354

355-
if err = models.UpdateIssue(issue); err != nil {
356-
ctx.Error(500, "UpdateIssue", err)
355+
if err = models.UpdateIssueByAPI(issue); err != nil {
356+
ctx.InternalServerError(err)
357357
return
358358
}
359359
if form.State != nil {
@@ -372,7 +372,11 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
372372
// Refetch from database to assign some automatic values
373373
issue, err = models.GetIssueByID(issue.ID)
374374
if err != nil {
375-
ctx.Error(500, "GetIssueByID", err)
375+
ctx.InternalServerError(err)
376+
return
377+
}
378+
if err = issue.LoadMilestone(); err != nil {
379+
ctx.InternalServerError(err)
376380
return
377381
}
378382
ctx.JSON(201, issue.APIFormat())

routers/api/v1/repo/pull.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,8 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
420420
}
421421
}
422422

423-
if err = models.UpdateIssue(issue); err != nil {
424-
ctx.Error(500, "UpdateIssue", err)
423+
if err = models.UpdateIssueByAPI(issue); err != nil {
424+
ctx.InternalServerError(err)
425425
return
426426
}
427427
if form.State != nil {

0 commit comments

Comments
 (0)