From 003b4e209ce27e21e68b6a48ad2a7f6a1bcb17fb Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 12 Dec 2022 13:29:27 +0800 Subject: [PATCH 1/4] Allow disable code tab (#20805) I know some users created a repository in an organization but just use issues and projects to handle the whole organizations issues. So that `Code` could be disabled per repository. image It could also become a wiki repository. image Co-authored-by: delvh --- routers/web/repo/setting.go | 9 +++++++++ services/forms/repo_form.go | 1 + templates/repo/settings/options.tmpl | 13 +++++++++++++ 3 files changed, 23 insertions(+) diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go index 8ba5fc9e349da..f35adcaa10e2a 100644 --- a/routers/web/repo/setting.go +++ b/routers/web/repo/setting.go @@ -397,6 +397,15 @@ func SettingsPost(ctx *context.Context) { repoChanged = true } + if form.EnableCode && !unit_model.TypeCode.UnitGlobalDisabled() { + units = append(units, repo_model.RepoUnit{ + RepoID: repo.ID, + Type: unit_model.TypeCode, + }) + } else if !unit_model.TypeCode.UnitGlobalDisabled() { + deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeCode) + } + if form.EnableWiki && form.EnableExternalWiki && !unit_model.TypeExternalWiki.UnitGlobalDisabled() { if !validation.IsValidExternalURL(form.ExternalWikiURL) { ctx.Flash.Error(ctx.Tr("repo.settings.external_wiki_url_error")) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index d4fb051d8daa9..89a013d9af8d0 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -134,6 +134,7 @@ type RepoSettingForm struct { EnablePrune bool // Advanced settings + EnableCode bool EnableWiki bool EnableExternalWiki bool ExternalWikiURL string diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index aa79f75617e73..e1f53072b8301 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -249,6 +249,19 @@ {{.CsrfTokenHtml}} + {{$isCodeEnabled := .Repository.UnitEnabled $.Context $.UnitTypeCode}} +
+ + {{if .UnitTypeCode.UnitGlobalDisabled}} +
+ {{else}} +
+ {{end}} + + +
+
+ {{$isWikiEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeWiki) (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}
From 6398ca745aabdc40f10465e71da99c5a3866990e Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 12 Dec 2022 16:09:26 +0800 Subject: [PATCH 2/4] refactor bind functions based on generics (#22055) --- modules/web/route.go | 12 +- routers/api/v1/api.go | 9 +- routers/private/internal.go | 9 +- routers/web/web.go | 326 ++++++++++++++++++------------------ 4 files changed, 168 insertions(+), 188 deletions(-) diff --git a/modules/web/route.go b/modules/web/route.go index cd72aabae5e6a..0f2fdc33b5a84 100644 --- a/modules/web/route.go +++ b/modules/web/route.go @@ -7,7 +7,6 @@ import ( goctx "context" "fmt" "net/http" - "reflect" "strings" "code.gitea.io/gitea/modules/context" @@ -18,16 +17,9 @@ import ( ) // Bind binding an obj to a handler -func Bind(obj interface{}) http.HandlerFunc { - tp := reflect.TypeOf(obj) - if tp.Kind() == reflect.Ptr { - tp = tp.Elem() - } - if tp.Kind() != reflect.Struct { - panic("Only structs are allowed to bind") - } +func Bind[T any](obj T) http.HandlerFunc { return Wrap(func(ctx *context.Context) { - theObj := reflect.New(tp).Interface() // create a new form obj for every request but not use obj directly + theObj := new(T) // create a new form obj for every request but not use obj directly binding.Bind(ctx.Req, theObj) SetForm(ctx, theObj) middleware.AssignForm(theObj, ctx.Data) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 14b168c24293e..82ff7ae0befcc 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -67,7 +67,6 @@ import ( gocontext "context" "fmt" "net/http" - "reflect" "strings" "code.gitea.io/gitea/models/organization" @@ -575,13 +574,9 @@ func mustEnableAttachments(ctx *context.APIContext) { } // bind binding an obj to a func(ctx *context.APIContext) -func bind(obj interface{}) http.HandlerFunc { - tp := reflect.TypeOf(obj) - for tp.Kind() == reflect.Ptr { - tp = tp.Elem() - } +func bind[T any](obj T) http.HandlerFunc { return web.Wrap(func(ctx *context.APIContext) { - theObj := reflect.New(tp).Interface() // create a new form obj for every request but not use obj directly + theObj := new(T) // create a new form obj for every request but not use obj directly errs := binding.Bind(ctx.Req, theObj) if len(errs) > 0 { ctx.Error(http.StatusUnprocessableEntity, "validationError", fmt.Sprintf("%s: %s", errs[0].FieldNames, errs[0].Error())) diff --git a/routers/private/internal.go b/routers/private/internal.go index d5c85480a774f..306e4ffb0040f 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -6,7 +6,6 @@ package private import ( "net/http" - "reflect" "strings" "code.gitea.io/gitea/modules/context" @@ -39,13 +38,9 @@ func CheckInternalToken(next http.Handler) http.Handler { } // bind binding an obj to a handler -func bind(obj interface{}) http.HandlerFunc { - tp := reflect.TypeOf(obj) - for tp.Kind() == reflect.Ptr { - tp = tp.Elem() - } +func bind[T any](obj T) http.HandlerFunc { return web.Wrap(func(ctx *context.PrivateContext) { - theObj := reflect.New(tp).Interface() // create a new form obj for every request but not use obj directly + theObj := new(T) // create a new form obj for every request but not use obj directly binding.Bind(ctx.Req, theObj) web.SetForm(ctx, theObj) }) diff --git a/routers/web/web.go b/routers/web/web.go index 889a89f0d4ae4..99c2a83917047 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -234,8 +234,6 @@ func RegisterRoutes(m *web.Route) { ignExploreSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: setting.Service.RequireSignInView || setting.Service.Explore.RequireSigninView}) ignSignInAndCsrf := context.Toggle(&context.ToggleOptions{DisableCSRF: true}) reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true}) - - bindIgnErr := web.Bind validation.AddBindingRules() linkAccountEnabled := func(ctx *context.Context) { @@ -356,32 +354,32 @@ func RegisterRoutes(m *web.Route) { // ***** START: User ***** m.Group("/user", func() { m.Get("/login", auth.SignIn) - m.Post("/login", bindIgnErr(forms.SignInForm{}), auth.SignInPost) + m.Post("/login", web.Bind(forms.SignInForm{}), auth.SignInPost) m.Group("", func() { m.Combo("/login/openid"). Get(auth.SignInOpenID). - Post(bindIgnErr(forms.SignInOpenIDForm{}), auth.SignInOpenIDPost) + Post(web.Bind(forms.SignInOpenIDForm{}), auth.SignInOpenIDPost) }, openIDSignInEnabled) m.Group("/openid", func() { m.Combo("/connect"). Get(auth.ConnectOpenID). - Post(bindIgnErr(forms.ConnectOpenIDForm{}), auth.ConnectOpenIDPost) + Post(web.Bind(forms.ConnectOpenIDForm{}), auth.ConnectOpenIDPost) m.Group("/register", func() { m.Combo(""). Get(auth.RegisterOpenID, openIDSignUpEnabled). - Post(bindIgnErr(forms.SignUpOpenIDForm{}), auth.RegisterOpenIDPost) + Post(web.Bind(forms.SignUpOpenIDForm{}), auth.RegisterOpenIDPost) }, openIDSignUpEnabled) }, openIDSignInEnabled) m.Get("/sign_up", auth.SignUp) - m.Post("/sign_up", bindIgnErr(forms.RegisterForm{}), auth.SignUpPost) + m.Post("/sign_up", web.Bind(forms.RegisterForm{}), auth.SignUpPost) m.Get("/link_account", linkAccountEnabled, auth.LinkAccount) - m.Post("/link_account_signin", linkAccountEnabled, bindIgnErr(forms.SignInForm{}), auth.LinkAccountPostSignIn) - m.Post("/link_account_signup", linkAccountEnabled, bindIgnErr(forms.RegisterForm{}), auth.LinkAccountPostRegister) + m.Post("/link_account_signin", linkAccountEnabled, web.Bind(forms.SignInForm{}), auth.LinkAccountPostSignIn) + m.Post("/link_account_signup", linkAccountEnabled, web.Bind(forms.RegisterForm{}), auth.LinkAccountPostRegister) m.Group("/two_factor", func() { m.Get("", auth.TwoFactor) - m.Post("", bindIgnErr(forms.TwoFactorAuthForm{}), auth.TwoFactorPost) + m.Post("", web.Bind(forms.TwoFactorAuthForm{}), auth.TwoFactorPost) m.Get("/scratch", auth.TwoFactorScratch) - m.Post("/scratch", bindIgnErr(forms.TwoFactorScratchAuthForm{}), auth.TwoFactorScratchPost) + m.Post("/scratch", web.Bind(forms.TwoFactorScratchAuthForm{}), auth.TwoFactorScratchPost) }) m.Group("/webauthn", func() { m.Get("", auth.WebAuthn) @@ -393,34 +391,34 @@ func RegisterRoutes(m *web.Route) { m.Any("/user/events", routing.MarkLongPolling, events.Events) m.Group("/login/oauth", func() { - m.Get("/authorize", bindIgnErr(forms.AuthorizationForm{}), auth.AuthorizeOAuth) - m.Post("/grant", bindIgnErr(forms.GrantApplicationForm{}), auth.GrantApplicationOAuth) + m.Get("/authorize", web.Bind(forms.AuthorizationForm{}), auth.AuthorizeOAuth) + m.Post("/grant", web.Bind(forms.GrantApplicationForm{}), auth.GrantApplicationOAuth) // TODO manage redirection - m.Post("/authorize", bindIgnErr(forms.AuthorizationForm{}), auth.AuthorizeOAuth) + m.Post("/authorize", web.Bind(forms.AuthorizationForm{}), auth.AuthorizeOAuth) }, ignSignInAndCsrf, reqSignIn) m.Get("/login/oauth/userinfo", ignSignInAndCsrf, auth.InfoOAuth) - m.Post("/login/oauth/access_token", CorsHandler(), bindIgnErr(forms.AccessTokenForm{}), ignSignInAndCsrf, auth.AccessTokenOAuth) + m.Post("/login/oauth/access_token", CorsHandler(), web.Bind(forms.AccessTokenForm{}), ignSignInAndCsrf, auth.AccessTokenOAuth) m.Get("/login/oauth/keys", ignSignInAndCsrf, auth.OIDCKeys) - m.Post("/login/oauth/introspect", CorsHandler(), bindIgnErr(forms.IntrospectTokenForm{}), ignSignInAndCsrf, auth.IntrospectOAuth) + m.Post("/login/oauth/introspect", CorsHandler(), web.Bind(forms.IntrospectTokenForm{}), ignSignInAndCsrf, auth.IntrospectOAuth) m.Group("/user/settings", func() { m.Get("", user_setting.Profile) - m.Post("", bindIgnErr(forms.UpdateProfileForm{}), user_setting.ProfilePost) + m.Post("", web.Bind(forms.UpdateProfileForm{}), user_setting.ProfilePost) m.Get("/change_password", auth.MustChangePassword) - m.Post("/change_password", bindIgnErr(forms.MustChangePasswordForm{}), auth.MustChangePasswordPost) - m.Post("/avatar", bindIgnErr(forms.AvatarForm{}), user_setting.AvatarPost) + m.Post("/change_password", web.Bind(forms.MustChangePasswordForm{}), auth.MustChangePasswordPost) + m.Post("/avatar", web.Bind(forms.AvatarForm{}), user_setting.AvatarPost) m.Post("/avatar/delete", user_setting.DeleteAvatar) m.Group("/account", func() { - m.Combo("").Get(user_setting.Account).Post(bindIgnErr(forms.ChangePasswordForm{}), user_setting.AccountPost) - m.Post("/email", bindIgnErr(forms.AddEmailForm{}), user_setting.EmailPost) + m.Combo("").Get(user_setting.Account).Post(web.Bind(forms.ChangePasswordForm{}), user_setting.AccountPost) + m.Post("/email", web.Bind(forms.AddEmailForm{}), user_setting.EmailPost) m.Post("/email/delete", user_setting.DeleteEmail) m.Post("/delete", user_setting.DeleteAccount) }) m.Group("/appearance", func() { m.Get("", user_setting.Appearance) - m.Post("/language", bindIgnErr(forms.UpdateLanguageForm{}), user_setting.UpdateUserLang) + m.Post("/language", web.Bind(forms.UpdateLanguageForm{}), user_setting.UpdateUserLang) m.Post("/hidden_comments", user_setting.UpdateUserHiddenComments) - m.Post("/theme", bindIgnErr(forms.UpdateThemeForm{}), user_setting.UpdateUIThemePost) + m.Post("/theme", web.Bind(forms.UpdateThemeForm{}), user_setting.UpdateUIThemePost) }) m.Group("/security", func() { m.Get("", security.Security) @@ -428,15 +426,15 @@ func RegisterRoutes(m *web.Route) { m.Post("/regenerate_scratch", security.RegenerateScratchTwoFactor) m.Post("/disable", security.DisableTwoFactor) m.Get("/enroll", security.EnrollTwoFactor) - m.Post("/enroll", bindIgnErr(forms.TwoFactorAuthForm{}), security.EnrollTwoFactorPost) + m.Post("/enroll", web.Bind(forms.TwoFactorAuthForm{}), security.EnrollTwoFactorPost) }) m.Group("/webauthn", func() { - m.Post("/request_register", bindIgnErr(forms.WebauthnRegistrationForm{}), security.WebAuthnRegister) + m.Post("/request_register", web.Bind(forms.WebauthnRegistrationForm{}), security.WebAuthnRegister) m.Post("/register", security.WebauthnRegisterPost) - m.Post("/delete", bindIgnErr(forms.WebauthnDeleteForm{}), security.WebauthnDelete) + m.Post("/delete", web.Bind(forms.WebauthnDeleteForm{}), security.WebauthnDelete) }) m.Group("/openid", func() { - m.Post("", bindIgnErr(forms.AddOpenIDForm{}), security.OpenIDPost) + m.Post("", web.Bind(forms.AddOpenIDForm{}), security.OpenIDPost) m.Post("/delete", security.DeleteOpenID) m.Post("/toggle_visibility", security.ToggleOpenIDVisibility) }, openIDSignInEnabled) @@ -444,28 +442,28 @@ func RegisterRoutes(m *web.Route) { }) m.Group("/applications/oauth2", func() { m.Get("/{id}", user_setting.OAuth2ApplicationShow) - m.Post("/{id}", bindIgnErr(forms.EditOAuth2ApplicationForm{}), user_setting.OAuthApplicationsEdit) + m.Post("/{id}", web.Bind(forms.EditOAuth2ApplicationForm{}), user_setting.OAuthApplicationsEdit) m.Post("/{id}/regenerate_secret", user_setting.OAuthApplicationsRegenerateSecret) - m.Post("", bindIgnErr(forms.EditOAuth2ApplicationForm{}), user_setting.OAuthApplicationsPost) + m.Post("", web.Bind(forms.EditOAuth2ApplicationForm{}), user_setting.OAuthApplicationsPost) m.Post("/{id}/delete", user_setting.DeleteOAuth2Application) m.Post("/{id}/revoke/{grantId}", user_setting.RevokeOAuth2Grant) }) m.Combo("/applications").Get(user_setting.Applications). - Post(bindIgnErr(forms.NewAccessTokenForm{}), user_setting.ApplicationsPost) + Post(web.Bind(forms.NewAccessTokenForm{}), user_setting.ApplicationsPost) m.Post("/applications/delete", user_setting.DeleteApplication) m.Combo("/keys").Get(user_setting.Keys). - Post(bindIgnErr(forms.AddKeyForm{}), user_setting.KeysPost) + Post(web.Bind(forms.AddKeyForm{}), user_setting.KeysPost) m.Post("/keys/delete", user_setting.DeleteKey) m.Group("/packages", func() { m.Get("", user_setting.Packages) m.Group("/rules", func() { m.Group("/add", func() { m.Get("", user_setting.PackagesRuleAdd) - m.Post("", bindIgnErr(forms.PackageCleanupRuleForm{}), user_setting.PackagesRuleAddPost) + m.Post("", web.Bind(forms.PackageCleanupRuleForm{}), user_setting.PackagesRuleAddPost) }) m.Group("/{id}", func() { m.Get("", user_setting.PackagesRuleEdit) - m.Post("", bindIgnErr(forms.PackageCleanupRuleForm{}), user_setting.PackagesRuleEditPost) + m.Post("", web.Bind(forms.PackageCleanupRuleForm{}), user_setting.PackagesRuleEditPost) m.Get("/preview", user_setting.PackagesRulePreview) }) }) @@ -507,7 +505,7 @@ func RegisterRoutes(m *web.Route) { // ***** START: Admin ***** m.Group("/admin", func() { m.Get("", adminReq, admin.Dashboard) - m.Post("", adminReq, bindIgnErr(forms.AdminDashboardForm{}), admin.DashboardPost) + m.Post("", adminReq, web.Bind(forms.AdminDashboardForm{}), admin.DashboardPost) m.Group("/config", func() { m.Get("", admin.Config) @@ -532,10 +530,10 @@ func RegisterRoutes(m *web.Route) { m.Group("/users", func() { m.Get("", admin.Users) - m.Combo("/new").Get(admin.NewUser).Post(bindIgnErr(forms.AdminCreateUserForm{}), admin.NewUserPost) - m.Combo("/{userid}").Get(admin.EditUser).Post(bindIgnErr(forms.AdminEditUserForm{}), admin.EditUserPost) + m.Combo("/new").Get(admin.NewUser).Post(web.Bind(forms.AdminCreateUserForm{}), admin.NewUserPost) + m.Combo("/{userid}").Get(admin.EditUser).Post(web.Bind(forms.AdminEditUserForm{}), admin.EditUserPost) m.Post("/{userid}/delete", admin.DeleteUser) - m.Post("/{userid}/avatar", bindIgnErr(forms.AvatarForm{}), admin.AvatarPost) + m.Post("/{userid}/avatar", web.Bind(forms.AvatarForm{}), admin.AvatarPost) m.Post("/{userid}/avatar/delete", admin.DeleteAvatar) }) @@ -566,39 +564,39 @@ func RegisterRoutes(m *web.Route) { m.Get("", repo.WebHooksEdit) m.Post("/replay/{uuid}", repo.ReplayWebhook) }) - m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) - m.Post("/gogs/{id}", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksEditPost) - m.Post("/slack/{id}", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) - m.Post("/discord/{id}", bindIgnErr(forms.NewDiscordHookForm{}), repo.DiscordHooksEditPost) - m.Post("/dingtalk/{id}", bindIgnErr(forms.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) - m.Post("/telegram/{id}", bindIgnErr(forms.NewTelegramHookForm{}), repo.TelegramHooksEditPost) - m.Post("/matrix/{id}", bindIgnErr(forms.NewMatrixHookForm{}), repo.MatrixHooksEditPost) - m.Post("/msteams/{id}", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) - m.Post("/feishu/{id}", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksEditPost) - m.Post("/wechatwork/{id}", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksEditPost) - m.Post("/packagist/{id}", bindIgnErr(forms.NewPackagistHookForm{}), repo.PackagistHooksEditPost) + m.Post("/gitea/{id}", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) + m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo.GogsHooksEditPost) + m.Post("/slack/{id}", web.Bind(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) + m.Post("/discord/{id}", web.Bind(forms.NewDiscordHookForm{}), repo.DiscordHooksEditPost) + m.Post("/dingtalk/{id}", web.Bind(forms.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) + m.Post("/telegram/{id}", web.Bind(forms.NewTelegramHookForm{}), repo.TelegramHooksEditPost) + m.Post("/matrix/{id}", web.Bind(forms.NewMatrixHookForm{}), repo.MatrixHooksEditPost) + m.Post("/msteams/{id}", web.Bind(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) + m.Post("/feishu/{id}", web.Bind(forms.NewFeishuHookForm{}), repo.FeishuHooksEditPost) + m.Post("/wechatwork/{id}", web.Bind(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksEditPost) + m.Post("/packagist/{id}", web.Bind(forms.NewPackagistHookForm{}), repo.PackagistHooksEditPost) }, webhooksEnabled) m.Group("/{configType:default-hooks|system-hooks}", func() { m.Get("/{type}/new", repo.WebhooksNew) - m.Post("/gitea/new", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksNewPost) - m.Post("/gogs/new", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksNewPost) - m.Post("/slack/new", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksNewPost) - m.Post("/discord/new", bindIgnErr(forms.NewDiscordHookForm{}), repo.DiscordHooksNewPost) - m.Post("/dingtalk/new", bindIgnErr(forms.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) - m.Post("/telegram/new", bindIgnErr(forms.NewTelegramHookForm{}), repo.TelegramHooksNewPost) - m.Post("/matrix/new", bindIgnErr(forms.NewMatrixHookForm{}), repo.MatrixHooksNewPost) - m.Post("/msteams/new", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) - m.Post("/feishu/new", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksNewPost) - m.Post("/wechatwork/new", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksNewPost) - m.Post("/packagist/new", bindIgnErr(forms.NewPackagistHookForm{}), repo.PackagistHooksNewPost) + m.Post("/gitea/new", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksNewPost) + m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo.GogsHooksNewPost) + m.Post("/slack/new", web.Bind(forms.NewSlackHookForm{}), repo.SlackHooksNewPost) + m.Post("/discord/new", web.Bind(forms.NewDiscordHookForm{}), repo.DiscordHooksNewPost) + m.Post("/dingtalk/new", web.Bind(forms.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) + m.Post("/telegram/new", web.Bind(forms.NewTelegramHookForm{}), repo.TelegramHooksNewPost) + m.Post("/matrix/new", web.Bind(forms.NewMatrixHookForm{}), repo.MatrixHooksNewPost) + m.Post("/msteams/new", web.Bind(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) + m.Post("/feishu/new", web.Bind(forms.NewFeishuHookForm{}), repo.FeishuHooksNewPost) + m.Post("/wechatwork/new", web.Bind(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksNewPost) + m.Post("/packagist/new", web.Bind(forms.NewPackagistHookForm{}), repo.PackagistHooksNewPost) }) m.Group("/auths", func() { m.Get("", admin.Authentications) - m.Combo("/new").Get(admin.NewAuthSource).Post(bindIgnErr(forms.AuthenticationForm{}), admin.NewAuthSourcePost) + m.Combo("/new").Get(admin.NewAuthSource).Post(web.Bind(forms.AuthenticationForm{}), admin.NewAuthSourcePost) m.Combo("/{authid}").Get(admin.EditAuthSource). - Post(bindIgnErr(forms.AuthenticationForm{}), admin.EditAuthSourcePost) + Post(web.Bind(forms.AuthenticationForm{}), admin.EditAuthSourcePost) m.Post("/{authid}/delete", admin.DeleteAuthSource) }) @@ -610,9 +608,9 @@ func RegisterRoutes(m *web.Route) { m.Group("/applications", func() { m.Get("", admin.Applications) - m.Post("/oauth2", bindIgnErr(forms.EditOAuth2ApplicationForm{}), admin.ApplicationsPost) + m.Post("/oauth2", web.Bind(forms.EditOAuth2ApplicationForm{}), admin.ApplicationsPost) m.Group("/oauth2/{id}", func() { - m.Combo("").Get(admin.EditApplication).Post(bindIgnErr(forms.EditOAuth2ApplicationForm{}), admin.EditApplicationPost) + m.Combo("").Get(admin.EditApplication).Post(web.Bind(forms.EditOAuth2ApplicationForm{}), admin.EditApplicationPost) m.Post("/regenerate_secret", admin.ApplicationsRegenerateSecret) m.Post("/delete", admin.DeleteApplication) }) @@ -683,7 +681,7 @@ func RegisterRoutes(m *web.Route) { m.Group("/org", func() { m.Group("", func() { m.Get("/create", org.Create) - m.Post("/create", bindIgnErr(forms.CreateOrgForm{}), org.CreatePost) + m.Post("/create", web.Bind(forms.CreateOrgForm{}), org.CreatePost) }) m.Group("/invite/{token}", func() { @@ -713,22 +711,22 @@ func RegisterRoutes(m *web.Route) { m.Group("/{org}", func() { m.Get("/teams/new", org.NewTeam) - m.Post("/teams/new", bindIgnErr(forms.CreateTeamForm{}), org.NewTeamPost) + m.Post("/teams/new", web.Bind(forms.CreateTeamForm{}), org.NewTeamPost) m.Get("/teams/-/search", org.SearchTeam) m.Get("/teams/{team}/edit", org.EditTeam) - m.Post("/teams/{team}/edit", bindIgnErr(forms.CreateTeamForm{}), org.EditTeamPost) + m.Post("/teams/{team}/edit", web.Bind(forms.CreateTeamForm{}), org.EditTeamPost) m.Post("/teams/{team}/delete", org.DeleteTeam) m.Group("/settings", func() { m.Combo("").Get(org.Settings). - Post(bindIgnErr(forms.UpdateOrgSettingForm{}), org.SettingsPost) - m.Post("/avatar", bindIgnErr(forms.AvatarForm{}), org.SettingsAvatar) + Post(web.Bind(forms.UpdateOrgSettingForm{}), org.SettingsPost) + m.Post("/avatar", web.Bind(forms.AvatarForm{}), org.SettingsAvatar) m.Post("/avatar/delete", org.SettingsDeleteAvatar) m.Group("/applications", func() { m.Get("", org.Applications) - m.Post("/oauth2", bindIgnErr(forms.EditOAuth2ApplicationForm{}), org.OAuthApplicationsPost) + m.Post("/oauth2", web.Bind(forms.EditOAuth2ApplicationForm{}), org.OAuthApplicationsPost) m.Group("/oauth2/{id}", func() { - m.Combo("").Get(org.OAuth2ApplicationShow).Post(bindIgnErr(forms.EditOAuth2ApplicationForm{}), org.OAuth2ApplicationEdit) + m.Combo("").Get(org.OAuth2ApplicationShow).Post(web.Bind(forms.EditOAuth2ApplicationForm{}), org.OAuth2ApplicationEdit) m.Post("/regenerate_secret", org.OAuthApplicationsRegenerateSecret) m.Post("/delete", org.DeleteOAuth2Application) }) @@ -743,38 +741,38 @@ func RegisterRoutes(m *web.Route) { m.Get("", org.Webhooks) m.Post("/delete", org.DeleteWebhook) m.Get("/{type}/new", repo.WebhooksNew) - m.Post("/gitea/new", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksNewPost) - m.Post("/gogs/new", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksNewPost) - m.Post("/slack/new", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksNewPost) - m.Post("/discord/new", bindIgnErr(forms.NewDiscordHookForm{}), repo.DiscordHooksNewPost) - m.Post("/dingtalk/new", bindIgnErr(forms.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) - m.Post("/telegram/new", bindIgnErr(forms.NewTelegramHookForm{}), repo.TelegramHooksNewPost) - m.Post("/matrix/new", bindIgnErr(forms.NewMatrixHookForm{}), repo.MatrixHooksNewPost) - m.Post("/msteams/new", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) - m.Post("/feishu/new", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksNewPost) - m.Post("/wechatwork/new", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksNewPost) + m.Post("/gitea/new", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksNewPost) + m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo.GogsHooksNewPost) + m.Post("/slack/new", web.Bind(forms.NewSlackHookForm{}), repo.SlackHooksNewPost) + m.Post("/discord/new", web.Bind(forms.NewDiscordHookForm{}), repo.DiscordHooksNewPost) + m.Post("/dingtalk/new", web.Bind(forms.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) + m.Post("/telegram/new", web.Bind(forms.NewTelegramHookForm{}), repo.TelegramHooksNewPost) + m.Post("/matrix/new", web.Bind(forms.NewMatrixHookForm{}), repo.MatrixHooksNewPost) + m.Post("/msteams/new", web.Bind(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) + m.Post("/feishu/new", web.Bind(forms.NewFeishuHookForm{}), repo.FeishuHooksNewPost) + m.Post("/wechatwork/new", web.Bind(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksNewPost) m.Group("/{id}", func() { m.Get("", repo.WebHooksEdit) m.Post("/replay/{uuid}", repo.ReplayWebhook) }) - m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) - m.Post("/gogs/{id}", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksEditPost) - m.Post("/slack/{id}", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) - m.Post("/discord/{id}", bindIgnErr(forms.NewDiscordHookForm{}), repo.DiscordHooksEditPost) - m.Post("/dingtalk/{id}", bindIgnErr(forms.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) - m.Post("/telegram/{id}", bindIgnErr(forms.NewTelegramHookForm{}), repo.TelegramHooksEditPost) - m.Post("/matrix/{id}", bindIgnErr(forms.NewMatrixHookForm{}), repo.MatrixHooksEditPost) - m.Post("/msteams/{id}", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) - m.Post("/feishu/{id}", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksEditPost) - m.Post("/wechatwork/{id}", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksEditPost) + m.Post("/gitea/{id}", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) + m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo.GogsHooksEditPost) + m.Post("/slack/{id}", web.Bind(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) + m.Post("/discord/{id}", web.Bind(forms.NewDiscordHookForm{}), repo.DiscordHooksEditPost) + m.Post("/dingtalk/{id}", web.Bind(forms.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) + m.Post("/telegram/{id}", web.Bind(forms.NewTelegramHookForm{}), repo.TelegramHooksEditPost) + m.Post("/matrix/{id}", web.Bind(forms.NewMatrixHookForm{}), repo.MatrixHooksEditPost) + m.Post("/msteams/{id}", web.Bind(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) + m.Post("/feishu/{id}", web.Bind(forms.NewFeishuHookForm{}), repo.FeishuHooksEditPost) + m.Post("/wechatwork/{id}", web.Bind(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksEditPost) }, webhooksEnabled) m.Group("/labels", func() { m.Get("", org.RetrieveLabels, org.Labels) - m.Post("/new", bindIgnErr(forms.CreateLabelForm{}), org.NewLabel) - m.Post("/edit", bindIgnErr(forms.CreateLabelForm{}), org.UpdateLabel) + m.Post("/new", web.Bind(forms.CreateLabelForm{}), org.NewLabel) + m.Post("/edit", web.Bind(forms.CreateLabelForm{}), org.UpdateLabel) m.Post("/delete", org.DeleteLabel) - m.Post("/initialize", bindIgnErr(forms.InitializeLabelsForm{}), org.InitializeLabels) + m.Post("/initialize", web.Bind(forms.InitializeLabelsForm{}), org.InitializeLabels) }) m.Route("/delete", "GET,POST", org.SettingsDelete) @@ -784,11 +782,11 @@ func RegisterRoutes(m *web.Route) { m.Group("/rules", func() { m.Group("/add", func() { m.Get("", org.PackagesRuleAdd) - m.Post("", bindIgnErr(forms.PackageCleanupRuleForm{}), org.PackagesRuleAddPost) + m.Post("", web.Bind(forms.PackageCleanupRuleForm{}), org.PackagesRuleAddPost) }) m.Group("/{id}", func() { m.Get("", org.PackagesRuleEdit) - m.Post("", bindIgnErr(forms.PackageCleanupRuleForm{}), org.PackagesRuleEditPost) + m.Post("", web.Bind(forms.PackageCleanupRuleForm{}), org.PackagesRuleEditPost) m.Get("/preview", org.PackagesRulePreview) }) }) @@ -804,12 +802,12 @@ func RegisterRoutes(m *web.Route) { // ***** START: Repository ***** m.Group("/repo", func() { m.Get("/create", repo.Create) - m.Post("/create", bindIgnErr(forms.CreateRepoForm{}), repo.CreatePost) + m.Post("/create", web.Bind(forms.CreateRepoForm{}), repo.CreatePost) m.Get("/migrate", repo.Migrate) - m.Post("/migrate", bindIgnErr(forms.MigrateRepoForm{}), repo.MigratePost) + m.Post("/migrate", web.Bind(forms.MigrateRepoForm{}), repo.MigratePost) m.Group("/fork", func() { m.Combo("/{repoid}").Get(repo.Fork). - Post(bindIgnErr(forms.CreateRepoForm{}), repo.ForkPost) + Post(web.Bind(forms.CreateRepoForm{}), repo.ForkPost) }, context.RepoIDAssignment(), context.UnitTypes(), reqRepoCodeReader) m.Get("/search", repo.SearchRepo) }, reqSignIn) @@ -826,7 +824,7 @@ func RegisterRoutes(m *web.Route) { m.Get("/files/{fileid}", user.DownloadPackageFile) m.Group("/settings", func() { m.Get("", user.PackageSettings) - m.Post("", bindIgnErr(forms.PackageSettingForm{}), user.PackageSettingsPost) + m.Post("", web.Bind(forms.PackageSettingForm{}), user.PackageSettingsPost) }, reqPackageAccess(perm.AccessModeWrite)) }) }) @@ -842,9 +840,9 @@ func RegisterRoutes(m *web.Route) { m.Group("/settings", func() { m.Group("", func() { m.Combo("").Get(repo.Settings). - Post(bindIgnErr(forms.RepoSettingForm{}), repo.SettingsPost) + Post(web.Bind(forms.RepoSettingForm{}), repo.SettingsPost) }, repo.SettingsCtxData) - m.Post("/avatar", bindIgnErr(forms.AvatarForm{}), repo.SettingsAvatar) + m.Post("/avatar", web.Bind(forms.AvatarForm{}), repo.SettingsAvatar) m.Post("/avatar/delete", repo.SettingsDeleteAvatar) m.Group("/collaboration", func() { @@ -860,16 +858,16 @@ func RegisterRoutes(m *web.Route) { m.Group("/branches", func() { m.Combo("").Get(repo.ProtectedBranch).Post(repo.ProtectedBranchPost) m.Combo("/*").Get(repo.SettingsProtectedBranch). - Post(bindIgnErr(forms.ProtectBranchForm{}), context.RepoMustNotBeArchived(), repo.SettingsProtectedBranchPost) + Post(web.Bind(forms.ProtectBranchForm{}), context.RepoMustNotBeArchived(), repo.SettingsProtectedBranchPost) }, repo.MustBeNotEmpty) - m.Post("/rename_branch", bindIgnErr(forms.RenameBranchForm{}), context.RepoMustNotBeArchived(), repo.RenameBranchPost) + m.Post("/rename_branch", web.Bind(forms.RenameBranchForm{}), context.RepoMustNotBeArchived(), repo.RenameBranchPost) m.Group("/tags", func() { m.Get("", repo.Tags) - m.Post("", bindIgnErr(forms.ProtectTagForm{}), context.RepoMustNotBeArchived(), repo.NewProtectedTagPost) + m.Post("", web.Bind(forms.ProtectTagForm{}), context.RepoMustNotBeArchived(), repo.NewProtectedTagPost) m.Post("/delete", context.RepoMustNotBeArchived(), repo.DeleteProtectedTagPost) m.Get("/{id}", repo.EditProtectedTag) - m.Post("/{id}", bindIgnErr(forms.ProtectTagForm{}), context.RepoMustNotBeArchived(), repo.EditProtectedTagPost) + m.Post("/{id}", web.Bind(forms.ProtectTagForm{}), context.RepoMustNotBeArchived(), repo.EditProtectedTagPost) }) m.Group("/hooks/git", func() { @@ -882,38 +880,38 @@ func RegisterRoutes(m *web.Route) { m.Get("", repo.Webhooks) m.Post("/delete", repo.DeleteWebhook) m.Get("/{type}/new", repo.WebhooksNew) - m.Post("/gitea/new", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksNewPost) - m.Post("/gogs/new", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksNewPost) - m.Post("/slack/new", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksNewPost) - m.Post("/discord/new", bindIgnErr(forms.NewDiscordHookForm{}), repo.DiscordHooksNewPost) - m.Post("/dingtalk/new", bindIgnErr(forms.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) - m.Post("/telegram/new", bindIgnErr(forms.NewTelegramHookForm{}), repo.TelegramHooksNewPost) - m.Post("/matrix/new", bindIgnErr(forms.NewMatrixHookForm{}), repo.MatrixHooksNewPost) - m.Post("/msteams/new", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) - m.Post("/feishu/new", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksNewPost) - m.Post("/wechatwork/new", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksNewPost) - m.Post("/packagist/new", bindIgnErr(forms.NewPackagistHookForm{}), repo.PackagistHooksNewPost) + m.Post("/gitea/new", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksNewPost) + m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo.GogsHooksNewPost) + m.Post("/slack/new", web.Bind(forms.NewSlackHookForm{}), repo.SlackHooksNewPost) + m.Post("/discord/new", web.Bind(forms.NewDiscordHookForm{}), repo.DiscordHooksNewPost) + m.Post("/dingtalk/new", web.Bind(forms.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) + m.Post("/telegram/new", web.Bind(forms.NewTelegramHookForm{}), repo.TelegramHooksNewPost) + m.Post("/matrix/new", web.Bind(forms.NewMatrixHookForm{}), repo.MatrixHooksNewPost) + m.Post("/msteams/new", web.Bind(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) + m.Post("/feishu/new", web.Bind(forms.NewFeishuHookForm{}), repo.FeishuHooksNewPost) + m.Post("/wechatwork/new", web.Bind(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksNewPost) + m.Post("/packagist/new", web.Bind(forms.NewPackagistHookForm{}), repo.PackagistHooksNewPost) m.Group("/{id}", func() { m.Get("", repo.WebHooksEdit) m.Post("/test", repo.TestWebhook) m.Post("/replay/{uuid}", repo.ReplayWebhook) }) - m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) - m.Post("/gogs/{id}", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksEditPost) - m.Post("/slack/{id}", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) - m.Post("/discord/{id}", bindIgnErr(forms.NewDiscordHookForm{}), repo.DiscordHooksEditPost) - m.Post("/dingtalk/{id}", bindIgnErr(forms.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) - m.Post("/telegram/{id}", bindIgnErr(forms.NewTelegramHookForm{}), repo.TelegramHooksEditPost) - m.Post("/matrix/{id}", bindIgnErr(forms.NewMatrixHookForm{}), repo.MatrixHooksEditPost) - m.Post("/msteams/{id}", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) - m.Post("/feishu/{id}", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksEditPost) - m.Post("/wechatwork/{id}", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksEditPost) - m.Post("/packagist/{id}", bindIgnErr(forms.NewPackagistHookForm{}), repo.PackagistHooksEditPost) + m.Post("/gitea/{id}", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) + m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo.GogsHooksEditPost) + m.Post("/slack/{id}", web.Bind(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) + m.Post("/discord/{id}", web.Bind(forms.NewDiscordHookForm{}), repo.DiscordHooksEditPost) + m.Post("/dingtalk/{id}", web.Bind(forms.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) + m.Post("/telegram/{id}", web.Bind(forms.NewTelegramHookForm{}), repo.TelegramHooksEditPost) + m.Post("/matrix/{id}", web.Bind(forms.NewMatrixHookForm{}), repo.MatrixHooksEditPost) + m.Post("/msteams/{id}", web.Bind(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) + m.Post("/feishu/{id}", web.Bind(forms.NewFeishuHookForm{}), repo.FeishuHooksEditPost) + m.Post("/wechatwork/{id}", web.Bind(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksEditPost) + m.Post("/packagist/{id}", web.Bind(forms.NewPackagistHookForm{}), repo.PackagistHooksEditPost) }, webhooksEnabled) m.Group("/keys", func() { m.Combo("").Get(repo.DeployKeys). - Post(bindIgnErr(forms.AddKeyForm{}), repo.DeployKeysPost) + Post(web.Bind(forms.AddKeyForm{}), repo.DeployKeysPost) m.Post("/delete", repo.DeleteDeployKey) }) @@ -952,7 +950,7 @@ func RegisterRoutes(m *web.Route) { m.Get("/compare", repo.MustBeNotEmpty, reqRepoCodeReader, repo.SetEditorconfigIfExists, ignSignIn, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff) m.Combo("/compare/*", repo.MustBeNotEmpty, reqRepoCodeReader, repo.SetEditorconfigIfExists). Get(ignSignIn, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff). - Post(reqSignIn, context.RepoMustNotBeArchived(), reqRepoPullsReader, repo.MustAllowPulls, bindIgnErr(forms.CreateIssueForm{}), repo.SetWhitespaceBehavior, repo.CompareAndPullRequestPost) + Post(reqSignIn, context.RepoMustNotBeArchived(), reqRepoPullsReader, repo.MustAllowPulls, web.Bind(forms.CreateIssueForm{}), repo.SetWhitespaceBehavior, repo.CompareAndPullRequestPost) m.Group("/{type:issues|pulls}", func() { m.Group("/{index}", func() { m.Get("/info", repo.GetIssueInfo) @@ -965,7 +963,7 @@ func RegisterRoutes(m *web.Route) { m.Group("/issues", func() { m.Group("/new", func() { m.Combo("").Get(context.RepoRef(), repo.NewIssue). - Post(bindIgnErr(forms.CreateIssueForm{}), repo.NewIssuePost) + Post(web.Bind(forms.CreateIssueForm{}), repo.NewIssuePost) m.Get("/choose", context.RepoRef(), repo.NewIssueChooseTemplate) }) m.Get("/search", repo.ListIssues) @@ -976,7 +974,7 @@ func RegisterRoutes(m *web.Route) { m.Group("/{index}", func() { m.Post("/title", repo.UpdateIssueTitle) m.Post("/content", repo.UpdateIssueContent) - m.Post("/deadline", bindIgnErr(structs.EditDeadlineOption{}), repo.UpdateIssueDeadline) + m.Post("/deadline", web.Bind(structs.EditDeadlineOption{}), repo.UpdateIssueDeadline) m.Post("/watch", repo.IssueWatch) m.Post("/ref", repo.UpdateIssueRef) m.Post("/viewed-files", repo.UpdateViewedFiles) @@ -984,17 +982,17 @@ func RegisterRoutes(m *web.Route) { m.Post("/add", repo.AddDependency) m.Post("/delete", repo.RemoveDependency) }) - m.Combo("/comments").Post(repo.MustAllowUserComment, bindIgnErr(forms.CreateCommentForm{}), repo.NewComment) + m.Combo("/comments").Post(repo.MustAllowUserComment, web.Bind(forms.CreateCommentForm{}), repo.NewComment) m.Group("/times", func() { - m.Post("/add", bindIgnErr(forms.AddTimeManuallyForm{}), repo.AddTimeManually) + m.Post("/add", web.Bind(forms.AddTimeManuallyForm{}), repo.AddTimeManually) m.Post("/{timeid}/delete", repo.DeleteTime) m.Group("/stopwatch", func() { m.Post("/toggle", repo.IssueStopwatch) m.Post("/cancel", repo.CancelStopwatch) }) }) - m.Post("/reactions/{action}", bindIgnErr(forms.ReactionForm{}), repo.ChangeIssueReaction) - m.Post("/lock", reqRepoIssueWriter, bindIgnErr(forms.IssueLockForm{}), repo.LockIssue) + m.Post("/reactions/{action}", web.Bind(forms.ReactionForm{}), repo.ChangeIssueReaction) + m.Post("/lock", reqRepoIssueWriter, web.Bind(forms.IssueLockForm{}), repo.LockIssue) m.Post("/unlock", reqRepoIssueWriter, repo.UnlockIssue) m.Post("/delete", reqRepoAdmin, repo.DeleteIssue) }, context.RepoMustNotBeArchived()) @@ -1011,7 +1009,7 @@ func RegisterRoutes(m *web.Route) { m.Post("/projects", reqRepoIssuesOrPullsWriter, reqRepoProjectsReader, repo.UpdateIssueProject) m.Post("/assignee", reqRepoIssuesOrPullsWriter, repo.UpdateIssueAssignee) m.Post("/request_review", reqRepoIssuesOrPullsReader, repo.UpdatePullReviewRequest) - m.Post("/dismiss_review", reqRepoAdmin, bindIgnErr(forms.DismissReviewForm{}), repo.DismissReview) + m.Post("/dismiss_review", reqRepoAdmin, web.Bind(forms.DismissReviewForm{}), repo.DismissReview) m.Post("/status", reqRepoIssuesOrPullsWriter, repo.UpdateIssueStatus) m.Post("/resolve_conversation", reqRepoIssuesOrPullsReader, repo.UpdateResolveConversation) m.Post("/attachments", repo.UploadIssueAttachment) @@ -1020,23 +1018,23 @@ func RegisterRoutes(m *web.Route) { m.Group("/comments/{id}", func() { m.Post("", repo.UpdateCommentContent) m.Post("/delete", repo.DeleteComment) - m.Post("/reactions/{action}", bindIgnErr(forms.ReactionForm{}), repo.ChangeCommentReaction) + m.Post("/reactions/{action}", web.Bind(forms.ReactionForm{}), repo.ChangeCommentReaction) }, context.RepoMustNotBeArchived()) m.Group("/comments/{id}", func() { m.Get("/attachments", repo.GetCommentAttachments) }) - m.Post("/markdown", bindIgnErr(structs.MarkdownOption{}), misc.Markdown) + m.Post("/markdown", web.Bind(structs.MarkdownOption{}), misc.Markdown) m.Group("/labels", func() { - m.Post("/new", bindIgnErr(forms.CreateLabelForm{}), repo.NewLabel) - m.Post("/edit", bindIgnErr(forms.CreateLabelForm{}), repo.UpdateLabel) + m.Post("/new", web.Bind(forms.CreateLabelForm{}), repo.NewLabel) + m.Post("/edit", web.Bind(forms.CreateLabelForm{}), repo.UpdateLabel) m.Post("/delete", repo.DeleteLabel) - m.Post("/initialize", bindIgnErr(forms.InitializeLabelsForm{}), repo.InitializeLabels) + m.Post("/initialize", web.Bind(forms.InitializeLabelsForm{}), repo.InitializeLabels) }, context.RepoMustNotBeArchived(), reqRepoIssuesOrPullsWriter, context.RepoRef()) m.Group("/milestones", func() { m.Combo("/new").Get(repo.NewMilestone). - Post(bindIgnErr(forms.CreateMilestoneForm{}), repo.NewMilestonePost) + Post(web.Bind(forms.CreateMilestoneForm{}), repo.NewMilestonePost) m.Get("/{id}/edit", repo.EditMilestone) - m.Post("/{id}/edit", bindIgnErr(forms.CreateMilestoneForm{}), repo.EditMilestonePost) + m.Post("/{id}/edit", web.Bind(forms.CreateMilestoneForm{}), repo.EditMilestonePost) m.Post("/{id}/{action}", repo.ChangeMilestoneStatus) m.Post("/delete", repo.DeleteMilestone) }, context.RepoMustNotBeArchived(), reqRepoIssuesOrPullsWriter, context.RepoRef()) @@ -1047,23 +1045,23 @@ func RegisterRoutes(m *web.Route) { m.Group("", func() { m.Group("", func() { m.Combo("/_edit/*").Get(repo.EditFile). - Post(bindIgnErr(forms.EditRepoFileForm{}), repo.EditFilePost) + Post(web.Bind(forms.EditRepoFileForm{}), repo.EditFilePost) m.Combo("/_new/*").Get(repo.NewFile). - Post(bindIgnErr(forms.EditRepoFileForm{}), repo.NewFilePost) - m.Post("/_preview/*", bindIgnErr(forms.EditPreviewDiffForm{}), repo.DiffPreviewPost) + Post(web.Bind(forms.EditRepoFileForm{}), repo.NewFilePost) + m.Post("/_preview/*", web.Bind(forms.EditPreviewDiffForm{}), repo.DiffPreviewPost) m.Combo("/_delete/*").Get(repo.DeleteFile). - Post(bindIgnErr(forms.DeleteRepoFileForm{}), repo.DeleteFilePost) + Post(web.Bind(forms.DeleteRepoFileForm{}), repo.DeleteFilePost) m.Combo("/_upload/*", repo.MustBeAbleToUpload). Get(repo.UploadFile). - Post(bindIgnErr(forms.UploadRepoFileForm{}), repo.UploadFilePost) + Post(web.Bind(forms.UploadRepoFileForm{}), repo.UploadFilePost) m.Combo("/_diffpatch/*").Get(repo.NewDiffPatch). - Post(bindIgnErr(forms.EditRepoFileForm{}), repo.NewDiffPatchPost) + Post(web.Bind(forms.EditRepoFileForm{}), repo.NewDiffPatchPost) m.Combo("/_cherrypick/{sha:([a-f0-9]{7,40})}/*").Get(repo.CherryPick). - Post(bindIgnErr(forms.CherryPickForm{}), repo.CherryPickPost) + Post(web.Bind(forms.CherryPickForm{}), repo.CherryPickPost) }, repo.MustBeEditable) m.Group("", func() { m.Post("/upload-file", repo.UploadFileToServer) - m.Post("/upload-remove", bindIgnErr(forms.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer) + m.Post("/upload-remove", web.Bind(forms.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer) }, repo.MustBeEditable, repo.MustBeAbleToUpload) }, context.RepoRef(), canEnableEditor, context.RepoMustNotBeArchived(), repo.MustBeNotEmpty) @@ -1072,7 +1070,7 @@ func RegisterRoutes(m *web.Route) { m.Post("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.CreateBranch) m.Post("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.CreateBranch) m.Post("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.CreateBranch) - }, bindIgnErr(forms.NewBranchForm{})) + }, web.Bind(forms.NewBranchForm{})) m.Post("/delete", repo.DeleteBranchPost) m.Post("/restore", repo.RestoreBranchPost) }, context.RepoMustNotBeArchived(), reqRepoCodeWriter, repo.MustBeNotEmpty) @@ -1090,7 +1088,7 @@ func RegisterRoutes(m *web.Route) { m.Get("/releases/attachments/{uuid}", repo.GetAttachment, repo.MustBeNotEmpty, reqRepoReleaseReader) m.Group("/releases", func() { m.Get("/new", repo.NewRelease) - m.Post("/new", bindIgnErr(forms.NewReleaseForm{}), repo.NewReleasePost) + m.Post("/new", web.Bind(forms.NewReleaseForm{}), repo.NewReleasePost) m.Post("/delete", repo.DeleteRelease) m.Post("/attachments", repo.UploadReleaseAttachment) m.Post("/attachments/remove", repo.DeleteAttachment) @@ -1099,7 +1097,7 @@ func RegisterRoutes(m *web.Route) { repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoCodeWriter, context.RepoRef()) m.Group("/releases", func() { m.Get("/edit/*", repo.EditRelease) - m.Post("/edit/*", bindIgnErr(forms.EditReleaseForm{}), repo.EditReleasePost) + m.Post("/edit/*", web.Bind(forms.EditReleaseForm{}), repo.EditReleasePost) }, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, func(ctx *context.Context) { var err error ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) @@ -1148,17 +1146,17 @@ func RegisterRoutes(m *web.Route) { m.Get("/{id}", repo.ViewProject) m.Group("", func() { m.Get("/new", repo.NewProject) - m.Post("/new", bindIgnErr(forms.CreateProjectForm{}), repo.NewProjectPost) + m.Post("/new", web.Bind(forms.CreateProjectForm{}), repo.NewProjectPost) m.Group("/{id}", func() { - m.Post("", bindIgnErr(forms.EditProjectBoardForm{}), repo.AddBoardToProjectPost) + m.Post("", web.Bind(forms.EditProjectBoardForm{}), repo.AddBoardToProjectPost) m.Post("/delete", repo.DeleteProject) m.Get("/edit", repo.EditProject) - m.Post("/edit", bindIgnErr(forms.CreateProjectForm{}), repo.EditProjectPost) + m.Post("/edit", web.Bind(forms.CreateProjectForm{}), repo.EditProjectPost) m.Post("/{action:open|close}", repo.ChangeProjectStatus) m.Group("/{boardID}", func() { - m.Put("", bindIgnErr(forms.EditProjectBoardForm{}), repo.EditProjectBoard) + m.Put("", web.Bind(forms.EditProjectBoardForm{}), repo.EditProjectBoard) m.Delete("", repo.DeleteProjectBoard) m.Post("/default", repo.SetDefaultProjectBoard) @@ -1174,14 +1172,14 @@ func RegisterRoutes(m *web.Route) { Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, - bindIgnErr(forms.NewWikiForm{}), + web.Bind(forms.NewWikiForm{}), repo.WikiPost) m.Combo("/*"). Get(repo.Wiki). Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, - bindIgnErr(forms.NewWikiForm{}), + web.Bind(forms.NewWikiForm{}), repo.WikiPost) m.Get("/commit/{sha:[a-f0-9]{7,40}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff) m.Get("/commit/{sha:[a-f0-9]{7,40}}.{ext:patch|diff}", repo.RawDiff) @@ -1239,17 +1237,17 @@ func RegisterRoutes(m *web.Route) { m.Get(".diff", repo.DownloadPullDiff) m.Get(".patch", repo.DownloadPullPatch) m.Get("/commits", context.RepoRef(), repo.ViewPullCommits) - m.Post("/merge", context.RepoMustNotBeArchived(), bindIgnErr(forms.MergePullRequestForm{}), repo.MergePullRequest) + m.Post("/merge", context.RepoMustNotBeArchived(), web.Bind(forms.MergePullRequestForm{}), repo.MergePullRequest) m.Post("/cancel_auto_merge", context.RepoMustNotBeArchived(), repo.CancelAutoMergePullRequest) m.Post("/update", repo.UpdatePullRequest) - m.Post("/set_allow_maintainer_edit", bindIgnErr(forms.UpdateAllowEditsForm{}), repo.SetAllowEdits) + m.Post("/set_allow_maintainer_edit", web.Bind(forms.UpdateAllowEditsForm{}), repo.SetAllowEdits) m.Post("/cleanup", context.RepoMustNotBeArchived(), context.RepoRef(), repo.CleanUpPullRequest) m.Group("/files", func() { m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.ViewPullFiles) m.Group("/reviews", func() { m.Get("/new_comment", repo.RenderNewCodeCommentForm) - m.Post("/comments", bindIgnErr(forms.CodeCommentForm{}), repo.CreateCodeComment) - m.Post("/submit", bindIgnErr(forms.SubmitReviewForm{}), repo.SubmitReview) + m.Post("/comments", web.Bind(forms.CodeCommentForm{}), repo.CreateCodeComment) + m.Post("/submit", web.Bind(forms.SubmitReviewForm{}), repo.SubmitReview) }, context.RepoMustNotBeArchived()) }) }, repo.MustAllowPulls) From 36a2d2f919ee445f0374c210309b336e7c3c1f8e Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 12 Dec 2022 20:45:21 +0800 Subject: [PATCH 3/4] Add a simple test for external renderer (#20033) Fix #16402 --- models/db/iterate_test.go | 2 +- models/fixtures/repo_unit.yml | 6 +++ models/fixtures/repository.yml | 27 ++++++++++++ models/fixtures/user.yml | 2 +- models/repo/repo_list_test.go | 6 +-- routers/web/user/home_test.go | 2 +- .../user30/renderer.git/HEAD | 1 + .../user30/renderer.git/config | 6 +++ .../user30/renderer.git/description | 1 + .../user30/renderer.git/hooks/post-receive | 15 +++++++ .../renderer.git/hooks/post-receive.d/gitea | 2 + .../user30/renderer.git/hooks/pre-receive | 15 +++++++ .../renderer.git/hooks/pre-receive.d/gitea | 2 + .../user30/renderer.git/hooks/update | 14 ++++++ .../user30/renderer.git/hooks/update.d/gitea | 2 + .../user30/renderer.git/info/exclude | 6 +++ .../06/0d5c2acd8bf4b6f14010acd1a73d73392ec46e | Bin 0 -> 56 bytes .../45/14a93050edb2c3165bdd0a3c03be063e879e68 | Bin 0 -> 50 bytes .../c9/61cc4d1ba6b7ee1ba228a9a02b00b7746d8033 | Bin 0 -> 789 bytes .../user30/renderer.git/packed-refs | 2 + tests/integration/api_repo_test.go | 6 +-- tests/integration/markup_external_test.go | 40 ++++++++++++++++++ tests/sqlite.ini.tmpl | 7 +++ tools/external_renderer.go | 23 ++++++++++ 24 files changed, 178 insertions(+), 9 deletions(-) create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/HEAD create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/config create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/description create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/hooks/post-receive create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/hooks/post-receive.d/gitea create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/hooks/pre-receive create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/hooks/pre-receive.d/gitea create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/hooks/update create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/hooks/update.d/gitea create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/info/exclude create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/objects/06/0d5c2acd8bf4b6f14010acd1a73d73392ec46e create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/objects/45/14a93050edb2c3165bdd0a3c03be063e879e68 create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/objects/c9/61cc4d1ba6b7ee1ba228a9a02b00b7746d8033 create mode 100644 tests/gitea-repositories-meta/user30/renderer.git/packed-refs create mode 100644 tests/integration/markup_external_test.go create mode 100644 tools/external_renderer.go diff --git a/models/db/iterate_test.go b/models/db/iterate_test.go index b0ea8b53ef1e5..57b1bd3cd192f 100644 --- a/models/db/iterate_test.go +++ b/models/db/iterate_test.go @@ -25,7 +25,7 @@ func TestIterate(t *testing.T) { return nil }) assert.NoError(t, err) - assert.EqualValues(t, 79, repoCnt) + assert.EqualValues(t, 80, repoCnt) err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repoUnit *repo_model.RepoUnit) error { reopUnit2 := repo_model.RepoUnit{ID: repoUnit.ID} diff --git a/models/fixtures/repo_unit.yml b/models/fixtures/repo_unit.yml index 59ab61834070c..73db47218bca0 100644 --- a/models/fixtures/repo_unit.yml +++ b/models/fixtures/repo_unit.yml @@ -544,3 +544,9 @@ repo_id: 51 type: 2 created_unix: 946684810 + +- + id: 80 + repo_id: 53 + type: 1 + created_unix: 946684810 diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index f09953be7e5ad..a5a3dd0601fa4 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -1558,3 +1558,30 @@ size: 0 is_fsck_enabled: true close_issues_via_commit_in_any_branch: false + +- + id: 53 + owner_id: 30 + owner_name: user30 + lower_name: renderer + name: renderer + is_archived: false + is_empty: false + is_private: false + num_issues: 0 + num_closed_issues: 0 + num_pulls: 0 + num_closed_pulls: 0 + num_milestones: 0 + num_closed_milestones: 0 + num_watches: 0 + num_projects: 0 + num_closed_projects: 0 + status: 0 + is_fork: false + fork_id: 0 + is_template: false + template_id: 0 + size: 0 + is_fsck_enabled: true + close_issues_via_commit_in_any_branch: false diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index 0e3348e146a82..1b870e8999bcb 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -1102,7 +1102,7 @@ num_followers: 0 num_following: 0 num_stars: 0 - num_repos: 3 + num_repos: 4 num_teams: 0 num_members: 0 visibility: 0 diff --git a/models/repo/repo_list_test.go b/models/repo/repo_list_test.go index bfbceb7e2ec3a..d87d70c189a62 100644 --- a/models/repo/repo_list_test.go +++ b/models/repo/repo_list_test.go @@ -235,12 +235,12 @@ func TestSearchRepository(t *testing.T) { { name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborative", opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, AllPublic: true, Template: util.OptionalBoolFalse}, - count: 28, + count: 29, }, { name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative", opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, AllPublic: true, AllLimited: true, Template: util.OptionalBoolFalse}, - count: 33, + count: 34, }, { name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName", @@ -255,7 +255,7 @@ func TestSearchRepository(t *testing.T) { { name: "AllPublic/PublicRepositoriesOfOrganization", opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse, Template: util.OptionalBoolFalse}, - count: 28, + count: 29, }, { name: "AllTemplates", diff --git a/routers/web/user/home_test.go b/routers/web/user/home_test.go index a75b3573a00d0..534b0b26207b6 100644 --- a/routers/web/user/home_test.go +++ b/routers/web/user/home_test.go @@ -26,7 +26,7 @@ func TestArchivedIssues(t *testing.T) { // Assume: User 30 has access to two Repos with Issues, one of the Repos being archived. repos, _, _ := repo_model.GetUserRepositories(&repo_model.SearchRepoOptions{Actor: ctx.Doer}) - assert.Len(t, repos, 2) + assert.Len(t, repos, 3) IsArchived := make(map[int64]bool) NumIssues := make(map[int64]int) for _, repo := range repos { diff --git a/tests/gitea-repositories-meta/user30/renderer.git/HEAD b/tests/gitea-repositories-meta/user30/renderer.git/HEAD new file mode 100644 index 0000000000000..cb089cd89a7d7 --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/tests/gitea-repositories-meta/user30/renderer.git/config b/tests/gitea-repositories-meta/user30/renderer.git/config new file mode 100644 index 0000000000000..e6da231579bcc --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/config @@ -0,0 +1,6 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = true + ignorecase = true + precomposeunicode = true diff --git a/tests/gitea-repositories-meta/user30/renderer.git/description b/tests/gitea-repositories-meta/user30/renderer.git/description new file mode 100644 index 0000000000000..04c23973b8a8a --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/description @@ -0,0 +1 @@ +The repository will be used to test third-party renderer in TestExternalMarkupRenderer diff --git a/tests/gitea-repositories-meta/user30/renderer.git/hooks/post-receive b/tests/gitea-repositories-meta/user30/renderer.git/hooks/post-receive new file mode 100644 index 0000000000000..f1f2709dddeea --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/hooks/post-receive @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +data=$(cat) +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" && test -f "${hook}" || continue +echo "${data}" | "${hook}" +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/tests/gitea-repositories-meta/user30/renderer.git/hooks/post-receive.d/gitea b/tests/gitea-repositories-meta/user30/renderer.git/hooks/post-receive.d/gitea new file mode 100644 index 0000000000000..43a948da3a983 --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/hooks/post-receive.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" post-receive diff --git a/tests/gitea-repositories-meta/user30/renderer.git/hooks/pre-receive b/tests/gitea-repositories-meta/user30/renderer.git/hooks/pre-receive new file mode 100644 index 0000000000000..f1f2709dddeea --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/hooks/pre-receive @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +data=$(cat) +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" && test -f "${hook}" || continue +echo "${data}" | "${hook}" +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/tests/gitea-repositories-meta/user30/renderer.git/hooks/pre-receive.d/gitea b/tests/gitea-repositories-meta/user30/renderer.git/hooks/pre-receive.d/gitea new file mode 100644 index 0000000000000..49d09406364a5 --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/hooks/pre-receive.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" pre-receive diff --git a/tests/gitea-repositories-meta/user30/renderer.git/hooks/update b/tests/gitea-repositories-meta/user30/renderer.git/hooks/update new file mode 100644 index 0000000000000..df5bd27f106f2 --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/hooks/update @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +exitcodes="" +hookname=$(basename $0) +GIT_DIR=${GIT_DIR:-$(dirname $0)} + +for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do +test -x "${hook}" && test -f "${hook}" || continue +"${hook}" $1 $2 $3 +exitcodes="${exitcodes} $?" +done + +for i in ${exitcodes}; do +[ ${i} -eq 0 ] || exit ${i} +done diff --git a/tests/gitea-repositories-meta/user30/renderer.git/hooks/update.d/gitea b/tests/gitea-repositories-meta/user30/renderer.git/hooks/update.d/gitea new file mode 100644 index 0000000000000..38101c242664a --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/hooks/update.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" update $1 $2 $3 diff --git a/tests/gitea-repositories-meta/user30/renderer.git/info/exclude b/tests/gitea-repositories-meta/user30/renderer.git/info/exclude new file mode 100644 index 0000000000000..a5196d1be8fb5 --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/tests/gitea-repositories-meta/user30/renderer.git/objects/06/0d5c2acd8bf4b6f14010acd1a73d73392ec46e b/tests/gitea-repositories-meta/user30/renderer.git/objects/06/0d5c2acd8bf4b6f14010acd1a73d73392ec46e new file mode 100644 index 0000000000000000000000000000000000000000..994f25602cd6d8b6a48735b7520ee0dc1f6c307b GIT binary patch literal 56 zcmV-80LTA$0V^p=O;s?qWH2-^Ff%bx2y%6F@paY9D9O!Xa1~i;5b$=>VX^4DTsF-6 O*zDTpWdHz1$qy%Vr5Mrx literal 0 HcmV?d00001 diff --git a/tests/gitea-repositories-meta/user30/renderer.git/objects/45/14a93050edb2c3165bdd0a3c03be063e879e68 b/tests/gitea-repositories-meta/user30/renderer.git/objects/45/14a93050edb2c3165bdd0a3c03be063e879e68 new file mode 100644 index 0000000000000000000000000000000000000000..b1fff27753835c235faa542aeeb6708413501109 GIT binary patch literal 50 zcmV-20L}k+0ZYosPf{>8XRt}hEVJX{EJ-acQAn*QNiE7t%uy&x%}YrwN-g5D(FaQd I08PXWv=3tx761SM literal 0 HcmV?d00001 diff --git a/tests/gitea-repositories-meta/user30/renderer.git/objects/c9/61cc4d1ba6b7ee1ba228a9a02b00b7746d8033 b/tests/gitea-repositories-meta/user30/renderer.git/objects/c9/61cc4d1ba6b7ee1ba228a9a02b00b7746d8033 new file mode 100644 index 0000000000000000000000000000000000000000..66488767ae90c8665d6a1ce53faa21a44d6421d9 GIT binary patch literal 789 zcmV+w1M2*E0iBdd6RJiOg|p^Y^qxwXS{keJQelum6a#up&z~m`^d0ZaKV(IR{ye{jOY!1cC%%%V!vh8I{gc z*^l5bcijiXRoa8!-(PL!?v-_a7HwKJzu~_9190MIBXTS+ZUD_nEK7aqH*?DV*Ksiv z&#C~w{x!-Ts!9jzD2 z_XdAlFzj`?wdZzI%W6@3|8fdoI3llLm>|NZy5Am&(qDU$+gDRbcjWL2FDGcxmT+Lr zW;S5sCFrAKt4n$QxJjW*0m%`^hlS>2K(Cj%*3coTqgpC;yKOu?8Cplmgo~cYEp2GD zuM*i^8yyrc(N?QA1PT!QgADnzEbIR35UGbkbKP~h3GKo{?VV(sa{G9g$DU11*+p+# z{gBNn`rKML*`(1FxW~`okU%0jrS=UPd{0~-G96qUuaEroxD~j(+(I*Ev}adVzA7kA z`AVei*)@oao)l=vLsxG7vcIzD=Um@k(mNRIv@iStKN%*v#gpt}Ee-qEr8b%EWVLP5 zjZEe^?ly)e3K)w!Kk4E^xOZAus#65kvHCPurWKy8bBcV+@V!t+L^?I7=aQ?DPsYrv zo4wT_hTJGHiSSKN`T^3K_xPB^Cw9-4ZY00RNGgq&=476$3=d(jd&xoERPSZxTA`D3 z7}9k`0l}`<4h@)92n^ZK;{E&FSm|ZqCkDF0(t2Cc##>WKJUT6Bt449p#K(hKS`U&) zm;x7=VO7;-P3v@ZRIyvZd$Old<{bUp4Xf7Vve367%MKO3Xj))P%^5CF`3iOJy<92K z(aS-&B;3l`F~gZ2$I{P@NX|UcFY7QjAsXwfd>n>oqV*$vRz&Nu&wU#DcF`O64+Y{S znUiaT3=-DiZ48*)JR=*;3ER|a;Jf$^swEt=h TRdwGtFpT{@!xQxrb9G4{#m9=~ literal 0 HcmV?d00001 diff --git a/tests/gitea-repositories-meta/user30/renderer.git/packed-refs b/tests/gitea-repositories-meta/user30/renderer.git/packed-refs new file mode 100644 index 0000000000000..63f8af0f129eb --- /dev/null +++ b/tests/gitea-repositories-meta/user30/renderer.git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +c961cc4d1ba6b7ee1ba228a9a02b00b7746d8033 refs/heads/master diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go index c84416104ca84..76850fb82746f 100644 --- a/tests/integration/api_repo_test.go +++ b/tests/integration/api_repo_test.go @@ -81,9 +81,9 @@ func TestAPISearchRepo(t *testing.T) { }{ { name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50&private=false", expectedResults: expectedResults{ - nil: {count: 30}, - user: {count: 30}, - user2: {count: 30}, + nil: {count: 31}, + user: {count: 31}, + user2: {count: 31}, }, }, { diff --git a/tests/integration/markup_external_test.go b/tests/integration/markup_external_test.go new file mode 100644 index 0000000000000..6ea0226ec6203 --- /dev/null +++ b/tests/integration/markup_external_test.go @@ -0,0 +1,40 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package integration + +import ( + "bytes" + "io" + "net/http" + "strings" + "testing" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestExternalMarkupRenderer(t *testing.T) { + defer tests.PrepareTestEnv(t)() + if !setting.Database.UseSQLite3 { + t.Skip() + return + } + + const repoURL = "user30/renderer" + req := NewRequest(t, "GET", repoURL+"/src/branch/master/README.html") + resp := MakeRequest(t, req, http.StatusOK) + assert.EqualValues(t, "text/html; charset=UTF-8", resp.Header()["Content-Type"][0]) + + bs, err := io.ReadAll(resp.Body) + assert.NoError(t, err) + + doc := NewHTMLParser(t, bytes.NewBuffer(bs)) + div := doc.Find("div.file-view") + data, err := div.Html() + assert.NoError(t, err) + assert.EqualValues(t, "
\n\ttest external renderer\n
", strings.TrimSpace(data)) +} diff --git a/tests/sqlite.ini.tmpl b/tests/sqlite.ini.tmpl index f5e8895e063a4..f6f8c70ed9908 100644 --- a/tests/sqlite.ini.tmpl +++ b/tests/sqlite.ini.tmpl @@ -107,3 +107,10 @@ PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/data/lfs [packages] ENABLED = true + +[markup.html] +ENABLED = true +FILE_EXTENSIONS = .html +RENDER_COMMAND = `go run tools/external_renderer.go` +IS_INPUT_FILE = false +RENDER_CONTENT_MODE=sanitized diff --git a/tools/external_renderer.go b/tools/external_renderer.go new file mode 100644 index 0000000000000..c1fcc78f50b9e --- /dev/null +++ b/tools/external_renderer.go @@ -0,0 +1,23 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +// gobuild: external_renderer + +package main + +import ( + "fmt" + "io" + "os" +) + +func main() { + if len(os.Args) > 1 { + fmt.Print(os.Args[1]) + } else { + _, err := io.Copy(os.Stdout, os.Stdin) + if err != nil { + fmt.Println(err) + } + } +} From 87c64f655a6085f23499156504e039c13da77b21 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 12 Dec 2022 23:02:51 +0800 Subject: [PATCH 4/4] Fix permission check on issue/pull lock (#22110) Fix #21826 --- routers/web/web.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/routers/web/web.go b/routers/web/web.go index 99c2a83917047..f9d97758a1bde 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -655,7 +655,6 @@ func RegisterRoutes(m *web.Route) { reqRepoReleaseWriter := context.RequireRepoWriter(unit.TypeReleases) reqRepoReleaseReader := context.RequireRepoReader(unit.TypeReleases) reqRepoWikiWriter := context.RequireRepoWriter(unit.TypeWiki) - reqRepoIssueWriter := context.RequireRepoWriter(unit.TypeIssues) reqRepoIssueReader := context.RequireRepoReader(unit.TypeIssues) reqRepoPullsReader := context.RequireRepoReader(unit.TypePullRequests) reqRepoIssuesOrPullsWriter := context.RequireRepoWriterOr(unit.TypeIssues, unit.TypePullRequests) @@ -992,8 +991,8 @@ func RegisterRoutes(m *web.Route) { }) }) m.Post("/reactions/{action}", web.Bind(forms.ReactionForm{}), repo.ChangeIssueReaction) - m.Post("/lock", reqRepoIssueWriter, web.Bind(forms.IssueLockForm{}), repo.LockIssue) - m.Post("/unlock", reqRepoIssueWriter, repo.UnlockIssue) + m.Post("/lock", reqRepoIssuesOrPullsWriter, web.Bind(forms.IssueLockForm{}), repo.LockIssue) + m.Post("/unlock", reqRepoIssuesOrPullsWriter, repo.UnlockIssue) m.Post("/delete", reqRepoAdmin, repo.DeleteIssue) }, context.RepoMustNotBeArchived()) m.Group("/{index}", func() {