Improve validation and error handling.

This commit is contained in:
floss4good 2025-03-03 11:52:31 +02:00
parent 23fe44db4d
commit 729ac5b9f2
No known key found for this signature in database
GPG key ID: 5B948B4F4DAF819D
5 changed files with 40 additions and 11 deletions

View file

@ -5,6 +5,8 @@ package moderation
import (
"context"
"errors"
"slices"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
@ -73,6 +75,17 @@ const (
ReportedContentTypeComment // 4
)
var allReportedContentTypes = []ReportedContentType{
ReportedContentTypeUser,
ReportedContentTypeRepository,
ReportedContentTypeIssue,
ReportedContentTypeComment,
}
func (t ReportedContentType) IsValid() bool {
return slices.Contains(allReportedContentTypes, t)
}
// AbuseReport represents a report of abusive content.
type AbuseReport struct {
ID int64 `xorm:"pk autoincr"`
@ -99,25 +112,31 @@ func init() {
db.RegisterModel(new(AbuseReport))
}
// IsReported reports whether one or more reports were already submitted for contentType and contentID.
// IsReported reports whether one or more reports were already submitted for contentType and contentID
// (regardless the status of the reports).
func IsReported(ctx context.Context, contentType ReportedContentType, contentID int64) bool {
// TODO: only consider the reports with 'New' status (and adjust the function name)?!
reported, _ := db.GetEngine(ctx).Exist(&AbuseReport{ContentType: contentType, ContentID: contentID})
return reported
}
// alreadyReportedBy returns if doerID has already submitted a report for contentType and contentID.
func alreadyReportedBy(ctx context.Context, doerID int64, contentType ReportedContentType, contentID int64) bool {
reported, _ := db.GetEngine(ctx).Exist(&AbuseReport{ReporterID: doerID, ContentType: contentType, ContentID: contentID})
// AlreadyReportedByAndOpen returns if doerID has already submitted a report for contentType and contentID that is still Open.
func AlreadyReportedByAndOpen(ctx context.Context, doerID int64, contentType ReportedContentType, contentID int64) bool {
reported, _ := db.GetEngine(ctx).Exist(&AbuseReport{
Status: ReportStatusTypeOpen,
ReporterID: doerID,
ContentType: contentType,
ContentID: contentID,
})
return reported
}
func ReportAbuse(ctx context.Context, report *AbuseReport) error {
if report.ContentType == ReportedContentTypeUser && report.ReporterID == report.ContentID {
return nil
return errors.New("reporting yourself is not allowed")
}
if alreadyReportedBy(ctx, report.ReporterID, report.ContentType, report.ContentID) {
if AlreadyReportedByAndOpen(ctx, report.ReporterID, report.ContentType, report.ContentID) {
log.Warn("Seems that user %d wanted to report again the content with type %d and ID %d; this request will be ignored.", report.ReporterID, report.ContentType, report.ContentID)
return nil
}

View file

@ -71,7 +71,7 @@ func createShadowCopy(ctx context.Context, contentType ReportedContentType, cont
// TODO: What should happen if an item is updated multiple times (and the reports already have a shadow copy ID)?
}).And(builder.IsNull{"shadow_copy_id"}).Cols("shadow_copy_id").Update(&AbuseReport{ShadowCopyID: &shadowCopy.ID})
if err != nil {
return fmt.Errorf("Could not link the shadow copy (%d) to reported content with type %d and ID %d. %w", shadowCopy.ID, contentType, contentID, err)
return fmt.Errorf("could not link the shadow copy (%d) to reported content with type %d and ID %d - %w", shadowCopy.ID, contentType, contentID, err)
}
return nil

View file

@ -3967,6 +3967,7 @@ report_content = Report content
report_abuse_form.header = Report abuse to administrator
report_abuse_form.details = This form should be used to report users who create spam profiles, repositories, issues, comments or behave inappropriately.
report_abuse_form.invalid = Invalid arguments
report_abuse_form.already_reported = You already reported this content
abuse_category = Category
abuse_category.placeholder = Please select a category
@ -3979,6 +3980,7 @@ report_remarks = Remarks
report_remarks.placeholder = Please provide some details regarding the abuse you are reporting.
submit_report = Submit report
reporting_failed = Something went wrong while trying to submit the new abuse report: %v
reported_thank_you = Thank you for your report. An administrator will look into it shortly.
[translation_meta]

View file

@ -44,6 +44,11 @@ func NewReport(ctx *context.Context) {
return
}
if moderation.AlreadyReportedByAndOpen(ctx, ctx.Doer.ID, contentType, contentID) {
ctx.RenderWithErr(ctx.Tr("moderation.report_abuse_form.already_reported"), tplSubmitAbuseReport, nil)
return
}
setContextDataAndRender(ctx, contentType, contentID)
}
@ -61,7 +66,7 @@ func setContextDataAndRender(ctx *context.Context, contentType moderation.Report
func CreatePost(ctx *context.Context) {
form := *web.GetForm(ctx).(*forms.ReportAbuseForm)
if form.ContentID <= 0 || form.ContentType == 0 {
if form.ContentID <= 0 || !form.ContentType.IsValid() {
ctx.RenderWithErr(ctx.Tr("moderation.report_abuse_form.invalid"), tplSubmitAbuseReport, nil)
return
}
@ -80,7 +85,8 @@ func CreatePost(ctx *context.Context) {
}
if err := moderation.ReportAbuse(ctx, &report); err != nil {
ctx.ServerError("Something went wrong while trying to submit the new abuse report.", err)
ctx.Flash.Error(ctx.Tr("moderation.reporting_failed", err))
ctx.Redirect(ctx.Doer.DashboardLink())
return
}

View file

@ -14,7 +14,7 @@
<input type="hidden" name="content_id" value="{{.ContentID}}" />
<input type="hidden" name="content_type" value="{{.ContentType}}" />
<fieldset>
<fieldset{{if not .ContentID}} disabled{{end}}>
<label{{if .Err_AbuseCategory}} class="error"{{end}}>
{{ctx.Locale.Tr "moderation.abuse_category"}}
<select class="ui selection dropdown" id="abuse_category" name="abuse_category" required autofocus>
@ -33,7 +33,9 @@
<div class="divider"></div>
<div class="text right actions">
<a class="ui cancel button" href="{{$.CancelLink}}">{{ctx.Locale.Tr "cancel"}}</a>
<button class="ui primary button"{{if not .ContentID}} disabled{{end}}>{{ctx.Locale.Tr "moderation.submit_report"}}</button>
{{if .ContentID}}
<button class="ui primary button">{{ctx.Locale.Tr "moderation.submit_report"}}</button>
{{end}}
</div>
</div>
</form>