Compare commits
No commits in common. "fc16f8a108ae3c191a9dd93df429538e650d26c4" and "620e4281174882a39794a7b651c6d5318d65b44d" have entirely different histories.
fc16f8a108
...
620e428117
46 changed files with 131 additions and 635 deletions
4
.github/workflows/release-tag-rc.yml
vendored
4
.github/workflows/release-tag-rc.yml
vendored
|
@ -56,10 +56,6 @@ jobs:
|
||||||
- name: upload binaries to s3
|
- name: upload binaries to s3
|
||||||
run: |
|
run: |
|
||||||
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
||||||
- name: Install GH CLI
|
|
||||||
uses: dev-hanz-ops/install-gh-cli-action@v0.1.0
|
|
||||||
with:
|
|
||||||
gh-cli-version: 2.39.1
|
|
||||||
- name: create github release
|
- name: create github release
|
||||||
run: |
|
run: |
|
||||||
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --draft --notes-from-tag dist/release/*
|
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --draft --notes-from-tag dist/release/*
|
||||||
|
|
6
.github/workflows/release-tag-version.yml
vendored
6
.github/workflows/release-tag-version.yml
vendored
|
@ -58,13 +58,9 @@ jobs:
|
||||||
- name: upload binaries to s3
|
- name: upload binaries to s3
|
||||||
run: |
|
run: |
|
||||||
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
||||||
- name: Install GH CLI
|
|
||||||
uses: dev-hanz-ops/install-gh-cli-action@v0.1.0
|
|
||||||
with:
|
|
||||||
gh-cli-version: 2.39.1
|
|
||||||
- name: create github release
|
- name: create github release
|
||||||
run: |
|
run: |
|
||||||
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --notes-from-tag dist/release/*
|
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --draft --notes-from-tag dist/release/*
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||||
docker-rootful:
|
docker-rootful:
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
pipeline:
|
|
||||||
nulo-container:
|
|
||||||
image: docker.io/woodpeckerci/plugin-docker-buildx
|
|
||||||
settings:
|
|
||||||
repo: gitea.nulo.in/nulo/forgejo
|
|
||||||
tag: v1.21.1-0
|
|
||||||
registry: https://gitea.nulo.in
|
|
||||||
username: Nulo
|
|
||||||
password:
|
|
||||||
from_secret: registry_secret
|
|
||||||
secrets: [REGISTRY_SECRET]
|
|
||||||
when:
|
|
||||||
branch: "nulo/release/v1.20"
|
|
||||||
event: "push"
|
|
||||||
|
|
27
CHANGELOG.md
27
CHANGELOG.md
|
@ -4,33 +4,6 @@ This changelog goes through all the changes that have been made in each release
|
||||||
without substantial changes to our git log; to see the highlights of what has
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.com).
|
been added to each release, please refer to the [blog](https://blog.gitea.com).
|
||||||
|
|
||||||
## [1.21.1](https://github.com/go-gitea/gitea/releases/tag/1.21.1) - 2023-11-26
|
|
||||||
|
|
||||||
* SECURITY
|
|
||||||
* Fix comment permissions (#28213) (#28216)
|
|
||||||
* BUGFIXES
|
|
||||||
* Fix delete-orphaned-repos (#28200) (#28202)
|
|
||||||
* Make CORS work for oauth2 handlers (#28184) (#28185)
|
|
||||||
* Fix missing buttons (#28179) (#28181)
|
|
||||||
* Fix no ActionTaskOutput table waring (#28149) (#28152)
|
|
||||||
* Fix empty action run title (#28113) (#28148)
|
|
||||||
* Use "is-loading" to avoid duplicate form submit for code comment (#28143) (#28147)
|
|
||||||
* Fix Matrix and MSTeams nil dereference (#28089) (#28105)
|
|
||||||
* Fix incorrect pgsql conn builder behavior (#28085) (#28098)
|
|
||||||
* Fix system config cache expiration timing (#28072) (#28090)
|
|
||||||
* Restricted users only see repos in orgs which their team was assigned to (#28025) (#28051)
|
|
||||||
* API
|
|
||||||
* Fix permissions for Token DELETE endpoint to match GET and POST (#27610) (#28099)
|
|
||||||
* ENHANCEMENTS
|
|
||||||
* Do not display search box when there's no packages yet (#28146) (#28159)
|
|
||||||
* Add missing `packages.cleanup.success` (#28129) (#28132)
|
|
||||||
* DOCS
|
|
||||||
* Docs: Replace deprecated IS_TLS_ENABLED mailer setting in email setup (#28205) (#28208)
|
|
||||||
* Fix the description about the default setting for action in quick start document (#28160) (#28168)
|
|
||||||
* Add guide page to actions when there's no workflows (#28145) (#28153)
|
|
||||||
* MISC
|
|
||||||
* Use full width for PR comparison (#28182) (#28186)
|
|
||||||
|
|
||||||
## [1.21.0](https://github.com/go-gitea/gitea/releases/tag/v1.21.0) - 2023-11-14
|
## [1.21.0](https://github.com/go-gitea/gitea/releases/tag/v1.21.0) - 2023-11-14
|
||||||
|
|
||||||
* BREAKING
|
* BREAKING
|
||||||
|
|
|
@ -79,10 +79,10 @@ RUN addgroup \
|
||||||
-s /bin/bash \
|
-s /bin/bash \
|
||||||
-u 1000 \
|
-u 1000 \
|
||||||
-G git \
|
-G git \
|
||||||
_gitea && \
|
git && \
|
||||||
echo "_gitea:*" | chpasswd -e
|
echo "git:*" | chpasswd -e
|
||||||
|
|
||||||
ENV USER _gitea
|
ENV USER git
|
||||||
ENV GITEA_CUSTOM /data/gitea
|
ENV GITEA_CUSTOM /data/gitea
|
||||||
|
|
||||||
VOLUME ["/data"]
|
VOLUME ["/data"]
|
||||||
|
|
|
@ -92,9 +92,10 @@ func CountUserGPGKeys(ctx context.Context, userID int64) (int64, error) {
|
||||||
return db.GetEngine(ctx).Where("owner_id=? AND primary_key_id=''", userID).Count(&GPGKey{})
|
return db.GetEngine(ctx).Where("owner_id=? AND primary_key_id=''", userID).Count(&GPGKey{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGPGKeyForUserByID(ctx context.Context, ownerID, keyID int64) (*GPGKey, error) {
|
// GetGPGKeyByID returns public key by given ID.
|
||||||
|
func GetGPGKeyByID(ctx context.Context, keyID int64) (*GPGKey, error) {
|
||||||
key := new(GPGKey)
|
key := new(GPGKey)
|
||||||
has, err := db.GetEngine(ctx).Where("id=? AND owner_id=?", keyID, ownerID).Get(key)
|
has, err := db.GetEngine(ctx).ID(keyID).Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
|
@ -224,7 +225,7 @@ func deleteGPGKey(ctx context.Context, keyID string) (int64, error) {
|
||||||
|
|
||||||
// DeleteGPGKey deletes GPG key information in database.
|
// DeleteGPGKey deletes GPG key information in database.
|
||||||
func DeleteGPGKey(ctx context.Context, doer *user_model.User, id int64) (err error) {
|
func DeleteGPGKey(ctx context.Context, doer *user_model.User, id int64) (err error) {
|
||||||
key, err := GetGPGKeyForUserByID(ctx, doer.ID, id)
|
key, err := GetGPGKeyByID(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if IsErrGPGKeyNotExist(err) {
|
if IsErrGPGKeyNotExist(err) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -232,6 +233,11 @@ func DeleteGPGKey(ctx context.Context, doer *user_model.User, id int64) (err err
|
||||||
return fmt.Errorf("GetPublicKeyByID: %w", 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)
|
ctx, committer, err := db.TxContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -66,12 +66,3 @@
|
||||||
tree_path: "README.md"
|
tree_path: "README.md"
|
||||||
created_unix: 946684812
|
created_unix: 946684812
|
||||||
invalidated: true
|
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
|
|
||||||
|
|
|
@ -1021,7 +1021,6 @@ type FindCommentsOptions struct {
|
||||||
Type CommentType
|
Type CommentType
|
||||||
IssueIDs []int64
|
IssueIDs []int64
|
||||||
Invalidated util.OptionalBool
|
Invalidated util.OptionalBool
|
||||||
IsPull util.OptionalBool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToConds implements FindOptions interface
|
// ToConds implements FindOptions interface
|
||||||
|
@ -1056,9 +1055,6 @@ func (opts *FindCommentsOptions) ToConds() builder.Cond {
|
||||||
if !opts.Invalidated.IsNone() {
|
if !opts.Invalidated.IsNone() {
|
||||||
cond = cond.And(builder.Eq{"comment.invalidated": opts.Invalidated.IsTrue()})
|
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
|
return cond
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1066,7 +1062,7 @@ func (opts *FindCommentsOptions) ToConds() builder.Cond {
|
||||||
func FindComments(ctx context.Context, opts *FindCommentsOptions) (CommentList, error) {
|
func FindComments(ctx context.Context, opts *FindCommentsOptions) (CommentList, error) {
|
||||||
comments := make([]*Comment, 0, 10)
|
comments := make([]*Comment, 0, 10)
|
||||||
sess := db.GetEngine(ctx).Where(opts.ToConds())
|
sess := db.GetEngine(ctx).Where(opts.ToConds())
|
||||||
if opts.RepoID > 0 || opts.IsPull != util.OptionalBoolNone {
|
if opts.RepoID > 0 {
|
||||||
sess.Join("INNER", "issue", "issue.id = comment.issue_id")
|
sess.Join("INNER", "issue", "issue.id = comment.issue_id")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,9 +218,9 @@ func GetIssueContentHistoryByID(dbCtx context.Context, id int64) (*ContentHistor
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIssueContentHistoryAndPrev get a history and the previous non-deleted history (to compare)
|
// GetIssueContentHistoryAndPrev get a history and the previous non-deleted history (to compare)
|
||||||
func GetIssueContentHistoryAndPrev(dbCtx context.Context, issueID, id int64) (history, prevHistory *ContentHistory, err error) {
|
func GetIssueContentHistoryAndPrev(dbCtx context.Context, id int64) (history, prevHistory *ContentHistory, err error) {
|
||||||
history = &ContentHistory{}
|
history = &ContentHistory{}
|
||||||
has, err := db.GetEngine(dbCtx).Where("id=? AND issue_id=?", id, issueID).Get(history)
|
has, err := db.GetEngine(dbCtx).ID(id).Get(history)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to get issue content history %v. err=%v", id, err)
|
log.Error("failed to get issue content history %v. err=%v", id, err)
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
|
|
@ -58,13 +58,13 @@ func TestContentHistory(t *testing.T) {
|
||||||
hasHistory2, _ := issues_model.HasIssueContentHistory(dbCtx, 10, 1)
|
hasHistory2, _ := issues_model.HasIssueContentHistory(dbCtx, 10, 1)
|
||||||
assert.False(t, hasHistory2)
|
assert.False(t, hasHistory2)
|
||||||
|
|
||||||
h6, h6Prev, _ := issues_model.GetIssueContentHistoryAndPrev(dbCtx, 10, 6)
|
h6, h6Prev, _ := issues_model.GetIssueContentHistoryAndPrev(dbCtx, 6)
|
||||||
assert.EqualValues(t, 6, h6.ID)
|
assert.EqualValues(t, 6, h6.ID)
|
||||||
assert.EqualValues(t, 5, h6Prev.ID)
|
assert.EqualValues(t, 5, h6Prev.ID)
|
||||||
|
|
||||||
// soft-delete
|
// soft-delete
|
||||||
_ = issues_model.SoftDeleteIssueContentHistory(dbCtx, 5)
|
_ = issues_model.SoftDeleteIssueContentHistory(dbCtx, 5)
|
||||||
h6, h6Prev, _ = issues_model.GetIssueContentHistoryAndPrev(dbCtx, 10, 6)
|
h6, h6Prev, _ = issues_model.GetIssueContentHistoryAndPrev(dbCtx, 6)
|
||||||
assert.EqualValues(t, 6, h6.ID)
|
assert.EqualValues(t, 6, h6.ID)
|
||||||
assert.EqualValues(t, 4, h6Prev.ID)
|
assert.EqualValues(t, 4, h6Prev.ID)
|
||||||
|
|
||||||
|
|
|
@ -311,18 +311,6 @@ func GetProjectByID(ctx context.Context, id int64) (*Project, error) {
|
||||||
return p, nil
|
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
|
// UpdateProject updates project properties
|
||||||
func UpdateProject(ctx context.Context, p *Project) error {
|
func UpdateProject(ctx context.Context, p *Project) error {
|
||||||
if !IsCardTypeValid(p.CardType) {
|
if !IsCardTypeValid(p.CardType) {
|
||||||
|
|
|
@ -207,21 +207,6 @@ func GetReleaseByID(ctx context.Context, id int64) (*Release, error) {
|
||||||
return rel, nil
|
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
|
// FindReleasesOptions describes the conditions to Find releases
|
||||||
type FindReleasesOptions struct {
|
type FindReleasesOptions struct {
|
||||||
db.ListOptions
|
db.ListOptions
|
||||||
|
|
|
@ -392,40 +392,39 @@ func CreateWebhooks(ctx context.Context, ws []*Webhook) error {
|
||||||
return db.Insert(ctx, ws)
|
return db.Insert(ctx, ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByID returns webhook of repository by given ID.
|
// getWebhook uses argument bean as query condition,
|
||||||
func GetWebhookByID(ctx context.Context, id int64) (*Webhook, error) {
|
// ID must be specified and do not assign unnecessary fields.
|
||||||
bean := new(Webhook)
|
func getWebhook(bean *Webhook) (*Webhook, error) {
|
||||||
has, err := db.GetEngine(ctx).ID(id).Get(bean)
|
has, err := db.GetEngine(db.DefaultContext).Get(bean)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
return nil, ErrWebhookNotExist{ID: id}
|
return nil, ErrWebhookNotExist{ID: bean.ID}
|
||||||
}
|
}
|
||||||
return bean, nil
|
return bean, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByRepoID returns webhook of repository by given ID.
|
// GetWebhookByID returns webhook of repository by given ID.
|
||||||
func GetWebhookByRepoID(ctx context.Context, repoID, id int64) (*Webhook, error) {
|
func GetWebhookByID(id int64) (*Webhook, error) {
|
||||||
webhook := new(Webhook)
|
return getWebhook(&Webhook{
|
||||||
has, err := db.GetEngine(ctx).Where("id=? AND repo_id=?", id, repoID).Get(webhook)
|
ID: id,
|
||||||
if err != nil {
|
})
|
||||||
return nil, err
|
|
||||||
} else if !has {
|
|
||||||
return nil, ErrWebhookNotExist{ID: id}
|
|
||||||
}
|
}
|
||||||
return webhook, nil
|
|
||||||
|
// GetWebhookByRepoID returns webhook of repository by given ID.
|
||||||
|
func GetWebhookByRepoID(repoID, id int64) (*Webhook, error) {
|
||||||
|
return getWebhook(&Webhook{
|
||||||
|
ID: id,
|
||||||
|
RepoID: repoID,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByOwnerID returns webhook of a user or organization by given ID.
|
// GetWebhookByOwnerID returns webhook of a user or organization by given ID.
|
||||||
func GetWebhookByOwnerID(ctx context.Context, ownerID, id int64) (*Webhook, error) {
|
func GetWebhookByOwnerID(ownerID, id int64) (*Webhook, error) {
|
||||||
webhook := new(Webhook)
|
return getWebhook(&Webhook{
|
||||||
has, err := db.GetEngine(ctx).Where("id=? AND owner_id=?", id, ownerID).Get(webhook)
|
ID: id,
|
||||||
if err != nil {
|
OwnerID: ownerID,
|
||||||
return nil, err
|
})
|
||||||
} else if !has {
|
|
||||||
return nil, ErrWebhookNotExist{ID: id}
|
|
||||||
}
|
|
||||||
return webhook, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListWebhookOptions are options to filter webhooks on ListWebhooksByOpts
|
// ListWebhookOptions are options to filter webhooks on ListWebhooksByOpts
|
||||||
|
@ -483,20 +482,20 @@ func UpdateWebhookLastStatus(w *Webhook) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhookByID uses argument bean as query condition,
|
// deleteWebhook uses argument bean as query condition,
|
||||||
// ID must be specified and do not assign unnecessary fields.
|
// ID must be specified and do not assign unnecessary fields.
|
||||||
func DeleteWebhookByID(ctx context.Context, id int64) (err error) {
|
func deleteWebhook(bean *Webhook) (err error) {
|
||||||
ctx, committer, err := db.TxContext(ctx)
|
ctx, committer, err := db.TxContext(db.DefaultContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer committer.Close()
|
defer committer.Close()
|
||||||
|
|
||||||
if count, err := db.DeleteByID(ctx, id, new(Webhook)); err != nil {
|
if count, err := db.DeleteByBean(ctx, bean); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if count == 0 {
|
} else if count == 0 {
|
||||||
return ErrWebhookNotExist{ID: id}
|
return ErrWebhookNotExist{ID: bean.ID}
|
||||||
} else if _, err = db.DeleteByBean(ctx, &HookTask{HookID: id}); err != nil {
|
} else if _, err = db.DeleteByBean(ctx, &HookTask{HookID: bean.ID}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,17 +503,17 @@ func DeleteWebhookByID(ctx context.Context, id int64) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhookByRepoID deletes webhook of repository by given ID.
|
// DeleteWebhookByRepoID deletes webhook of repository by given ID.
|
||||||
func DeleteWebhookByRepoID(ctx context.Context, repoID, id int64) error {
|
func DeleteWebhookByRepoID(repoID, id int64) error {
|
||||||
if _, err := GetWebhookByRepoID(ctx, repoID, id); err != nil {
|
return deleteWebhook(&Webhook{
|
||||||
return err
|
ID: id,
|
||||||
}
|
RepoID: repoID,
|
||||||
return DeleteWebhookByID(ctx, id)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhookByOwnerID deletes webhook of a user or organization by given ID.
|
// DeleteWebhookByOwnerID deletes webhook of a user or organization by given ID.
|
||||||
func DeleteWebhookByOwnerID(ctx context.Context, ownerID, id int64) error {
|
func DeleteWebhookByOwnerID(ownerID, id int64) error {
|
||||||
if _, err := GetWebhookByOwnerID(ctx, ownerID, id); err != nil {
|
return deleteWebhook(&Webhook{
|
||||||
return err
|
ID: id,
|
||||||
}
|
OwnerID: ownerID,
|
||||||
return DeleteWebhookByID(ctx, id)
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,22 +101,22 @@ func TestCreateWebhook(t *testing.T) {
|
||||||
|
|
||||||
func TestGetWebhookByRepoID(t *testing.T) {
|
func TestGetWebhookByRepoID(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
hook, err := GetWebhookByRepoID(db.DefaultContext, 1, 1)
|
hook, err := GetWebhookByRepoID(1, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, int64(1), hook.ID)
|
assert.Equal(t, int64(1), hook.ID)
|
||||||
|
|
||||||
_, err = GetWebhookByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
|
_, err = GetWebhookByRepoID(unittest.NonexistentID, unittest.NonexistentID)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrWebhookNotExist(err))
|
assert.True(t, IsErrWebhookNotExist(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetWebhookByOwnerID(t *testing.T) {
|
func TestGetWebhookByOwnerID(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
hook, err := GetWebhookByOwnerID(db.DefaultContext, 3, 3)
|
hook, err := GetWebhookByOwnerID(3, 3)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, int64(3), hook.ID)
|
assert.Equal(t, int64(3), hook.ID)
|
||||||
|
|
||||||
_, err = GetWebhookByOwnerID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
|
_, err = GetWebhookByOwnerID(unittest.NonexistentID, unittest.NonexistentID)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrWebhookNotExist(err))
|
assert.True(t, IsErrWebhookNotExist(err))
|
||||||
}
|
}
|
||||||
|
@ -174,10 +174,10 @@ func TestUpdateWebhook(t *testing.T) {
|
||||||
func TestDeleteWebhookByRepoID(t *testing.T) {
|
func TestDeleteWebhookByRepoID(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2, RepoID: 1})
|
unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2, RepoID: 1})
|
||||||
assert.NoError(t, DeleteWebhookByRepoID(db.DefaultContext, 1, 2))
|
assert.NoError(t, DeleteWebhookByRepoID(1, 2))
|
||||||
unittest.AssertNotExistsBean(t, &Webhook{ID: 2, RepoID: 1})
|
unittest.AssertNotExistsBean(t, &Webhook{ID: 2, RepoID: 1})
|
||||||
|
|
||||||
err := DeleteWebhookByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
|
err := DeleteWebhookByRepoID(unittest.NonexistentID, unittest.NonexistentID)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrWebhookNotExist(err))
|
assert.True(t, IsErrWebhookNotExist(err))
|
||||||
}
|
}
|
||||||
|
@ -185,10 +185,10 @@ func TestDeleteWebhookByRepoID(t *testing.T) {
|
||||||
func TestDeleteWebhookByOwnerID(t *testing.T) {
|
func TestDeleteWebhookByOwnerID(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 3, OwnerID: 3})
|
unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 3, OwnerID: 3})
|
||||||
assert.NoError(t, DeleteWebhookByOwnerID(db.DefaultContext, 3, 3))
|
assert.NoError(t, DeleteWebhookByOwnerID(3, 3))
|
||||||
unittest.AssertNotExistsBean(t, &Webhook{ID: 3, OwnerID: 3})
|
unittest.AssertNotExistsBean(t, &Webhook{ID: 3, OwnerID: 3})
|
||||||
|
|
||||||
err := DeleteWebhookByOwnerID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
|
err := DeleteWebhookByOwnerID(unittest.NonexistentID, unittest.NonexistentID)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrWebhookNotExist(err))
|
assert.True(t, IsErrWebhookNotExist(err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1266,8 +1266,8 @@ func Routes() *web.Route {
|
||||||
m.Group("/{username}/{reponame}", func() {
|
m.Group("/{username}/{reponame}", func() {
|
||||||
m.Group("/issues", func() {
|
m.Group("/issues", func() {
|
||||||
m.Combo("").Get(repo.ListIssues).
|
m.Combo("").Get(repo.ListIssues).
|
||||||
Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueOption{}), reqRepoReader(unit.TypeIssues), repo.CreateIssue)
|
Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue)
|
||||||
m.Get("/pinned", reqRepoReader(unit.TypeIssues), repo.ListPinnedIssues)
|
m.Get("/pinned", repo.ListPinnedIssues)
|
||||||
m.Group("/comments", func() {
|
m.Group("/comments", func() {
|
||||||
m.Get("", repo.ListRepoIssueComments)
|
m.Get("", repo.ListRepoIssueComments)
|
||||||
m.Group("/{id}", func() {
|
m.Group("/{id}", func() {
|
||||||
|
|
|
@ -301,7 +301,7 @@ func DeleteHook(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
if err := webhook.DeleteWebhookByRepoID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil {
|
if err := webhook.DeleteWebhookByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil {
|
||||||
if webhook.IsErrWebhookNotExist(err) {
|
if webhook.IsErrWebhookNotExist(err) {
|
||||||
ctx.NotFound()
|
ctx.NotFound()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -463,24 +463,6 @@ func ListIssues(ctx *context.APIContext) {
|
||||||
isPull = util.OptionalBoolNone
|
isPull = util.OptionalBoolNone
|
||||||
}
|
}
|
||||||
|
|
||||||
if isPull != util.OptionalBoolNone && !ctx.Repo.CanReadIssuesOrPulls(isPull.IsTrue()) {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if isPull == util.OptionalBoolNone {
|
|
||||||
canReadIssues := ctx.Repo.CanRead(unit.TypeIssues)
|
|
||||||
canReadPulls := ctx.Repo.CanRead(unit.TypePullRequests)
|
|
||||||
if !canReadIssues && !canReadPulls {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
} else if !canReadIssues {
|
|
||||||
isPull = util.OptionalBoolTrue
|
|
||||||
} else if !canReadPulls {
|
|
||||||
isPull = util.OptionalBoolFalse
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: we should be more efficient here
|
// FIXME: we should be more efficient here
|
||||||
createdByID := getUserIDForFilter(ctx, "created_by")
|
createdByID := getUserIDForFilter(ctx, "created_by")
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
|
@ -612,10 +594,6 @@ func GetIssue(ctx *context.APIContext) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, issue))
|
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, issue))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,9 @@ import (
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
access_model "code.gitea.io/gitea/models/perm/access"
|
access_model "code.gitea.io/gitea/models/perm/access"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unit"
|
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/util"
|
|
||||||
"code.gitea.io/gitea/modules/web"
|
"code.gitea.io/gitea/modules/web"
|
||||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||||
"code.gitea.io/gitea/services/convert"
|
"code.gitea.io/gitea/services/convert"
|
||||||
|
@ -73,11 +71,6 @@ func ListIssueComments(ctx *context.APIContext) {
|
||||||
ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err)
|
ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
issue.Repo = ctx.Repo.Repository
|
issue.Repo = ctx.Repo.Repository
|
||||||
|
|
||||||
opts := &issues_model.FindCommentsOptions{
|
opts := &issues_model.FindCommentsOptions{
|
||||||
|
@ -278,27 +271,12 @@ func ListRepoIssueComments(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var isPull util.OptionalBool
|
|
||||||
canReadIssue := ctx.Repo.CanRead(unit.TypeIssues)
|
|
||||||
canReadPull := ctx.Repo.CanRead(unit.TypePullRequests)
|
|
||||||
if canReadIssue && canReadPull {
|
|
||||||
isPull = util.OptionalBoolNone
|
|
||||||
} else if canReadIssue {
|
|
||||||
isPull = util.OptionalBoolFalse
|
|
||||||
} else if canReadPull {
|
|
||||||
isPull = util.OptionalBoolTrue
|
|
||||||
} else {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := &issues_model.FindCommentsOptions{
|
opts := &issues_model.FindCommentsOptions{
|
||||||
ListOptions: utils.GetListOptions(ctx),
|
ListOptions: utils.GetListOptions(ctx),
|
||||||
RepoID: ctx.Repo.Repository.ID,
|
RepoID: ctx.Repo.Repository.ID,
|
||||||
Type: issues_model.CommentTypeComment,
|
Type: issues_model.CommentTypeComment,
|
||||||
Since: since,
|
Since: since,
|
||||||
Before: before,
|
Before: before,
|
||||||
IsPull: isPull,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
comments, err := issues_model.FindComments(ctx, opts)
|
comments, err := issues_model.FindComments(ctx, opts)
|
||||||
|
@ -387,11 +365,6 @@ func CreateIssueComment(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin {
|
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin {
|
||||||
ctx.Error(http.StatusForbidden, "CreateIssueComment", errors.New(ctx.Tr("repo.issues.comment_on_locked")))
|
ctx.Error(http.StatusForbidden, "CreateIssueComment", errors.New(ctx.Tr("repo.issues.comment_on_locked")))
|
||||||
return
|
return
|
||||||
|
@ -471,11 +444,6 @@ func GetIssueComment(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if comment.Type != issues_model.CommentTypeComment {
|
if comment.Type != issues_model.CommentTypeComment {
|
||||||
ctx.Status(http.StatusNoContent)
|
ctx.Status(http.StatusNoContent)
|
||||||
return
|
return
|
||||||
|
@ -594,17 +562,7 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := comment.LoadIssue(ctx); err != nil {
|
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.IsAdmin()) {
|
||||||
ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.Status(http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
|
|
||||||
ctx.Status(http.StatusForbidden)
|
ctx.Status(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -718,17 +676,7 @@ func deleteIssueComment(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := comment.LoadIssue(ctx); err != nil {
|
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.IsAdmin()) {
|
||||||
ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.Status(http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
|
|
||||||
ctx.Status(http.StatusForbidden)
|
ctx.Status(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
} else if comment.Type != issues_model.CommentTypeComment {
|
} else if comment.Type != issues_model.CommentTypeComment {
|
||||||
|
|
|
@ -352,10 +352,6 @@ func getIssueCommentSafe(ctx *context.APIContext) *issues_model.Comment {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
comment.Issue.Repo = ctx.Repo.Repository
|
comment.Issue.Repo = ctx.Repo.Repository
|
||||||
|
|
||||||
return comment
|
return comment
|
||||||
|
|
|
@ -63,12 +63,6 @@ func GetIssueCommentReactions(ctx *context.APIContext) {
|
||||||
|
|
||||||
if err := comment.LoadIssue(ctx); err != nil {
|
if err := comment.LoadIssue(ctx); err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "comment.LoadIssue", err)
|
ctx.Error(http.StatusInternalServerError, "comment.LoadIssue", err)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
||||||
|
@ -198,19 +192,9 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = comment.LoadIssue(ctx); err != nil {
|
err = comment.LoadIssue(ctx)
|
||||||
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "comment.LoadIssue() failed", err)
|
ctx.Error(http.StatusInternalServerError, "comment.LoadIssue() failed", err)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if comment.Issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull) {
|
if comment.Issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull) {
|
||||||
|
|
|
@ -159,12 +159,6 @@ func GetDeployKey(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// this check make it more consistent
|
|
||||||
if key.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = key.GetContent(); err != nil {
|
if err = key.GetContent(); err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "GetContent", err)
|
ctx.Error(http.StatusInternalServerError, "GetContent", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -49,12 +49,13 @@ func GetRelease(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
id := ctx.ParamsInt64(":id")
|
id := ctx.ParamsInt64(":id")
|
||||||
release, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
|
release, err := repo_model.GetReleaseByID(ctx, id)
|
||||||
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
|
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
|
||||||
ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err)
|
ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil && repo_model.IsErrReleaseNotExist(err) || release.IsTag {
|
if err != nil && repo_model.IsErrReleaseNotExist(err) ||
|
||||||
|
release.IsTag || release.RepoID != ctx.Repo.Repository.ID {
|
||||||
ctx.NotFound()
|
ctx.NotFound()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -314,12 +315,13 @@ func EditRelease(ctx *context.APIContext) {
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.EditReleaseOption)
|
form := web.GetForm(ctx).(*api.EditReleaseOption)
|
||||||
id := ctx.ParamsInt64(":id")
|
id := ctx.ParamsInt64(":id")
|
||||||
rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
|
rel, err := repo_model.GetReleaseByID(ctx, id)
|
||||||
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
|
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
|
||||||
ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err)
|
ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil && repo_model.IsErrReleaseNotExist(err) || rel.IsTag {
|
if err != nil && repo_model.IsErrReleaseNotExist(err) ||
|
||||||
|
rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID {
|
||||||
ctx.NotFound()
|
ctx.NotFound()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -391,16 +393,17 @@ func DeleteRelease(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
|
|
||||||
id := ctx.ParamsInt64(":id")
|
id := ctx.ParamsInt64(":id")
|
||||||
rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
|
rel, err := repo_model.GetReleaseByID(ctx, id)
|
||||||
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
|
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
|
||||||
ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err)
|
ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil && repo_model.IsErrReleaseNotExist(err) || rel.IsTag {
|
if err != nil && repo_model.IsErrReleaseNotExist(err) ||
|
||||||
|
rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID {
|
||||||
ctx.NotFound()
|
ctx.NotFound()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, rel, ctx.Doer, false); err != nil {
|
if err := release_service.DeleteReleaseByID(ctx, id, ctx.Doer, false); err != nil {
|
||||||
if models.IsErrProtectedTagName(err) {
|
if models.IsErrProtectedTagName(err) {
|
||||||
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
|
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
|
||||||
return
|
return
|
||||||
|
|
|
@ -17,23 +17,6 @@ import (
|
||||||
"code.gitea.io/gitea/services/convert"
|
"code.gitea.io/gitea/services/convert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkReleaseMatchRepo(ctx *context.APIContext, releaseID int64) bool {
|
|
||||||
release, err := repo_model.GetReleaseByID(ctx, releaseID)
|
|
||||||
if err != nil {
|
|
||||||
if repo_model.IsErrReleaseNotExist(err) {
|
|
||||||
ctx.NotFound()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if release.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.NotFound()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetReleaseAttachment gets a single attachment of the release
|
// GetReleaseAttachment gets a single attachment of the release
|
||||||
func GetReleaseAttachment(ctx *context.APIContext) {
|
func GetReleaseAttachment(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id} repository repoGetReleaseAttachment
|
// swagger:operation GET /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id} repository repoGetReleaseAttachment
|
||||||
|
@ -71,10 +54,6 @@ func GetReleaseAttachment(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
releaseID := ctx.ParamsInt64(":id")
|
releaseID := ctx.ParamsInt64(":id")
|
||||||
if !checkReleaseMatchRepo(ctx, releaseID) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
attachID := ctx.ParamsInt64(":attachment_id")
|
attachID := ctx.ParamsInt64(":attachment_id")
|
||||||
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
|
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -197,7 +176,13 @@ func CreateReleaseAttachment(ctx *context.APIContext) {
|
||||||
|
|
||||||
// Check if release exists an load release
|
// Check if release exists an load release
|
||||||
releaseID := ctx.ParamsInt64(":id")
|
releaseID := ctx.ParamsInt64(":id")
|
||||||
if !checkReleaseMatchRepo(ctx, releaseID) {
|
release, err := repo_model.GetReleaseByID(ctx, releaseID)
|
||||||
|
if err != nil {
|
||||||
|
if repo_model.IsErrReleaseNotExist(err) {
|
||||||
|
ctx.NotFound()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +203,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) {
|
||||||
attach, err := attachment.UploadAttachment(file, setting.Repository.Release.AllowedTypes, header.Size, &repo_model.Attachment{
|
attach, err := attachment.UploadAttachment(file, setting.Repository.Release.AllowedTypes, header.Size, &repo_model.Attachment{
|
||||||
Name: filename,
|
Name: filename,
|
||||||
UploaderID: ctx.Doer.ID,
|
UploaderID: ctx.Doer.ID,
|
||||||
RepoID: ctx.Repo.Repository.ID,
|
RepoID: release.RepoID,
|
||||||
ReleaseID: releaseID,
|
ReleaseID: releaseID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -279,10 +264,6 @@ func EditReleaseAttachment(ctx *context.APIContext) {
|
||||||
|
|
||||||
// Check if release exists an load release
|
// Check if release exists an load release
|
||||||
releaseID := ctx.ParamsInt64(":id")
|
releaseID := ctx.ParamsInt64(":id")
|
||||||
if !checkReleaseMatchRepo(ctx, releaseID) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
attachID := ctx.ParamsInt64(":attachment_id")
|
attachID := ctx.ParamsInt64(":attachment_id")
|
||||||
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
|
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -347,10 +328,6 @@ func DeleteReleaseAttachment(ctx *context.APIContext) {
|
||||||
|
|
||||||
// Check if release exists an load release
|
// Check if release exists an load release
|
||||||
releaseID := ctx.ParamsInt64(":id")
|
releaseID := ctx.ParamsInt64(":id")
|
||||||
if !checkReleaseMatchRepo(ctx, releaseID) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
attachID := ctx.ParamsInt64(":attachment_id")
|
attachID := ctx.ParamsInt64(":attachment_id")
|
||||||
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
|
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -112,7 +112,7 @@ func DeleteReleaseByTag(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, release, ctx.Doer, false); err != nil {
|
if err = releaseservice.DeleteReleaseByID(ctx, release.ID, ctx.Doer, false); err != nil {
|
||||||
if models.IsErrProtectedTagName(err) {
|
if models.IsErrProtectedTagName(err) {
|
||||||
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
|
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
|
||||||
return
|
return
|
||||||
|
|
|
@ -268,7 +268,7 @@ func DeleteTag(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, tag, ctx.Doer, true); err != nil {
|
if err = releaseservice.DeleteReleaseByID(ctx, tag.ID, ctx.Doer, true); err != nil {
|
||||||
if models.IsErrProtectedTagName(err) {
|
if models.IsErrProtectedTagName(err) {
|
||||||
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
|
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
|
||||||
return
|
return
|
||||||
|
|
|
@ -343,10 +343,6 @@ func GetOauth2Application(ctx *context.APIContext) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if app.UID != ctx.Doer.ID {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
app.ClientSecret = ""
|
app.ClientSecret = ""
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ func GetGPGKey(ctx *context.APIContext) {
|
||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
key, err := asymkey_model.GetGPGKeyForUserByID(ctx, ctx.Doer.ID, ctx.ParamsInt64(":id"))
|
key, err := asymkey_model.GetGPGKeyByID(ctx, ctx.ParamsInt64(":id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if asymkey_model.IsErrGPGKeyNotExist(err) {
|
if asymkey_model.IsErrGPGKeyNotExist(err) {
|
||||||
ctx.NotFound()
|
ctx.NotFound()
|
||||||
|
|
|
@ -62,11 +62,6 @@ func GetHook(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.Doer.IsAdmin && hook.OwnerID != ctx.Doer.ID {
|
|
||||||
ctx.NotFound()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
apiHook, err := webhook_service.ToHook(ctx.Doer.HomeLink(), hook)
|
apiHook, err := webhook_service.ToHook(ctx.Doer.HomeLink(), hook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.InternalServerError(err)
|
ctx.InternalServerError(err)
|
||||||
|
|
|
@ -53,7 +53,7 @@ func ListOwnerHooks(ctx *context.APIContext, owner *user_model.User) {
|
||||||
|
|
||||||
// GetOwnerHook gets an user or organization webhook. Errors are written to ctx.
|
// GetOwnerHook gets an user or organization webhook. Errors are written to ctx.
|
||||||
func GetOwnerHook(ctx *context.APIContext, ownerID, hookID int64) (*webhook.Webhook, error) {
|
func GetOwnerHook(ctx *context.APIContext, ownerID, hookID int64) (*webhook.Webhook, error) {
|
||||||
w, err := webhook.GetWebhookByOwnerID(ctx, ownerID, hookID)
|
w, err := webhook.GetWebhookByOwnerID(ownerID, hookID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if webhook.IsErrWebhookNotExist(err) {
|
if webhook.IsErrWebhookNotExist(err) {
|
||||||
ctx.NotFound()
|
ctx.NotFound()
|
||||||
|
@ -68,7 +68,7 @@ func GetOwnerHook(ctx *context.APIContext, ownerID, hookID int64) (*webhook.Webh
|
||||||
// GetRepoHook get a repo's webhook. If there is an error, write to `ctx`
|
// GetRepoHook get a repo's webhook. If there is an error, write to `ctx`
|
||||||
// accordingly and return the error
|
// accordingly and return the error
|
||||||
func GetRepoHook(ctx *context.APIContext, repoID, hookID int64) (*webhook.Webhook, error) {
|
func GetRepoHook(ctx *context.APIContext, repoID, hookID int64) (*webhook.Webhook, error) {
|
||||||
w, err := webhook.GetWebhookByRepoID(ctx, repoID, hookID)
|
w, err := webhook.GetWebhookByRepoID(repoID, hookID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if webhook.IsErrWebhookNotExist(err) {
|
if webhook.IsErrWebhookNotExist(err) {
|
||||||
ctx.NotFound()
|
ctx.NotFound()
|
||||||
|
@ -401,7 +401,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh
|
||||||
|
|
||||||
// DeleteOwnerHook deletes the hook owned by the owner.
|
// DeleteOwnerHook deletes the hook owned by the owner.
|
||||||
func DeleteOwnerHook(ctx *context.APIContext, owner *user_model.User, hookID int64) {
|
func DeleteOwnerHook(ctx *context.APIContext, owner *user_model.User, hookID int64) {
|
||||||
if err := webhook.DeleteWebhookByOwnerID(ctx, owner.ID, hookID); err != nil {
|
if err := webhook.DeleteWebhookByOwnerID(owner.ID, hookID); err != nil {
|
||||||
if webhook.IsErrWebhookNotExist(err) {
|
if webhook.IsErrWebhookNotExist(err) {
|
||||||
ctx.NotFound()
|
ctx.NotFound()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -233,7 +233,7 @@ func Webhooks(ctx *context.Context) {
|
||||||
|
|
||||||
// DeleteWebhook response for delete webhook
|
// DeleteWebhook response for delete webhook
|
||||||
func DeleteWebhook(ctx *context.Context) {
|
func DeleteWebhook(ctx *context.Context) {
|
||||||
if err := webhook.DeleteWebhookByOwnerID(ctx, ctx.Org.Organization.ID, ctx.FormInt64("id")); err != nil {
|
if err := webhook.DeleteWebhookByOwnerID(ctx.Org.Organization.ID, ctx.FormInt64("id")); err != nil {
|
||||||
ctx.Flash.Error("DeleteWebhookByOwnerID: " + err.Error())
|
ctx.Flash.Error("DeleteWebhookByOwnerID: " + err.Error())
|
||||||
} else {
|
} else {
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
|
||||||
|
|
|
@ -3098,11 +3098,6 @@ func UpdateCommentContent(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
|
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
|
||||||
ctx.Error(http.StatusForbidden)
|
ctx.Error(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
|
@ -3169,11 +3164,6 @@ func DeleteComment(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
|
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
|
||||||
ctx.Error(http.StatusForbidden)
|
ctx.Error(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
|
@ -3300,11 +3290,6 @@ func ChangeCommentReaction(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull)) {
|
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull)) {
|
||||||
if log.IsTrace() {
|
if log.IsTrace() {
|
||||||
if ctx.IsSigned {
|
if ctx.IsSigned {
|
||||||
|
@ -3448,21 +3433,6 @@ func GetCommentAttachments(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := comment.LoadIssue(ctx); err != nil {
|
|
||||||
ctx.NotFoundOrServerError("LoadIssue", issues_model.IsErrIssueNotExist, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ctx.Repo.Permission.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
|
||||||
ctx.NotFound("CanReadIssuesOrPulls", issues_model.ErrCommentNotExist{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !comment.Type.HasAttachmentSupport() {
|
if !comment.Type.HasAttachmentSupport() {
|
||||||
ctx.ServerError("GetCommentAttachments", fmt.Errorf("comment type %v does not support attachments", comment.Type))
|
ctx.ServerError("GetCommentAttachments", fmt.Errorf("comment type %v does not support attachments", comment.Type))
|
||||||
return
|
return
|
||||||
|
|
|
@ -122,7 +122,7 @@ func GetContentHistoryDetail(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
historyID := ctx.FormInt64("history_id")
|
historyID := ctx.FormInt64("history_id")
|
||||||
history, prevHistory, err := issues_model.GetIssueContentHistoryAndPrev(ctx, issue.ID, historyID)
|
history, prevHistory, err := issues_model.GetIssueContentHistoryAndPrev(ctx, historyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(http.StatusNotFound, map[string]any{
|
ctx.JSON(http.StatusNotFound, map[string]any{
|
||||||
"message": "Can not find the content history",
|
"message": "Can not find the content history",
|
||||||
|
@ -198,19 +198,11 @@ func SoftDeleteContentHistory(ctx *context.Context) {
|
||||||
log.Error("can not get comment for issue content history %v. err=%v", historyID, err)
|
log.Error("can not get comment for issue content history %v. err=%v", historyID, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if comment.IssueID != issue.ID {
|
|
||||||
ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if history, err = issues_model.GetIssueContentHistoryByID(ctx, historyID); err != nil {
|
if history, err = issues_model.GetIssueContentHistoryByID(ctx, historyID); err != nil {
|
||||||
log.Error("can not get issue content history %v. err=%v", historyID, err)
|
log.Error("can not get issue content history %v. err=%v", historyID, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if history.IssueID != issue.ID {
|
|
||||||
ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
canSoftDelete := canSoftDeleteContentHistory(ctx, issue, comment, history)
|
canSoftDelete := canSoftDeleteContentHistory(ctx, issue, comment, history)
|
||||||
if !canSoftDelete {
|
if !canSoftDelete {
|
||||||
|
|
|
@ -89,10 +89,6 @@ func IssuePinMove(ctx *context.Context) {
|
||||||
log.Error(err.Error())
|
log.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if issue.RepoID != ctx.Repo.Repository.ID {
|
|
||||||
ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = issue.MovePin(ctx, form.Position)
|
err = issue.MovePin(ctx, form.Position)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -464,7 +464,7 @@ func AddBoardToProjectPost(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
project, err := project_model.GetProjectForRepoByID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if project_model.IsErrProjectNotExist(err) {
|
if project_model.IsErrProjectNotExist(err) {
|
||||||
ctx.NotFound("", nil)
|
ctx.NotFound("", nil)
|
||||||
|
|
|
@ -615,27 +615,7 @@ func DeleteTag(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteReleaseOrTag(ctx *context.Context, isDelTag bool) {
|
func deleteReleaseOrTag(ctx *context.Context, isDelTag bool) {
|
||||||
redirect := func() {
|
if err := releaseservice.DeleteReleaseByID(ctx, ctx.FormInt64("id"), ctx.Doer, isDelTag); err != nil {
|
||||||
if isDelTag {
|
|
||||||
ctx.JSONRedirect(ctx.Repo.RepoLink + "/tags")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.JSONRedirect(ctx.Repo.RepoLink + "/releases")
|
|
||||||
}
|
|
||||||
|
|
||||||
rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, ctx.FormInt64("id"))
|
|
||||||
if err != nil {
|
|
||||||
if repo_model.IsErrReleaseNotExist(err) {
|
|
||||||
ctx.NotFound("GetReleaseForRepoByID", err)
|
|
||||||
} else {
|
|
||||||
ctx.Flash.Error("DeleteReleaseByID: " + err.Error())
|
|
||||||
redirect()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, rel, ctx.Doer, isDelTag); err != nil {
|
|
||||||
if models.IsErrProtectedTagName(err) {
|
if models.IsErrProtectedTagName(err) {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.release.tag_name_protected"))
|
ctx.Flash.Error(ctx.Tr("repo.release.tag_name_protected"))
|
||||||
} else {
|
} else {
|
||||||
|
@ -649,5 +629,10 @@ func deleteReleaseOrTag(ctx *context.Context, isDelTag bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect()
|
if isDelTag {
|
||||||
|
ctx.JSONRedirect(ctx.Repo.RepoLink + "/tags")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSONRedirect(ctx.Repo.RepoLink + "/releases")
|
||||||
}
|
}
|
||||||
|
|
|
@ -617,9 +617,9 @@ func checkWebhook(ctx *context.Context) (*ownerRepoCtx, *webhook.Webhook) {
|
||||||
|
|
||||||
var w *webhook.Webhook
|
var w *webhook.Webhook
|
||||||
if orCtx.RepoID > 0 {
|
if orCtx.RepoID > 0 {
|
||||||
w, err = webhook.GetWebhookByRepoID(ctx, orCtx.RepoID, ctx.ParamsInt64(":id"))
|
w, err = webhook.GetWebhookByRepoID(orCtx.RepoID, ctx.ParamsInt64(":id"))
|
||||||
} else if orCtx.OwnerID > 0 {
|
} else if orCtx.OwnerID > 0 {
|
||||||
w, err = webhook.GetWebhookByOwnerID(ctx, orCtx.OwnerID, ctx.ParamsInt64(":id"))
|
w, err = webhook.GetWebhookByOwnerID(orCtx.OwnerID, ctx.ParamsInt64(":id"))
|
||||||
} else if orCtx.IsAdmin {
|
} else if orCtx.IsAdmin {
|
||||||
w, err = webhook.GetSystemOrDefaultWebhook(ctx, ctx.ParamsInt64(":id"))
|
w, err = webhook.GetSystemOrDefaultWebhook(ctx, ctx.ParamsInt64(":id"))
|
||||||
}
|
}
|
||||||
|
@ -671,7 +671,7 @@ func WebHooksEdit(ctx *context.Context) {
|
||||||
// TestWebhook test if web hook is work fine
|
// TestWebhook test if web hook is work fine
|
||||||
func TestWebhook(ctx *context.Context) {
|
func TestWebhook(ctx *context.Context) {
|
||||||
hookID := ctx.ParamsInt64(":id")
|
hookID := ctx.ParamsInt64(":id")
|
||||||
w, err := webhook.GetWebhookByRepoID(ctx, ctx.Repo.Repository.ID, hookID)
|
w, err := webhook.GetWebhookByRepoID(ctx.Repo.Repository.ID, hookID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Flash.Error("GetWebhookByRepoID: " + err.Error())
|
ctx.Flash.Error("GetWebhookByRepoID: " + err.Error())
|
||||||
ctx.Status(http.StatusInternalServerError)
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
@ -752,7 +752,7 @@ func ReplayWebhook(ctx *context.Context) {
|
||||||
|
|
||||||
// DeleteWebhook delete a webhook
|
// DeleteWebhook delete a webhook
|
||||||
func DeleteWebhook(ctx *context.Context) {
|
func DeleteWebhook(ctx *context.Context) {
|
||||||
if err := webhook.DeleteWebhookByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormInt64("id")); err != nil {
|
if err := webhook.DeleteWebhookByRepoID(ctx.Repo.Repository.ID, ctx.FormInt64("id")); err != nil {
|
||||||
ctx.Flash.Error("DeleteWebhookByRepoID: " + err.Error())
|
ctx.Flash.Error("DeleteWebhookByRepoID: " + err.Error())
|
||||||
} else {
|
} else {
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
|
||||||
|
|
|
@ -36,7 +36,7 @@ func Webhooks(ctx *context.Context) {
|
||||||
|
|
||||||
// DeleteWebhook response for delete webhook
|
// DeleteWebhook response for delete webhook
|
||||||
func DeleteWebhook(ctx *context.Context) {
|
func DeleteWebhook(ctx *context.Context) {
|
||||||
if err := webhook.DeleteWebhookByOwnerID(ctx, ctx.Doer.ID, ctx.FormInt64("id")); err != nil {
|
if err := webhook.DeleteWebhookByOwnerID(ctx.Doer.ID, ctx.FormInt64("id")); err != nil {
|
||||||
ctx.Flash.Error("DeleteWebhookByOwnerID: " + err.Error())
|
ctx.Flash.Error("DeleteWebhookByOwnerID: " + err.Error())
|
||||||
} else {
|
} else {
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
|
||||||
|
|
|
@ -291,7 +291,17 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteReleaseByID deletes a release and corresponding Git tag by given ID.
|
// DeleteReleaseByID deletes a release and corresponding Git tag by given ID.
|
||||||
func DeleteReleaseByID(ctx context.Context, repo *repo_model.Repository, rel *repo_model.Release, doer *user_model.User, delTag bool) error {
|
func DeleteReleaseByID(ctx context.Context, id int64, doer *user_model.User, delTag bool) error {
|
||||||
|
rel, err := repo_model.GetReleaseByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("GetReleaseByID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := repo_model.GetRepositoryByID(ctx, rel.RepoID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("GetRepositoryByID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if delTag {
|
if delTag {
|
||||||
protectedTags, err := git_model.GetProtectedTags(ctx, rel.RepoID)
|
protectedTags, err := git_model.GetProtectedTags(ctx, rel.RepoID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -324,19 +334,19 @@ func DeleteReleaseByID(ctx context.Context, repo *repo_model.Repository, rel *re
|
||||||
}, repository.NewPushCommits())
|
}, repository.NewPushCommits())
|
||||||
notify_service.DeleteRef(ctx, doer, repo, refName)
|
notify_service.DeleteRef(ctx, doer, repo, refName)
|
||||||
|
|
||||||
if err := repo_model.DeleteReleaseByID(ctx, rel.ID); err != nil {
|
if err := repo_model.DeleteReleaseByID(ctx, id); err != nil {
|
||||||
return fmt.Errorf("DeleteReleaseByID: %w", err)
|
return fmt.Errorf("DeleteReleaseByID: %w", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rel.IsTag = true
|
rel.IsTag = true
|
||||||
|
|
||||||
if err := repo_model.UpdateRelease(ctx, rel); err != nil {
|
if err = repo_model.UpdateRelease(ctx, rel); err != nil {
|
||||||
return fmt.Errorf("Update: %w", err)
|
return fmt.Errorf("Update: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rel.Repo = repo
|
rel.Repo = repo
|
||||||
if err := rel.LoadAttributes(ctx); err != nil {
|
if err = rel.LoadAttributes(ctx); err != nil {
|
||||||
return fmt.Errorf("LoadAttributes: %w", err)
|
return fmt.Errorf("LoadAttributes: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ import (
|
||||||
|
|
||||||
// Deliver deliver hook task
|
// Deliver deliver hook task
|
||||||
func Deliver(ctx context.Context, t *webhook_model.HookTask) error {
|
func Deliver(ctx context.Context, t *webhook_model.HookTask) error {
|
||||||
w, err := webhook_model.GetWebhookByID(ctx, t.HookID)
|
w, err := webhook_model.GetWebhookByID(t.HookID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,14 +36,6 @@ func TestAPIGetCommentAttachment(t *testing.T) {
|
||||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID})
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID})
|
||||||
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||||
|
|
||||||
t.Run("UnrelatedCommentID", func(t *testing.T) {
|
|
||||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
|
||||||
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
|
||||||
token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue)
|
|
||||||
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, attachment.ID, token)
|
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
})
|
|
||||||
|
|
||||||
session := loginUser(t, repoOwner.Name)
|
session := loginUser(t, repoOwner.Name)
|
||||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue)
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue)
|
||||||
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, attachment.ID, token)
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, attachment.ID, token)
|
||||||
|
|
|
@ -230,25 +230,12 @@ func TestAPIEditComment(t *testing.T) {
|
||||||
defer tests.PrepareTestEnv(t)()
|
defer tests.PrepareTestEnv(t)()
|
||||||
const newCommentBody = "This is the new comment body"
|
const newCommentBody = "This is the new comment body"
|
||||||
|
|
||||||
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 8},
|
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{},
|
||||||
unittest.Cond("type = ?", issues_model.CommentTypeComment))
|
unittest.Cond("type = ?", issues_model.CommentTypeComment))
|
||||||
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
|
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
|
||||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
|
||||||
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||||
|
|
||||||
t.Run("UnrelatedCommentID", func(t *testing.T) {
|
|
||||||
// Using the ID of a comment that does not belong to the repository must fail
|
|
||||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
|
||||||
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
|
||||||
token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue)
|
|
||||||
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s",
|
|
||||||
repoOwner.Name, repo.Name, comment.ID, token)
|
|
||||||
req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{
|
|
||||||
"body": newCommentBody,
|
|
||||||
})
|
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
})
|
|
||||||
|
|
||||||
token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue)
|
token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue)
|
||||||
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s",
|
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s",
|
||||||
repoOwner.Name, repo.Name, comment.ID, token)
|
repoOwner.Name, repo.Name, comment.ID, token)
|
||||||
|
@ -321,22 +308,12 @@ func TestAPIEditCommentWithDate(t *testing.T) {
|
||||||
func TestAPIDeleteComment(t *testing.T) {
|
func TestAPIDeleteComment(t *testing.T) {
|
||||||
defer tests.PrepareTestEnv(t)()
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 8},
|
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{},
|
||||||
unittest.Cond("type = ?", issues_model.CommentTypeComment))
|
unittest.Cond("type = ?", issues_model.CommentTypeComment))
|
||||||
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
|
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
|
||||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
|
||||||
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||||
|
|
||||||
t.Run("UnrelatedCommentID", func(t *testing.T) {
|
|
||||||
// Using the ID of a comment that does not belong to the repository must fail
|
|
||||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
|
||||||
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
|
||||||
token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue)
|
|
||||||
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s",
|
|
||||||
repoOwner.Name, repo.Name, comment.ID, token)
|
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
})
|
|
||||||
|
|
||||||
token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue)
|
token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue)
|
||||||
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s",
|
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s",
|
||||||
repoOwner.Name, repo.Name, comment.ID, token)
|
repoOwner.Name, repo.Name, comment.ID, token)
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
auth_model "code.gitea.io/gitea/models/auth"
|
auth_model "code.gitea.io/gitea/models/auth"
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
@ -108,26 +107,6 @@ func TestAPICommentReactions(t *testing.T) {
|
||||||
})
|
})
|
||||||
MakeRequest(t, req, http.StatusOK)
|
MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
t.Run("UnrelatedCommentID", func(t *testing.T) {
|
|
||||||
// Using the ID of a comment that does not belong to the repository must fail
|
|
||||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
|
||||||
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
|
||||||
token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue)
|
|
||||||
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/reactions?token=%s",
|
|
||||||
repoOwner.Name, repo.Name, comment.ID, token)
|
|
||||||
req = NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{
|
|
||||||
Reaction: "+1",
|
|
||||||
})
|
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
req = NewRequestWithJSON(t, "DELETE", urlStr, &api.EditReactionOption{
|
|
||||||
Reaction: "+1",
|
|
||||||
})
|
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
|
|
||||||
req = NewRequestf(t, "GET", urlStr)
|
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Add allowed reaction
|
// Add allowed reaction
|
||||||
req = NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{
|
req = NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{
|
||||||
Reaction: "+1",
|
Reaction: "+1",
|
||||||
|
|
|
@ -72,17 +72,6 @@ func TestCreateReadOnlyDeployKey(t *testing.T) {
|
||||||
Content: rawKeyBody.Key,
|
Content: rawKeyBody.Key,
|
||||||
Mode: perm.AccessModeRead,
|
Mode: perm.AccessModeRead,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Using the ID of a key that does not belong to the repository must fail
|
|
||||||
{
|
|
||||||
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/keys/%d?token=%s", repoOwner.Name, repo.Name, newDeployKey.ID, token))
|
|
||||||
MakeRequest(t, req, http.StatusOK)
|
|
||||||
|
|
||||||
session5 := loginUser(t, "user5")
|
|
||||||
token5 := getTokenForLoggedInUser(t, session5, auth_model.AccessTokenScopeWriteRepository)
|
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/user5/repo4/keys/%d?token=%s", newDeployKey.ID, token5))
|
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateReadWriteDeployKey(t *testing.T) {
|
func TestCreateReadWriteDeployKey(t *testing.T) {
|
||||||
|
|
|
@ -206,106 +206,6 @@ func TestIssueCommentClose(t *testing.T) {
|
||||||
assert.Equal(t, "Description", val)
|
assert.Equal(t, "Description", val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIssueCommentDelete(t *testing.T) {
|
|
||||||
defer tests.PrepareTestEnv(t)()
|
|
||||||
session := loginUser(t, "user2")
|
|
||||||
issueURL := testNewIssue(t, session, "user2", "repo1", "Title", "Description")
|
|
||||||
comment1 := "Test comment 1"
|
|
||||||
commentID := testIssueAddComment(t, session, issueURL, comment1, "")
|
|
||||||
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: commentID})
|
|
||||||
assert.Equal(t, comment1, comment.Content)
|
|
||||||
|
|
||||||
// Using the ID of a comment that does not belong to the repository must fail
|
|
||||||
req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d/delete", "user5", "repo4", commentID), map[string]string{
|
|
||||||
"_csrf": GetCSRF(t, session, issueURL),
|
|
||||||
})
|
|
||||||
session.MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d/delete", "user2", "repo1", commentID), map[string]string{
|
|
||||||
"_csrf": GetCSRF(t, session, issueURL),
|
|
||||||
})
|
|
||||||
session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: commentID})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIssueCommentAttachment(t *testing.T) {
|
|
||||||
defer tests.PrepareTestEnv(t)()
|
|
||||||
const repoURL = "user2/repo1"
|
|
||||||
const content = "Test comment 4"
|
|
||||||
const status = ""
|
|
||||||
session := loginUser(t, "user2")
|
|
||||||
issueURL := testNewIssue(t, session, "user2", "repo1", "Title", "Description")
|
|
||||||
|
|
||||||
req := NewRequest(t, "GET", issueURL)
|
|
||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
|
|
||||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
||||||
link, exists := htmlDoc.doc.Find("#comment-form").Attr("action")
|
|
||||||
assert.True(t, exists, "The template has changed")
|
|
||||||
|
|
||||||
uuid := createAttachment(t, session, repoURL, "image.png", generateImg(), http.StatusOK)
|
|
||||||
|
|
||||||
commentCount := htmlDoc.doc.Find(".comment-list .comment .render-content").Length()
|
|
||||||
|
|
||||||
req = NewRequestWithValues(t, "POST", link, map[string]string{
|
|
||||||
"_csrf": htmlDoc.GetCSRF(),
|
|
||||||
"content": content,
|
|
||||||
"status": status,
|
|
||||||
"files": uuid,
|
|
||||||
})
|
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
|
|
||||||
req = NewRequest(t, "GET", test.RedirectURL(resp))
|
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
|
|
||||||
htmlDoc = NewHTMLParser(t, resp.Body)
|
|
||||||
|
|
||||||
val := htmlDoc.doc.Find(".comment-list .comment .render-content p").Eq(commentCount).Text()
|
|
||||||
assert.Equal(t, content, val)
|
|
||||||
|
|
||||||
idAttr, has := htmlDoc.doc.Find(".comment-list .comment").Eq(commentCount).Attr("id")
|
|
||||||
idStr := idAttr[strings.LastIndexByte(idAttr, '-')+1:]
|
|
||||||
assert.True(t, has)
|
|
||||||
id, err := strconv.Atoi(idStr)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.NotEqual(t, 0, id)
|
|
||||||
|
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/comments/%d/attachments", "user2", "repo1", id))
|
|
||||||
session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
|
|
||||||
// Using the ID of a comment that does not belong to the repository must fail
|
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/comments/%d/attachments", "user5", "repo4", id))
|
|
||||||
session.MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIssueCommentUpdate(t *testing.T) {
|
|
||||||
defer tests.PrepareTestEnv(t)()
|
|
||||||
session := loginUser(t, "user2")
|
|
||||||
issueURL := testNewIssue(t, session, "user2", "repo1", "Title", "Description")
|
|
||||||
comment1 := "Test comment 1"
|
|
||||||
commentID := testIssueAddComment(t, session, issueURL, comment1, "")
|
|
||||||
|
|
||||||
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: commentID})
|
|
||||||
assert.Equal(t, comment1, comment.Content)
|
|
||||||
|
|
||||||
modifiedContent := comment.Content + "MODIFIED"
|
|
||||||
|
|
||||||
// Using the ID of a comment that does not belong to the repository must fail
|
|
||||||
req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d", "user5", "repo4", commentID), map[string]string{
|
|
||||||
"_csrf": GetCSRF(t, session, issueURL),
|
|
||||||
"content": modifiedContent,
|
|
||||||
})
|
|
||||||
session.MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
|
|
||||||
req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d", "user2", "repo1", commentID), map[string]string{
|
|
||||||
"_csrf": GetCSRF(t, session, issueURL),
|
|
||||||
"content": modifiedContent,
|
|
||||||
})
|
|
||||||
session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
|
|
||||||
comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: commentID})
|
|
||||||
assert.Equal(t, modifiedContent, comment.Content)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIssueReaction(t *testing.T) {
|
func TestIssueReaction(t *testing.T) {
|
||||||
defer tests.PrepareTestEnv(t)()
|
defer tests.PrepareTestEnv(t)()
|
||||||
session := loginUser(t, "user2")
|
session := loginUser(t, "user2")
|
||||||
|
@ -657,45 +557,3 @@ func TestUpdateIssueDeadline(t *testing.T) {
|
||||||
|
|
||||||
assert.EqualValues(t, "2022-04-06", apiIssue.Deadline.Format("2006-01-02"))
|
assert.EqualValues(t, "2022-04-06", apiIssue.Deadline.Format("2006-01-02"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIssuePinMove(t *testing.T) {
|
|
||||||
defer tests.PrepareTestEnv(t)()
|
|
||||||
session := loginUser(t, "user2")
|
|
||||||
issueURL, issue := testIssueWithBean(t, "user2", 1, "Title", "Content")
|
|
||||||
assert.EqualValues(t, 0, issue.PinOrder)
|
|
||||||
|
|
||||||
req := NewRequestWithValues(t, "POST", fmt.Sprintf("%s/pin", issueURL), map[string]string{
|
|
||||||
"_csrf": GetCSRF(t, session, issueURL),
|
|
||||||
})
|
|
||||||
session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID})
|
|
||||||
|
|
||||||
position := 1
|
|
||||||
assert.EqualValues(t, position, issue.PinOrder)
|
|
||||||
|
|
||||||
newPosition := 2
|
|
||||||
|
|
||||||
// Using the ID of an issue that does not belong to the repository must fail
|
|
||||||
{
|
|
||||||
session5 := loginUser(t, "user5")
|
|
||||||
movePinURL := "/user5/repo4/issues/move_pin?_csrf=" + GetCSRF(t, session5, issueURL)
|
|
||||||
req = NewRequestWithJSON(t, "POST", movePinURL, map[string]any{
|
|
||||||
"id": issue.ID,
|
|
||||||
"position": newPosition,
|
|
||||||
})
|
|
||||||
session5.MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
|
|
||||||
issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID})
|
|
||||||
assert.EqualValues(t, position, issue.PinOrder)
|
|
||||||
}
|
|
||||||
|
|
||||||
movePinURL := issueURL[:strings.LastIndexByte(issueURL, '/')] + "/move_pin?_csrf=" + GetCSRF(t, session, issueURL)
|
|
||||||
req = NewRequestWithJSON(t, "POST", movePinURL, map[string]any{
|
|
||||||
"id": issue.ID,
|
|
||||||
"position": newPosition,
|
|
||||||
})
|
|
||||||
session.MakeRequest(t, req, http.StatusNoContent)
|
|
||||||
|
|
||||||
issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID})
|
|
||||||
assert.EqualValues(t, newPosition, issue.PinOrder)
|
|
||||||
}
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ func TestMirrorPull(t *testing.T) {
|
||||||
|
|
||||||
release, err := repo_model.GetRelease(db.DefaultContext, repo.ID, "v0.2")
|
release, err := repo_model.GetRelease(db.DefaultContext, repo.ID, "v0.2")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NoError(t, release_service.DeleteReleaseByID(ctx, repo, release, user, true))
|
assert.NoError(t, release_service.DeleteReleaseByID(ctx, release.ID, user, true))
|
||||||
|
|
||||||
ok = mirror_service.SyncPullMirror(ctx, mirror.ID)
|
ok = mirror_service.SyncPullMirror(ctx, mirror.ID)
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
|
|
@ -93,44 +93,6 @@ func TestCreateRelease(t *testing.T) {
|
||||||
checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", translation.NewLocale("en-US").Tr("repo.release.stable"), 4)
|
checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", translation.NewLocale("en-US").Tr("repo.release.stable"), 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteRelease(t *testing.T) {
|
|
||||||
defer tests.PrepareTestEnv(t)()
|
|
||||||
|
|
||||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 57, OwnerName: "user2", LowerName: "repo-release"})
|
|
||||||
release := unittest.AssertExistsAndLoadBean(t, &repo_model.Release{TagName: "v2.0"})
|
|
||||||
assert.False(t, release.IsTag)
|
|
||||||
|
|
||||||
// Using the ID of a comment that does not belong to the repository must fail
|
|
||||||
session5 := loginUser(t, "user5")
|
|
||||||
otherRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user5", LowerName: "repo4"})
|
|
||||||
|
|
||||||
req := NewRequestWithValues(t, "POST", fmt.Sprintf("%s/releases/delete?id=%d", otherRepo.Link(), release.ID), map[string]string{
|
|
||||||
"_csrf": GetCSRF(t, session5, otherRepo.Link()),
|
|
||||||
})
|
|
||||||
session5.MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
|
|
||||||
session := loginUser(t, "user2")
|
|
||||||
req = NewRequestWithValues(t, "POST", fmt.Sprintf("%s/releases/delete?id=%d", repo.Link(), release.ID), map[string]string{
|
|
||||||
"_csrf": GetCSRF(t, session, repo.Link()),
|
|
||||||
})
|
|
||||||
session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
release = unittest.AssertExistsAndLoadBean(t, &repo_model.Release{ID: release.ID})
|
|
||||||
|
|
||||||
if assert.True(t, release.IsTag) {
|
|
||||||
req = NewRequestWithValues(t, "POST", fmt.Sprintf("%s/tags/delete?id=%d", otherRepo.Link(), release.ID), map[string]string{
|
|
||||||
"_csrf": GetCSRF(t, session5, otherRepo.Link()),
|
|
||||||
})
|
|
||||||
session5.MakeRequest(t, req, http.StatusNotFound)
|
|
||||||
|
|
||||||
req = NewRequestWithValues(t, "POST", fmt.Sprintf("%s/tags/delete?id=%d", repo.Link(), release.ID), map[string]string{
|
|
||||||
"_csrf": GetCSRF(t, session, repo.Link()),
|
|
||||||
})
|
|
||||||
session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
|
|
||||||
unittest.AssertNotExistsBean(t, &repo_model.Release{ID: release.ID})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateReleasePreRelease(t *testing.T) {
|
func TestCreateReleasePreRelease(t *testing.T) {
|
||||||
defer tests.PrepareTestEnv(t)()
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue