From fe6680c316372a3251a0c6f9d1a3f8c5fe4c428a Mon Sep 17 00:00:00 2001 From: Steve Howell Date: Tue, 21 Aug 2018 20:13:14 +0000 Subject: [PATCH] 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. --- zerver/lib/actions.py | 50 +++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index 581a20158f..95c7e8b48f 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -4435,35 +4435,47 @@ def estimate_recent_invites(realms: Iterable[Realm], *, days: int) -> int: return 0 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.''' msg = _("You do not have enough remaining invites. " "Please contact %s to have your limit raised. " "No invitations were sent.") % (settings.ZULIP_ADMINISTRATOR,) - 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) + if not settings.OPEN_REALM_CREATION: + return - 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) + recent_invites = estimate_recent_invites([realm], days=1) + if num_invitees + recent_invites > 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 realm.date_created <= timezone_now() - newrealm_age: + # 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( + 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, invitee_emails: SizedTextIterable, streams: Iterable[Stream], 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 if not realm.invite_required: @@ -4570,7 +4582,7 @@ def do_revoke_user_invite(prereg_user: PreregistrationUser) -> None: notify_invites_changed(prereg_user) 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.save()