]> source.dussan.org Git - gitea.git/commitdiff
Implement ghost comment mitigation (#14349)
author6543 <6543@obermui.de>
Sun, 17 Jan 2021 20:48:38 +0000 (21:48 +0100)
committerGitHub <noreply@github.com>
Sun, 17 Jan 2021 20:48:38 +0000 (21:48 +0100)
* Implement ghost comment mitigation

Adds a config option USER_DELETE_WITH_COMMENTS_MAX_DAYS to the [service] section. See https://codeberg.org/Codeberg/Discussion/issues/24 for the underlying issue.

* cleanup

* use setting module correctly

* add to docs

Co-authored-by: Moritz Marquardt <git@momar.de>
custom/conf/app.example.ini
docs/content/doc/advanced/config-cheat-sheet.en-us.md
models/user.go
modules/setting/service.go
options/locale/locale_en-US.ini
routers/user/setting/account.go
templates/user/settings/account.tmpl

index e68727eb84524ed61c443318c6817636fb77f041..3920f5112ce58a9e323b0449c6af5e58823ce1d5 100644 (file)
@@ -688,6 +688,9 @@ AUTO_WATCH_NEW_REPOS = true
 ; Default value for AutoWatchOnChanges
 ; Make the user watch a repository When they commit for the first time
 AUTO_WATCH_ON_CHANGES = false
+; Default value for the minimum age a user has to exist before deletion to keep issue comments.
+; If a user deletes his account before that amount of days, his comments will be deleted as well.
+USER_DELETE_WITH_COMMENTS_MAX_DAYS = 0
 
 [webhook]
 ; Hook task queue length, increase if webhook shooting starts hanging
index 17d349b583938e1058fccc7b31fcdbb7abf4679d..5b86cadd445f8f72c5d0be4f47c742bef685e674 100644 (file)
@@ -474,6 +474,7 @@ relation to port exhaustion.
 - `ALLOW_ONLY_EXTERNAL_REGISTRATION`: **false** Set to true to force registration only using third-party services.
 - `NO_REPLY_ADDRESS`: **DOMAIN** Default value for the domain part of the user's email address in the git log if he has set KeepEmailPrivate to true.
   The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS.
+- `USER_DELETE_WITH_COMMENTS_MAX_DAYS`: **0** If a user deletes his account before that amount of days, his comments will be deleted as well.
 
 ## SSH Minimum Key Sizes (`ssh.minimum_key_sizes`)
 
index de12b804fd3c9b405c8eba78b53929714eeb70bb..584c9d032d74c698d12b0150e3dff655a70a2fe5 100644 (file)
@@ -1151,6 +1151,15 @@ func deleteUser(e *xorm.Session, u *User) error {
                return fmt.Errorf("deleteBeans: %v", err)
        }
 
+       if setting.Service.UserDeleteWithCommentsMaxDays != 0 &&
+               u.CreatedUnix.AsTime().Add(time.Duration(setting.Service.UserDeleteWithCommentsMaxDays)*24*time.Hour).After(time.Now()) {
+               if err = deleteBeans(e,
+                       &Comment{PosterID: u.ID},
+               ); err != nil {
+                       return fmt.Errorf("deleteBeans: %v", err)
+               }
+       }
+
        // ***** START: PublicKey *****
        if _, err = e.Delete(&PublicKey{OwnerID: u.ID}); err != nil {
                return fmt.Errorf("deletePublicKeys: %v", err)
@@ -1205,7 +1214,8 @@ func deleteUser(e *xorm.Session, u *User) error {
 }
 
 // DeleteUser completely and permanently deletes everything of a user,
-// but issues/comments/pulls will be kept and shown as someone has been deleted.
+// but issues/comments/pulls will be kept and shown as someone has been deleted,
+// unless the user is younger than USER_DELETE_WITH_COMMENTS_MAX_DAYS.
 func DeleteUser(u *User) (err error) {
        if u.IsOrganization() {
                return fmt.Errorf("%s is an organization not a user", u.Name)
index 5e74641d2705c60fb28d058ed4f474ab4063641f..86f46898ac109f96c2a1200f98496e8ef6d704c6 100644 (file)
@@ -50,6 +50,7 @@ var Service struct {
        AutoWatchNewRepos                       bool
        AutoWatchOnChanges                      bool
        DefaultOrgMemberVisible                 bool
+       UserDeleteWithCommentsMaxDays           int
 
        // OpenID settings
        EnableOpenIDSignIn bool
@@ -102,6 +103,7 @@ func newService() {
        Service.DefaultOrgVisibility = sec.Key("DEFAULT_ORG_VISIBILITY").In("public", structs.ExtractKeysFromMapString(structs.VisibilityModes))
        Service.DefaultOrgVisibilityMode = structs.VisibilityModes[Service.DefaultOrgVisibility]
        Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool()
+       Service.UserDeleteWithCommentsMaxDays = sec.Key("USER_DELETE_WITH_COMMENTS_MAX_DAYS").MustInt(0)
 
        sec = Cfg.Section("openid")
        Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock)
index 73451eeebb136813a0ad3b080f8ece87e0a593f5..5e5363726701ada09766d29a2bf6be30aa50507a 100644 (file)
@@ -646,6 +646,7 @@ repos_none = You do not own any repositories
 
 delete_account = Delete Your Account
 delete_prompt = This operation will permanently delete your user account. It <strong>CAN NOT</strong> be undone.
+delete_with_all_comments = Your account is younger than %d days. To avoid ghost comments, all issue/PR comments will be deleted with it.
 confirm_delete_account = Confirm Deletion
 delete_account_title = Delete User Account
 delete_account_desc = Are you sure you want to permanently delete this user account?
index ca9b5b3c3205b39ceef937ad604b1b0fbbbd2bb6..3b4191f0beeb28468f40c71abd7090ce2bf7b4fb 100644 (file)
@@ -7,6 +7,7 @@ package setting
 
 import (
        "errors"
+       "time"
 
        "code.gitea.io/gitea/models"
        "code.gitea.io/gitea/modules/auth"
@@ -300,4 +301,9 @@ func loadAccountData(ctx *context.Context) {
        ctx.Data["EmailNotificationsPreference"] = ctx.User.EmailNotifications()
        ctx.Data["ActivationsPending"] = pendingActivation
        ctx.Data["CanAddEmails"] = !pendingActivation || !setting.Service.RegisterEmailConfirm
+
+       if setting.Service.UserDeleteWithCommentsMaxDays != 0 {
+               ctx.Data["UserDeleteWithCommentsMaxDays"] = setting.Service.UserDeleteWithCommentsMaxDays
+               ctx.Data["UserDeleteWithComments"] = ctx.User.CreatedUnix.AsTime().Add(time.Duration(setting.Service.UserDeleteWithCommentsMaxDays) * 24 * time.Hour).After(time.Now())
+       }
 }
index d753f9082e4b7c1da84f01a5b635952b4f7774d4..4f7d8a50c705a8ee510dbf337829b325c5d47247 100644 (file)
                <div class="ui attached error segment">
                        <div class="ui red message">
                                <p class="text left">{{svg "octicon-alert"}} {{.i18n.Tr "settings.delete_prompt" | Str2html}}</p>
+                               {{ if .UserDeleteWithComments }}
+                               <p class="text left" style="font-weight: bold;">{{.i18n.Tr "settings.delete_with_all_comments" .UserDeleteWithCommentsMaxDays | Str2html}}</p>
+                               {{ end }}
                        </div>
                        <form class="ui form ignore-dirty" id="delete-form" action="{{AppSubUrl}}/user/settings/account/delete" method="post">
                                {{.CsrfTokenHtml}}