Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement ghost comment mitigation #14349

Merged
merged 10 commits into from
Jan 17, 2021
3 changes: 3 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
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 @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions modules/setting/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var Service struct {
AutoWatchNewRepos bool
AutoWatchOnChanges bool
DefaultOrgMemberVisible bool
UserDeleteWithCommentsMaxDays int

// OpenID settings
EnableOpenIDSignIn bool
Expand Down Expand Up @@ -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)
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 @@ -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?
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 @@ -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())
}
}
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