Skip to content

Commit

Permalink
Implement ghost comment mitigation (go-gitea#14349)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
2 people authored and ashimokawa committed Feb 26, 2021
1 parent c3078cd commit 88925d5
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 1 deletion.
3 changes: 3 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,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
Expand Down
1 change: 1 addition & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`)

Expand Down
12 changes: 11 additions & 1 deletion models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,15 @@ func deleteUser(e Engine, 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)
Expand Down Expand Up @@ -1207,7 +1216,8 @@ func deleteUser(e Engine, 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)
Expand Down
2 changes: 2 additions & 0 deletions modules/setting/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ var Service struct {
AutoWatchNewRepos bool
AutoWatchOnChanges bool
DefaultOrgMemberVisible bool
UserDeleteWithCommentsMaxDays int

// OpenID settings
EnableOpenIDSignIn bool
Expand Down Expand Up @@ -96,6 +97,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)
Expand Down
1 change: 1 addition & 0 deletions options/locale/locale_de-DE.ini
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ repos_none=Du besitzt keine Repositories

delete_account=Konto löschen
delete_prompt=Wenn du fortfährst, wird dein Account permanent gelöscht. Dies <strong>KANN NICHT</strong> rückgängig gemacht werden.
delete_with_all_comments = Dein Account ist jünger als %d Tage. Um Geisterkommentare zu vermeiden, werden alle Issue/PR-Kommentare zusammen mit deinem Benutzeraccount gelöscht.
confirm_delete_account=Löschen bestätigen
delete_account_title=Benutzerkonto löschen
delete_account_desc=Bist du sicher, dass du diesen Account dauerhaft löschen möchtest?
Expand Down
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,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?
Expand Down
6 changes: 6 additions & 0 deletions routers/user/setting/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package setting

import (
"errors"
"time"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
Expand Down Expand Up @@ -301,4 +302,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())
}
}
3 changes: 3 additions & 0 deletions templates/user/settings/account.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@
<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}}
Expand Down

0 comments on commit 88925d5

Please sign in to comment.