mirror of https://github.com/zulip/zulip.git
invitations: Limit realms to 100 invites per day.
To guard against using zulip invites as a vector for spam. Stopgap measure until we figure out something better.
This commit is contained in:
parent
8dc0adbed8
commit
7d1c88f0fb
|
@ -3931,6 +3931,19 @@ def do_invite_users(user_profile: UserProfile,
|
|||
streams: Iterable[Stream],
|
||||
invite_as_admin: Optional[bool]=False,
|
||||
body: Optional[str]=None) -> None:
|
||||
if settings.OPEN_REALM_CREATION:
|
||||
# Discourage using invitation emails as a vector for carrying spam
|
||||
sent_invites = Confirmation.objects.filter(
|
||||
realm=user_profile.realm,
|
||||
date_sent__gte=timezone_now() - datetime.timedelta(days=1),
|
||||
type=Confirmation.INVITATION).count()
|
||||
if len(invitee_emails) + sent_invites > user_profile.realm.max_invites:
|
||||
raise InvitationError(
|
||||
_("You do not have enough remaining invites; "
|
||||
"try again with fewer emails, or contact %s. "
|
||||
"No invitations were sent." % (settings.ZULIP_ADMINISTRATOR)),
|
||||
[], sent_invitations=False)
|
||||
|
||||
validated_emails = [] # type: List[Text]
|
||||
errors = [] # type: List[Tuple[Text, str]]
|
||||
skipped = [] # type: List[Tuple[Text, str]]
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.6 on 2017-11-30 04:58
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('zerver', '0124_stream_enable_notifications'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='realm',
|
||||
name='max_invites',
|
||||
field=models.IntegerField(default=100),
|
||||
),
|
||||
]
|
|
@ -170,6 +170,8 @@ class Realm(models.Model):
|
|||
authentication_methods = BitField(flags=AUTHENTICATION_FLAGS,
|
||||
default=2**31 - 1) # type: BitHandler
|
||||
waiting_period_threshold = models.PositiveIntegerField(default=0) # type: int
|
||||
DEFAULT_MAX_INVITES = 100
|
||||
max_invites = models.IntegerField(default=DEFAULT_MAX_INVITES) # type: int
|
||||
|
||||
# Define the types of the various automatically managed properties
|
||||
property_types = dict(
|
||||
|
|
|
@ -665,6 +665,25 @@ earl-test@zulip.com""", ["Denmark"]))
|
|||
self.check_sent_emails(["bob-test@zulip.com", "carol-test@zulip.com",
|
||||
"dave-test@zulip.com", "earl-test@zulip.com"])
|
||||
|
||||
def test_invite_too_many_users(self) -> None:
|
||||
# Only a light test of this pathway; e.g. doesn't test that
|
||||
# the limit gets reset after 24 hours
|
||||
self.login(self.example_email("iago"))
|
||||
self.client_post("/json/invites",
|
||||
{"invitee_emails": "1@zulip.com, 2@zulip.com",
|
||||
"stream": ["Denmark"],
|
||||
"custom_body": ''}),
|
||||
|
||||
self.assert_json_error(
|
||||
self.client_post("/json/invites",
|
||||
{"invitee_emails": ", ".join(
|
||||
[str(i) for i in range(get_realm("zulip").max_invites - 1)]),
|
||||
"stream": ["Denmark"],
|
||||
"custom_body": ''}),
|
||||
"You do not have enough remaining invites; "
|
||||
"try again with fewer emails, or contact zulip-admin@example.com. "
|
||||
"No invitations were sent.")
|
||||
|
||||
def test_missing_or_invalid_params(self) -> None:
|
||||
"""
|
||||
Tests inviting with various missing or invalid parameters.
|
||||
|
|
Loading…
Reference in New Issue