mirror of https://github.com/zulip/zulip.git
antispam: Add a sitewide ratelimit on invites by new realms.
This applies only on a server open for anyone to create a realm. Moreover, if the server admins have granted any given realm a max_invites greater than the default, that realm is exempt too.
This commit is contained in:
parent
dc1eeef30a
commit
22071a44a7
|
@ -4119,10 +4119,10 @@ class InvitationError(JsonableError):
|
||||||
self.errors = errors # type: List[Tuple[Text, str]]
|
self.errors = errors # type: List[Tuple[Text, str]]
|
||||||
self.sent_invitations = sent_invitations # type: bool
|
self.sent_invitations = sent_invitations # type: bool
|
||||||
|
|
||||||
def estimate_recent_invites(realm: Realm, *, days: int) -> int:
|
def estimate_recent_invites(realms: Iterable[Realm], *, days: int) -> int:
|
||||||
'''An upper bound on the number of invites sent in the last `days` days'''
|
'''An upper bound on the number of invites sent in the last `days` days'''
|
||||||
recent_invites = RealmCount.objects.filter(
|
recent_invites = RealmCount.objects.filter(
|
||||||
realm=realm,
|
realm__in=realms,
|
||||||
property='invites_sent::day',
|
property='invites_sent::day',
|
||||||
end_time__gte=timezone_now() - datetime.timedelta(days=days)
|
end_time__gte=timezone_now() - datetime.timedelta(days=days)
|
||||||
).aggregate(Sum('value'))['value__sum']
|
).aggregate(Sum('value'))['value__sum']
|
||||||
|
@ -4131,15 +4131,27 @@ def estimate_recent_invites(realm: Realm, *, days: int) -> int:
|
||||||
return recent_invites
|
return recent_invites
|
||||||
|
|
||||||
def check_invite_limit(user: UserProfile, num_invitees: int) -> None:
|
def check_invite_limit(user: UserProfile, num_invitees: int) -> None:
|
||||||
# Discourage using invitation emails as a vector for carrying spam
|
'''Discourage using invitation emails as a vector for carrying spam.'''
|
||||||
if settings.OPEN_REALM_CREATION:
|
msg = _("You do not have enough remaining invites. "
|
||||||
recent_invites = estimate_recent_invites(user.realm, days=1)
|
|
||||||
if num_invitees + recent_invites > user.realm.max_invites:
|
|
||||||
raise InvitationError(
|
|
||||||
_("You do not have enough remaining invites. "
|
|
||||||
"Please contact %s to have your limit raised. "
|
"Please contact %s to have your limit raised. "
|
||||||
"No invitations were sent." % (settings.ZULIP_ADMINISTRATOR)),
|
"No invitations were sent.") % (settings.ZULIP_ADMINISTRATOR,)
|
||||||
[], sent_invitations=False)
|
if settings.OPEN_REALM_CREATION:
|
||||||
|
recent_invites = estimate_recent_invites([user.realm], days=1)
|
||||||
|
if num_invitees + recent_invites > user.realm.max_invites:
|
||||||
|
raise InvitationError(msg, [], sent_invitations=False)
|
||||||
|
|
||||||
|
default_max = settings.INVITES_DEFAULT_REALM_DAILY_MAX
|
||||||
|
newrealm_age = datetime.timedelta(days=settings.INVITES_NEW_REALM_DAYS)
|
||||||
|
if (user.realm.date_created > timezone_now() - newrealm_age
|
||||||
|
and user.realm.max_invites <= default_max):
|
||||||
|
new_realms = Realm.objects.filter(
|
||||||
|
date_created__gte=timezone_now() - newrealm_age,
|
||||||
|
_max_invites__lte=default_max,
|
||||||
|
).all()
|
||||||
|
for days, count in settings.INVITES_NEW_REALM_LIMIT_DAYS:
|
||||||
|
recent_invites = estimate_recent_invites(new_realms, days=days)
|
||||||
|
if num_invitees + recent_invites > count:
|
||||||
|
raise InvitationError(msg, [], sent_invitations=False)
|
||||||
|
|
||||||
def do_invite_users(user_profile: UserProfile,
|
def do_invite_users(user_profile: UserProfile,
|
||||||
invitee_emails: SizedTextIterable,
|
invitee_emails: SizedTextIterable,
|
||||||
|
|
|
@ -309,6 +309,11 @@ DEFAULT_SETTINGS.update({
|
||||||
# Default for a realm's `max_invites`; which applies per day,
|
# Default for a realm's `max_invites`; which applies per day,
|
||||||
# and only applies if OPEN_REALM_CREATION is true.
|
# and only applies if OPEN_REALM_CREATION is true.
|
||||||
'INVITES_DEFAULT_REALM_DAILY_MAX': 100,
|
'INVITES_DEFAULT_REALM_DAILY_MAX': 100,
|
||||||
|
# Global rate-limit (list of pairs (days, max)) on invites from new realms.
|
||||||
|
# Only applies if OPEN_REALM_CREATION is true.
|
||||||
|
'INVITES_NEW_REALM_LIMIT_DAYS': [(1, 100)],
|
||||||
|
# Definition of a new realm for INVITES_NEW_REALM_LIMIT.
|
||||||
|
'INVITES_NEW_REALM_DAYS': 7,
|
||||||
|
|
||||||
# Controls for which links are published in portico footers/headers/etc.
|
# Controls for which links are published in portico footers/headers/etc.
|
||||||
'EMAIL_DELIVERER_DISABLED': False,
|
'EMAIL_DELIVERER_DISABLED': False,
|
||||||
|
|
Loading…
Reference in New Issue