diff --git a/modules/setting/restricted_user.go b/modules/setting/restricted_user.go new file mode 100644 index 0000000000000..6ef42460fed72 --- /dev/null +++ b/modules/setting/restricted_user.go @@ -0,0 +1,14 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package setting + +var RestrictedUser = struct { + AllowEditDueDate bool +}{} + +func loadRestrictedUserFrom(rootCfg ConfigProvider) { + sec := rootCfg.Section("restricted_user") + + RestrictedUser.AllowEditDueDate = sec.Key("ALLOW_EDIT_DUE_DATE").MustBool(false) +} diff --git a/modules/setting/setting.go b/modules/setting/setting.go index e14997801fed4..d22c5eca90171 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -203,6 +203,7 @@ func LoadSettings() { loadDBSetting(CfgProvider) loadServiceFrom(CfgProvider) + loadRestrictedUserFrom(CfgProvider) loadOAuth2ClientFrom(CfgProvider) loadCacheFrom(CfgProvider) loadSessionFrom(CfgProvider) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index b11e889eb502e..22b7bda6acdb2 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -845,6 +845,11 @@ func EditIssue(ctx *context.APIContext) { // Update or remove the deadline, only if set and allowed if (form.Deadline != nil || form.RemoveDeadline != nil) && canWrite { + if ctx.Doer.IsRestricted && !setting.RestrictedUser.AllowEditDueDate { + ctx.APIError(http.StatusForbidden, "restricted users cannot modify due dates") + return + } + var deadlineUnix timeutil.TimeStamp if form.RemoveDeadline == nil || !*form.RemoveDeadline { diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 54b7e5df2a01c..374dfaf3a1c85 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -24,6 +24,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/optional" + "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/util" @@ -397,6 +398,11 @@ func UpdateIssueDeadline(ctx *context.Context) { return } + if ctx.Doer.IsRestricted && !setting.RestrictedUser.AllowEditDueDate { + ctx.HTTPError(http.StatusForbidden, "", "restricted users cannot modify due dates") + return + } + deadlineUnix, _ := common.ParseDeadlineDateToEndOfDay(ctx.FormString("deadline")) if err := issues_model.UpdateIssueDeadline(ctx, issue, deadlineUnix, ctx.Doer); err != nil { ctx.HTTPError(http.StatusInternalServerError, "UpdateIssueDeadline", err.Error()) diff --git a/routers/web/repo/issue_view.go b/routers/web/repo/issue_view.go index d9f6c33e3fbc5..11d76bdc63dd1 100644 --- a/routers/web/repo/issue_view.go +++ b/routers/web/repo/issue_view.go @@ -412,6 +412,7 @@ func ViewIssue(ctx *context.Context) { ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login?redirect_to=" + url.QueryEscape(ctx.Data["Link"].(string)) ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.Doer.ID) ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) + ctx.Data["AllowEditDueDate"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !(ctx.Doer.IsRestricted && !setting.RestrictedUser.AllowEditDueDate) ctx.Data["HasProjectsWritePermission"] = ctx.Repo.CanWrite(unit.TypeProjects) ctx.Data["IsRepoAdmin"] = ctx.IsSigned && (ctx.Repo.IsAdmin() || ctx.Doer.IsAdmin) ctx.Data["LockReasons"] = setting.Repository.Issue.LockReasons diff --git a/templates/repo/issue/sidebar/due_date.tmpl b/templates/repo/issue/sidebar/due_date.tmpl index e6e19f6f86f5a..1799a057f87a1 100644 --- a/templates/repo/issue/sidebar/due_date.tmpl +++ b/templates/repo/issue/sidebar/due_date.tmpl @@ -7,7 +7,7 @@ {{svg "octicon-calendar"}} {{DateUtils.AbsoluteLong .Issue.DeadlineUnix}}
- {{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}} + {{if and .AllowEditDueDate (not .Repository.IsArchived)}} {{svg "octicon-pencil"}} {{svg "octicon-trash"}} {{end}} @@ -17,7 +17,7 @@ {{ctx.Locale.Tr "repo.issues.due_date_not_set"}} {{end}} - {{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}} + {{if and .AllowEditDueDate (not .Repository.IsArchived)}}