refactor: Flatten code in check_invite_limit().

Using early-exit here allows us to more easily
comment why there are certain exemptions to
this logic.

We also only require callers to pass in realm,
not the whole user object.
This commit is contained in:
Steve Howell 2018-08-21 20:13:14 +00:00 committed by Tim Abbott
parent cac9a02d6d
commit fe6680c316
1 changed files with 31 additions and 19 deletions

View File

@ -4435,24 +4435,36 @@ def estimate_recent_invites(realms: Iterable[Realm], *, days: int) -> int:
return 0 return 0
return recent_invites return recent_invites
def check_invite_limit(user: UserProfile, num_invitees: int) -> None: def check_invite_limit(realm: Realm, num_invitees: int) -> None:
'''Discourage using invitation emails as a vector for carrying spam.''' '''Discourage using invitation emails as a vector for carrying spam.'''
msg = _("You do not have enough remaining invites. " msg = _("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,)
if settings.OPEN_REALM_CREATION: if not settings.OPEN_REALM_CREATION:
recent_invites = estimate_recent_invites([user.realm], days=1) return
if num_invitees + recent_invites > user.realm.max_invites:
recent_invites = estimate_recent_invites([realm], days=1)
if num_invitees + recent_invites > realm.max_invites:
raise InvitationError(msg, [], sent_invitations=False) raise InvitationError(msg, [], sent_invitations=False)
default_max = settings.INVITES_DEFAULT_REALM_DAILY_MAX default_max = settings.INVITES_DEFAULT_REALM_DAILY_MAX
newrealm_age = datetime.timedelta(days=settings.INVITES_NEW_REALM_DAYS) newrealm_age = datetime.timedelta(days=settings.INVITES_NEW_REALM_DAYS)
if (user.realm.date_created > timezone_now() - newrealm_age if realm.date_created <= timezone_now() - newrealm_age:
and user.realm.max_invites <= default_max): # If this isn't a "newly-created" realm, we're done. The
# remaining code applies an aggregate limit across all
# "new" realms, to address sudden bursts of spam realms.
return
if realm.max_invites > default_max:
# If a user is on a realm where we've bumped up
# max_invites, then we exempt them from invite limits.
return
new_realms = Realm.objects.filter( new_realms = Realm.objects.filter(
date_created__gte=timezone_now() - newrealm_age, date_created__gte=timezone_now() - newrealm_age,
_max_invites__lte=default_max, _max_invites__lte=default_max,
).all() ).all()
for days, count in settings.INVITES_NEW_REALM_LIMIT_DAYS: for days, count in settings.INVITES_NEW_REALM_LIMIT_DAYS:
recent_invites = estimate_recent_invites(new_realms, days=days) recent_invites = estimate_recent_invites(new_realms, days=days)
if num_invitees + recent_invites > count: if num_invitees + recent_invites > count:
@ -4463,7 +4475,7 @@ def do_invite_users(user_profile: UserProfile,
streams: Iterable[Stream], streams: Iterable[Stream],
invite_as_admin: Optional[bool]=False) -> None: invite_as_admin: Optional[bool]=False) -> None:
check_invite_limit(user_profile, len(invitee_emails)) check_invite_limit(user_profile.realm, len(invitee_emails))
realm = user_profile.realm realm = user_profile.realm
if not realm.invite_required: if not realm.invite_required:
@ -4570,7 +4582,7 @@ def do_revoke_user_invite(prereg_user: PreregistrationUser) -> None:
notify_invites_changed(prereg_user) notify_invites_changed(prereg_user)
def do_resend_user_invite_email(prereg_user: PreregistrationUser) -> int: def do_resend_user_invite_email(prereg_user: PreregistrationUser) -> int:
check_invite_limit(prereg_user.referred_by, 1) check_invite_limit(prereg_user.referred_by.realm, 1)
prereg_user.invited_at = timezone_now() prereg_user.invited_at = timezone_now()
prereg_user.save() prereg_user.save()