Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
code.gitea.io/sdk/gitea v0.24.1
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
connectrpc.com/connect v1.19.1
gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed
gitea.com/go-chi/binding v0.0.0-20260414111559-654cea7ac60a
gitea.com/go-chi/cache v0.2.1
gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098
gitea.com/go-chi/session v0.0.0-20251124165456-68e0254e989e
Expand Down Expand Up @@ -57,7 +57,6 @@ require (
github.com/go-redsync/redsync/v4 v4.16.0
github.com/go-sql-driver/mysql v1.9.3
github.com/go-webauthn/webauthn v0.16.4
github.com/goccy/go-json v0.10.6
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
github.com/golang-jwt/jwt/v5 v5.3.1
Expand Down Expand Up @@ -196,6 +195,7 @@ require (
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/go-webauthn/x v0.2.3 // indirect
github.com/goccy/go-json v0.10.6 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
gitea.com/gitea/act v0.261.10 h1:ndwbtuMXXz1dpYF2iwY1/PkgKNETo4jmPXfinTZt8cs=
gitea.com/gitea/act v0.261.10/go.mod h1:oIkqQHvU0lfuIWwcpqa4FmU+t3prA89tgkuHUTsrI2c=
gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed h1:EZZBtilMLSZNWtHHcgq2mt6NSGhJSZBuduAlinMEmso=
gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed/go.mod h1:E3i3cgB04dDx0v3CytCgRTTn9Z/9x891aet3r456RVw=
gitea.com/go-chi/binding v0.0.0-20260414111559-654cea7ac60a h1:JHoBrfuTSF9Ke9aNfSYj1XRPBHjKPgCApVprnt2Am0M=
gitea.com/go-chi/binding v0.0.0-20260414111559-654cea7ac60a/go.mod h1:FOsLJIMdpiHzBp3Vby6Wfkdw2ppGscrjgU1IC7E4/zQ=
gitea.com/go-chi/cache v0.2.1 h1:bfAPkvXlbcZxPCpcmDVCWoHgiBSBmZN/QosnZvEC0+g=
gitea.com/go-chi/cache v0.2.1/go.mod h1:Qic0HZ8hOHW62ETGbonpwz8WYypj9NieU9659wFUJ8Q=
gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098 h1:p2ki+WK0cIeNQuqjR98IP2KZQKRzJJiV7aTeMAFwaWo=
Expand Down
35 changes: 0 additions & 35 deletions modules/json/jsongoccy.go

This file was deleted.

2 changes: 1 addition & 1 deletion modules/json/jsonlegacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func getDefaultJSONHandler() Interface {
return jsonGoccy{}
return jsonV1{}
}

func MarshalKeepOptionalEmpty(v any) ([]byte, error) {
Expand Down
17 changes: 17 additions & 0 deletions modules/validation/binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ package validation

import (
"fmt"
"io"
"regexp"
"strings"

"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/util"

"gitea.com/go-chi/binding"
Expand All @@ -31,8 +33,23 @@ const (
ErrInvalidBadgeSlug = "InvalidBadgeSlug"
)

type jsonProvider struct{}

func (j jsonProvider) Marshal(v any) ([]byte, error) { return json.Marshal(v) }

func (j jsonProvider) Unmarshal(data []byte, v any) error { return json.Unmarshal(data, v) }

func (j jsonProvider) NewDecoder(reader io.Reader) binding.JSONDecoder {
return json.NewDecoder(reader)
}

func (j jsonProvider) NewEncoder(writer io.Writer) binding.JSONEncoder {
return json.NewEncoder(writer)
}

// AddBindingRules adds additional binding rules
func AddBindingRules() {
binding.JSONProvider = jsonProvider{}
addGitRefNameBindingRule()
addValidURLListBindingRule()
addValidURLBindingRule()
Expand Down
43 changes: 39 additions & 4 deletions services/forms/repo_form.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (

issues_model "code.gitea.io/gitea/models/issues"
project_model "code.gitea.io/gitea/models/project"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web/middleware"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/webhook"
Expand Down Expand Up @@ -523,16 +525,49 @@ func (f *InitializeLabelsForm) Validate(req *http.Request, errs binding.Errors)
type MergePullRequestForm struct {
// required: true
// enum: ["merge","rebase","rebase-merge","squash","fast-forward-only","manually-merged"]
Do string `binding:"Required;In(merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged)"`
MergeTitleField string
MergeMessageField string
MergeCommitID string // only used for manually-merged
Do string `json:"do" binding:"Required;In(merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged)"`
MergeTitleField string `json:"merge_title_field,omitempty"`
MergeMessageField string `json:"merge_message_field,omitempty"`
MergeCommitID string `json:"merge_commit_id,omitempty"` // only used for manually-merged
HeadCommitID string `json:"head_commit_id,omitempty"`
ForceMerge bool `json:"force_merge,omitempty"`
MergeWhenChecksSucceed bool `json:"merge_when_checks_succeed,omitempty"`
DeleteBranchAfterMerge *bool `json:"delete_branch_after_merge,omitempty"`
}

func (f *MergePullRequestForm) UnmarshalJSON(b []byte) error {
// This is for backward compatibility, to support both field names like "do" and "Do",
// because old code doesn't have "json" tag for these fields
type aux struct {
Do1 string `json:"do"`
Do2 string `json:"Do"`
MergeTitleField1 string `json:"merge_title_field"`
MergeTitleField2 string `json:"MergeTitleField"`
MergeMessageField1 string `json:"merge_message_field"`
MergeMessageField2 string `json:"MergeMessageField"`
MergeCommitID1 string `json:"merge_commit_id"`
MergeCommitID2 string `json:"MergeCommitID"`

HeadCommitID string `json:"head_commit_id"`
ForceMerge bool `json:"force_merge"`
MergeWhenChecksSucceed bool `json:"merge_when_checks_succeed"`
DeleteBranchAfterMerge *bool `json:"delete_branch_after_merge"`
}
var a aux
if err := json.Unmarshal(b, &a); err != nil {
return err
}
f.Do = util.IfZero(a.Do1, a.Do2)
f.MergeTitleField = util.IfZero(a.MergeTitleField1, a.MergeTitleField2)
f.MergeMessageField = util.IfZero(a.MergeMessageField1, a.MergeMessageField2)
f.MergeCommitID = util.IfZero(a.MergeCommitID1, a.MergeCommitID2)
f.HeadCommitID = a.HeadCommitID
f.ForceMerge = a.ForceMerge
f.MergeWhenChecksSucceed = a.MergeWhenChecksSucceed
f.DeleteBranchAfterMerge = a.DeleteBranchAfterMerge
return nil
}

// Validate validates the fields
func (f *MergePullRequestForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
ctx := context.GetValidateContext(req)
Expand Down
48 changes: 48 additions & 0 deletions services/forms/repo_form_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ package forms
import (
"testing"

"code.gitea.io/gitea/modules/json"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestSubmitReviewForm_IsEmpty(t *testing.T) {
Expand Down Expand Up @@ -37,3 +40,48 @@ func TestSubmitReviewForm_IsEmpty(t *testing.T) {
assert.Equal(t, v.expected, v.form.HasEmptyContent())
}
}

func TestMergePullRequestForm(t *testing.T) {
expected := &MergePullRequestForm{
Do: "merge",
MergeTitleField: "title",
MergeMessageField: "message",
MergeCommitID: "merge-id",
HeadCommitID: "head-id",
ForceMerge: true,
MergeWhenChecksSucceed: true,
DeleteBranchAfterMerge: new(true),
}

t.Run("NewFields", func(t *testing.T) {
input := `{
"do": "merge",
"merge_title_field": "title",
"merge_message_field": "message",
"merge_commit_id": "merge-id",
"head_commit_id": "head-id",
"force_merge": true,
"merge_when_checks_succeed": true,
"delete_branch_after_merge": true
}`
var m *MergePullRequestForm
require.NoError(t, json.Unmarshal([]byte(input), &m))
assert.Equal(t, expected, m)
})

t.Run("OldFields", func(t *testing.T) {
input := `{
"Do": "merge",
"MergeTitleField": "title",
"MergeMessageField": "message",
"MergeCommitID": "merge-id",
"head_commit_id": "head-id",
"force_merge": true,
"merge_when_checks_succeed": true,
"delete_branch_after_merge": true
}`
var m *MergePullRequestForm
require.NoError(t, json.Unmarshal([]byte(input), &m))
assert.Equal(t, expected, m)
})
}
36 changes: 20 additions & 16 deletions templates/swagger/v1_json.tmpl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions tests/integration/api_issue_reaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ func TestAPIIssuesReactions(t *testing.T) {
DecodeJSON(t, resp, &apiNewReaction)

// Add existing reaction
MakeRequest(t, req, http.StatusForbidden)
req = NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{
Reaction: "rocket",
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusOK)

// Blocked user can't react to comment
user34 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 34})
Expand Down Expand Up @@ -142,7 +145,10 @@ func TestAPICommentReactions(t *testing.T) {
DecodeJSON(t, resp, &apiNewReaction)

// Add existing reaction
MakeRequest(t, req, http.StatusForbidden)
req = NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{
Reaction: "+1",
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusOK)

// Get end result of reaction list of issue #1
req = NewRequest(t, "GET", urlStr).
Expand Down