diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2023-11-26 07:43:23 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-25 23:43:23 +0000 |
commit | bc3d8bff73a5bd307dc825254b51bfedd722f078 (patch) | |
tree | 3e36c10cc0015ce9339f3520411ec9ff742e1d7c /models | |
parent | 7f81110461903685807f2e863d67fe89db1be060 (diff) | |
download | gitea-bc3d8bff73a5bd307dc825254b51bfedd722f078.tar.gz gitea-bc3d8bff73a5bd307dc825254b51bfedd722f078.zip |
Fix comment permissions (#28213) (#28216)
backport #28213
This PR will fix some missed checks for private repositories' data on
web routes and API routes.
Diffstat (limited to 'models')
-rw-r--r-- | models/asymkey/gpg_key.go | 12 | ||||
-rw-r--r-- | models/fixtures/comment.yml | 9 | ||||
-rw-r--r-- | models/fixtures/issue.yml | 2 | ||||
-rw-r--r-- | models/issues/comment.go | 6 | ||||
-rw-r--r-- | models/issues/content_history.go | 4 | ||||
-rw-r--r-- | models/issues/content_history_test.go | 4 | ||||
-rw-r--r-- | models/project/project.go | 12 | ||||
-rw-r--r-- | models/repo/release.go | 15 | ||||
-rw-r--r-- | models/webhook/webhook.go | 77 | ||||
-rw-r--r-- | models/webhook/webhook_test.go | 16 |
10 files changed, 96 insertions, 61 deletions
diff --git a/models/asymkey/gpg_key.go b/models/asymkey/gpg_key.go index 21d271bed4..15e0de7ff5 100644 --- a/models/asymkey/gpg_key.go +++ b/models/asymkey/gpg_key.go @@ -92,10 +92,9 @@ func CountUserGPGKeys(ctx context.Context, userID int64) (int64, error) { return db.GetEngine(ctx).Where("owner_id=? AND primary_key_id=''", userID).Count(&GPGKey{}) } -// GetGPGKeyByID returns public key by given ID. -func GetGPGKeyByID(ctx context.Context, keyID int64) (*GPGKey, error) { +func GetGPGKeyForUserByID(ctx context.Context, ownerID, keyID int64) (*GPGKey, error) { key := new(GPGKey) - has, err := db.GetEngine(ctx).ID(keyID).Get(key) + has, err := db.GetEngine(ctx).Where("id=? AND owner_id=?", keyID, ownerID).Get(key) if err != nil { return nil, err } else if !has { @@ -225,7 +224,7 @@ func deleteGPGKey(ctx context.Context, keyID string) (int64, error) { // DeleteGPGKey deletes GPG key information in database. func DeleteGPGKey(ctx context.Context, doer *user_model.User, id int64) (err error) { - key, err := GetGPGKeyByID(ctx, id) + key, err := GetGPGKeyForUserByID(ctx, doer.ID, id) if err != nil { if IsErrGPGKeyNotExist(err) { return nil @@ -233,11 +232,6 @@ func DeleteGPGKey(ctx context.Context, doer *user_model.User, id int64) (err err return fmt.Errorf("GetPublicKeyByID: %w", err) } - // Check if user has access to delete this key. - if !doer.IsAdmin && doer.ID != key.OwnerID { - return ErrGPGKeyAccessDenied{doer.ID, key.ID} - } - ctx, committer, err := db.TxContext(ctx) if err != nil { return err diff --git a/models/fixtures/comment.yml b/models/fixtures/comment.yml index bd64680c8c..17586caa21 100644 --- a/models/fixtures/comment.yml +++ b/models/fixtures/comment.yml @@ -66,3 +66,12 @@ tree_path: "README.md" created_unix: 946684812 invalidated: true + +- + id: 8 + type: 0 # comment + poster_id: 2 + issue_id: 4 # in repo_id 2 + content: "comment in private pository" + created_unix: 946684811 + updated_unix: 946684811 diff --git a/models/fixtures/issue.yml b/models/fixtures/issue.yml index ccc1fe41fb..0c9b6ff406 100644 --- a/models/fixtures/issue.yml +++ b/models/fixtures/issue.yml @@ -61,7 +61,7 @@ priority: 0 is_closed: true is_pull: false - num_comments: 0 + num_comments: 1 created_unix: 946684830 updated_unix: 978307200 is_locked: false diff --git a/models/issues/comment.go b/models/issues/comment.go index df1a300354..9eaa8a6eba 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -1016,6 +1016,7 @@ type FindCommentsOptions struct { Type CommentType IssueIDs []int64 Invalidated util.OptionalBool + IsPull util.OptionalBool } // ToConds implements FindOptions interface @@ -1050,6 +1051,9 @@ func (opts *FindCommentsOptions) ToConds() builder.Cond { if !opts.Invalidated.IsNone() { cond = cond.And(builder.Eq{"comment.invalidated": opts.Invalidated.IsTrue()}) } + if opts.IsPull != util.OptionalBoolNone { + cond = cond.And(builder.Eq{"issue.is_pull": opts.IsPull.IsTrue()}) + } return cond } @@ -1057,7 +1061,7 @@ func (opts *FindCommentsOptions) ToConds() builder.Cond { func FindComments(ctx context.Context, opts *FindCommentsOptions) (CommentList, error) { comments := make([]*Comment, 0, 10) sess := db.GetEngine(ctx).Where(opts.ToConds()) - if opts.RepoID > 0 { + if opts.RepoID > 0 || opts.IsPull != util.OptionalBoolNone { sess.Join("INNER", "issue", "issue.id = comment.issue_id") } diff --git a/models/issues/content_history.go b/models/issues/content_history.go index cc06b184d7..8c333bc6dd 100644 --- a/models/issues/content_history.go +++ b/models/issues/content_history.go @@ -218,9 +218,9 @@ func GetIssueContentHistoryByID(dbCtx context.Context, id int64) (*ContentHistor } // GetIssueContentHistoryAndPrev get a history and the previous non-deleted history (to compare) -func GetIssueContentHistoryAndPrev(dbCtx context.Context, id int64) (history, prevHistory *ContentHistory, err error) { +func GetIssueContentHistoryAndPrev(dbCtx context.Context, issueID, id int64) (history, prevHistory *ContentHistory, err error) { history = &ContentHistory{} - has, err := db.GetEngine(dbCtx).ID(id).Get(history) + has, err := db.GetEngine(dbCtx).Where("id=? AND issue_id=?", id, issueID).Get(history) if err != nil { log.Error("failed to get issue content history %v. err=%v", id, err) return nil, nil, err diff --git a/models/issues/content_history_test.go b/models/issues/content_history_test.go index 53638e967f..0ea1d0f7b2 100644 --- a/models/issues/content_history_test.go +++ b/models/issues/content_history_test.go @@ -58,13 +58,13 @@ func TestContentHistory(t *testing.T) { hasHistory2, _ := issues_model.HasIssueContentHistory(dbCtx, 10, 1) assert.False(t, hasHistory2) - h6, h6Prev, _ := issues_model.GetIssueContentHistoryAndPrev(dbCtx, 6) + h6, h6Prev, _ := issues_model.GetIssueContentHistoryAndPrev(dbCtx, 10, 6) assert.EqualValues(t, 6, h6.ID) assert.EqualValues(t, 5, h6Prev.ID) // soft-delete _ = issues_model.SoftDeleteIssueContentHistory(dbCtx, 5) - h6, h6Prev, _ = issues_model.GetIssueContentHistoryAndPrev(dbCtx, 6) + h6, h6Prev, _ = issues_model.GetIssueContentHistoryAndPrev(dbCtx, 10, 6) assert.EqualValues(t, 6, h6.ID) assert.EqualValues(t, 4, h6Prev.ID) diff --git a/models/project/project.go b/models/project/project.go index 3a1bfe1dbd..199fd04651 100644 --- a/models/project/project.go +++ b/models/project/project.go @@ -311,6 +311,18 @@ func GetProjectByID(ctx context.Context, id int64) (*Project, error) { return p, nil } +// GetProjectForRepoByID returns the projects in a repository +func GetProjectForRepoByID(ctx context.Context, repoID, id int64) (*Project, error) { + p := new(Project) + has, err := db.GetEngine(ctx).Where("id=? AND repo_id=?", id, repoID).Get(p) + if err != nil { + return nil, err + } else if !has { + return nil, ErrProjectNotExist{ID: id} + } + return p, nil +} + // UpdateProject updates project properties func UpdateProject(ctx context.Context, p *Project) error { if !IsCardTypeValid(p.CardType) { diff --git a/models/repo/release.go b/models/repo/release.go index ff31ec4510..223d3f2501 100644 --- a/models/repo/release.go +++ b/models/repo/release.go @@ -207,6 +207,21 @@ func GetReleaseByID(ctx context.Context, id int64) (*Release, error) { return rel, nil } +// GetReleaseForRepoByID returns release with given ID. +func GetReleaseForRepoByID(ctx context.Context, repoID, id int64) (*Release, error) { + rel := new(Release) + has, err := db.GetEngine(ctx). + Where("id=? AND repo_id=?", id, repoID). + Get(rel) + if err != nil { + return nil, err + } else if !has { + return nil, ErrReleaseNotExist{id, ""} + } + + return rel, nil +} + // FindReleasesOptions describes the conditions to Find releases type FindReleasesOptions struct { db.ListOptions diff --git a/models/webhook/webhook.go b/models/webhook/webhook.go index fc2bbed083..36e1662e67 100644 --- a/models/webhook/webhook.go +++ b/models/webhook/webhook.go @@ -392,39 +392,40 @@ func CreateWebhooks(ctx context.Context, ws []*Webhook) error { return db.Insert(ctx, ws) } -// getWebhook uses argument bean as query condition, -// ID must be specified and do not assign unnecessary fields. -func getWebhook(bean *Webhook) (*Webhook, error) { - has, err := db.GetEngine(db.DefaultContext).Get(bean) +// GetWebhookByID returns webhook of repository by given ID. +func GetWebhookByID(ctx context.Context, id int64) (*Webhook, error) { + bean := new(Webhook) + has, err := db.GetEngine(ctx).ID(id).Get(bean) if err != nil { return nil, err } else if !has { - return nil, ErrWebhookNotExist{ID: bean.ID} + return nil, ErrWebhookNotExist{ID: id} } return bean, nil } -// GetWebhookByID returns webhook of repository by given ID. -func GetWebhookByID(id int64) (*Webhook, error) { - return getWebhook(&Webhook{ - ID: id, - }) -} - // GetWebhookByRepoID returns webhook of repository by given ID. -func GetWebhookByRepoID(repoID, id int64) (*Webhook, error) { - return getWebhook(&Webhook{ - ID: id, - RepoID: repoID, - }) +func GetWebhookByRepoID(ctx context.Context, repoID, id int64) (*Webhook, error) { + webhook := new(Webhook) + has, err := db.GetEngine(ctx).Where("id=? AND repo_id=?", id, repoID).Get(webhook) + if err != nil { + return nil, err + } else if !has { + return nil, ErrWebhookNotExist{ID: id} + } + return webhook, nil } // GetWebhookByOwnerID returns webhook of a user or organization by given ID. -func GetWebhookByOwnerID(ownerID, id int64) (*Webhook, error) { - return getWebhook(&Webhook{ - ID: id, - OwnerID: ownerID, - }) +func GetWebhookByOwnerID(ctx context.Context, ownerID, id int64) (*Webhook, error) { + webhook := new(Webhook) + has, err := db.GetEngine(ctx).Where("id=? AND owner_id=?", id, ownerID).Get(webhook) + if err != nil { + return nil, err + } else if !has { + return nil, ErrWebhookNotExist{ID: id} + } + return webhook, nil } // ListWebhookOptions are options to filter webhooks on ListWebhooksByOpts @@ -482,20 +483,20 @@ func UpdateWebhookLastStatus(w *Webhook) error { return err } -// deleteWebhook uses argument bean as query condition, +// DeleteWebhookByID uses argument bean as query condition, // ID must be specified and do not assign unnecessary fields. -func deleteWebhook(bean *Webhook) (err error) { - ctx, committer, err := db.TxContext(db.DefaultContext) +func DeleteWebhookByID(ctx context.Context, id int64) (err error) { + ctx, committer, err := db.TxContext(ctx) if err != nil { return err } defer committer.Close() - if count, err := db.DeleteByBean(ctx, bean); err != nil { + if count, err := db.DeleteByID(ctx, id, new(Webhook)); err != nil { return err } else if count == 0 { - return ErrWebhookNotExist{ID: bean.ID} - } else if _, err = db.DeleteByBean(ctx, &HookTask{HookID: bean.ID}); err != nil { + return ErrWebhookNotExist{ID: id} + } else if _, err = db.DeleteByBean(ctx, &HookTask{HookID: id}); err != nil { return err } @@ -503,17 +504,17 @@ func deleteWebhook(bean *Webhook) (err error) { } // DeleteWebhookByRepoID deletes webhook of repository by given ID. -func DeleteWebhookByRepoID(repoID, id int64) error { - return deleteWebhook(&Webhook{ - ID: id, - RepoID: repoID, - }) +func DeleteWebhookByRepoID(ctx context.Context, repoID, id int64) error { + if _, err := GetWebhookByRepoID(ctx, repoID, id); err != nil { + return err + } + return DeleteWebhookByID(ctx, id) } // DeleteWebhookByOwnerID deletes webhook of a user or organization by given ID. -func DeleteWebhookByOwnerID(ownerID, id int64) error { - return deleteWebhook(&Webhook{ - ID: id, - OwnerID: ownerID, - }) +func DeleteWebhookByOwnerID(ctx context.Context, ownerID, id int64) error { + if _, err := GetWebhookByOwnerID(ctx, ownerID, id); err != nil { + return err + } + return DeleteWebhookByID(ctx, id) } diff --git a/models/webhook/webhook_test.go b/models/webhook/webhook_test.go index de6568c321..b7d2d3d41a 100644 --- a/models/webhook/webhook_test.go +++ b/models/webhook/webhook_test.go @@ -101,22 +101,22 @@ func TestCreateWebhook(t *testing.T) { func TestGetWebhookByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hook, err := GetWebhookByRepoID(1, 1) + hook, err := GetWebhookByRepoID(db.DefaultContext, 1, 1) assert.NoError(t, err) assert.Equal(t, int64(1), hook.ID) - _, err = GetWebhookByRepoID(unittest.NonexistentID, unittest.NonexistentID) + _, err = GetWebhookByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) assert.Error(t, err) assert.True(t, IsErrWebhookNotExist(err)) } func TestGetWebhookByOwnerID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hook, err := GetWebhookByOwnerID(3, 3) + hook, err := GetWebhookByOwnerID(db.DefaultContext, 3, 3) assert.NoError(t, err) assert.Equal(t, int64(3), hook.ID) - _, err = GetWebhookByOwnerID(unittest.NonexistentID, unittest.NonexistentID) + _, err = GetWebhookByOwnerID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) assert.Error(t, err) assert.True(t, IsErrWebhookNotExist(err)) } @@ -174,10 +174,10 @@ func TestUpdateWebhook(t *testing.T) { func TestDeleteWebhookByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2, RepoID: 1}) - assert.NoError(t, DeleteWebhookByRepoID(1, 2)) + assert.NoError(t, DeleteWebhookByRepoID(db.DefaultContext, 1, 2)) unittest.AssertNotExistsBean(t, &Webhook{ID: 2, RepoID: 1}) - err := DeleteWebhookByRepoID(unittest.NonexistentID, unittest.NonexistentID) + err := DeleteWebhookByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) assert.Error(t, err) assert.True(t, IsErrWebhookNotExist(err)) } @@ -185,10 +185,10 @@ func TestDeleteWebhookByRepoID(t *testing.T) { func TestDeleteWebhookByOwnerID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 3, OwnerID: 3}) - assert.NoError(t, DeleteWebhookByOwnerID(3, 3)) + assert.NoError(t, DeleteWebhookByOwnerID(db.DefaultContext, 3, 3)) unittest.AssertNotExistsBean(t, &Webhook{ID: 3, OwnerID: 3}) - err := DeleteWebhookByOwnerID(unittest.NonexistentID, unittest.NonexistentID) + err := DeleteWebhookByOwnerID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) assert.Error(t, err) assert.True(t, IsErrWebhookNotExist(err)) } |