admin: add account spam restriction (join/message gate)
Adds a narrower spam sanction alongside the existing account freeze: a restricted account keeps every existing membership and conversation, but cannot join new channels/groups (public join or invite link) and cannot start a new conversation with a non-contact. Reachable both as a standalone admin action and as a decision on a reported user's moderation case, with the same idempotent-supersession and appeal wiring freeze already has.
This commit is contained in:
parent
3ca8ef1a16
commit
f33e25af8d
32 changed files with 750 additions and 44 deletions
|
|
@ -53,3 +53,21 @@ type AccountFreezeNotification struct {
|
|||
Frozen bool
|
||||
Attempts int
|
||||
}
|
||||
|
||||
// AccountRestriction is the durable, narrower spam sanction: unlike
|
||||
// AccountFreeze it does not make the account read-only. A restricted account
|
||||
// keeps every existing membership and conversation; it can only not join new
|
||||
// channels/groups and not start new conversations with non-contacts. Until,
|
||||
// when set, is when the restriction auto-lifts; a zero Until means it stays
|
||||
// in effect until an admin clears it.
|
||||
type AccountRestriction struct {
|
||||
UserID int64
|
||||
Restricted bool
|
||||
Version int64
|
||||
Since time.Time
|
||||
Until time.Time
|
||||
Reason string
|
||||
Actor string
|
||||
CommandID string
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ const (
|
|||
ModerationActionClearPeerFlags ModerationActionKind = "clear_peer_flags"
|
||||
ModerationActionFreezeAccount ModerationActionKind = "freeze_account"
|
||||
ModerationActionUnfreezeAccount ModerationActionKind = "unfreeze_account"
|
||||
ModerationActionRestrictAccount ModerationActionKind = "restrict_account"
|
||||
ModerationActionUnrestrictAccount ModerationActionKind = "unrestrict_account"
|
||||
ModerationActionDeletePrivateMessage ModerationActionKind = "delete_private_message"
|
||||
ModerationActionDeleteChannelMessage ModerationActionKind = "delete_channel_message"
|
||||
ModerationActionDeleteAccount ModerationActionKind = "delete_account"
|
||||
|
|
@ -121,6 +123,7 @@ func (k ModerationActionKind) Valid() bool {
|
|||
case ModerationActionMarkScam, ModerationActionMarkFake,
|
||||
ModerationActionClearPeerFlags, ModerationActionFreezeAccount,
|
||||
ModerationActionUnfreezeAccount,
|
||||
ModerationActionRestrictAccount, ModerationActionUnrestrictAccount,
|
||||
ModerationActionDeletePrivateMessage,
|
||||
ModerationActionDeleteChannelMessage,
|
||||
ModerationActionDeleteAccount:
|
||||
|
|
@ -159,8 +162,9 @@ func (s ModerationActionStatus) Valid() bool {
|
|||
type ModerationSanctionFamily string
|
||||
|
||||
const (
|
||||
ModerationSanctionPeerFlags ModerationSanctionFamily = "peer_flags"
|
||||
ModerationSanctionAccountFreeze ModerationSanctionFamily = "account_freeze"
|
||||
ModerationSanctionPeerFlags ModerationSanctionFamily = "peer_flags"
|
||||
ModerationSanctionAccountFreeze ModerationSanctionFamily = "account_freeze"
|
||||
ModerationSanctionAccountRestrict ModerationSanctionFamily = "account_restrict"
|
||||
)
|
||||
|
||||
func (k ModerationActionKind) SanctionFamily() (ModerationSanctionFamily, bool) {
|
||||
|
|
@ -170,6 +174,8 @@ func (k ModerationActionKind) SanctionFamily() (ModerationSanctionFamily, bool)
|
|||
return ModerationSanctionPeerFlags, true
|
||||
case ModerationActionFreezeAccount, ModerationActionUnfreezeAccount:
|
||||
return ModerationSanctionAccountFreeze, true
|
||||
case ModerationActionRestrictAccount, ModerationActionUnrestrictAccount:
|
||||
return ModerationSanctionAccountRestrict, true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,6 +189,14 @@ func AccountFrozenRestrictionReasons() []UserRestrictionReason {
|
|||
}}
|
||||
}
|
||||
|
||||
func AccountRestrictedRestrictionReasons() []UserRestrictionReason {
|
||||
return []UserRestrictionReason{{
|
||||
Platform: "all",
|
||||
Reason: "spam-restricted",
|
||||
Text: "This account has been restricted for suspected spam.",
|
||||
}}
|
||||
}
|
||||
|
||||
// PremiumActiveAt 报告用户在 now(Unix 秒)时刻是否为有效会员。
|
||||
// bot 永不为会员(官方语义;授予路径同样排除 bot,这里是双保险)。
|
||||
func (u User) PremiumActiveAt(now int64) bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue