Beispiel #1
0
    def handle(self, *args: Any, **options: str) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        encoding = sys.getfilesystemencoding()
        stream_name = options['stream_name']
        create_stream_if_needed(realm, force_text(stream_name, encoding))
Beispiel #2
0
 def test_new_stream_link(self, mock_django_timezone: mock.MagicMock) -> None:
     cutoff = datetime.datetime(year=2017, month=11, day=1)
     mock_django_timezone.return_value = datetime.datetime(year=2017, month=11, day=5)
     cordelia = self.example_user('cordelia')
     create_stream_if_needed(cordelia.realm, 'New stream')
     new_stream = gather_new_streams(cordelia, cutoff)[1]
     expected_html = "<a href='http://zulip.testserver/#narrow/stream/New.20stream'>New stream</a>"
     self.assertIn(expected_html, new_stream['html'])
Beispiel #3
0
 def test_new_stream_link(self, mock_django_timezone: mock.MagicMock) -> None:
     cutoff = datetime.datetime(year=2017, month=11, day=1)
     mock_django_timezone.return_value = datetime.datetime(year=2017, month=11, day=5)
     cordelia = self.example_user('cordelia')
     create_stream_if_needed(cordelia.realm, 'New stream')
     new_stream = gather_new_streams(cordelia, cutoff)[1]
     expected_html = "<a href='http://zulip.testserver/#narrow/stream/New.20stream'>New stream</a>"
     self.assertIn(expected_html, new_stream['html'])
Beispiel #4
0
    def handle(self, *args, **options):
        # type: (*Any, **str) -> None
        string_id = options['realm']
        encoding = sys.getfilesystemencoding()
        stream_name = options['stream_name']

        realm = get_realm(force_text(string_id, encoding))
        if realm is None:
            print("Unknown string_id %s" % (string_id,))
            exit(1)

        create_stream_if_needed(realm, force_text(stream_name, encoding))
Beispiel #5
0
    def handle(self, *args, **options):
        # type: (*Any, **str) -> None
        string_id = options['realm']
        encoding = sys.getfilesystemencoding()
        stream_name = options['stream_name']

        realm = get_realm(force_text(string_id, encoding))
        if realm is None:
            print("Unknown string_id %s" % (string_id, ))
            exit(1)

        create_stream_if_needed(realm, force_text(stream_name, encoding))
Beispiel #6
0
    def test_register(self):
        realm = get_realm("zulip.com")
        streams = ["stream_%s" % i for i in range(40)]
        for stream in streams:
            create_stream_if_needed(realm, stream)

        set_default_streams(realm, streams)
        with queries_captured() as queries:
            self.register("test", "test")
        # Ensure the number of queries we make is not O(streams)
        self.assert_length(queries, 67)
        user_profile = get_user_profile_by_email('*****@*****.**')
        self.assertEqual(get_session_dict_user(self.client.session), user_profile.id)
Beispiel #7
0
    def test_register(self):
        realm = get_realm("zulip.com")
        streams = ["stream_%s" % i for i in range(40)]
        for stream in streams:
            create_stream_if_needed(realm, stream)

        set_default_streams(realm, streams)
        with queries_captured() as queries:
            self.register("test", "test")
        # Ensure the number of queries we make is not O(streams)
        self.assert_length(queries, 74)
        user_profile = get_user_profile_by_email('*****@*****.**')
        self.assertEqual(get_session_dict_user(self.client.session), user_profile.id)
Beispiel #8
0
    def test_slow_query_log(self, mock_logging_info: Mock) -> None:
        error_bot = get_system_bot(settings.ERROR_BOT)
        create_stream_if_needed(error_bot.realm, settings.SLOW_QUERY_LOGS_STREAM)

        self.log_data['time_started'] = time.time() - self.SLOW_QUERY_TIME
        write_log_line(self.log_data, path='/socket/open', method='SOCKET',
                       remote_ip='123.456.789.012', email='unknown', client_name='?')
        last_message = self.get_last_message()
        self.assertEqual(last_message.sender.email, "*****@*****.**")
        self.assertIn("logs", str(last_message.recipient))
        self.assertEqual(last_message.topic_name(), "testserver: slow queries")
        self.assertRegexpMatches(last_message.content,
                                 r"123\.456\.789\.012 SOCKET  200 10\.\ds .*")
Beispiel #9
0
    def test_invite_user_signup_initial_history(self):
        """
        Test that a new user invited to a stream receives some initial
        history but only from public streams.
        """
        self.login("*****@*****.**")
        user_profile = get_user_profile_by_email("*****@*****.**")
        private_stream_name = "Secret"
        (stream, _) = create_stream_if_needed(user_profile.realm,
                                              private_stream_name,
                                              invite_only=True)
        do_add_subscription(user_profile, stream)
        public_msg_id = self.send_message("*****@*****.**", "Denmark",
                                          Recipient.STREAM, "Public topic",
                                          "Public message")
        secret_msg_id = self.send_message("*****@*****.**",
                                          private_stream_name,
                                          Recipient.STREAM, "Secret topic",
                                          "Secret message")
        invitee = "*****@*****.**"
        self.assert_json_success(
            self.invite(invitee, [private_stream_name, "Denmark"]))
        self.assertTrue(find_key_by_email(invitee))

        self.submit_reg_form_for_user("alice-test", "password")
        invitee_profile = get_user_profile_by_email(invitee)
        invitee_msg_ids = [
            um.message_id
            for um in UserMessage.objects.filter(user_profile=invitee_profile)
        ]
        self.assertTrue(public_msg_id in invitee_msg_ids)
        self.assertFalse(secret_msg_id in invitee_msg_ids)
Beispiel #10
0
    def test_rename_stream(self):
        realm = get_realm('zulip.com')
        stream, _ = create_stream_if_needed(realm, 'old_name')
        new_name = u'stream with a brand new name'
        self.subscribe_to_stream(self.user_profile.email, stream.name)

        action = lambda: do_rename_stream(realm, stream.name, new_name)
        events = self.do_test(action)

        schema_checker = check_dict([
            ('type', equals('stream')),
            ('op', equals('update')),
            ('property', equals('email_address')),
            ('value', check_string),
            ('name', equals('old_name')),
        ])
        error = schema_checker('events[0]', events[0])
        self.assert_on_error(error)

        schema_checker = check_dict([
            ('type', equals('stream')),
            ('op', equals('update')),
            ('property', equals('name')),
            ('value', equals(new_name)),
            ('name', equals('old_name')),
        ])
        error = schema_checker('events[1]', events[1])
        self.assert_on_error(error)
Beispiel #11
0
 def subscribe_to_stream(self, email, stream_name, realm=None):
     realm = get_realm(resolve_email_to_domain(email))
     stream = get_stream(stream_name, realm)
     if stream is None:
         stream, _ = create_stream_if_needed(realm, stream_name)
     user_profile = get_user_profile_by_email(email)
     do_add_subscription(user_profile, stream, no_log=True)
Beispiel #12
0
    def handle(self, **options):
        # type: (**Any) -> None
        if options["domain"] is None or options["streams"] is None or \
                (options["users"] is None and options["all_users"] is None):
            self.print_help("python manage.py", "add_users_to_streams")
            exit(1)

        stream_names = set([stream.strip() for stream in options["streams"].split(",")])
        realm = get_realm(options["domain"])

        if options["all_users"]:
            user_profiles = UserProfile.objects.filter(realm=realm)
        else:
            emails = set([email.strip() for email in options["users"].split(",")])
            user_profiles = []
            for email in emails:
                user_profiles.append(get_user_profile_by_email(email))

        for stream_name in set(stream_names):
            for user_profile in user_profiles:
                stream, _ = create_stream_if_needed(user_profile.realm, stream_name)
                did_subscribe = do_add_subscription(user_profile, stream)
                print("%s %s to %s" % (
                    "Subscribed" if did_subscribe else "Already subscribed",
                    user_profile.email, stream_name))
Beispiel #13
0
    def handle(self, **options):
        # type: (**Any) -> None
        if options["domain"] is None or options["streams"] is None or \
                (options["users"] is None and options["all_users"] is None):
            self.print_help("python manage.py", "add_users_to_streams")
            exit(1)

        stream_names = set(
            [stream.strip() for stream in options["streams"].split(",")])
        realm = get_realm(options["domain"])

        if options["all_users"]:
            user_profiles = UserProfile.objects.filter(realm=realm)
        else:
            emails = set(
                [email.strip() for email in options["users"].split(",")])
            user_profiles = []
            for email in emails:
                user_profiles.append(get_user_profile_by_email(email))

        for stream_name in set(stream_names):
            for user_profile in user_profiles:
                stream, _ = create_stream_if_needed(user_profile.realm,
                                                    stream_name)
                _ignore, already_subscribed = bulk_add_subscriptions(
                    [stream], [user_profile])
                was_there_already = user_profile.id in {
                    tup[0].id
                    for tup in already_subscribed
                }
                print("%s %s to %s" %
                      ("Already subscribed" if was_there_already else
                       "Subscribed", user_profile.email, stream_name))
    def handle(self, *args, **options):
        # type: (*Any, **Any) -> None
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        streams = []
        if options["streams"]:
            stream_names = set(
                [stream.strip() for stream in options["streams"].split(",")])

            for stream_name in set(stream_names):
                stream, _ = create_stream_if_needed(realm, stream_name)
                streams.append(stream)

        referred_by = self.get_user(options['referred_by'], realm)
        invite = MultiuseInvite.objects.create(realm=realm,
                                               referred_by=referred_by)

        if streams:
            invite.streams = streams
            invite.save()

        invite_link = create_confirmation_link(invite, realm.host,
                                               Confirmation.MULTIUSE_INVITE)
        print(
            "You can use %s to invite as many number of people to the organization."
            % (invite_link, ))
Beispiel #15
0
    def test_invite_user_signup_initial_history(self):
        # type: () -> None
        """
        Test that a new user invited to a stream receives some initial
        history but only from public streams.
        """
        self.login("*****@*****.**")
        user_profile = get_user_profile_by_email("*****@*****.**")
        private_stream_name = "Secret"
        (stream, _) = create_stream_if_needed(user_profile.realm, private_stream_name, invite_only=True)
        do_add_subscription(user_profile, stream)
        public_msg_id = self.send_message("*****@*****.**", "Denmark", Recipient.STREAM,
                                          "Public topic", "Public message")
        secret_msg_id = self.send_message("*****@*****.**", private_stream_name, Recipient.STREAM,
                                          "Secret topic", "Secret message")
        invitee = "*****@*****.**"
        self.assert_json_success(self.invite(invitee, [private_stream_name, "Denmark"]))
        self.assertTrue(find_key_by_email(invitee))

        self.submit_reg_form_for_user("alice-test", "password")
        invitee_profile = get_user_profile_by_email(invitee)
        invitee_msg_ids = [um.message_id for um in
                           UserMessage.objects.filter(user_profile=invitee_profile)]
        self.assertTrue(public_msg_id in invitee_msg_ids)
        self.assertFalse(secret_msg_id in invitee_msg_ids)
Beispiel #16
0
    def handle(self, **options):
        if options["domain"] is None or options["streams"] is None or \
                (options["users"] is None and options["all_users"] is None):
            self.print_help("python manage.py", "add_users_to_streams")
            exit(1)

        stream_names = set(
            [stream.strip() for stream in options["streams"].split(",")])
        realm = get_realm(options["domain"])

        if options["all_users"]:
            user_profiles = UserProfile.objects.filter(realm=realm)
        else:
            emails = set(
                [email.strip() for email in options["users"].split(",")])
            user_profiles = []
            for email in emails:
                user_profiles.append(get_user_profile_by_email(email))

        for stream_name in set(stream_names):
            for user_profile in user_profiles:
                stream, _ = create_stream_if_needed(user_profile.realm,
                                                    stream_name)
                did_subscribe = do_add_subscription(user_profile, stream)
                print("%s %s to %s" %
                      ("Subscribed" if did_subscribe else "Already subscribed",
                       user_profile.email, stream_name))
    def handle(self, *args, **options):
        # type: (*Any, **Any) -> None
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        streams = []
        stream_names = set([stream.strip() for stream in options["streams"].split(",")])
        for stream_name in set(stream_names):
            stream, _ = create_stream_if_needed(realm, stream_name)
            streams.append(stream)

        try:
            default_stream_group = DefaultStreamGroup.objects.get(
                name=options["name"], realm=realm, description=options["description"])
        except DefaultStreamGroup.DoesNotExist:
            default_stream_group = DefaultStreamGroup.objects.create(
                name=options["name"], realm=realm, description=options["description"])
        default_stream_group.streams = streams
        default_stream_group.save()

        default_stream_groups = DefaultStreamGroup.objects.all()
        for default_stream_group in default_stream_groups:
            print(default_stream_group.name)
            print(default_stream_group.description)
            for stream in default_stream_group.streams.all():
                print(stream.name)
            print("")
Beispiel #18
0
    def handle(self, *args, **options):
        # type: (*Any, **Any) -> None
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        streams = []
        stream_names = set(
            [stream.strip() for stream in options["streams"].split(",")])
        for stream_name in set(stream_names):
            stream, _ = create_stream_if_needed(realm, stream_name)
            streams.append(stream)

        try:
            default_stream_group = DefaultStreamGroup.objects.get(
                name=options["name"],
                realm=realm,
                description=options["description"])
        except DefaultStreamGroup.DoesNotExist:
            default_stream_group = DefaultStreamGroup.objects.create(
                name=options["name"],
                realm=realm,
                description=options["description"])
        default_stream_group.streams = streams
        default_stream_group.save()

        default_stream_groups = DefaultStreamGroup.objects.all()
        for default_stream_group in default_stream_groups:
            print(default_stream_group.name)
            print(default_stream_group.description)
            for stream in default_stream_group.streams.all():
                print(stream.name)
            print("")
Beispiel #19
0
 def subscribe_to_stream(self, email, stream_name, realm=None):
     realm = get_realm(resolve_email_to_domain(email))
     stream = get_stream(stream_name, realm)
     if stream is None:
         stream, _ = create_stream_if_needed(realm, stream_name)
     user_profile = get_user_profile_by_email(email)
     do_add_subscription(user_profile, stream, no_log=True)
Beispiel #20
0
    def handle(self, **options):
        # type: (**Any) -> None
        if (
            options["string_id"] is None
            or options["streams"] is None
            or (options["users"] is None and options["all_users"] is None)
        ):
            self.print_help("./manage.py", "add_users_to_streams")
            exit(1)

        stream_names = set([stream.strip() for stream in options["streams"].split(",")])
        realm = get_realm_by_string_id(options["string_id"])

        if options["all_users"]:
            user_profiles = UserProfile.objects.filter(realm=realm)
        else:
            emails = set([email.strip() for email in options["users"].split(",")])
            user_profiles = []
            for email in emails:
                user_profiles.append(get_user_profile_by_email(email))

        for stream_name in set(stream_names):
            for user_profile in user_profiles:
                stream, _ = create_stream_if_needed(user_profile.realm, stream_name)
                _ignore, already_subscribed = bulk_add_subscriptions([stream], [user_profile])
                was_there_already = user_profile.id in {tup[0].id for tup in already_subscribed}
                print(
                    "%s %s to %s"
                    % ("Already subscribed" if was_there_already else "Subscribed", user_profile.email, stream_name)
                )
Beispiel #21
0
    def test_rename_stream(self):
        realm = get_realm('zulip.com')
        stream, _ = create_stream_if_needed(realm, 'old_name')
        new_name = u'stream with a brand new name'
        self.subscribe_to_stream(self.user_profile.email, stream.name)

        action = lambda: do_rename_stream(realm, stream.name, new_name)
        events = self.do_test(action)

        schema_checker = check_dict([
            ('type', equals('stream')),
            ('op', equals('update')),
            ('property', equals('email_address')),
            ('value', check_string),
            ('name', equals('old_name')),
        ])
        error = schema_checker('events[0]', events[0])
        self.assert_on_error(error)

        schema_checker = check_dict([
            ('type', equals('stream')),
            ('op', equals('update')),
            ('property', equals('name')),
            ('value', equals(new_name)),
            ('name', equals('old_name')),
        ])
        error = schema_checker('events[1]', events[1])
        self.assert_on_error(error)
Beispiel #22
0
 def subscribe(self, user_profile: UserProfile, stream_name: str) -> Stream:
     try:
         stream = get_stream(stream_name, user_profile.realm)
         from_stream_creation = False
     except Stream.DoesNotExist:
         stream, from_stream_creation = create_stream_if_needed(user_profile.realm, stream_name)
     bulk_add_subscriptions([stream], [user_profile], from_stream_creation=from_stream_creation)
     return stream
Beispiel #23
0
 def subscribe(self, user_profile: UserProfile, stream_name: Text) -> Stream:
     try:
         stream = get_stream(stream_name, user_profile.realm)
         from_stream_creation = False
     except Stream.DoesNotExist:
         stream, from_stream_creation = create_stream_if_needed(user_profile.realm, stream_name)
     bulk_add_subscriptions([stream], [user_profile], from_stream_creation=from_stream_creation)
     return stream
Beispiel #24
0
def setup_initial_private_stream(user):
    # type: (UserProfile) -> None
    stream, _ = create_stream_if_needed(
        user.realm,
        "core team",
        invite_only=True,
        stream_description="A private stream for core team members.")
    bulk_add_subscriptions([stream], [user])
Beispiel #25
0
def list_to_streams(streams_raw,
                    user_profile,
                    autocreate=False,
                    invite_only=False):
    # type: (List[str], UserProfile, Optional[bool], Optional[bool]) -> Tuple[List[Stream], List[Stream]]
    """Converts plaintext stream names to a list of Streams, validating input in the process

    For each stream name, we validate it to ensure it meets our
    requirements for a proper stream name: that is, that it is shorter
    than Stream.MAX_NAME_LENGTH characters and passes
    valid_stream_name.

    This function in autocreate mode should be atomic: either an exception will be raised
    during a precheck, or all the streams specified will have been created if applicable.

    @param streams_raw The list of stream names to process
    @param user_profile The user for whom we are retreiving the streams
    @param autocreate Whether we should create streams if they don't already exist
    @param invite_only Whether newly created streams should have the invite_only bit set
    """
    existing_streams = []
    created_streams = []
    # Validate all streams, getting extant ones, then get-or-creating the rest.
    stream_set = set(stream_name.strip() for stream_name in streams_raw)
    rejects = []
    for stream_name in stream_set:
        if len(stream_name) > Stream.MAX_NAME_LENGTH:
            raise JsonableError(
                _("Stream name (%s) too long.") % (stream_name, ))
        if not valid_stream_name(stream_name):
            raise JsonableError(
                _("Invalid stream name (%s).") % (stream_name, ))

    existing_stream_map = bulk_get_streams(user_profile.realm, stream_set)

    for stream_name in stream_set:
        stream = existing_stream_map.get(stream_name.lower())
        if stream is None:
            rejects.append(stream_name)
        else:
            existing_streams.append(stream)
    if rejects:
        if not user_profile.can_create_streams():
            raise JsonableError(_('User cannot create streams.'))
        elif not autocreate:
            raise JsonableError(
                _("Stream(s) (%s) do not exist") % ", ".join(rejects))

        for stream_name in rejects:
            stream, created = create_stream_if_needed(user_profile.realm,
                                                      stream_name,
                                                      invite_only=invite_only)
            if created:
                created_streams.append(stream)
            else:
                existing_streams.append(stream)

    return existing_streams, created_streams
Beispiel #26
0
 def subscribe_to_stream(self, email, stream_name, realm=None):
     # type: (text_type, text_type, Optional[Realm]) -> None
     if realm is None:
         realm = get_realm_by_email_domain(email)
     stream = get_stream(stream_name, realm)
     if stream is None:
         stream, _ = create_stream_if_needed(realm, stream_name)
     user_profile = get_user_profile_by_email(email)
     bulk_add_subscriptions([stream], [user_profile])
Beispiel #27
0
 def subscribe_to_stream(self, email, stream_name, realm=None):
     # type: (text_type, text_type, Optional[Realm]) -> None
     if realm is None:
         realm = get_realm_by_email_domain(email)
     stream = get_stream(stream_name, realm)
     if stream is None:
         stream, _ = create_stream_if_needed(realm, stream_name)
     user_profile = get_user_profile_by_email(email)
     bulk_add_subscriptions([stream], [user_profile])
Beispiel #28
0
def list_to_streams(streams_raw, user_profile, autocreate=False, invite_only=False):
    # type: (Iterable[text_type], UserProfile, Optional[bool], Optional[bool]) -> Tuple[List[Stream], List[Stream]]
    """Converts plaintext stream names to a list of Streams, validating input in the process

    For each stream name, we validate it to ensure it meets our
    requirements for a proper stream name: that is, that it is shorter
    than Stream.MAX_NAME_LENGTH characters and passes
    valid_stream_name.

    This function in autocreate mode should be atomic: either an exception will be raised
    during a precheck, or all the streams specified will have been created if applicable.

    @param streams_raw The list of stream names to process
    @param user_profile The user for whom we are retreiving the streams
    @param autocreate Whether we should create streams if they don't already exist
    @param invite_only Whether newly created streams should have the invite_only bit set
    """
    existing_streams = []
    created_streams = []
    # Validate all streams, getting extant ones, then get-or-creating the rest.
    stream_set = set(stream_name.strip() for stream_name in streams_raw)
    rejects = []
    for stream_name in stream_set:
        if len(stream_name) > Stream.MAX_NAME_LENGTH:
            raise JsonableError(_("Stream name (%s) too long.") % (stream_name,))
        if not valid_stream_name(stream_name):
            raise JsonableError(_("Invalid stream name (%s).") % (stream_name,))

    existing_stream_map = bulk_get_streams(user_profile.realm, stream_set)

    for stream_name in stream_set:
        stream = existing_stream_map.get(stream_name.lower())
        if stream is None:
            rejects.append(stream_name)
        else:
            existing_streams.append(stream)
    if rejects:
        if not user_profile.can_create_streams():
            raise JsonableError(_('User cannot create streams.'))
        elif not autocreate:
            raise JsonableError(_("Stream(s) (%s) do not exist") % ", ".join(rejects))

        for stream_name in rejects:
            stream, created = create_stream_if_needed(user_profile.realm,
                                                      stream_name,
                                                      invite_only=invite_only)
            if created:
                created_streams.append(stream)
            else:
                # We already checked for existing streams above; this
                # next line is present to handle races where a stream
                # was created while this function was executing.
                existing_streams.append(stream)

    return existing_streams, created_streams
Beispiel #29
0
 def subscribe_to_stream(self, email, stream_name, realm=None):
     # type: (Text, Text, Optional[Realm]) -> Stream
     if realm is None:
         realm = get_realm_by_email_domain(email)
     try:
         stream = get_stream(stream_name, realm)
         from_creation = False
     except Stream.DoesNotExist:
         stream, from_creation = create_stream_if_needed(realm, stream_name)
     user_profile = get_user_profile_by_email(email)
     bulk_add_subscriptions([stream], [user_profile], from_creation=from_creation)
     return stream
Beispiel #30
0
 def subscribe_to_stream(self, email, stream_name, realm=None):
     # type: (Text, Text, Optional[Realm]) -> Stream
     if realm is None:
         realm = get_realm_by_email_domain(email)
     try:
         stream = get_stream(stream_name, realm)
         from_creation = False
     except Stream.DoesNotExist:
         stream, from_creation = create_stream_if_needed(realm, stream_name)
     user_profile = get_user_profile_by_email(email)
     bulk_add_subscriptions([stream], [user_profile], from_creation=from_creation)
     return stream
Beispiel #31
0
    def test_slow_queries_worker(self) -> None:
        error_bot = get_system_bot(settings.ERROR_BOT)
        fake_client = self.FakeClient()
        worker = SlowQueryWorker()

        create_stream_if_needed(error_bot.realm, 'errors')

        send_mock = patch(
            'zerver.worker.queue_processors.internal_send_stream_message')

        with send_mock as sm, loopworker_sleep_mock as tm:
            with simulated_queue_client(lambda: fake_client):
                try:
                    worker.setup()
                    # `write_log_line` is where we publish slow queries to the queue.
                    with patch('zerver.middleware.is_slow_query',
                               return_value=True):
                        write_log_line(log_data=dict(test='data'),
                                       email='*****@*****.**',
                                       remote_ip='127.0.0.1',
                                       client_name='website',
                                       path='/test/',
                                       method='GET')
                    worker.start()
                except AbortLoop:
                    pass

        self.assertEqual(tm.call_args[0][0], 60)  # should sleep 60 seconds

        sm.assert_called_once()
        args = [c[0] for c in sm.call_args_list][0]
        self.assertEqual(args[0], error_bot.realm)
        self.assertEqual(args[1].email, error_bot.email)
        self.assertEqual(args[2].name, "errors")
        self.assertEqual(args[3], "testserver: slow queries")
        # Testing for specific query times can lead to test discrepancies.
        logging_info = re.sub(r'\(db: [0-9]+ms/\d+q\)', '', args[4])
        self.assertEqual(
            logging_info, '    127.0.0.1       GET     200 -1000ms '
            ' /test/ ([email protected] via website) ([email protected])\n')
    def handle(self, *args: Any, **options: Any) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        streams = []  # type: List[Stream]
        if options["streams"]:
            stream_names = set([stream.strip() for stream in options["streams"].split(",")])
            for stream_name in set(stream_names):
                stream, _ = create_stream_if_needed(realm, stream_name)
                streams.append(stream)

        referred_by = self.get_user(options['referred_by'], realm)
        invite_link = do_create_multiuse_invite_link(referred_by, streams)
        print("You can use %s to invite as many number of people to the organization." % (invite_link,))
    def handle(self, **options: Any) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        user_profiles = self.get_users(options, realm)
        stream_names = set([stream.strip() for stream in options["streams"].split(",")])

        for stream_name in set(stream_names):
            for user_profile in user_profiles:
                stream, _ = create_stream_if_needed(realm, stream_name)
                _ignore, already_subscribed = bulk_add_subscriptions([stream], [user_profile])
                was_there_already = user_profile.id in {tup[0].id for tup in already_subscribed}
                print("%s %s to %s" % (
                    "Already subscribed" if was_there_already else "Subscribed",
                    user_profile.email, stream_name))
Beispiel #34
0
    def handle(self, **options: Any) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        user_profiles = self.get_users(options, realm)
        stream_names = set([stream.strip() for stream in options["streams"].split(",")])

        for stream_name in set(stream_names):
            for user_profile in user_profiles:
                stream, _ = create_stream_if_needed(realm, stream_name)
                _ignore, already_subscribed = bulk_add_subscriptions([stream], [user_profile])
                was_there_already = user_profile.id in {tup[0].id for tup in already_subscribed}
                print("%s %s to %s" % (
                    "Already subscribed" if was_there_already else "Subscribed",
                    user_profile.email, stream_name))
Beispiel #35
0
    def test_invite_with_non_ascii_streams(self):
        """
        Inviting someone to streams with non-ASCII characters succeeds.
        """
        self.login("*****@*****.**")
        invitee = "*****@*****.**"

        stream_name = u"hümbüǵ"
        realm = get_realm("zulip.com")
        stream, _ = create_stream_if_needed(realm, stream_name)

        # Make sure we're subscribed before inviting someone.
        do_add_subscription(get_user_profile_by_email("*****@*****.**"),
                            stream,
                            no_log=True)

        self.assert_json_success(self.invite(invitee, [stream_name]))
Beispiel #36
0
    def test_invite_with_non_ascii_streams(self):
        """
        Inviting someone to streams with non-ASCII characters succeeds.
        """
        self.login("*****@*****.**")
        invitee = "*****@*****.**"

        stream_name = u"hümbüǵ"
        realm = get_realm("zulip.com")
        stream, _ = create_stream_if_needed(realm, stream_name)

        # Make sure we're subscribed before inviting someone.
        do_add_subscription(
            get_user_profile_by_email("*****@*****.**"),
            stream, no_log=True)

        self.assert_json_success(self.invite(invitee, [stream_name]))
    def handle(self, *args: Any, **options: Any) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        streams = []  # type: List[Stream]
        if options["streams"]:
            stream_names = set(
                [stream.strip() for stream in options["streams"].split(",")])
            for stream_name in set(stream_names):
                stream, _ = create_stream_if_needed(realm, stream_name)
                streams.append(stream)

        referred_by = self.get_user(options['referred_by'], realm)
        invite_link = do_create_multiuse_invite_link(referred_by, streams)
        print(
            "You can use %s to invite as many number of people to the organization."
            % (invite_link, ))
    def handle(self, *args: Any, **options: Any) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        streams = []
        if options["streams"]:
            stream_names = set([stream.strip() for stream in options["streams"].split(",")])

            for stream_name in set(stream_names):
                stream, _ = create_stream_if_needed(realm, stream_name)
                streams.append(stream)

        referred_by = self.get_user(options['referred_by'], realm)
        invite = MultiuseInvite.objects.create(realm=realm, referred_by=referred_by)

        if streams:
            invite.streams = streams
            invite.save()

        invite_link = create_confirmation_link(invite, realm.host, Confirmation.MULTIUSE_INVITE)
        print("You can use %s to invite as many number of people to the organization." % (invite_link,))
Beispiel #39
0
def setup_initial_private_stream(user):
    # type: (UserProfile) -> None
    stream, _ = create_stream_if_needed(user.realm, "core team", invite_only=True,
                                        stream_description="A private stream for core team members.")
    bulk_add_subscriptions([stream], [user])
Beispiel #40
0
    def test_scrub_realm(self) -> None:
        zulip = get_realm("zulip")
        lear = get_realm("lear")

        iago = self.example_user("iago")
        othello = self.example_user("othello")

        cordelia = self.lear_user("cordelia")
        king = self.lear_user("king")

        create_stream_if_needed(lear, "Shakespeare")

        self.subscribe(cordelia, "Shakespeare")
        self.subscribe(king, "Shakespeare")

        Message.objects.all().delete()
        UserMessage.objects.all().delete()

        for i in range(5):
            self.send_stream_message(iago, "Scotland")
            self.send_stream_message(othello, "Scotland")
            self.send_stream_message(cordelia, "Shakespeare")
            self.send_stream_message(king, "Shakespeare")

        Attachment.objects.filter(realm=zulip).delete()
        Attachment.objects.create(realm=zulip,
                                  owner=iago,
                                  path_id="a/b/temp1.txt")
        Attachment.objects.create(realm=zulip,
                                  owner=othello,
                                  path_id="a/b/temp2.txt")

        Attachment.objects.filter(realm=lear).delete()
        Attachment.objects.create(realm=lear,
                                  owner=cordelia,
                                  path_id="c/d/temp1.txt")
        Attachment.objects.create(realm=lear,
                                  owner=king,
                                  path_id="c/d/temp2.txt")

        CustomProfileField.objects.create(realm=lear)

        self.assertEqual(
            Message.objects.filter(sender__in=[iago, othello]).count(), 10)
        self.assertEqual(
            Message.objects.filter(sender__in=[cordelia, king]).count(), 10)
        self.assertEqual(
            UserMessage.objects.filter(
                user_profile__in=[iago, othello]).count(), 20)
        self.assertEqual(
            UserMessage.objects.filter(
                user_profile__in=[cordelia, king]).count(), 20)

        self.assertNotEqual(
            CustomProfileField.objects.filter(realm=zulip).count(), 0)

        with mock.patch('logging.warning'):
            do_scrub_realm(zulip)

        self.assertEqual(
            Message.objects.filter(sender__in=[iago, othello]).count(), 0)
        self.assertEqual(
            Message.objects.filter(sender__in=[cordelia, king]).count(), 10)
        self.assertEqual(
            UserMessage.objects.filter(
                user_profile__in=[iago, othello]).count(), 0)
        self.assertEqual(
            UserMessage.objects.filter(
                user_profile__in=[cordelia, king]).count(), 20)

        self.assertEqual(Attachment.objects.filter(realm=zulip).count(), 0)
        self.assertEqual(Attachment.objects.filter(realm=lear).count(), 2)

        self.assertEqual(
            CustomProfileField.objects.filter(realm=zulip).count(), 0)
        self.assertNotEqual(
            CustomProfileField.objects.filter(realm=lear).count(), 0)

        zulip_users = UserProfile.objects.filter(realm=zulip)
        for user in zulip_users:
            self.assertTrue(re.search("Scrubbed [a-z0-9]{15}", user.full_name))
            self.assertTrue(
                re.search("scrubbed-[a-z0-9]{15}@" + zulip.host, user.email))
            self.assertTrue(
                re.search("scrubbed-[a-z0-9]{15}@" + zulip.host,
                          user.delivery_email))

        lear_users = UserProfile.objects.filter(realm=lear)
        for user in lear_users:
            self.assertIsNone(
                re.search("Scrubbed [a-z0-9]{15}", user.full_name))
            self.assertIsNone(
                re.search("scrubbed-[a-z0-9]{15}@" + zulip.host, user.email))
            self.assertIsNone(
                re.search("scrubbed-[a-z0-9]{15}@" + zulip.host,
                          user.delivery_email))
Beispiel #41
0
 def subscribe_to_stream(self, email, stream_name, realm=None):
     realm = Realm.objects.get(domain=resolve_email_to_domain(email))
     stream, _ = create_stream_if_needed(realm, stream_name)
     user_profile = get_user_profile_by_email(email)
     do_add_subscription(user_profile, stream, no_log=True)
Beispiel #42
0
    def handle(self, *args: Any, **options: str) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        stream_name = options['stream_name']
        create_stream_if_needed(realm, stream_name)
Beispiel #43
0
 def handle(self, *args, **options):
     # type: (*Any, **str) -> None
     realm = self.get_realm(options)
     encoding = sys.getfilesystemencoding()
     stream_name = options['stream_name']
     create_stream_if_needed(realm, force_text(stream_name, encoding))
Beispiel #44
0
    def handle(self, *args: Any, **options: str) -> None:
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        stream_name = options['stream_name']
        create_stream_if_needed(realm, stream_name)
Beispiel #45
0
    def add_message_formatting_conversation(self) -> None:
        realm = get_realm('zulip')
        stream, _ = create_stream_if_needed(realm, 'zulip features')

        UserProfile.objects.filter(email__contains='stage').delete()
        starr = do_create_user('*****@*****.**', 'password', realm, 'Ada Starr', '')
        self.set_avatar(starr, 'static/images/features/starr.png')
        fisher = do_create_user('*****@*****.**', 'password', realm, 'Bel Fisher', '')
        self.set_avatar(fisher, 'static/images/features/fisher.png')
        twitter_bot = do_create_user('*****@*****.**', 'password', realm, 'Twitter Bot', '',
                                     bot_type=UserProfile.DEFAULT_BOT)
        self.set_avatar(twitter_bot, 'static/images/features/twitter.png')

        bulk_add_subscriptions([stream], list(UserProfile.objects.filter(realm=realm)))

        staged_messages = [
            {'sender': starr,
             'content': "Hey @**Bel Fisher**, check out Zulip's Markdown formatting! "
             "You can have:\n* bulleted lists\n  * with sub-bullets too\n"
             "* **bold**, *italic*, and ~~strikethrough~~ text\n"
             "* LaTeX for mathematical formulas, both inline -- $$O(n^2)$$ -- and displayed:\n"
             "```math\n\\int_a^b f(t)\, dt=F(b)-F(a)\n```"},
            {'sender': fisher,
             'content': "My favorite is the syntax highlighting for code blocks\n"
             "```python\ndef fib(n: int) -> int:\n    # returns the n-th Fibonacci number\n"
             "    return fib(n-1) + fib(n-2)\n```"},
            {'sender': starr,
             'content': "I think you forgot your base case there, Bel :laughing:\n"
             "```quote\n```python\ndef fib(n: int) -> int:\n    # returns the n-th Fibonacci number\n"
             "    return fib(n-1) + fib(n-2)\n```\n```"},
            {'sender': fisher,
             'content': "I'm also a big fan of inline link, tweet, video, and image previews. "
             "Check out this picture of Çet Whalin[](/static/images/features/whale.png)!"},
            {'sender': starr,
             'content': "I just set up a custom linkifier, "
                        "so `#1234` becomes [#1234](github.com/zulip/zulip/1234), "
             "a link to the corresponding GitHub issue."},
            {'sender': twitter_bot,
             'content': 'https://twitter.com/gvanrossum/status/786661035637772288'},
            {'sender': fisher,
             'content': "Oops, the Twitter bot I set up shouldn't be posting here. Let me go fix that."},
        ]  # type: List[Dict[str, Any]]

        messages = [internal_prep_stream_message(
            realm, message['sender'], stream.name, 'message formatting', message['content']
        ) for message in staged_messages]

        message_ids = do_send_messages(messages)

        preview_message = Message.objects.get(id__in=message_ids, content__icontains='image previews')
        do_add_reaction_legacy(starr, preview_message, 'whale')

        twitter_message = Message.objects.get(id__in=message_ids, content__icontains='gvanrossum')
        # Setting up a twitter integration in dev is a decent amount of work. If you need
        # to update this tweet, either copy the format below, or send the link to the tweet
        # to chat.zulip.org and ask an admin of that server to get you the rendered_content.
        twitter_message.rendered_content = (
            '<p><a>https://twitter.com/gvanrossum/status/786661035637772288</a></p>\n'
            '<div class="inline-preview-twitter"><div class="twitter-tweet">'
            '<a><img class="twitter-avatar" '
            'src="https://pbs.twimg.com/profile_images/424495004/GuidoAvatar_bigger.jpg"></a>'
            '<p>Great blog post about Zulip\'s use of mypy: '
            '<a>http://blog.zulip.org/2016/10/13/static-types-in-python-oh-mypy/</a></p>'
            '<span>- Guido van Rossum (@gvanrossum)</span></div></div>')
        twitter_message.save(update_fields=['rendered_content'])

        # Put a short pause between the whale reaction and this, so that the
        # thumbs_up shows up second
        do_add_reaction_legacy(starr, preview_message, 'thumbs_up')
Beispiel #46
0
    def add_message_formatting_conversation(self) -> None:
        realm = get_realm('zulip')
        stream, _ = create_stream_if_needed(realm, 'zulip features')

        UserProfile.objects.filter(email__contains='stage').delete()
        starr = do_create_user('*****@*****.**', 'password', realm,
                               'Ada Starr', '')
        self.set_avatar(starr, 'static/images/features/starr.png')
        fisher = do_create_user('*****@*****.**', 'password', realm,
                                'Bel Fisher', '')
        self.set_avatar(fisher, 'static/images/features/fisher.png')
        twitter_bot = do_create_user('*****@*****.**',
                                     'password',
                                     realm,
                                     'Twitter Bot',
                                     '',
                                     bot_type=UserProfile.DEFAULT_BOT)
        self.set_avatar(twitter_bot, 'static/images/features/twitter.png')

        bulk_add_subscriptions([stream],
                               list(UserProfile.objects.filter(realm=realm)))

        staged_messages = [
            {
                'sender':
                starr,
                'content':
                "Hey @**Bel Fisher**, check out Zulip's Markdown formatting! "
                "You can have:\n* bulleted lists\n  * with sub-bullets too\n"
                "* **bold**, *italic*, and ~~strikethrough~~ text\n"
                "* LaTeX for mathematical formulas, both inline -- $$O(n^2)$$ -- and displayed:\n"
                "```math\n\\int_a^b f(t)\, dt=F(b)-F(a)\n```"
            },
            {
                'sender':
                fisher,
                'content':
                "My favorite is the syntax highlighting for code blocks\n"
                "```python\ndef fib(n):\n    # returns the n-th Fibonacci number\n"
                "    return fib(n-1) + fib(n-2)\n```"
            },
            {
                'sender':
                starr,
                'content':
                "I think you forgot your base case there, Bel :laughing:\n"
                "```quote\n```python\ndef fib(n):\n    # returns the n-th Fibonacci number\n"
                "    return fib(n-1) + fib(n-2)\n```\n```"
            },
            {
                'sender':
                fisher,
                'content':
                "I'm also a big fan of inline link, tweet, video, and image previews. "
                "Check out this picture of Çet Whalin[](/static/images/features/whale.png)!"
            },
            {
                'sender':
                starr,
                'content':
                "I just set up a custom linkifier, "
                "so `#1234` becomes [#1234](github.com/zulip/zulip/1234), "
                "a link to the corresponding GitHub issue."
            },
            {
                'sender':
                twitter_bot,
                'content':
                'https://twitter.com/gvanrossum/status/786661035637772288'
            },
            {
                'sender':
                fisher,
                'content':
                "Oops, the Twitter bot I set up shouldn't be posting here. Let me go fix that."
            },
        ]  # type: List[Dict[str, Any]]

        messages = [
            internal_prep_stream_message(realm, message['sender'], stream.name,
                                         'message formatting',
                                         message['content'])
            for message in staged_messages
        ]

        message_ids = do_send_messages(messages)

        preview_message = Message.objects.get(
            id__in=message_ids, content__icontains='image previews')
        do_add_reaction_legacy(starr, preview_message, 'whale')

        twitter_message = Message.objects.get(id__in=message_ids,
                                              content__icontains='gvanrossum')
        # Setting up a twitter integration in dev is a decent amount of work. If you need
        # to update this tweet, either copy the format below, or send the link to the tweet
        # to chat.zulip.org and ask an admin of that server to get you the rendered_content.
        twitter_message.rendered_content = (
            '<p><a>https://twitter.com/gvanrossum/status/786661035637772288</a></p>\n'
            '<div class="inline-preview-twitter"><div class="twitter-tweet">'
            '<a><img class="twitter-avatar" '
            'src="https://pbs.twimg.com/profile_images/424495004/GuidoAvatar_bigger.jpg"></a>'
            '<p>Great blog post about Zulip\'s use of mypy: '
            '<a>http://blog.zulip.org/2016/10/13/static-types-in-python-oh-mypy/</a></p>'
            '<span>- Guido van Rossum (@gvanrossum)</span></div></div>')
        twitter_message.save(update_fields=['rendered_content'])

        # Put a short pause between the whale reaction and this, so that the
        # thumbs_up shows up second
        do_add_reaction_legacy(starr, preview_message, 'thumbs_up')
Beispiel #47
0
 def handle(self, *args, **options):
     # type: (*Any, **str) -> None
     realm = self.get_realm(options)
     encoding = sys.getfilesystemencoding()
     stream_name = options['stream_name']
     create_stream_if_needed(realm, force_text(stream_name, encoding))
Beispiel #48
0
 def subscribe_to_stream(self, email, stream_name, realm=None):
     realm = Realm.objects.get(domain=resolve_email_to_domain(email))
     stream, _ = create_stream_if_needed(realm, stream_name)
     user_profile = get_user_profile_by_email(email)
     do_add_subscription(user_profile, stream, no_log=True)
    def test_export_realm_with_member_consent(self) -> None:
        realm = Realm.objects.get(string_id='zulip')

        # Create private streams and subscribe users for testing export
        create_stream_if_needed(realm, "Private A", invite_only=True)
        self.subscribe(self.example_user("iago"), "Private A")
        self.subscribe(self.example_user("othello"), "Private A")
        self.send_stream_message(self.example_email("iago"), "Private A",
                                 "Hello Stream A")

        create_stream_if_needed(realm, "Private B", invite_only=True)
        self.subscribe(self.example_user("prospero"), "Private B")
        stream_b_message_id = self.send_stream_message(
            self.example_email("prospero"), "Private B", "Hello Stream B")
        self.subscribe(self.example_user("hamlet"), "Private B")

        create_stream_if_needed(realm, "Private C", invite_only=True)
        self.subscribe(self.example_user("othello"), "Private C")
        self.subscribe(self.example_user("prospero"), "Private C")
        stream_c_message_id = self.send_stream_message(
            self.example_email("othello"), "Private C", "Hello Stream C")

        # Create huddles
        self.send_huddle_message(
            self.example_email("iago"),
            [self.example_email("cordelia"),
             self.example_email("AARON")])
        huddle_a = Huddle.objects.last()
        self.send_huddle_message(self.example_email("ZOE"), [
            self.example_email("hamlet"),
            self.example_email("AARON"),
            self.example_email("othello")
        ])
        huddle_b = Huddle.objects.last()

        huddle_c_message_id = self.send_huddle_message(
            self.example_email("AARON"), [
                self.example_email("cordelia"),
                self.example_email("ZOE"),
                self.example_email("othello")
            ])

        # Create PMs
        pm_a_msg_id = self.send_personal_message(self.example_email("AARON"),
                                                 self.example_email("othello"))
        pm_b_msg_id = self.send_personal_message(
            self.example_email("cordelia"), self.example_email("iago"))
        pm_c_msg_id = self.send_personal_message(self.example_email("hamlet"),
                                                 self.example_email("othello"))
        pm_d_msg_id = self.send_personal_message(self.example_email("iago"),
                                                 self.example_email("hamlet"))

        # Send message advertising export and make users react
        self.send_stream_message(self.example_email("othello"),
                                 "Verona",
                                 topic_name="Export",
                                 content="Thumbs up for export")
        message = Message.objects.last()
        consented_user_ids = [
            self.example_user(user).id for user in ["iago", "hamlet"]
        ]
        do_add_reaction(self.example_user("iago"), message, "+1", "1f44d",
                        Reaction.UNICODE_EMOJI)
        do_add_reaction(self.example_user("hamlet"), message, "+1", "1f44d",
                        Reaction.UNICODE_EMOJI)

        realm_emoji = RealmEmoji.objects.get(realm=realm)
        realm_emoji.delete()
        full_data = self._export_realm(realm, consent_message_id=message.id)
        realm_emoji.save()

        data = full_data['realm']

        self.assertEqual(len(data['zerver_userprofile_crossrealm']), 0)
        self.assertEqual(len(data['zerver_userprofile_mirrordummy']), 0)

        exported_user_emails = self.get_set(data['zerver_userprofile'],
                                            'email')
        self.assertIn(self.example_email('cordelia'), exported_user_emails)
        self.assertIn(self.example_email('hamlet'), exported_user_emails)
        self.assertIn(self.example_email('iago'), exported_user_emails)
        self.assertIn(self.example_email('othello'), exported_user_emails)
        self.assertIn('*****@*****.**', exported_user_emails)
        self.assertIn('*****@*****.**', exported_user_emails)

        exported_streams = self.get_set(data['zerver_stream'], 'name')
        self.assertEqual(
            exported_streams,
            set([
                u'Denmark', u'Rome', u'Scotland', u'Venice', u'Verona',
                u'Private A', u'Private B', u'Private C'
            ]))

        data = full_data['message']
        exported_usermessages = UserMessage.objects.filter(user_profile__in=[
            self.example_user("iago"),
            self.example_user("hamlet")
        ])
        um = exported_usermessages[0]
        self.assertEqual(len(data["zerver_usermessage"]),
                         len(exported_usermessages))
        exported_um = self.find_by_id(data['zerver_usermessage'], um.id)
        self.assertEqual(exported_um['message'], um.message_id)
        self.assertEqual(exported_um['user_profile'], um.user_profile_id)

        exported_message = self.find_by_id(data['zerver_message'],
                                           um.message_id)
        self.assertEqual(exported_message['content'], um.message.content)

        public_stream_names = [
            'Denmark', 'Rome', 'Scotland', 'Venice', 'Verona'
        ]
        public_stream_ids = Stream.objects.filter(
            name__in=public_stream_names).values_list("id", flat=True)
        public_stream_recipients = Recipient.objects.filter(
            type_id__in=public_stream_ids, type=Recipient.STREAM)
        public_stream_message_ids = Message.objects.filter(
            recipient__in=public_stream_recipients).values_list("id",
                                                                flat=True)

        # Messages from Private Stream C are not exported since no member gave consent
        private_stream_ids = Stream.objects.filter(
            name__in=["Private A", "Private B"]).values_list("id", flat=True)
        private_stream_recipients = Recipient.objects.filter(
            type_id__in=private_stream_ids, type=Recipient.STREAM)
        private_stream_message_ids = Message.objects.filter(
            recipient__in=private_stream_recipients).values_list("id",
                                                                 flat=True)

        pm_recipients = Recipient.objects.filter(
            type_id__in=consented_user_ids, type=Recipient.PERSONAL)
        pm_query = Q(recipient__in=pm_recipients) | Q(
            sender__in=consented_user_ids)
        exported_pm_ids = Message.objects.filter(pm_query).values_list(
            "id", flat=True).values_list("id", flat=True)

        # Third huddle is not exported since none of the members gave consent
        huddle_recipients = Recipient.objects.filter(
            type_id__in=[huddle_a.id, huddle_b.id], type=Recipient.HUDDLE)
        pm_query = Q(recipient__in=huddle_recipients) | Q(
            sender__in=consented_user_ids)
        exported_huddle_ids = Message.objects.filter(pm_query).values_list(
            "id", flat=True).values_list("id", flat=True)

        exported_msg_ids = set(public_stream_message_ids) | set(private_stream_message_ids) \
            | set(exported_pm_ids) | set(exported_huddle_ids)
        self.assertEqual(self.get_set(data["zerver_message"], "id"),
                         exported_msg_ids)

        # TODO: This behavior is wrong and should be fixed. The message should not be exported
        # since it was sent before the only consented user iago joined the stream.
        self.assertIn(stream_b_message_id, exported_msg_ids)

        self.assertNotIn(stream_c_message_id, exported_msg_ids)
        self.assertNotIn(huddle_c_message_id, exported_msg_ids)

        self.assertNotIn(pm_a_msg_id, exported_msg_ids)
        self.assertIn(pm_b_msg_id, exported_msg_ids)
        self.assertIn(pm_c_msg_id, exported_msg_ids)
        self.assertIn(pm_d_msg_id, exported_msg_ids)
Beispiel #50
0
    def test_scrub_realm(self) -> None:
        zulip = get_realm("zulip")
        lear = get_realm("lear")

        iago = self.example_user("iago")
        othello = self.example_user("othello")

        cordelia = self.lear_user("cordelia")
        king = self.lear_user("king")

        create_stream_if_needed(lear, "Shakespeare")

        self.subscribe(cordelia, "Shakespeare")
        self.subscribe(king, "Shakespeare")

        Message.objects.all().delete()
        UserMessage.objects.all().delete()

        for i in range(5):
            self.send_stream_message(iago.email, "Scotland")
            self.send_stream_message(othello.email, "Scotland")
            self.send_stream_message(cordelia.email, "Shakespeare", sender_realm="lear")
            self.send_stream_message(king.email, "Shakespeare", sender_realm="lear")

        Attachment.objects.filter(realm=zulip).delete()
        Attachment.objects.create(realm=zulip, owner=iago, path_id="a/b/temp1.txt")
        Attachment.objects.create(realm=zulip, owner=othello, path_id="a/b/temp2.txt")

        Attachment.objects.filter(realm=lear).delete()
        Attachment.objects.create(realm=lear, owner=cordelia, path_id="c/d/temp1.txt")
        Attachment.objects.create(realm=lear, owner=king, path_id="c/d/temp2.txt")

        CustomProfileField.objects.create(realm=lear)

        self.assertEqual(Message.objects.filter(sender__in=[iago, othello]).count(), 10)
        self.assertEqual(Message.objects.filter(sender__in=[cordelia, king]).count(), 10)
        self.assertEqual(UserMessage.objects.filter(user_profile__in=[iago, othello]).count(), 20)
        self.assertEqual(UserMessage.objects.filter(user_profile__in=[cordelia, king]).count(), 20)

        self.assertNotEqual(CustomProfileField.objects.filter(realm=zulip).count(), 0)

        with mock.patch('logging.warning'):
            do_scrub_realm(zulip)

        self.assertEqual(Message.objects.filter(sender__in=[iago, othello]).count(), 0)
        self.assertEqual(Message.objects.filter(sender__in=[cordelia, king]).count(), 10)
        self.assertEqual(UserMessage.objects.filter(user_profile__in=[iago, othello]).count(), 0)
        self.assertEqual(UserMessage.objects.filter(user_profile__in=[cordelia, king]).count(), 20)

        self.assertEqual(Attachment.objects.filter(realm=zulip).count(), 0)
        self.assertEqual(Attachment.objects.filter(realm=lear).count(), 2)

        self.assertEqual(CustomProfileField.objects.filter(realm=zulip).count(), 0)
        self.assertNotEqual(CustomProfileField.objects.filter(realm=lear).count(), 0)

        zulip_users = UserProfile.objects.filter(realm=zulip)
        for user in zulip_users:
            self.assertTrue(re.search("Scrubbed [a-z0-9]{15}", user.full_name))
            self.assertTrue(re.search("scrubbed-[a-z0-9]{15}@" + zulip.host, user.email))
            self.assertTrue(re.search("scrubbed-[a-z0-9]{15}@" + zulip.host, user.delivery_email))

        lear_users = UserProfile.objects.filter(realm=lear)
        for user in lear_users:
            self.assertIsNone(re.search("Scrubbed [a-z0-9]{15}", user.full_name))
            self.assertIsNone(re.search("scrubbed-[a-z0-9]{15}@" + zulip.host, user.email))
            self.assertIsNone(re.search("scrubbed-[a-z0-9]{15}@" + zulip.host, user.delivery_email))