mirror of
https://github.com/gogs/gogs.git
synced 2026-01-31 03:29:21 +01:00
Standardize HTTP status codes (#7851)
Co-authored-by: Joe Chen <jc@unknwon.io>
This commit is contained in:
@@ -147,13 +147,13 @@ func (c *Context) RedirectSubpath(location string, status ...int) {
|
||||
}
|
||||
|
||||
// RenderWithErr used for page has form validation but need to prompt error to users.
|
||||
func (c *Context) RenderWithErr(msg, tpl string, f any) {
|
||||
func (c *Context) RenderWithErr(msg string, status int, tpl string, f any) {
|
||||
if f != nil {
|
||||
form.Assign(f, c.Data)
|
||||
}
|
||||
c.Flash.ErrorMsg = msg
|
||||
c.Data["Flash"] = c.Flash
|
||||
c.HTML(http.StatusOK, tpl)
|
||||
c.HTML(status, tpl)
|
||||
}
|
||||
|
||||
// NotFound renders the 404 page.
|
||||
|
||||
@@ -151,7 +151,7 @@ func NewAuthSourcePost(c *context.Context, f form.Authentication) {
|
||||
c.Data["HasTLS"] = hasTLS
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplAdminAuthNew)
|
||||
c.HTML(http.StatusBadRequest, tmplAdminAuthNew)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ func NewAuthSourcePost(c *context.Context, f form.Authentication) {
|
||||
if err != nil {
|
||||
if database.IsErrLoginSourceAlreadyExist(err) {
|
||||
c.FormErr("Name")
|
||||
c.RenderWithErr(c.Tr("admin.auths.login_source_exist", f.Name), tmplAdminAuthNew, f)
|
||||
c.RenderWithErr(c.Tr("admin.auths.login_source_exist", f.Name), http.StatusUnprocessableEntity, tmplAdminAuthNew, f)
|
||||
} else {
|
||||
c.Error(err, "create login source")
|
||||
}
|
||||
@@ -223,7 +223,7 @@ func EditAuthSourcePost(c *context.Context, f form.Authentication) {
|
||||
c.Data["HasTLS"] = source.Provider.HasTLS()
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplAdminAuthEdit)
|
||||
c.HTML(http.StatusBadRequest, tmplAdminAuthEdit)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -68,7 +69,7 @@ func NewUserPost(c *context.Context, f form.AdminCrateUser) {
|
||||
c.Data["CanSendEmail"] = conf.Email.Enabled
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplAdminUserNew)
|
||||
c.HTML(http.StatusBadRequest, tmplAdminUserNew)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -89,13 +90,13 @@ func NewUserPost(c *context.Context, f form.AdminCrateUser) {
|
||||
switch {
|
||||
case database.IsErrUserAlreadyExist(err):
|
||||
c.Data["Err_UserName"] = true
|
||||
c.RenderWithErr(c.Tr("form.username_been_taken"), tmplAdminUserNew, &f)
|
||||
c.RenderWithErr(c.Tr("form.username_been_taken"), http.StatusUnprocessableEntity, tmplAdminUserNew, &f)
|
||||
case database.IsErrEmailAlreadyUsed(err):
|
||||
c.Data["Err_Email"] = true
|
||||
c.RenderWithErr(c.Tr("form.email_been_used"), tmplAdminUserNew, &f)
|
||||
c.RenderWithErr(c.Tr("form.email_been_used"), http.StatusUnprocessableEntity, tmplAdminUserNew, &f)
|
||||
case database.IsErrNameNotAllowed(err):
|
||||
c.Data["Err_UserName"] = true
|
||||
c.RenderWithErr(c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), tmplAdminUserNew, &f)
|
||||
c.RenderWithErr(c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tmplAdminUserNew, &f)
|
||||
default:
|
||||
c.Error(err, "create user")
|
||||
}
|
||||
@@ -166,7 +167,7 @@ func EditUserPost(c *context.Context, f form.AdminEditUser) {
|
||||
}
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplAdminUserEdit)
|
||||
c.HTML(http.StatusBadRequest, tmplAdminUserEdit)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -203,7 +204,7 @@ func EditUserPost(c *context.Context, f form.AdminEditUser) {
|
||||
if err != nil {
|
||||
if database.IsErrEmailAlreadyUsed(err) {
|
||||
c.Data["Err_Email"] = true
|
||||
c.RenderWithErr(c.Tr("form.email_been_used"), tmplAdminUserEdit, &f)
|
||||
c.RenderWithErr(c.Tr("form.email_been_used"), http.StatusUnprocessableEntity, tmplAdminUserEdit, &f)
|
||||
} else {
|
||||
c.Error(err, "update user")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/mail"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -194,13 +195,12 @@ func InstallPost(c *context.Context, f form.Install) {
|
||||
c.HasValue("Err_AdminEmail") {
|
||||
c.FormErr("Admin")
|
||||
}
|
||||
|
||||
c.Success(INSTALL)
|
||||
c.HTML(http.StatusBadRequest, INSTALL)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := exec.LookPath("git"); err != nil {
|
||||
c.RenderWithErr(c.Tr("install.test_git_failed", err), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.test_git_failed", err), http.StatusInternalServerError, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ func InstallPost(c *context.Context, f form.Install) {
|
||||
|
||||
if conf.Database.Type == "sqlite3" && conf.Database.Path == "" {
|
||||
c.FormErr("DbPath")
|
||||
c.RenderWithErr(c.Tr("install.err_empty_db_path"), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.err_empty_db_path"), http.StatusBadRequest, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -230,10 +230,10 @@ func InstallPost(c *context.Context, f form.Install) {
|
||||
if err := database.NewTestEngine(); err != nil {
|
||||
if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
|
||||
c.FormErr("DbType")
|
||||
c.RenderWithErr(c.Tr("install.sqlite3_not_available", "https://gogs.io/docs/installation/install_from_binary.html"), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.sqlite3_not_available", "https://gogs.io/docs/installation/install_from_binary.html"), http.StatusInternalServerError, INSTALL, &f)
|
||||
} else {
|
||||
c.FormErr("DbSetting")
|
||||
c.RenderWithErr(c.Tr("install.invalid_db_setting", err), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.invalid_db_setting", err), http.StatusBadRequest, INSTALL, &f)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -242,7 +242,7 @@ func InstallPost(c *context.Context, f form.Install) {
|
||||
f.RepoRootPath = strings.ReplaceAll(f.RepoRootPath, "\\", "/")
|
||||
if err := os.MkdirAll(f.RepoRootPath, os.ModePerm); err != nil {
|
||||
c.FormErr("RepoRootPath")
|
||||
c.RenderWithErr(c.Tr("install.invalid_repo_path", err), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.invalid_repo_path", err), http.StatusBadRequest, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -250,21 +250,21 @@ func InstallPost(c *context.Context, f form.Install) {
|
||||
f.LogRootPath = strings.ReplaceAll(f.LogRootPath, "\\", "/")
|
||||
if err := os.MkdirAll(f.LogRootPath, os.ModePerm); err != nil {
|
||||
c.FormErr("LogRootPath")
|
||||
c.RenderWithErr(c.Tr("install.invalid_log_root_path", err), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.invalid_log_root_path", err), http.StatusBadRequest, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
|
||||
currentUser, match := conf.CheckRunUser(f.RunUser)
|
||||
if !match {
|
||||
c.FormErr("RunUser")
|
||||
c.RenderWithErr(c.Tr("install.run_user_not_match", f.RunUser, currentUser), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.run_user_not_match", f.RunUser, currentUser), http.StatusForbidden, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
|
||||
// Check host address and port
|
||||
if len(f.SMTPHost) > 0 && !strings.Contains(f.SMTPHost, ":") {
|
||||
c.FormErr("SMTP", "SMTPHost")
|
||||
c.RenderWithErr(c.Tr("install.smtp_host_missing_port"), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.smtp_host_missing_port"), http.StatusBadRequest, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ func InstallPost(c *context.Context, f form.Install) {
|
||||
_, err := mail.ParseAddress(f.SMTPFrom)
|
||||
if err != nil {
|
||||
c.FormErr("SMTP", "SMTPFrom")
|
||||
c.RenderWithErr(c.Tr("install.invalid_smtp_from", err), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.invalid_smtp_from", err), http.StatusBadRequest, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -281,19 +281,19 @@ func InstallPost(c *context.Context, f form.Install) {
|
||||
// Check logic loophole between disable self-registration and no admin account.
|
||||
if f.DisableRegistration && f.AdminName == "" {
|
||||
c.FormErr("Services", "Admin")
|
||||
c.RenderWithErr(c.Tr("install.no_admin_and_disable_registration"), INSTALL, f)
|
||||
c.RenderWithErr(c.Tr("install.no_admin_and_disable_registration"), http.StatusUnprocessableEntity, INSTALL, f)
|
||||
return
|
||||
}
|
||||
|
||||
// Check admin password.
|
||||
if len(f.AdminName) > 0 && f.AdminPasswd == "" {
|
||||
c.FormErr("Admin", "AdminPasswd")
|
||||
c.RenderWithErr(c.Tr("install.err_empty_admin_password"), INSTALL, f)
|
||||
c.RenderWithErr(c.Tr("install.err_empty_admin_password"), http.StatusBadRequest, INSTALL, f)
|
||||
return
|
||||
}
|
||||
if f.AdminPasswd != f.AdminConfirmPasswd {
|
||||
c.FormErr("Admin", "AdminPasswd")
|
||||
c.RenderWithErr(c.Tr("form.password_not_match"), INSTALL, f)
|
||||
c.RenderWithErr(c.Tr("form.password_not_match"), http.StatusBadRequest, INSTALL, f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -367,21 +367,21 @@ func InstallPost(c *context.Context, f form.Install) {
|
||||
cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
|
||||
secretKey, err := strutil.RandomChars(15)
|
||||
if err != nil {
|
||||
c.RenderWithErr(c.Tr("install.secret_key_failed", err), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.secret_key_failed", err), http.StatusInternalServerError, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
cfg.Section("security").Key("SECRET_KEY").SetValue(secretKey)
|
||||
|
||||
_ = os.MkdirAll(filepath.Dir(conf.CustomConf), os.ModePerm)
|
||||
if err := cfg.SaveTo(conf.CustomConf); err != nil {
|
||||
c.RenderWithErr(c.Tr("install.save_config_failed", err), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.save_config_failed", err), http.StatusInternalServerError, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
|
||||
// NOTE: We reuse the current value because this handler does not have access to CLI flags.
|
||||
err = GlobalInit(conf.CustomConf)
|
||||
if err != nil {
|
||||
c.RenderWithErr(c.Tr("install.init_failed", err), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.init_failed", err), http.StatusInternalServerError, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -401,7 +401,7 @@ func InstallPost(c *context.Context, f form.Install) {
|
||||
if !database.IsErrUserAlreadyExist(err) {
|
||||
conf.Security.InstallLock = false
|
||||
c.FormErr("AdminName", "AdminEmail")
|
||||
c.RenderWithErr(c.Tr("install.invalid_admin_setting", err), INSTALL, &f)
|
||||
c.RenderWithErr(c.Tr("install.invalid_admin_setting", err), http.StatusBadRequest, INSTALL, &f)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
"gogs.io/gogs/internal/context"
|
||||
@@ -21,7 +23,7 @@ func CreatePost(c *context.Context, f form.CreateOrg) {
|
||||
c.Title("new_org")
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(CREATE)
|
||||
c.HTML(http.StatusBadRequest, CREATE)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -35,9 +37,9 @@ func CreatePost(c *context.Context, f form.CreateOrg) {
|
||||
c.Data["Err_OrgName"] = true
|
||||
switch {
|
||||
case database.IsErrUserAlreadyExist(err):
|
||||
c.RenderWithErr(c.Tr("form.org_name_been_taken"), CREATE, &f)
|
||||
c.RenderWithErr(c.Tr("form.org_name_been_taken"), http.StatusUnprocessableEntity, CREATE, &f)
|
||||
case database.IsErrNameNotAllowed(err):
|
||||
c.RenderWithErr(c.Tr("org.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), CREATE, &f)
|
||||
c.RenderWithErr(c.Tr("org.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, CREATE, &f)
|
||||
default:
|
||||
c.Error(err, "create organization")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
"gogs.io/gogs/internal/auth"
|
||||
@@ -27,7 +29,7 @@ func SettingsPost(c *context.Context, f form.UpdateOrgSetting) {
|
||||
c.Data["PageIsSettingsOptions"] = true
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplOrgSettingsOptions)
|
||||
c.HTML(http.StatusBadRequest, tmplOrgSettingsOptions)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -38,18 +40,14 @@ func SettingsPost(c *context.Context, f form.UpdateOrgSetting) {
|
||||
err := database.Handle.Users().ChangeUsername(c.Req.Context(), c.Org.Organization.ID, f.Name)
|
||||
if err != nil {
|
||||
c.Data["OrgName"] = true
|
||||
var msg string
|
||||
switch {
|
||||
case database.IsErrUserAlreadyExist(err):
|
||||
msg = c.Tr("form.username_been_taken")
|
||||
c.RenderWithErr(c.Tr("form.username_been_taken"), http.StatusUnprocessableEntity, tmplOrgSettingsOptions, &f)
|
||||
case database.IsErrNameNotAllowed(err):
|
||||
msg = c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value())
|
||||
c.RenderWithErr(c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tmplOrgSettingsOptions, &f)
|
||||
default:
|
||||
c.Error(err, "change organization name")
|
||||
return
|
||||
}
|
||||
|
||||
c.RenderWithErr(msg, tmplOrgSettingsOptions, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -104,7 +102,7 @@ func SettingsDelete(c *context.Context) {
|
||||
if c.Req.Method == "POST" {
|
||||
if _, err := database.Handle.Users().Authenticate(c.Req.Context(), c.User.Name, c.Query("password"), c.User.LoginSource); err != nil {
|
||||
if auth.IsErrBadCredentials(err) {
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_password"), tmplOrgSettingsDelete, nil)
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_password"), http.StatusUnauthorized, tmplOrgSettingsDelete, nil)
|
||||
} else {
|
||||
c.Error(err, "authenticate user")
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ func NewTeamPost(c *context.Context, f form.CreateTeam) {
|
||||
c.Data["Team"] = t
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplOrgTeamNew)
|
||||
c.HTML(http.StatusBadRequest, tmplOrgTeamNew)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -167,9 +167,9 @@ func NewTeamPost(c *context.Context, f form.CreateTeam) {
|
||||
c.Data["Err_TeamName"] = true
|
||||
switch {
|
||||
case database.IsErrTeamAlreadyExist(err):
|
||||
c.RenderWithErr(c.Tr("form.team_name_been_taken"), tmplOrgTeamNew, &f)
|
||||
c.RenderWithErr(c.Tr("form.team_name_been_taken"), http.StatusUnprocessableEntity, tmplOrgTeamNew, &f)
|
||||
case database.IsErrNameNotAllowed(err):
|
||||
c.RenderWithErr(c.Tr("org.form.team_name_not_allowed", err.(database.ErrNameNotAllowed).Value()), tmplOrgTeamNew, &f)
|
||||
c.RenderWithErr(c.Tr("org.form.team_name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tmplOrgTeamNew, &f)
|
||||
default:
|
||||
c.Error(err, "new team")
|
||||
}
|
||||
@@ -214,7 +214,7 @@ func EditTeamPost(c *context.Context, f form.CreateTeam) {
|
||||
c.Data["Team"] = t
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplOrgTeamNew)
|
||||
c.HTML(http.StatusBadRequest, tmplOrgTeamNew)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ func EditTeamPost(c *context.Context, f form.CreateTeam) {
|
||||
c.Data["Err_TeamName"] = true
|
||||
switch {
|
||||
case database.IsErrTeamAlreadyExist(err):
|
||||
c.RenderWithErr(c.Tr("form.team_name_been_taken"), tmplOrgTeamNew, &f)
|
||||
c.RenderWithErr(c.Tr("form.team_name_been_taken"), http.StatusUnprocessableEntity, tmplOrgTeamNew, &f)
|
||||
default:
|
||||
c.Error(err, "update team")
|
||||
}
|
||||
|
||||
@@ -153,20 +153,20 @@ func editFilePost(c *context.Context, f form.EditRepoFile, isNewFile bool) {
|
||||
c.Data["PreviewableFileModes"] = strings.Join(conf.Repository.Editor.PreviewableFileModes, ",")
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplEditorEdit)
|
||||
c.HTML(http.StatusBadRequest, tmplEditorEdit)
|
||||
return
|
||||
}
|
||||
|
||||
if f.TreePath == "" {
|
||||
c.FormErr("TreePath")
|
||||
c.RenderWithErr(c.Tr("repo.editor.filename_cannot_be_empty"), tmplEditorEdit, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.filename_cannot_be_empty"), http.StatusBadRequest, tmplEditorEdit, &f)
|
||||
return
|
||||
}
|
||||
|
||||
if oldBranchName != branchName {
|
||||
if _, err := c.Repo.Repository.GetBranch(branchName); err == nil {
|
||||
c.FormErr("NewBranchName")
|
||||
c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), tmplEditorEdit, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), http.StatusUnprocessableEntity, tmplEditorEdit, &f)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -187,18 +187,18 @@ func editFilePost(c *context.Context, f form.EditRepoFile, isNewFile bool) {
|
||||
if index != len(treeNames)-1 {
|
||||
if !entry.IsTree() {
|
||||
c.FormErr("TreePath")
|
||||
c.RenderWithErr(c.Tr("repo.editor.directory_is_a_file", part), tmplEditorEdit, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.directory_is_a_file", part), http.StatusUnprocessableEntity, tmplEditorEdit, &f)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// 🚨 SECURITY: Do not allow editing if the target file is a symlink.
|
||||
if entry.IsSymlink() {
|
||||
c.FormErr("TreePath")
|
||||
c.RenderWithErr(c.Tr("repo.editor.file_is_a_symlink", part), tmplEditorEdit, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.file_is_a_symlink", part), http.StatusUnprocessableEntity, tmplEditorEdit, &f)
|
||||
return
|
||||
} else if entry.IsTree() {
|
||||
c.FormErr("TreePath")
|
||||
c.RenderWithErr(c.Tr("repo.editor.filename_is_a_directory", part), tmplEditorEdit, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.filename_is_a_directory", part), http.StatusUnprocessableEntity, tmplEditorEdit, &f)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -209,7 +209,7 @@ func editFilePost(c *context.Context, f form.EditRepoFile, isNewFile bool) {
|
||||
if err != nil {
|
||||
if gitutil.IsErrRevisionNotExist(err) {
|
||||
c.FormErr("TreePath")
|
||||
c.RenderWithErr(c.Tr("repo.editor.file_editing_no_longer_exists", oldTreePath), tmplEditorEdit, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.file_editing_no_longer_exists", oldTreePath), http.StatusNotFound, tmplEditorEdit, &f)
|
||||
} else {
|
||||
c.Error(err, "get tree entry")
|
||||
}
|
||||
@@ -219,7 +219,7 @@ func editFilePost(c *context.Context, f form.EditRepoFile, isNewFile bool) {
|
||||
// 🚨 SECURITY: Do not allow editing if the old file is a symlink.
|
||||
if entry.IsSymlink() {
|
||||
c.FormErr("TreePath")
|
||||
c.RenderWithErr(c.Tr("repo.editor.file_is_a_symlink", oldTreePath), tmplEditorEdit, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.file_is_a_symlink", oldTreePath), http.StatusUnprocessableEntity, tmplEditorEdit, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ func editFilePost(c *context.Context, f form.EditRepoFile, isNewFile bool) {
|
||||
|
||||
for _, file := range files {
|
||||
if file == f.TreePath {
|
||||
c.RenderWithErr(c.Tr("repo.editor.file_changed_while_editing", c.Repo.RepoLink+"/compare/"+lastCommit+"..."+c.Repo.CommitID), tmplEditorEdit, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.file_changed_while_editing", c.Repo.RepoLink+"/compare/"+lastCommit+"..."+c.Repo.CommitID), http.StatusConflict, tmplEditorEdit, &f)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -250,7 +250,7 @@ func editFilePost(c *context.Context, f form.EditRepoFile, isNewFile bool) {
|
||||
}
|
||||
if entry != nil {
|
||||
c.FormErr("TreePath")
|
||||
c.RenderWithErr(c.Tr("repo.editor.file_already_exists", f.TreePath), tmplEditorEdit, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.file_already_exists", f.TreePath), http.StatusUnprocessableEntity, tmplEditorEdit, &f)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -280,7 +280,7 @@ func editFilePost(c *context.Context, f form.EditRepoFile, isNewFile bool) {
|
||||
}); err != nil {
|
||||
log.Error("Failed to update repo file: %v", err)
|
||||
c.FormErr("TreePath")
|
||||
c.RenderWithErr(c.Tr("repo.editor.fail_to_update_file", f.TreePath, errInternalServerError), tmplEditorEdit, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.fail_to_update_file", f.TreePath, errInternalServerError), http.StatusInternalServerError, tmplEditorEdit, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -358,14 +358,14 @@ func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
|
||||
c.Data["new_branch_name"] = branchName
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplEditorDelete)
|
||||
c.HTML(http.StatusBadRequest, tmplEditorDelete)
|
||||
return
|
||||
}
|
||||
|
||||
if oldBranchName != branchName {
|
||||
if _, err := c.Repo.Repository.GetBranch(branchName); err == nil {
|
||||
c.FormErr("NewBranchName")
|
||||
c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), tmplEditorDelete, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), http.StatusUnprocessableEntity, tmplEditorDelete, &f)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -388,7 +388,7 @@ func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
|
||||
Message: message,
|
||||
}); err != nil {
|
||||
log.Error("Failed to delete repo file: %v", err)
|
||||
c.RenderWithErr(c.Tr("repo.editor.fail_to_delete_file", c.Repo.TreePath, errInternalServerError), tmplEditorDelete, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.fail_to_delete_file", c.Repo.TreePath, errInternalServerError), http.StatusInternalServerError, tmplEditorDelete, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -456,14 +456,14 @@ func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
|
||||
c.Data["new_branch_name"] = branchName
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplEditorUpload)
|
||||
c.HTML(http.StatusBadRequest, tmplEditorUpload)
|
||||
return
|
||||
}
|
||||
|
||||
if oldBranchName != branchName {
|
||||
if _, err := c.Repo.Repository.GetBranch(branchName); err == nil {
|
||||
c.FormErr("NewBranchName")
|
||||
c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), tmplEditorUpload, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), http.StatusUnprocessableEntity, tmplEditorUpload, &f)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -485,7 +485,7 @@ func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
|
||||
// User can only upload files to a directory.
|
||||
if !entry.IsTree() {
|
||||
c.FormErr("TreePath")
|
||||
c.RenderWithErr(c.Tr("repo.editor.directory_is_a_file", part), tmplEditorUpload, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.directory_is_a_file", part), http.StatusUnprocessableEntity, tmplEditorUpload, &f)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -510,7 +510,7 @@ func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
|
||||
}); err != nil {
|
||||
log.Error("Failed to upload files: %v", err)
|
||||
c.FormErr("TreePath")
|
||||
c.RenderWithErr(c.Tr("repo.editor.unable_to_upload_files", f.TreePath, errInternalServerError), tmplEditorUpload, &f)
|
||||
c.RenderWithErr(c.Tr("repo.editor.unable_to_upload_files", f.TreePath, errInternalServerError), http.StatusInternalServerError, tmplEditorUpload, &f)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ func NewIssuePost(c *context.Context, f form.NewIssue) {
|
||||
}
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplRepoIssueNew)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoIssueNew)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1148,7 +1148,7 @@ func NewMilestonePost(c *context.Context, f form.CreateMilestone) {
|
||||
c.Data["DateLang"] = conf.I18n.DateLang(c.Language())
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplRepoIssueMilestoneNew)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoIssueMilestoneNew)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1158,7 +1158,7 @@ func NewMilestonePost(c *context.Context, f form.CreateMilestone) {
|
||||
deadline, err := time.ParseInLocation("2006-01-02", f.Deadline, time.Local)
|
||||
if err != nil {
|
||||
c.Data["Err_Deadline"] = true
|
||||
c.RenderWithErr(c.Tr("repo.milestones.invalid_due_date_format"), tmplRepoIssueMilestoneNew, &f)
|
||||
c.RenderWithErr(c.Tr("repo.milestones.invalid_due_date_format"), http.StatusBadRequest, tmplRepoIssueMilestoneNew, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1204,7 +1204,7 @@ func EditMilestonePost(c *context.Context, f form.CreateMilestone) {
|
||||
c.Data["DateLang"] = conf.I18n.DateLang(c.Language())
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplRepoIssueMilestoneNew)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoIssueMilestoneNew)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1214,7 +1214,7 @@ func EditMilestonePost(c *context.Context, f form.CreateMilestone) {
|
||||
deadline, err := time.ParseInLocation("2006-01-02", f.Deadline, time.Local)
|
||||
if err != nil {
|
||||
c.Data["Err_Deadline"] = true
|
||||
c.RenderWithErr(c.Tr("repo.milestones.invalid_due_date_format"), tmplRepoIssueMilestoneNew, &f)
|
||||
c.RenderWithErr(c.Tr("repo.milestones.invalid_due_date_format"), http.StatusBadRequest, tmplRepoIssueMilestoneNew, &f)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ func ForkPost(c *context.Context, f form.CreateRepo) {
|
||||
c.Data["ContextUser"] = ctxUser
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplRepoPullsFork)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoPullsFork)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ func ForkPost(c *context.Context, f form.CreateRepo) {
|
||||
|
||||
// Cannot fork to same owner
|
||||
if ctxUser.ID == baseRepo.OwnerID {
|
||||
c.RenderWithErr(c.Tr("repo.settings.cannot_fork_to_same_owner"), tmplRepoPullsFork, &f)
|
||||
c.RenderWithErr(c.Tr("repo.settings.cannot_fork_to_same_owner"), http.StatusUnprocessableEntity, tmplRepoPullsFork, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -138,11 +138,11 @@ func ForkPost(c *context.Context, f form.CreateRepo) {
|
||||
c.Data["Err_RepoName"] = true
|
||||
switch {
|
||||
case database.IsErrReachLimitOfRepo(err):
|
||||
c.RenderWithErr(c.Tr("repo.form.reach_limit_of_creation", err.(database.ErrReachLimitOfRepo).Limit), tmplRepoPullsFork, &f)
|
||||
c.RenderWithErr(c.Tr("repo.form.reach_limit_of_creation", err.(database.ErrReachLimitOfRepo).Limit), http.StatusForbidden, tmplRepoPullsFork, &f)
|
||||
case database.IsErrRepoAlreadyExist(err):
|
||||
c.RenderWithErr(c.Tr("repo.settings.new_owner_has_same_repo"), tmplRepoPullsFork, &f)
|
||||
c.RenderWithErr(c.Tr("repo.settings.new_owner_has_same_repo"), http.StatusUnprocessableEntity, tmplRepoPullsFork, &f)
|
||||
case database.IsErrNameNotAllowed(err):
|
||||
c.RenderWithErr(c.Tr("repo.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), tmplRepoPullsFork, &f)
|
||||
c.RenderWithErr(c.Tr("repo.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tmplRepoPullsFork, &f)
|
||||
default:
|
||||
c.Error(err, "fork repository")
|
||||
}
|
||||
@@ -709,7 +709,7 @@ func CompareAndPullRequestPost(c *context.Context, f form.NewIssue) {
|
||||
return
|
||||
}
|
||||
|
||||
c.Success(tmplRepoPullsCompare)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoPullsCompare)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
@@ -169,12 +170,12 @@ func NewReleasePost(c *context.Context, f form.NewRelease) {
|
||||
renderReleaseAttachmentSettings(c)
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplRepoReleaseNew)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoReleaseNew)
|
||||
return
|
||||
}
|
||||
|
||||
if !c.Repo.GitRepo.HasBranch(f.Target) {
|
||||
c.RenderWithErr(c.Tr("form.target_branch_not_exist"), tmplRepoReleaseNew, &f)
|
||||
c.RenderWithErr(c.Tr("form.target_branch_not_exist"), http.StatusUnprocessableEntity, tmplRepoReleaseNew, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -222,9 +223,9 @@ func NewReleasePost(c *context.Context, f form.NewRelease) {
|
||||
c.Data["Err_TagName"] = true
|
||||
switch {
|
||||
case database.IsErrReleaseAlreadyExist(err):
|
||||
c.RenderWithErr(c.Tr("repo.release.tag_name_already_exist"), tmplRepoReleaseNew, &f)
|
||||
c.RenderWithErr(c.Tr("repo.release.tag_name_already_exist"), http.StatusUnprocessableEntity, tmplRepoReleaseNew, &f)
|
||||
case database.IsErrInvalidTagName(err):
|
||||
c.RenderWithErr(c.Tr("repo.release.tag_name_invalid"), tmplRepoReleaseNew, &f)
|
||||
c.RenderWithErr(c.Tr("repo.release.tag_name_invalid"), http.StatusBadRequest, tmplRepoReleaseNew, &f)
|
||||
default:
|
||||
c.Error(err, "new release")
|
||||
}
|
||||
@@ -280,7 +281,7 @@ func EditReleasePost(c *context.Context, f form.EditRelease) {
|
||||
c.Data["IsDraft"] = rel.IsDraft
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplRepoReleaseNew)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoReleaseNew)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -86,13 +86,13 @@ func Create(c *context.Context) {
|
||||
func handleCreateError(c *context.Context, err error, name, tpl string, form any) {
|
||||
switch {
|
||||
case database.IsErrReachLimitOfRepo(err):
|
||||
c.RenderWithErr(c.Tr("repo.form.reach_limit_of_creation", err.(database.ErrReachLimitOfRepo).Limit), tpl, form)
|
||||
c.RenderWithErr(c.Tr("repo.form.reach_limit_of_creation", err.(database.ErrReachLimitOfRepo).Limit), http.StatusForbidden, tpl, form)
|
||||
case database.IsErrRepoAlreadyExist(err):
|
||||
c.Data["Err_RepoName"] = true
|
||||
c.RenderWithErr(c.Tr("form.repo_name_been_taken"), tpl, form)
|
||||
c.RenderWithErr(c.Tr("form.repo_name_been_taken"), http.StatusUnprocessableEntity, tpl, form)
|
||||
case database.IsErrNameNotAllowed(err):
|
||||
c.Data["Err_RepoName"] = true
|
||||
c.RenderWithErr(c.Tr("repo.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), tpl, form)
|
||||
c.RenderWithErr(c.Tr("repo.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tpl, form)
|
||||
default:
|
||||
c.Error(err, name)
|
||||
}
|
||||
@@ -112,7 +112,7 @@ func CreatePost(c *context.Context, f form.CreateRepo) {
|
||||
c.Data["ContextUser"] = ctxUser
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(CREATE)
|
||||
c.HTML(http.StatusBadRequest, CREATE)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ func MigratePost(c *context.Context, f form.MigrateRepo) {
|
||||
c.Data["ContextUser"] = ctxUser
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(MIGRATE)
|
||||
c.HTML(http.StatusBadRequest, MIGRATE)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -177,13 +177,13 @@ func MigratePost(c *context.Context, f form.MigrateRepo) {
|
||||
addrErr := err.(database.ErrInvalidCloneAddr)
|
||||
switch {
|
||||
case addrErr.IsURLError:
|
||||
c.RenderWithErr(c.Tr("repo.migrate.clone_address")+c.Tr("form.url_error"), MIGRATE, &f)
|
||||
c.RenderWithErr(c.Tr("repo.migrate.clone_address")+c.Tr("form.url_error"), http.StatusBadRequest, MIGRATE, &f)
|
||||
case addrErr.IsPermissionDenied:
|
||||
c.RenderWithErr(c.Tr("repo.migrate.permission_denied"), MIGRATE, &f)
|
||||
c.RenderWithErr(c.Tr("repo.migrate.permission_denied"), http.StatusForbidden, MIGRATE, &f)
|
||||
case addrErr.IsInvalidPath:
|
||||
c.RenderWithErr(c.Tr("repo.migrate.invalid_local_path"), MIGRATE, &f)
|
||||
c.RenderWithErr(c.Tr("repo.migrate.invalid_local_path"), http.StatusBadRequest, MIGRATE, &f)
|
||||
case addrErr.IsBlockedLocalAddress:
|
||||
c.RenderWithErr(c.Tr("repo.migrate.clone_address_resolved_to_blocked_local_address"), MIGRATE, &f)
|
||||
c.RenderWithErr(c.Tr("repo.migrate.clone_address_resolved_to_blocked_local_address"), http.StatusForbidden, MIGRATE, &f)
|
||||
default:
|
||||
c.Error(err, "unexpected error")
|
||||
}
|
||||
@@ -216,11 +216,11 @@ func MigratePost(c *context.Context, f form.MigrateRepo) {
|
||||
if strings.Contains(err.Error(), "Authentication failed") ||
|
||||
strings.Contains(err.Error(), "could not read Username") {
|
||||
c.Data["Err_Auth"] = true
|
||||
c.RenderWithErr(c.Tr("form.auth_failed", database.HandleMirrorCredentials(err.Error(), true)), MIGRATE, &f)
|
||||
c.RenderWithErr(c.Tr("form.auth_failed", database.HandleMirrorCredentials(err.Error(), true)), http.StatusUnauthorized, MIGRATE, &f)
|
||||
return
|
||||
} else if strings.Contains(err.Error(), "fatal:") {
|
||||
c.Data["Err_CloneAddr"] = true
|
||||
c.RenderWithErr(c.Tr("repo.migrate.failed", database.HandleMirrorCredentials(err.Error(), true)), MIGRATE, &f)
|
||||
c.RenderWithErr(c.Tr("repo.migrate.failed", database.HandleMirrorCredentials(err.Error(), true)), http.StatusInternalServerError, MIGRATE, &f)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package repo
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -49,7 +50,7 @@ func SettingsPost(c *context.Context, f form.RepoSetting) {
|
||||
switch c.Query("action") {
|
||||
case "update":
|
||||
if c.HasError() {
|
||||
c.Success(tmplRepoSettingsOptions)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoSettingsOptions)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -63,9 +64,9 @@ func SettingsPost(c *context.Context, f form.RepoSetting) {
|
||||
c.FormErr("RepoName")
|
||||
switch {
|
||||
case database.IsErrRepoAlreadyExist(err):
|
||||
c.RenderWithErr(c.Tr("form.repo_name_been_taken"), tmplRepoSettingsOptions, &f)
|
||||
c.RenderWithErr(c.Tr("form.repo_name_been_taken"), http.StatusUnprocessableEntity, tmplRepoSettingsOptions, &f)
|
||||
case database.IsErrNameNotAllowed(err):
|
||||
c.RenderWithErr(c.Tr("repo.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), tmplRepoSettingsOptions, &f)
|
||||
c.RenderWithErr(c.Tr("repo.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tmplRepoSettingsOptions, &f)
|
||||
default:
|
||||
c.Error(err, "change repository name")
|
||||
}
|
||||
@@ -175,7 +176,7 @@ func SettingsPost(c *context.Context, f form.RepoSetting) {
|
||||
return
|
||||
}
|
||||
if repo.Name != f.RepoName {
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), tmplRepoSettingsOptions, nil)
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), http.StatusBadRequest, tmplRepoSettingsOptions, nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -209,7 +210,7 @@ func SettingsPost(c *context.Context, f form.RepoSetting) {
|
||||
return
|
||||
}
|
||||
if repo.Name != f.RepoName {
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), tmplRepoSettingsOptions, nil)
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), http.StatusBadRequest, tmplRepoSettingsOptions, nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -222,13 +223,13 @@ func SettingsPost(c *context.Context, f form.RepoSetting) {
|
||||
|
||||
newOwner := c.Query("new_owner_name")
|
||||
if !database.Handle.Users().IsUsernameUsed(c.Req.Context(), newOwner, c.Repo.Owner.ID) {
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_owner_name"), tmplRepoSettingsOptions, nil)
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_owner_name"), http.StatusBadRequest, tmplRepoSettingsOptions, nil)
|
||||
return
|
||||
}
|
||||
|
||||
if err := database.TransferOwnership(c.User, newOwner, repo); err != nil {
|
||||
if database.IsErrRepoAlreadyExist(err) {
|
||||
c.RenderWithErr(c.Tr("repo.settings.new_owner_has_same_repo"), tmplRepoSettingsOptions, nil)
|
||||
c.RenderWithErr(c.Tr("repo.settings.new_owner_has_same_repo"), http.StatusUnprocessableEntity, tmplRepoSettingsOptions, nil)
|
||||
} else {
|
||||
c.Error(err, "transfer ownership")
|
||||
}
|
||||
@@ -244,7 +245,7 @@ func SettingsPost(c *context.Context, f form.RepoSetting) {
|
||||
return
|
||||
}
|
||||
if repo.Name != f.RepoName {
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), tmplRepoSettingsOptions, nil)
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), http.StatusBadRequest, tmplRepoSettingsOptions, nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -270,7 +271,7 @@ func SettingsPost(c *context.Context, f form.RepoSetting) {
|
||||
return
|
||||
}
|
||||
if repo.Name != f.RepoName {
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), tmplRepoSettingsOptions, nil)
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), http.StatusBadRequest, tmplRepoSettingsOptions, nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -436,7 +437,7 @@ func SettingsBranches(c *context.Context) {
|
||||
|
||||
if c.Repo.Repository.IsBare {
|
||||
c.Flash.Info(c.Tr("repo.settings.branches_bare"), true)
|
||||
c.Success(tmplRepoSettingsBranches)
|
||||
c.HTML(http.StatusUnprocessableEntity, tmplRepoSettingsBranches)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -652,7 +653,7 @@ func SettingsDeployKeysPost(c *context.Context, f form.AddSSHKey) {
|
||||
c.Data["Deploykeys"] = keys
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplRepoSettingsDeployKeys)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoSettingsDeployKeys)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -675,10 +676,10 @@ func SettingsDeployKeysPost(c *context.Context, f form.AddSSHKey) {
|
||||
switch {
|
||||
case database.IsErrKeyAlreadyExist(err):
|
||||
c.Data["Err_Content"] = true
|
||||
c.RenderWithErr(c.Tr("repo.settings.key_been_used"), tmplRepoSettingsDeployKeys, &f)
|
||||
c.RenderWithErr(c.Tr("repo.settings.key_been_used"), http.StatusUnprocessableEntity, tmplRepoSettingsDeployKeys, &f)
|
||||
case database.IsErrKeyNameAlreadyUsed(err):
|
||||
c.Data["Err_Title"] = true
|
||||
c.RenderWithErr(c.Tr("repo.settings.key_name_used"), tmplRepoSettingsDeployKeys, &f)
|
||||
c.RenderWithErr(c.Tr("repo.settings.key_name_used"), http.StatusUnprocessableEntity, tmplRepoSettingsDeployKeys, &f)
|
||||
default:
|
||||
c.Error(err, "add deploy key")
|
||||
}
|
||||
|
||||
@@ -116,32 +116,32 @@ func WebhooksNew(c *context.Context, orCtx *orgRepoContext) {
|
||||
c.Success(orCtx.TmplNew)
|
||||
}
|
||||
|
||||
func validateWebhook(l macaron.Locale, w *database.Webhook) (field, msg string, ok bool) {
|
||||
func validateWebhook(l macaron.Locale, w *database.Webhook) (field, msg string, status int) {
|
||||
// 🚨 SECURITY: Local addresses must not be allowed by non-admins to prevent SSRF,
|
||||
// see https://github.com/gogs/gogs/issues/5366 for details.
|
||||
payloadURL, err := url.Parse(w.URL)
|
||||
if err != nil {
|
||||
return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_parse_payload_url", err), false
|
||||
return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_parse_payload_url", err), http.StatusBadRequest
|
||||
}
|
||||
|
||||
if netutil.IsBlockedLocalHostname(payloadURL.Hostname(), conf.Security.LocalNetworkAllowlist) {
|
||||
return "PayloadURL", l.Tr("repo.settings.webhook.url_resolved_to_blocked_local_address"), false
|
||||
return "PayloadURL", l.Tr("repo.settings.webhook.url_resolved_to_blocked_local_address"), http.StatusForbidden
|
||||
}
|
||||
return "", "", true
|
||||
return "", "", http.StatusOK
|
||||
}
|
||||
|
||||
func validateAndCreateWebhook(c *context.Context, orCtx *orgRepoContext, w *database.Webhook) {
|
||||
c.Data["Webhook"] = w
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(orCtx.TmplNew)
|
||||
c.HTML(http.StatusBadRequest, orCtx.TmplNew)
|
||||
return
|
||||
}
|
||||
|
||||
field, msg, ok := validateWebhook(c.Locale, w)
|
||||
if !ok {
|
||||
field, msg, status := validateWebhook(c.Locale, w)
|
||||
if status != http.StatusOK {
|
||||
c.FormErr(field)
|
||||
c.RenderWithErr(msg, orCtx.TmplNew, nil)
|
||||
c.RenderWithErr(msg, status, orCtx.TmplNew, nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -338,14 +338,14 @@ func validateAndUpdateWebhook(c *context.Context, orCtx *orgRepoContext, w *data
|
||||
c.Data["Webhook"] = w
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(orCtx.TmplNew)
|
||||
c.HTML(http.StatusBadRequest, orCtx.TmplNew)
|
||||
return
|
||||
}
|
||||
|
||||
field, msg, ok := validateWebhook(c.Locale, w)
|
||||
if !ok {
|
||||
field, msg, status := validateWebhook(c.Locale, w)
|
||||
if status != http.StatusOK {
|
||||
c.FormErr(field)
|
||||
c.RenderWithErr(msg, orCtx.TmplNew, nil)
|
||||
c.RenderWithErr(msg, status, orCtx.TmplNew, nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -9,7 +10,7 @@ import (
|
||||
"gogs.io/gogs/internal/mocks"
|
||||
)
|
||||
|
||||
func Test_validateWebhook(t *testing.T) {
|
||||
func TestValidateWebhook(t *testing.T) {
|
||||
l := &mocks.Locale{
|
||||
MockLang: "en",
|
||||
MockTr: func(s string, _ ...any) string {
|
||||
@@ -18,33 +19,33 @@ func Test_validateWebhook(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
actor *database.User
|
||||
webhook *database.Webhook
|
||||
expField string
|
||||
expMsg string
|
||||
expOK bool
|
||||
name string
|
||||
actor *database.User
|
||||
webhook *database.Webhook
|
||||
wantField string
|
||||
wantMsg string
|
||||
wantStatus int
|
||||
}{
|
||||
{
|
||||
name: "admin bypass local address check",
|
||||
webhook: &database.Webhook{URL: "https://www.google.com"},
|
||||
expOK: true,
|
||||
name: "admin bypass local address check",
|
||||
webhook: &database.Webhook{URL: "https://www.google.com"},
|
||||
wantStatus: http.StatusOK,
|
||||
},
|
||||
|
||||
{
|
||||
name: "local address not allowed",
|
||||
webhook: &database.Webhook{URL: "http://localhost:3306"},
|
||||
expField: "PayloadURL",
|
||||
expMsg: "repo.settings.webhook.url_resolved_to_blocked_local_address",
|
||||
expOK: false,
|
||||
name: "local address not allowed",
|
||||
webhook: &database.Webhook{URL: "http://localhost:3306"},
|
||||
wantField: "PayloadURL",
|
||||
wantMsg: "repo.settings.webhook.url_resolved_to_blocked_local_address",
|
||||
wantStatus: http.StatusForbidden,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
field, msg, ok := validateWebhook(l, test.webhook)
|
||||
assert.Equal(t, test.expOK, ok)
|
||||
assert.Equal(t, test.expMsg, msg)
|
||||
assert.Equal(t, test.expField, field)
|
||||
field, msg, status := validateWebhook(l, test.webhook)
|
||||
assert.Equal(t, test.wantStatus, status)
|
||||
assert.Equal(t, test.wantMsg, msg)
|
||||
assert.Equal(t, test.wantField, field)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -199,14 +200,14 @@ func NewWikiPost(c *context.Context, f form.NewWiki) {
|
||||
c.Data["RequireSimpleMDE"] = true
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplRepoWikiNew)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoWikiNew)
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.Repo.Repository.AddWikiPage(c.User, f.Title, f.Content, f.Message); err != nil {
|
||||
if database.IsErrWikiAlreadyExist(err) {
|
||||
c.Data["Err_Title"] = true
|
||||
c.RenderWithErr(c.Tr("repo.wiki.page_already_exists"), tmplRepoWikiNew, &f)
|
||||
c.RenderWithErr(c.Tr("repo.wiki.page_already_exists"), http.StatusUnprocessableEntity, tmplRepoWikiNew, &f)
|
||||
} else {
|
||||
c.Error(err, "add wiki page")
|
||||
}
|
||||
@@ -240,7 +241,7 @@ func EditWikiPost(c *context.Context, f form.NewWiki) {
|
||||
c.Data["RequireSimpleMDE"] = true
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplRepoWikiNew)
|
||||
c.HTML(http.StatusBadRequest, tmplRepoWikiNew)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ func LoginPost(c *context.Context, f form.SignIn) {
|
||||
c.Data["LoginSources"] = loginSources
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplUserAuthLogin)
|
||||
c.HTML(http.StatusBadRequest, tmplUserAuthLogin)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -167,10 +167,10 @@ func LoginPost(c *context.Context, f form.SignIn) {
|
||||
switch {
|
||||
case auth.IsErrBadCredentials(err):
|
||||
c.FormErr("UserName", "Password")
|
||||
c.RenderWithErr(c.Tr("form.username_password_incorrect"), tmplUserAuthLogin, &f)
|
||||
c.RenderWithErr(c.Tr("form.username_password_incorrect"), http.StatusUnauthorized, tmplUserAuthLogin, &f)
|
||||
case database.IsErrLoginSourceMismatch(err):
|
||||
c.FormErr("LoginSource")
|
||||
c.RenderWithErr(c.Tr("form.auth_source_mismatch"), tmplUserAuthLogin, &f)
|
||||
c.RenderWithErr(c.Tr("form.auth_source_mismatch"), http.StatusUnprocessableEntity, tmplUserAuthLogin, &f)
|
||||
|
||||
default:
|
||||
c.Error(err, "authenticate user")
|
||||
@@ -320,19 +320,19 @@ func SignUpPost(c *context.Context, cpt *captcha.Captcha, f form.Register) {
|
||||
}
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplUserAuthSignup)
|
||||
c.HTML(http.StatusBadRequest, tmplUserAuthSignup)
|
||||
return
|
||||
}
|
||||
|
||||
if conf.Auth.EnableRegistrationCaptcha && !cpt.VerifyReq(c.Req) {
|
||||
c.FormErr("Captcha")
|
||||
c.RenderWithErr(c.Tr("form.captcha_incorrect"), tmplUserAuthSignup, &f)
|
||||
c.RenderWithErr(c.Tr("form.captcha_incorrect"), http.StatusUnauthorized, tmplUserAuthSignup, &f)
|
||||
return
|
||||
}
|
||||
|
||||
if f.Password != f.Retype {
|
||||
c.FormErr("Password")
|
||||
c.RenderWithErr(c.Tr("form.password_not_match"), tmplUserAuthSignup, &f)
|
||||
c.RenderWithErr(c.Tr("form.password_not_match"), http.StatusBadRequest, tmplUserAuthSignup, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -349,13 +349,13 @@ func SignUpPost(c *context.Context, cpt *captcha.Captcha, f form.Register) {
|
||||
switch {
|
||||
case database.IsErrUserAlreadyExist(err):
|
||||
c.FormErr("UserName")
|
||||
c.RenderWithErr(c.Tr("form.username_been_taken"), tmplUserAuthSignup, &f)
|
||||
c.RenderWithErr(c.Tr("form.username_been_taken"), http.StatusUnprocessableEntity, tmplUserAuthSignup, &f)
|
||||
case database.IsErrEmailAlreadyUsed(err):
|
||||
c.FormErr("Email")
|
||||
c.RenderWithErr(c.Tr("form.email_been_used"), tmplUserAuthSignup, &f)
|
||||
c.RenderWithErr(c.Tr("form.email_been_used"), http.StatusUnprocessableEntity, tmplUserAuthSignup, &f)
|
||||
case database.IsErrNameNotAllowed(err):
|
||||
c.FormErr("UserName")
|
||||
c.RenderWithErr(c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), tmplUserAuthSignup, &f)
|
||||
c.RenderWithErr(c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tmplUserAuthSignup, &f)
|
||||
default:
|
||||
c.Error(err, "create user")
|
||||
}
|
||||
@@ -569,7 +569,7 @@ func ForgotPasswdPost(c *context.Context) {
|
||||
|
||||
if !u.IsLocal() {
|
||||
c.FormErr("Email")
|
||||
c.RenderWithErr(c.Tr("auth.non_local_account"), tmplUserAuthForgotPassword, nil)
|
||||
c.RenderWithErr(c.Tr("auth.non_local_account"), http.StatusForbidden, tmplUserAuthForgotPassword, nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -618,7 +618,7 @@ func ResetPasswdPost(c *context.Context) {
|
||||
if len(password) < 6 {
|
||||
c.Data["IsResetForm"] = true
|
||||
c.Data["Err_Password"] = true
|
||||
c.RenderWithErr(c.Tr("auth.password_too_short"), tmplUserAuthResetPassword, nil)
|
||||
c.RenderWithErr(c.Tr("auth.password_too_short"), http.StatusBadRequest, tmplUserAuthResetPassword, nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"html/template"
|
||||
"image/png"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/pquerna/otp"
|
||||
@@ -72,7 +73,7 @@ func SettingsPost(c *context.Context, f form.UpdateProfile) {
|
||||
c.Data["origin_name"] = c.User.Name
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplUserSettingsProfile)
|
||||
c.HTML(http.StatusBadRequest, tmplUserSettingsProfile)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -83,18 +84,14 @@ func SettingsPost(c *context.Context, f form.UpdateProfile) {
|
||||
err := database.Handle.Users().ChangeUsername(c.Req.Context(), c.User.ID, f.Name)
|
||||
if err != nil {
|
||||
c.FormErr("Name")
|
||||
var msg string
|
||||
switch {
|
||||
case database.IsErrUserAlreadyExist(errors.Cause(err)):
|
||||
msg = c.Tr("form.username_been_taken")
|
||||
c.RenderWithErr(c.Tr("form.username_been_taken"), http.StatusUnprocessableEntity, tmplUserSettingsProfile, &f)
|
||||
case database.IsErrNameNotAllowed(errors.Cause(err)):
|
||||
msg = c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value())
|
||||
c.RenderWithErr(c.Tr("user.form.name_not_allowed", err.(database.ErrNameNotAllowed).Value()), http.StatusBadRequest, tmplUserSettingsProfile, &f)
|
||||
default:
|
||||
c.Error(err, "change user name")
|
||||
return
|
||||
}
|
||||
|
||||
c.RenderWithErr(msg, tmplUserSettingsProfile, &f)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -203,7 +200,7 @@ func SettingsPasswordPost(c *context.Context, f form.ChangePassword) {
|
||||
c.PageIs("SettingsPassword")
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplUserSettingsPassword)
|
||||
c.HTML(http.StatusBadRequest, tmplUserSettingsPassword)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -267,14 +264,14 @@ func SettingsEmailPost(c *context.Context, f form.AddEmail) {
|
||||
c.Data["Emails"] = emails
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplUserSettingsEmail)
|
||||
c.HTML(http.StatusBadRequest, tmplUserSettingsEmail)
|
||||
return
|
||||
}
|
||||
|
||||
err = database.Handle.Users().AddEmail(c.Req.Context(), c.User.ID, f.Email, !conf.Auth.RequireEmailConfirmation)
|
||||
if err != nil {
|
||||
if database.IsErrEmailAlreadyUsed(err) {
|
||||
c.RenderWithErr(c.Tr("form.email_been_used"), tmplUserSettingsEmail, &f)
|
||||
c.RenderWithErr(c.Tr("form.email_been_used"), http.StatusUnprocessableEntity, tmplUserSettingsEmail, &f)
|
||||
} else {
|
||||
c.Errorf(err, "add email address")
|
||||
}
|
||||
@@ -344,7 +341,7 @@ func SettingsSSHKeysPost(c *context.Context, f form.AddSSHKey) {
|
||||
c.Data["Keys"] = keys
|
||||
|
||||
if c.HasError() {
|
||||
c.Success(tmplUserSettingsSSHKeys)
|
||||
c.HTML(http.StatusBadRequest, tmplUserSettingsSSHKeys)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -364,10 +361,10 @@ func SettingsSSHKeysPost(c *context.Context, f form.AddSSHKey) {
|
||||
switch {
|
||||
case database.IsErrKeyAlreadyExist(err):
|
||||
c.FormErr("Content")
|
||||
c.RenderWithErr(c.Tr("settings.ssh_key_been_used"), tmplUserSettingsSSHKeys, &f)
|
||||
c.RenderWithErr(c.Tr("settings.ssh_key_been_used"), http.StatusUnprocessableEntity, tmplUserSettingsSSHKeys, &f)
|
||||
case database.IsErrKeyNameAlreadyUsed(err):
|
||||
c.FormErr("Title")
|
||||
c.RenderWithErr(c.Tr("settings.ssh_key_name_used"), tmplUserSettingsSSHKeys, &f)
|
||||
c.RenderWithErr(c.Tr("settings.ssh_key_name_used"), http.StatusUnprocessableEntity, tmplUserSettingsSSHKeys, &f)
|
||||
default:
|
||||
c.Errorf(err, "add public key")
|
||||
}
|
||||
@@ -619,7 +616,7 @@ func (h *SettingsHandler) ApplicationsPost() macaron.Handler {
|
||||
}
|
||||
|
||||
c.Data["Tokens"] = tokens
|
||||
c.Success(tmplUserSettingsApplications)
|
||||
c.HTML(http.StatusBadRequest, tmplUserSettingsApplications)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -661,7 +658,7 @@ func SettingsDelete(c *context.Context) {
|
||||
if c.Req.Method == "POST" {
|
||||
if _, err := database.Handle.Users().Authenticate(c.Req.Context(), c.User.Name, c.Query("password"), c.User.LoginSource); err != nil {
|
||||
if auth.IsErrBadCredentials(err) {
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_password"), tmplUserSettingsDelete, nil)
|
||||
c.RenderWithErr(c.Tr("form.enterred_invalid_password"), http.StatusUnauthorized, tmplUserSettingsDelete, nil)
|
||||
} else {
|
||||
c.Errorf(err, "authenticate user")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user