Beispiel #1
0
def create_user_backend(request: HttpRequest, user_profile: UserProfile,
                        email: str=REQ(), password: str=REQ(), full_name_raw: str=REQ("full_name"),
                        short_name: str=REQ()) -> HttpResponse:
    full_name = check_full_name(full_name_raw)
    form = CreateUserForm({'full_name': full_name, 'email': email})
    if not form.is_valid():
        return json_error(_('Bad name or username'))

    # Check that the new user's email address belongs to the admin's realm
    # (Since this is an admin API, we don't require the user to have been
    # invited first.)
    realm = user_profile.realm
    try:
        email_allowed_for_realm(email, user_profile.realm)
    except DomainNotAllowedForRealmError:
        return json_error(_("Email '%(email)s' not allowed in this organization") %
                          {'email': email})
    except DisposableEmailError:
        return json_error(_("Disposable email addresses are not allowed in this organization"))
    except EmailContainsPlusError:
        return json_error(_("Email addresses containing + are not allowed."))

    try:
        get_user_by_delivery_email(email, user_profile.realm)
        return json_error(_("Email '%s' already in use") % (email,))
    except UserProfile.DoesNotExist:
        pass

    do_create_user(email, password, realm, full_name, short_name)
    return json_success()
Beispiel #2
0
    def handle(self, **options: Any) -> None:
        realm = self.get_realm(options)
        if realm is None:
            realm = Realm.objects.filter(string_id__startswith='realm') \
                                 .order_by('-string_id').first()
        if realm is None:
            print('Warning: Using default zulip realm, which has an unusual configuration.\n'
                  'Try running `python manage.py add_new_realm`, and then running this again.')
            realm = Realm.objects.get(string_id='zulip')
            domain = 'zulip.com'
        else:
            domain = realm.string_id + '.zulip.com'

        name = '%02d-user' % (UserProfile.objects.filter(email__contains='user@').count(),)
        do_create_user('%s@%s' % (name, domain), 'password', realm, name, name)
Beispiel #3
0
    def get_or_create_user(self, username, ldap_user):
        # type: (str, _LDAPUser) -> Tuple[UserProfile, bool]
        try:
            user_profile = get_user_profile_by_email(username)
            if not user_profile.is_active or user_profile.realm.deactivated:
                raise ZulipLDAPException("Realm has been deactivated")
            if not ldap_auth_enabled(user_profile.realm):
                raise ZulipLDAPException("LDAP Authentication is not enabled")
            return user_profile, False
        except UserProfile.DoesNotExist:
            # No need to check for an inactive user since they don't exist yet
            if self._realm.deactivated:
                raise ZulipLDAPException("Realm has been deactivated")

            full_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["full_name"]
            short_name = full_name = ldap_user.attrs[full_name_attr][0]
            try:
                full_name = check_full_name(full_name)
            except JsonableError as e:
                raise ZulipLDAPException(e.error)
            if "short_name" in settings.AUTH_LDAP_USER_ATTR_MAP:
                short_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["short_name"]
                short_name = ldap_user.attrs[short_name_attr][0]

            user_profile = do_create_user(username, None, self._realm, full_name, short_name)
            return user_profile, True
Beispiel #4
0
def create_user_backend(request, user_profile, email=REQ(), password=REQ(),
                        full_name=REQ(), short_name=REQ()):
    # type: (HttpRequest, UserProfile, text_type, text_type, text_type, text_type) -> HttpResponse
    form = CreateUserForm({'full_name': full_name, 'email': email})
    if not form.is_valid():
        return json_error(_('Bad name or username'))

    # Check that the new user's email address belongs to the admin's realm
    # (Since this is an admin API, we don't require the user to have been
    # invited first.)
    realm = user_profile.realm
    if not email_allowed_for_realm(email, user_profile.realm):
        return json_error(_("Email '%(email)s' does not belong to domain '%(domain)s'") %
                          {'email': email, 'domain': realm.domain})

    try:
        user_profile = get_user_profile_by_email(email)
        return json_error(
            _("Email '%s' already in use") % (email,),
            dict(api_key=user_profile.api_key)
        )
    except UserProfile.DoesNotExist:
        pass

    user_profile = do_create_user(email, password, realm, full_name, short_name)
    return json_success(dict(api_key=user_profile.api_key))
 def setUp(self) -> None:
     self.user_profile = self.example_user("othello")
     self.bot_profile = do_create_user(email="*****@*****.**",
                                       password="******",
                                       realm=get_realm("zulip"),
                                       full_name="FooBot",
                                       short_name="foo-bot",
                                       bot_type=UserProfile.OUTGOING_WEBHOOK_BOT,
                                       bot_owner=self.user_profile)
     self.second_bot_profile = do_create_user(email="*****@*****.**",
                                              password="******",
                                              realm=get_realm("zulip"),
                                              full_name="BarBot",
                                              short_name="bar-bot",
                                              bot_type=UserProfile.OUTGOING_WEBHOOK_BOT,
                                              bot_owner=self.user_profile)
Beispiel #6
0
def add_bot_backend(request, user_profile, full_name=REQ(), short_name=REQ(),
                    default_sending_stream_name=REQ('default_sending_stream', default=None),
                    default_events_register_stream_name=REQ('default_events_register_stream', default=None),
                    default_all_public_streams=REQ(validator=check_bool, default=None)):
    # type: (HttpRequest, UserProfile, text_type, text_type, Optional[text_type], Optional[text_type], Optional[bool]) -> HttpResponse
    short_name += "-bot"
    email = short_name + "@" + user_profile.realm.domain
    form = CreateUserForm({'full_name': full_name, 'email': email})
    if not form.is_valid():
        # We validate client-side as well
        return json_error(_('Bad name or username'))

    try:
        get_user_profile_by_email(email)
        return json_error(_("Username already in use"))
    except UserProfile.DoesNotExist:
        pass

    if len(request.FILES) == 0:
        avatar_source = UserProfile.AVATAR_FROM_GRAVATAR
    elif len(request.FILES) != 1:
        return json_error(_("You may only upload one file at a time"))
    else:
        user_file = list(request.FILES.values())[0]
        upload_avatar_image(user_file, user_profile, email)
        avatar_source = UserProfile.AVATAR_FROM_USER

    default_sending_stream = None
    if default_sending_stream_name is not None:
        default_sending_stream = stream_or_none(default_sending_stream_name, user_profile.realm)
    if default_sending_stream and not default_sending_stream.is_public() and not \
        subscribed_to_stream(user_profile, default_sending_stream):
        return json_error(_('Insufficient permission'))

    default_events_register_stream = None
    if default_events_register_stream_name is not None:
        default_events_register_stream = stream_or_none(default_events_register_stream_name,
                                                        user_profile.realm)
    if default_events_register_stream and not default_events_register_stream.is_public() and not \
        subscribed_to_stream(user_profile, default_events_register_stream):
        return json_error(_('Insufficient permission'))


    bot_profile = do_create_user(email=email, password='',
                                 realm=user_profile.realm, full_name=full_name,
                                 short_name=short_name, active=True,
                                 bot_type=UserProfile.DEFAULT_BOT,
                                 bot_owner=user_profile,
                                 avatar_source=avatar_source,
                                 default_sending_stream=default_sending_stream,
                                 default_events_register_stream=default_events_register_stream,
                                 default_all_public_streams=default_all_public_streams)
    json_result = dict(
            api_key=bot_profile.api_key,
            avatar_url=avatar_url(bot_profile),
            default_sending_stream=get_stream_name(bot_profile.default_sending_stream),
            default_events_register_stream=get_stream_name(bot_profile.default_events_register_stream),
            default_all_public_streams=bot_profile.default_all_public_streams,
    )
    return json_success(json_result)
Beispiel #7
0
    def get_or_build_user(self, username: str, ldap_user: _LDAPUser) -> Tuple[UserProfile, bool]:
        return_data = {}  # type: Dict[str, Any]

        if settings.LDAP_EMAIL_ATTR is not None:
            # Get email from ldap attributes.
            if settings.LDAP_EMAIL_ATTR not in ldap_user.attrs:
                return_data["ldap_missing_attribute"] = settings.LDAP_EMAIL_ATTR
                raise ZulipLDAPException("LDAP user doesn't have the needed %s attribute" % (
                    settings.LDAP_EMAIL_ATTR,))

            username = ldap_user.attrs[settings.LDAP_EMAIL_ATTR][0]

        if 'userAccountControl' in settings.AUTH_LDAP_USER_ATTR_MAP:  # nocoverage
            ldap_disabled = self.is_account_control_disabled_user(ldap_user)
            if ldap_disabled:
                # Treat disabled users as deactivated in Zulip.
                return_data["inactive_user"] = True
                raise ZulipLDAPException("User has been deactivated")

        user_profile = common_get_active_user(username, self._realm, return_data)
        if user_profile is not None:
            # An existing user, successfully authed; return it.
            return user_profile, False

        if return_data.get("inactive_realm"):
            # This happens if there is a user account in a deactivated realm
            raise ZulipLDAPException("Realm has been deactivated")
        if return_data.get("inactive_user"):
            raise ZulipLDAPException("User has been deactivated")
        if return_data.get("invalid_subdomain"):
            # TODO: Implement something in the caller for this to
            # provide a nice user-facing error message for this
            # situation (right now it just acts like any other auth
            # failure).
            raise ZulipLDAPException("Wrong subdomain")
        if self._realm.deactivated:
            # This happens if no account exists, but the realm is
            # deactivated, so we shouldn't create a new user account
            raise ZulipLDAPException("Realm has been deactivated")

        # We have valid LDAP credentials; time to create an account.
        full_name, short_name = self.get_mapped_name(ldap_user)
        try:
            full_name = check_full_name(full_name)
        except JsonableError as e:
            raise ZulipLDAPException(e.msg)

        opts = {}   # type: Dict[str, Any]
        if self._prereg_user:
            invited_as = self._prereg_user.invited_as
            opts['prereg_user'] = self._prereg_user
            opts['is_realm_admin'] = invited_as == PreregistrationUser.INVITE_AS['REALM_ADMIN']
            opts['is_guest'] = invited_as == PreregistrationUser.INVITE_AS['GUEST_USER']
            opts['default_stream_groups'] = get_default_stream_groups(self._realm)

        user_profile = do_create_user(username, None, self._realm, full_name, short_name, **opts)
        self.sync_avatar_from_ldap(user_profile, ldap_user)
        self.sync_custom_profile_fields_from_ldap(user_profile, ldap_user)

        return user_profile, True
 def setUp(self) -> None:
     self.user_profile = self.example_user("othello")
     self.bot_profile = do_create_user(email="*****@*****.**",
                                       password="******",
                                       realm=get_realm("zulip"),
                                       full_name="EmbeddedBo1",
                                       short_name="embedded-bot-1",
                                       bot_type=UserProfile.EMBEDDED_BOT,
                                       bot_owner=self.user_profile)
     self.second_bot_profile = do_create_user(email="*****@*****.**",
                                              password="******",
                                              realm=get_realm("zulip"),
                                              full_name="EmbeddedBot2",
                                              short_name="embedded-bot-2",
                                              bot_type=UserProfile.EMBEDDED_BOT,
                                              bot_owner=self.user_profile)
Beispiel #9
0
    def test_requires_billing_update_for_is_active_changes(self) -> None:
        count = RealmAuditLog.objects.count()
        realm = get_realm("zulip")
        user1 = do_create_user('*****@*****.**', 'password', realm, 'full name', 'short name')
        do_deactivate_user(user1)
        do_reactivate_user(user1)
        # Not a proper use of do_activate_user, but it's fine to call it like this for this test
        do_activate_user(user1)
        self.assertEqual(count + 4,
                         RealmAuditLog.objects.filter(requires_billing_update=False).count())

        realm.has_seat_based_plan = True
        realm.save(update_fields=['has_seat_based_plan'])
        user2 = do_create_user('*****@*****.**', 'password', realm, 'full name', 'short name')
        do_deactivate_user(user2)
        do_reactivate_user(user2)
        do_activate_user(user2)
        self.assertEqual(4, RealmAuditLog.objects.filter(requires_billing_update=True).count())
Beispiel #10
0
def add_bot_backend(request, user_profile, full_name_raw=REQ("full_name"), short_name=REQ(),
                    default_sending_stream_name=REQ('default_sending_stream', default=None),
                    default_events_register_stream_name=REQ('default_events_register_stream', default=None),
                    default_all_public_streams=REQ(validator=check_bool, default=None)):
    # type: (HttpRequest, UserProfile, Text, Text, Optional[Text], Optional[Text], Optional[bool]) -> HttpResponse
    short_name += "-bot"
    full_name = check_full_name(full_name_raw)
    email = '%s@%s' % (short_name, user_profile.realm.get_bot_domain())
    form = CreateUserForm({'full_name': full_name, 'email': email})
    if not form.is_valid():
        # We validate client-side as well
        return json_error(_('Bad name or username'))

    try:
        get_user_profile_by_email(email)
        return json_error(_("Username already in use"))
    except UserProfile.DoesNotExist:
        pass

    if len(request.FILES) == 0:
        avatar_source = UserProfile.AVATAR_FROM_GRAVATAR
    elif len(request.FILES) != 1:
        return json_error(_("You may only upload one file at a time"))
    else:
        avatar_source = UserProfile.AVATAR_FROM_USER

    default_sending_stream = None
    if default_sending_stream_name is not None:
        (default_sending_stream, ignored_rec, ignored_sub) = access_stream_by_name(
            user_profile, default_sending_stream_name)

    default_events_register_stream = None
    if default_events_register_stream_name is not None:
        (default_events_register_stream, ignored_rec, ignored_sub) = access_stream_by_name(
            user_profile, default_events_register_stream_name)

    bot_profile = do_create_user(email=email, password='',
                                 realm=user_profile.realm, full_name=full_name,
                                 short_name=short_name, active=True,
                                 bot_type=UserProfile.DEFAULT_BOT,
                                 bot_owner=user_profile,
                                 avatar_source=avatar_source,
                                 default_sending_stream=default_sending_stream,
                                 default_events_register_stream=default_events_register_stream,
                                 default_all_public_streams=default_all_public_streams)
    if len(request.FILES) == 1:
        user_file = list(request.FILES.values())[0]
        upload_avatar_image(user_file, user_profile, bot_profile)
    json_result = dict(
        api_key=bot_profile.api_key,
        avatar_url=avatar_url(bot_profile),
        default_sending_stream=get_stream_name(bot_profile.default_sending_stream),
        default_events_register_stream=get_stream_name(bot_profile.default_events_register_stream),
        default_all_public_streams=bot_profile.default_all_public_streams,
    )
    return json_success(json_result)
Beispiel #11
0
 def create_test_bot(self, email: Text, user_profile: UserProfile, full_name: Text,
                     short_name: Text, bot_type: int, service_name: str=None) -> UserProfile:
     bot_profile = do_create_user(email=email, password='', realm=user_profile.realm,
                                  full_name=full_name, short_name=short_name,
                                  bot_type=bot_type, bot_owner=user_profile)
     if bot_type in (UserProfile.OUTGOING_WEBHOOK_BOT, UserProfile.EMBEDDED_BOT):
         add_service(name=service_name, user_profile=bot_profile,
                     base_url='', interface=Service.GENERIC,
                     token='abcdef')
     return bot_profile
    def test_get_user(self) -> None:
        mit_realm = get_realm("zephyr")
        user_profile = self.example_user("hamlet")
        email = user_profile.email

        self.assertEqual(self.command.get_user(email, self.zulip_realm), user_profile)
        self.assertEqual(self.command.get_user(email, None), user_profile)

        error_message = "The realm '<Realm: zephyr 2>' does not contain a user with email"
        with self.assertRaisesRegex(CommandError, error_message):
            self.command.get_user(email, mit_realm)

        with self.assertRaisesRegex(CommandError, "server does not contain a user with email"):
            self.command.get_user('*****@*****.**', None)

        do_create_user(email, 'password', mit_realm, 'full_name', 'short_name')

        with self.assertRaisesRegex(CommandError, "server contains multiple users with that email"):
            self.command.get_user(email, None)
    def setUp(self):
        # type: () -> None
        self.user_profile = self.example_user("othello")
        self.bot_profile = do_create_user(email="*****@*****.**",
                                          password="******",
                                          realm=get_realm("zulip"),
                                          full_name="FooBot",
                                          short_name="foo-bot",
                                          bot_type=UserProfile.OUTGOING_WEBHOOK_BOT,
                                          bot_owner=self.user_profile)
        self.second_bot_profile = do_create_user(email="*****@*****.**",
                                                 password="******",
                                                 realm=get_realm("zulip"),
                                                 full_name="BarBot",
                                                 short_name="bar-bot",
                                                 bot_type=UserProfile.OUTGOING_WEBHOOK_BOT,
                                                 bot_owner=self.user_profile)

        # TODO: In future versions this won't be required
        self.subscribe(self.bot_profile, 'Denmark')
Beispiel #14
0
 def create_bot(self, owner: UserProfile, bot_email: str, bot_name: str) -> UserProfile:
     user = do_create_user(
         email=bot_email,
         password='******',
         realm=owner.realm,
         full_name=bot_name,
         short_name=bot_name,
         bot_type=UserProfile.DEFAULT_BOT,
         bot_owner=owner
     )
     return user
Beispiel #15
0
    def handle(self, *args: Any, **options: Any) -> None:
        if not options["tos"]:
            raise CommandError("""You must confirm that this user has accepted the
Terms of Service by passing --this-user-has-accepted-the-tos.""")
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        try:
            email = options['email']
            full_name = options['full_name']
            try:
                validators.validate_email(email)
            except ValidationError:
                raise CommandError("Invalid email address.")
        except KeyError:
            if 'email' in options or 'full_name' in options:
                raise CommandError("""Either specify an email and full name as two
parameters, or specify no parameters for interactive user creation.""")
            else:
                while True:
                    email = input("Email: ")
                    try:
                        validators.validate_email(email)
                        break
                    except ValidationError:
                        print("Invalid email address.", file=sys.stderr)
                full_name = input("Full name: ")

        try:
            if 'password' in options:
                pw = options['password']
            if 'password_file' in options:
                pw = open(options['password_file'], 'r').read()
            else:
                user_initial_password = initial_password(email)
                if user_initial_password is None:
                    raise CommandError("Password is unusable.")
                pw = user_initial_password.encode()
            do_create_user(email, pw, realm, full_name, email_to_username(email))
        except IntegrityError:
            raise CommandError("User already exists.")
Beispiel #16
0
def create_user_backend(request, user_profile, email=REQ, password=REQ,
                        full_name=REQ, short_name=REQ):
    form = CreateUserForm({'full_name': full_name, 'email': email})
    if not form.is_valid():
        return json_error('Bad name or username')

    # Check that the new user's email address belongs to the admin's realm
    # (Since this is an admin API, we don't require the user to have been
    # invited first.)
    realm = user_profile.realm
    if not email_allowed_for_realm(email, user_profile.realm):
        return json_error("Email '%s' does not belong to domain '%s'" % (email, realm.domain))

    try:
        get_user_profile_by_email(email)
        return json_error("Email '%s' already in use" % (email,))
    except UserProfile.DoesNotExist:
        pass

    do_create_user(email, password, realm, full_name, short_name)
    return json_success()
Beispiel #17
0
 def create_bot(self, owner, bot_email, bot_name):
     # type: (UserProfile, Text, Text) -> UserProfile
     user = do_create_user(
         email=bot_email,
         password='******',
         realm=owner.realm,
         full_name=bot_name,
         short_name=bot_name,
         bot_type=UserProfile.DEFAULT_BOT,
         bot_owner=owner
     )
     return user
    def _get_outgoing_bot(self) -> UserProfile:
        outgoing_bot = do_create_user(
            email="*****@*****.**",
            password="******",
            realm=get_realm("zulip"),
            full_name="BarBot",
            short_name='bb',
            bot_type=UserProfile.OUTGOING_WEBHOOK_BOT,
            bot_owner=self.example_user('cordelia'),
        )

        return outgoing_bot
Beispiel #19
0
    def handle(self, **options: Any) -> None:
        string_id = 'realm%02d' % (
            Realm.objects.filter(string_id__startswith='realm').count(),)
        realm = do_create_realm(string_id, string_id)
        setup_initial_streams(realm)

        name = '%02d-user' % (
            UserProfile.objects.filter(email__contains='user@').count(),)
        user = do_create_user('%s@%s.zulip.com' % (name, string_id),
                              'password', realm, name, name, is_realm_admin=True)
        bulk_add_subscriptions([realm.signup_notifications_stream], [user])

        send_initial_realm_messages(realm)
Beispiel #20
0
def create_user_dev(request):
    if request.method != 'POST':
        return json_error("Wrong method")
    json_data = simplejson.loads(request.body)
    email = json_data['email']
    password = json_data['password']
    realm = Realm.objects.get(name='Tijee_test')
    full_name = json_data['full_name']
    short_name = email_to_username(email)
    if (UserProfile.objects.filter(email=email).count()!=0):
        return json_error("The email has been used!") 
    user_profile = do_create_user(email, password, realm, full_name, short_name)
    return json_success({'user_id':user_profile.id, 'user_name':user_profile.full_name, 'user_email':user_profile.email})
Beispiel #21
0
    def handle(self, **options):
        # type: (**Any) -> None
        string_id = 'realm%02d' % (
            Realm.objects.filter(string_id__startswith='realm').count(),)
        realm = do_create_realm(string_id, string_id)
        setup_initial_streams(realm)

        name = '%02d-user' % (
            UserProfile.objects.filter(email__contains='user@').count(),)
        user = do_create_user('%s@%s.zulip.com' % (name, string_id),
                              'password', realm, name, name, is_realm_admin=True)
        setup_initial_private_stream(user)

        send_initial_realm_messages(realm)
Beispiel #22
0
 def test_user_activation(self) -> None:
     realm = get_realm('zulip')
     now = timezone_now()
     user = do_create_user('email', 'password', realm, 'full_name', 'short_name')
     do_deactivate_user(user)
     do_activate_user(user)
     do_deactivate_user(user)
     do_reactivate_user(user)
     self.assertEqual(RealmAuditLog.objects.filter(event_time__gte=now).count(), 5)
     event_types = list(RealmAuditLog.objects.filter(
         realm=realm, acting_user=None, modified_user=user, modified_stream=None,
         event_time__gte=now, event_time__lte=now+timedelta(minutes=60))
         .order_by('event_time').values_list('event_type', flat=True))
     self.assertEqual(event_types, [RealmAuditLog.USER_CREATED, RealmAuditLog.USER_DEACTIVATED, RealmAuditLog.USER_ACTIVATED,
                                    RealmAuditLog.USER_DEACTIVATED, RealmAuditLog.USER_REACTIVATED])
    def test_get_user(self) -> None:
        mit_realm = get_realm("zephyr")
        user_profile = self.example_user("hamlet")
        email = user_profile.delivery_email

        self.assertEqual(self.command.get_user(email, self.zulip_realm),
                         user_profile)
        self.assertEqual(self.command.get_user(email, None), user_profile)

        error_message = "The realm '%s' does not contain a user with email" % (
            mit_realm, )
        with self.assertRaisesRegex(CommandError, error_message):
            self.command.get_user(email, mit_realm)

        with self.assertRaisesRegex(
                CommandError, "server does not contain a user with email"):
            self.command.get_user('*****@*****.**', None)

        do_create_user(email, 'password', mit_realm, 'full_name', 'short_name')

        with self.assertRaisesRegex(
                CommandError,
                "server contains multiple users with that email"):
            self.command.get_user(email, None)
Beispiel #24
0
    def test_gather_new_users(self, mock_django_timezone: mock.MagicMock) -> None:
        cutoff = timezone_now()
        do_create_user('*****@*****.**', password='******', realm=get_realm('zulip'), full_name='abc', short_name='abc')

        # Normal users get info about new users
        user = self.example_user('aaron')
        gathered_no_of_user, _ = gather_new_users(user, cutoff)
        self.assertEqual(gathered_no_of_user, 1)

        # Definitely, admin users get info about new users
        user = self.example_user('iago')
        gathered_no_of_user, _ = gather_new_users(user, cutoff)
        self.assertEqual(gathered_no_of_user, 1)

        # Guest users don't get info about new users
        user = self.example_user('polonius')
        gathered_no_of_user, _ = gather_new_users(user, cutoff)
        self.assertEqual(gathered_no_of_user, 0)

        # Zephyr users also don't get info about new users in their realm
        user = self.mit_user('starnine')
        do_create_user('*****@*****.**', password='******', realm=user.realm, full_name='abc', short_name='abc')
        gathered_no_of_user, _ = gather_new_users(user, cutoff)
        self.assertEqual(gathered_no_of_user, 0)
Beispiel #25
0
    def test_gather_new_users(self, mock_django_timezone: mock.MagicMock) -> None:
        cutoff = timezone_now()
        do_create_user('*****@*****.**', password='******', realm=get_realm('zulip'), full_name='abc', short_name='abc')

        # Normal users get info about new users
        user = self.example_user('aaron')
        gathered_no_of_user, _ = gather_new_users(user, cutoff)
        self.assertEqual(gathered_no_of_user, 1)

        # Definitely, admin users get info about new users
        user = self.example_user('iago')
        gathered_no_of_user, _ = gather_new_users(user, cutoff)
        self.assertEqual(gathered_no_of_user, 1)

        # Guest users don't get info about new users
        user = self.example_user('polonius')
        gathered_no_of_user, _ = gather_new_users(user, cutoff)
        self.assertEqual(gathered_no_of_user, 0)

        # Zephyr users also don't get info about new users in their realm
        user = self.mit_user('starnine')
        do_create_user('*****@*****.**', password='******', realm=user.realm, full_name='abc', short_name='abc')
        gathered_no_of_user, _ = gather_new_users(user, cutoff)
        self.assertEqual(gathered_no_of_user, 0)
Beispiel #26
0
def create_user_backend(request, user_profile, email=REQ(), password=REQ(),
                        full_name_raw=REQ("full_name"), short_name=REQ()):
    # type: (HttpRequest, UserProfile, Text, Text, Text, Text) -> HttpResponse
    full_name = check_full_name(full_name_raw)
    form = CreateUserForm({'full_name': full_name, 'email': email})
    if not form.is_valid():
        return json_error(_('Bad name or username'))

    # Check that the new user's email address belongs to the admin's realm
    # (Since this is an admin API, we don't require the user to have been
    # invited first.)
    realm = user_profile.realm
    if not email_allowed_for_realm(email, user_profile.realm):
        return json_error(_("Email '%(email)s' not allowed for realm '%(realm)s'") %
                          {'email': email, 'realm': realm.string_id})

    try:
        get_user(email, user_profile.realm)
        return json_error(_("Email '%s' already in use") % (email,))
    except UserProfile.DoesNotExist:
        pass

    do_create_user(email, password, realm, full_name, short_name)
    return json_success()
Beispiel #27
0
    def get_or_create_user(self, username, ldap_user):
        try:
            return get_user_profile_by_email(username), False
        except UserProfile.DoesNotExist:
            domain = resolve_email_to_domain(username)
            realm = get_realm(domain)

            full_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["full_name"]
            short_name = full_name = ldap_user.attrs[full_name_attr]
            if "short_name" in settings.AUTH_LDAP_USER_ATTR_MAP:
                short_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["short_name"]
                short_name = ldap_user.attrs[short_name_attr]

            user_profile = do_create_user(username, None, realm, full_name, short_name)
            return user_profile, False
Beispiel #28
0
    def handle(self, **options):
        # type: (**Any) -> None
        string_id = 'realm%02d' % (
            Realm.objects.filter(string_id__startswith='realm').count(),)
        realm = do_create_realm(string_id, string_id)
        setup_initial_streams(realm)

        name = '%02d-user' % (
            UserProfile.objects.filter(email__contains='user@').count(),)
        user = do_create_user('%s@%s.zulip.com' % (name, string_id),
                              'password', realm, name, name, is_realm_admin=True)
        send_initial_pms(user)
        setup_initial_private_stream(user)

        send_initial_realm_messages(realm)
Beispiel #29
0
    def create_non_active_user(self, realm: Realm, email: str, name: str) -> UserProfile:
        user = do_create_user(
            email=email,
            password='******',
            realm=realm,
            full_name=name,
            short_name=name,
        )

        # Doing a full-stack deactivation would be expensive here,
        # and we really only need to flip the flag to get a valid
        # test.
        user.is_active = False
        user.save()
        return user
Beispiel #30
0
def create_user_backend(
    request: HttpRequest,
    user_profile: UserProfile,
    email: str = REQ(),
    password: str = REQ(),
    full_name_raw: str = REQ("full_name"),
    short_name: str = REQ()
) -> HttpResponse:
    full_name = check_full_name(full_name_raw)
    form = CreateUserForm({'full_name': full_name, 'email': email})
    if not form.is_valid():
        return json_error(_('Bad name or username'))

    # Check that the new user's email address belongs to the admin's realm
    # (Since this is an admin API, we don't require the user to have been
    # invited first.)
    realm = user_profile.realm
    try:
        email_allowed_for_realm(email, user_profile.realm)
    except DomainNotAllowedForRealmError:
        return json_error(
            _("Email '%(email)s' not allowed in this organization") %
            {'email': email})
    except DisposableEmailError:
        return json_error(
            _("Disposable email addresses are not allowed in this organization"
              ))

    try:
        get_user(email, user_profile.realm)
        return json_error(_("Email '%s' already in use") % (email, ))
    except UserProfile.DoesNotExist:
        pass

    do_create_user(email, password, realm, full_name, short_name)
    return json_success()
Beispiel #31
0
    def test_requires_billing_update_for_is_active_changes(self) -> None:
        count = RealmAuditLog.objects.count()
        realm = get_realm("zulip")
        user1 = do_create_user('*****@*****.**', 'password', realm,
                               'full name', 'short name')
        do_deactivate_user(user1)
        do_reactivate_user(user1)
        # Not a proper use of do_activate_user, but it's fine to call it like this for this test
        do_activate_user(user1)
        self.assertEqual(
            count + 4,
            RealmAuditLog.objects.filter(
                requires_billing_update=False).count())

        realm.has_seat_based_plan = True
        realm.save(update_fields=['has_seat_based_plan'])
        user2 = do_create_user('*****@*****.**', 'password', realm,
                               'full name', 'short name')
        do_deactivate_user(user2)
        do_reactivate_user(user2)
        do_activate_user(user2)
        self.assertEqual(
            4,
            RealmAuditLog.objects.filter(requires_billing_update=True).count())
Beispiel #32
0
def create_user_backend(request, user_profile, email=REQ(), password=REQ(),
                        full_name_raw=REQ("full_name"), short_name=REQ()):
    # type: (HttpRequest, UserProfile, Text, Text, Text, Text) -> HttpResponse
    full_name = check_full_name(full_name_raw)
    form = CreateUserForm({'full_name': full_name, 'email': email})
    if not form.is_valid():
        return json_error(_('Bad name or username'))

    # Check that the new user's email address belongs to the admin's realm
    # (Since this is an admin API, we don't require the user to have been
    # invited first.)
    realm = user_profile.realm
    if not email_allowed_for_realm(email, user_profile.realm):
        return json_error(_("Email '%(email)s' not allowed for realm '%(realm)s'") %
                          {'email': email, 'realm': realm.string_id})

    try:
        get_user_profile_by_email(email)
        return json_error(_("Email '%s' already in use") % (email,))
    except UserProfile.DoesNotExist:
        pass

    do_create_user(email, password, realm, full_name, short_name)
    return json_success()
Beispiel #33
0
 def test_user_activation(self) -> None:
     realm = get_realm('zulip')
     now = timezone_now()
     user = do_create_user('email', 'password', realm, 'full_name', 'short_name')
     do_deactivate_user(user)
     do_activate_user(user)
     do_deactivate_user(user)
     do_reactivate_user(user)
     self.assertEqual(RealmAuditLog.objects.filter(event_time__gte=now).count(), 5)
     event_types = list(RealmAuditLog.objects.filter(
         realm=realm, acting_user=None, modified_user=user, modified_stream=None,
         event_time__gte=now, event_time__lte=now+timedelta(minutes=60))
         .order_by('event_time').values_list('event_type', flat=True))
     self.assertEqual(event_types, [RealmAuditLog.USER_CREATED, RealmAuditLog.USER_DEACTIVATED, RealmAuditLog.USER_ACTIVATED,
                                    RealmAuditLog.USER_DEACTIVATED, RealmAuditLog.USER_REACTIVATED])
Beispiel #34
0
    def create_non_active_user(self, realm: Realm, email: str, name: str) -> UserProfile:
        user = do_create_user(
            email=email,
            password='******',
            realm=realm,
            full_name=name,
            short_name=name,
        )

        # Doing a full-stack deactivation would be expensive here,
        # and we really only need to flip the flag to get a valid
        # test.
        user.is_active = False
        user.save()
        return user
Beispiel #35
0
def deactivate_own_user() -> Dict[str, object]:
    test_user_email = "*****@*****.**"
    deactivate_test_user = do_create_user(
        test_user_email,
        "secret",
        get_realm("zulip"),
        "Mr. Delete",
        role=200,
        acting_user=None,
    )
    realm = get_realm("zulip")
    test_user = get_user(test_user_email, realm)
    test_user_api_key = get_api_key(test_user)
    # change authentication line to allow test_client to delete itself.
    AUTHENTICATION_LINE[0] = f"{deactivate_test_user.email}:{test_user_api_key}"
    return {}
Beispiel #36
0
    def test_check_admin_different_realm_emoji(self) -> None:
        # Test that two different realm emojis in two different realms but
        # having same name can be administered independently.
        realm_1 = do_create_realm("test_realm", "test_realm")
        emoji_author_1 = do_create_user("*****@*****.**",
                                        password="******",
                                        realm=realm_1,
                                        full_name="abc",
                                        acting_user=None)
        self.create_test_emoji("test_emoji", emoji_author_1)

        emoji_author_2 = self.example_user("othello")
        self.create_test_emoji("test_emoji", emoji_author_2)
        self.login_user(emoji_author_2)
        result = self.client_delete("/json/realm/emoji/test_emoji")
        self.assert_json_success(result)
Beispiel #37
0
    def handle(self, **options: Any) -> None:
        string_id = 'realm{:02}'.format(
            Realm.objects.filter(string_id__startswith='realm').count())
        realm = do_create_realm(string_id, string_id)

        name = '{:02}-user'.format(
            UserProfile.objects.filter(email__contains='user@').count())
        user = do_create_user(f'{name}@{string_id}.zulip.com',
                              'password',
                              realm,
                              name,
                              name,
                              role=UserProfile.ROLE_REALM_ADMINISTRATOR)
        bulk_add_subscriptions([realm.signup_notifications_stream], [user])

        send_initial_realm_messages(realm)
    def handle(self, **options: Any) -> None:
        string_id = 'realm%02d' % (Realm.objects.filter(
            string_id__startswith='realm').count(), )
        realm = do_create_realm(string_id, string_id)

        name = '%02d-user' % (UserProfile.objects.filter(
            email__contains='user@').count(), )
        user = do_create_user('%s@%s.zulip.com' % (name, string_id),
                              'password',
                              realm,
                              name,
                              name,
                              is_realm_admin=True)
        bulk_add_subscriptions([realm.signup_notifications_stream], [user])

        send_initial_realm_messages(realm)
    def test_check_admin_different_realm_emoji(self) -> None:
        # Test that two different realm emojis in two different realms but
        # having same name can be administered independently.
        realm_1 = do_create_realm('test_realm', 'test_realm')
        emoji_author_1 = do_create_user('*****@*****.**',
                                        password='******',
                                        realm=realm_1,
                                        full_name='abc',
                                        short_name='abc')
        self.create_test_emoji('test_emoji', emoji_author_1)

        emoji_author_2 = self.example_user('othello')
        self.create_test_emoji('test_emoji', emoji_author_2)
        self.login(emoji_author_2.email)
        result = self.client_delete('/json/realm/emoji/test_emoji')
        self.assert_json_success(result)
Beispiel #40
0
def create_user_backend(
        request: HttpRequest,
        user_profile: UserProfile,
        email: str = REQ(),
        password: str = REQ(),
        full_name_raw: str = REQ("full_name"),
) -> HttpResponse:
    if not user_profile.can_create_users:
        raise JsonableError(_("User not authorized for this query"))

    full_name = check_full_name(full_name_raw)
    form = CreateUserForm({"full_name": full_name, "email": email})
    if not form.is_valid():
        raise JsonableError(_("Bad name or username"))

    # Check that the new user's email address belongs to the admin's realm
    # (Since this is an admin API, we don't require the user to have been
    # invited first.)
    realm = user_profile.realm
    try:
        email_allowed_for_realm(email, user_profile.realm)
    except DomainNotAllowedForRealmError:
        raise JsonableError(
            _("Email '{email}' not allowed in this organization").format(
                email=email, ))
    except DisposableEmailError:
        raise JsonableError(
            _("Disposable email addresses are not allowed in this organization"
              ))
    except EmailContainsPlusError:
        raise JsonableError(_("Email addresses containing + are not allowed."))

    try:
        get_user_by_delivery_email(email, user_profile.realm)
        raise JsonableError(_("Email '{}' already in use").format(email))
    except UserProfile.DoesNotExist:
        pass

    if not check_password_strength(password):
        raise JsonableError(PASSWORD_TOO_WEAK_ERROR)

    target_user = do_create_user(email,
                                 password,
                                 realm,
                                 full_name,
                                 acting_user=user_profile)
    return json_success({"user_id": target_user.id})
Beispiel #41
0
    def get_or_build_user(self, username: str, ldap_user: _LDAPUser) -> Tuple[UserProfile, bool]:
        return_data = {}  # type: Dict[str, Any]

        if settings.LDAP_EMAIL_ATTR is not None:
            # Get email from ldap attributes.
            if settings.LDAP_EMAIL_ATTR not in ldap_user.attrs:
                return_data["ldap_missing_attribute"] = settings.LDAP_EMAIL_ATTR
                raise ZulipLDAPException("LDAP user doesn't have the needed %s attribute" % (
                    settings.LDAP_EMAIL_ATTR,))

            username = ldap_user.attrs[settings.LDAP_EMAIL_ATTR][0]

        user_profile = common_get_active_user(username, self._realm, return_data)
        if user_profile is not None:
            # An existing user, successfully authed; return it.
            return user_profile, False

        if return_data.get("inactive_realm"):
            # This happens if there is a user account in a deactivated realm
            raise ZulipLDAPException("Realm has been deactivated")
        if return_data.get("inactive_user"):
            raise ZulipLDAPException("User has been deactivated")
        if return_data.get("invalid_subdomain"):
            # TODO: Implement something in the caller for this to
            # provide a nice user-facing error message for this
            # situation (right now it just acts like any other auth
            # failure).
            raise ZulipLDAPException("Wrong subdomain")
        if self._realm.deactivated:
            # This happens if no account exists, but the realm is
            # deactivated, so we shouldn't create a new user account
            raise ZulipLDAPException("Realm has been deactivated")

        # We have valid LDAP credentials; time to create an account.
        full_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["full_name"]
        short_name = full_name = ldap_user.attrs[full_name_attr][0]
        try:
            full_name = check_full_name(full_name)
        except JsonableError as e:
            raise ZulipLDAPException(e.msg)
        if "short_name" in settings.AUTH_LDAP_USER_ATTR_MAP:
            short_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["short_name"]
            short_name = ldap_user.attrs[short_name_attr][0]

        user_profile = do_create_user(username, None, self._realm, full_name, short_name)

        return user_profile, True
Beispiel #42
0
    def get_or_build_user(self, username: str, ldap_user: _LDAPUser) -> Tuple[UserProfile, bool]:
        return_data = {}  # type: Dict[str, Any]

        if settings.LDAP_EMAIL_ATTR is not None:
            # Get email from ldap attributes.
            if settings.LDAP_EMAIL_ATTR not in ldap_user.attrs:
                return_data["ldap_missing_attribute"] = settings.LDAP_EMAIL_ATTR
                raise ZulipLDAPException("LDAP user doesn't have the needed %s attribute" % (
                    settings.LDAP_EMAIL_ATTR,))

            username = ldap_user.attrs[settings.LDAP_EMAIL_ATTR][0]

        user_profile = common_get_active_user(username, self._realm, return_data)
        if user_profile is not None:
            # An existing user, successfully authed; return it.
            return user_profile, False

        if return_data.get("inactive_realm"):
            # This happens if there is a user account in a deactivated realm
            raise ZulipLDAPException("Realm has been deactivated")
        if return_data.get("inactive_user"):
            raise ZulipLDAPException("User has been deactivated")
        if return_data.get("invalid_subdomain"):
            # TODO: Implement something in the caller for this to
            # provide a nice user-facing error message for this
            # situation (right now it just acts like any other auth
            # failure).
            raise ZulipLDAPException("Wrong subdomain")
        if self._realm.deactivated:
            # This happens if no account exists, but the realm is
            # deactivated, so we shouldn't create a new user account
            raise ZulipLDAPException("Realm has been deactivated")

        # We have valid LDAP credentials; time to create an account.
        full_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["full_name"]
        short_name = full_name = ldap_user.attrs[full_name_attr][0]
        try:
            full_name = check_full_name(full_name)
        except JsonableError as e:
            raise ZulipLDAPException(e.msg)
        if "short_name" in settings.AUTH_LDAP_USER_ATTR_MAP:
            short_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["short_name"]
            short_name = ldap_user.attrs[short_name_attr][0]

        user_profile = do_create_user(username, None, self._realm, full_name, short_name)

        return user_profile, True
Beispiel #43
0
    def get_or_create_user(self, username, ldap_user):
        try:
            return get_user_profile_by_email(username), False
        except UserProfile.DoesNotExist:
            domain = resolve_email_to_domain(username)
            realm = get_realm(domain)

            full_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["full_name"]
            short_name = full_name = ldap_user.attrs[full_name_attr][0]
            if "short_name" in settings.AUTH_LDAP_USER_ATTR_MAP:
                short_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP[
                    "short_name"]
                short_name = ldap_user.attrs[short_name_attr][0]

            user_profile = do_create_user(username, None, realm, full_name,
                                          short_name)
            return user_profile, False
Beispiel #44
0
    def handle(self, *args: Any, **options: Any) -> None:
        if not options["tos"]:
            raise CommandError(
                """You must confirm that this user has accepted the
Terms of Service by passing --this-user-has-accepted-the-tos.""")
        realm = self.get_realm(options)
        assert realm is not None  # Should be ensured by parser

        try:
            email = options['email']
            full_name = options['full_name']
            try:
                validators.validate_email(email)
            except ValidationError:
                raise CommandError("Invalid email address.")
        except KeyError:
            if 'email' in options or 'full_name' in options:
                raise CommandError(
                    """Either specify an email and full name as two
parameters, or specify no parameters for interactive user creation.""")
            else:
                while True:
                    email = input("Email: ")
                    try:
                        validators.validate_email(email)
                        break
                    except ValidationError:
                        print("Invalid email address.", file=sys.stderr)
                full_name = input("Full name: ")

        try:
            if 'password' in options:
                pw = options['password']
            if 'password_file' in options:
                pw = open(options['password_file'], 'r').read()
            else:
                user_initial_password = initial_password(email)
                if user_initial_password is None:
                    raise CommandError("Password is unusable.")
                pw = user_initial_password.encode()
            notify_new_user(do_create_user(email, pw, realm, full_name,
                                           email_to_username(email)),
                            internal=True)
        except IntegrityError:
            raise CommandError("User already exists.")
Beispiel #45
0
    def handle(self, *args, **options):
        # type: (*Any, **Any) -> None
        if not options["tos"]:
            raise CommandError(
                """You must confirm that this user has accepted the
Terms of Service by passing --this-user-has-accepted-the-tos.""")

        if not options["string_id"]:
            raise CommandError(
                """Please specify a realm by passing --realm.""")

        try:
            realm = get_realm(options["string_id"])
        except Realm.DoesNotExist:
            raise CommandError("Realm does not exist.")

        try:
            email = options['email']
            full_name = options['full_name']
            try:
                validators.validate_email(email)
            except ValidationError:
                raise CommandError("Invalid email address.")
        except KeyError:
            if 'email' in options or 'full_name' in options:
                raise CommandError(
                    """Either specify an email and full name as two
parameters, or specify no parameters for interactive user creation.""")
            else:
                while True:
                    email = input("Email: ")
                    try:
                        validators.validate_email(email)
                        break
                    except ValidationError:
                        print("Invalid email address.", file=sys.stderr)
                full_name = input("Full name: ")

        try:
            pw = options.get('password', initial_password(email))
            notify_new_user(do_create_user(email, pw, realm, full_name,
                                           email_to_username(email)),
                            internal=True)
        except IntegrityError:
            raise CommandError("User already exists.")
Beispiel #46
0
    def test_no_email_digest_for_bots(self, mock_django_timezone: mock.MagicMock,
                                      mock_queue_digest_recipient: mock.MagicMock) -> None:
        cutoff = timezone_now()
        # A Tuesday
        mock_django_timezone.return_value = datetime.datetime(year=2016, month=1, day=5)
        bot = do_create_user('*****@*****.**', 'password', get_realm('zulip'), 'some_bot', '',
                             bot_type=UserProfile.DEFAULT_BOT)
        UserActivity.objects.create(
            last_visit=cutoff - datetime.timedelta(days=1),
            user_profile=bot,
            count=0,
            client=get_client('test_client'))

        # Check that bots are not sent emails
        enqueue_emails(cutoff)
        for arg in mock_queue_digest_recipient.call_args_list:
            user = arg[0][0]
            self.assertNotEqual(user.id, bot.id)
Beispiel #47
0
 def test_active_users_log_by_is_bot(self):
     # type: () -> None
     property = 'active_users_log:is_bot:day'
     user = do_create_user('email', 'password', self.default_realm, 'full_name', 'short_name')
     self.assertEqual(1, RealmCount.objects.filter(property=property, subgroup=False)
                      .aggregate(Sum('value'))['value__sum'])
     do_deactivate_user(user)
     self.assertEqual(0, RealmCount.objects.filter(property=property, subgroup=False)
                      .aggregate(Sum('value'))['value__sum'])
     do_activate_user(user)
     self.assertEqual(1, RealmCount.objects.filter(property=property, subgroup=False)
                      .aggregate(Sum('value'))['value__sum'])
     do_deactivate_user(user)
     self.assertEqual(0, RealmCount.objects.filter(property=property, subgroup=False)
                      .aggregate(Sum('value'))['value__sum'])
     do_reactivate_user(user)
     self.assertEqual(1, RealmCount.objects.filter(property=property, subgroup=False)
                      .aggregate(Sum('value'))['value__sum'])
Beispiel #48
0
    def handle(self, **options):
        # type: (**Any) -> None
        realm = self.get_realm(options)
        if realm is None:
            realm = Realm.objects.filter(string_id__startswith='realm') \
                                 .order_by('-string_id').first()
        if realm is None:
            print('Warning: Using default zulip realm, which has an unusual configuration.\n'
                  'Try running `python manage.py add_new_realm`, and then running this again.')
            realm = Realm.objects.get(string_id='zulip')
            domain = 'zulip.com'
        else:
            domain = realm.string_id + '.zulip.com'

        name = '%02d-user' % (UserProfile.objects.filter(email__contains='user@').count(),)
        user = do_create_user('%s@%s' % (name, domain),
                              'password', realm, name, name)
        send_initial_pms(user)
Beispiel #49
0
 def test_active_users_log_by_is_bot(self):
     # type: () -> None
     property = 'active_users_log:is_bot:day'
     user = do_create_user('email', 'password', self.default_realm, 'full_name', 'short_name')
     self.assertEqual(1, RealmCount.objects.filter(property=property, subgroup=False)
                      .aggregate(Sum('value'))['value__sum'])
     do_deactivate_user(user)
     self.assertEqual(0, RealmCount.objects.filter(property=property, subgroup=False)
                      .aggregate(Sum('value'))['value__sum'])
     do_activate_user(user)
     self.assertEqual(1, RealmCount.objects.filter(property=property, subgroup=False)
                      .aggregate(Sum('value'))['value__sum'])
     do_deactivate_user(user)
     self.assertEqual(0, RealmCount.objects.filter(property=property, subgroup=False)
                      .aggregate(Sum('value'))['value__sum'])
     do_reactivate_user(user)
     self.assertEqual(1, RealmCount.objects.filter(property=property, subgroup=False)
                      .aggregate(Sum('value'))['value__sum'])
Beispiel #50
0
    def test_no_email_digest_for_bots(self, mock_django_timezone: mock.MagicMock,
                                      mock_queue_digest_recipient: mock.MagicMock) -> None:
        cutoff = timezone_now()
        # A Tuesday
        mock_django_timezone.return_value = datetime.datetime(year=2016, month=1, day=5)
        bot = do_create_user('*****@*****.**', 'password', get_realm('zulip'), 'some_bot', '',
                             bot_type=UserProfile.DEFAULT_BOT)
        UserActivity.objects.create(
            last_visit=cutoff - datetime.timedelta(days=1),
            user_profile=bot,
            count=0,
            client=get_client('test_client'))

        # Check that bots are not sent emails
        enqueue_emails(cutoff)
        for arg in mock_queue_digest_recipient.call_args_list:
            user = arg[0][0]
            self.assertNotEqual(user.id, bot.id)
Beispiel #51
0
    def test_billing_quantity_changes_end_to_end(
            self, mock_customer_with_subscription: Mock, mock_create_subscription: Mock,
            mock_create_customer: Mock) -> None:
        self.login(self.example_email("hamlet"))
        processor = BillingProcessor.objects.create(
            log_row=RealmAuditLog.objects.order_by('id').first(), state=BillingProcessor.DONE)

        def check_billing_processor_update(event_type: str, quantity: int) -> None:
            def check_subscription_save(subscription: stripe.Subscription, idempotency_key: str) -> None:
                self.assertEqual(subscription.quantity, quantity)
                log_row = RealmAuditLog.objects.filter(
                    event_type=event_type, requires_billing_update=True).order_by('-id').first()
                self.assertEqual(idempotency_key, 'process_billing_log_entry:%s' % (log_row.id,))
                self.assertEqual(subscription.proration_date, datetime_to_timestamp(log_row.event_time))
            with patch.object(stripe.Subscription, 'save', autospec=True,
                              side_effect=check_subscription_save):
                run_billing_processor_one_step(processor)

        # Test STRIPE_PLAN_QUANTITY_RESET
        new_seat_count = 123
        # change the seat count while the user is going through the upgrade flow
        with patch('corporate.lib.stripe.get_seat_count', return_value=new_seat_count):
            self.client_post("/upgrade/", {'stripeToken': self.token,
                                           'signed_seat_count': self.signed_seat_count,
                                           'salt': self.salt,
                                           'plan': Plan.CLOUD_ANNUAL})
        check_billing_processor_update(RealmAuditLog.STRIPE_PLAN_QUANTITY_RESET, new_seat_count)

        # Test USER_CREATED
        user = do_create_user('*****@*****.**', 'password', get_realm('zulip'), 'full name', 'short name')
        check_billing_processor_update(RealmAuditLog.USER_CREATED, self.quantity + 1)

        # Test USER_DEACTIVATED
        do_deactivate_user(user)
        check_billing_processor_update(RealmAuditLog.USER_DEACTIVATED, self.quantity - 1)

        # Test USER_REACTIVATED
        do_reactivate_user(user)
        check_billing_processor_update(RealmAuditLog.USER_REACTIVATED, self.quantity + 1)

        # Test USER_ACTIVATED
        # Not a proper use of do_activate_user, but it's fine to call it like this for this test
        do_activate_user(user)
        check_billing_processor_update(RealmAuditLog.USER_ACTIVATED, self.quantity + 1)
Beispiel #52
0
 def test_user_activation(self) -> None:
     realm = get_realm("zulip")
     now = timezone_now()
     user = do_create_user("email",
                           "password",
                           realm,
                           "full_name",
                           acting_user=None)
     do_deactivate_user(user, acting_user=user)
     do_activate_user(user, acting_user=user)
     do_deactivate_user(user, acting_user=user)
     do_reactivate_user(user, acting_user=user)
     self.assertEqual(
         RealmAuditLog.objects.filter(event_time__gte=now).count(), 5)
     event_types = list(
         RealmAuditLog.objects.filter(
             realm=realm,
             acting_user=user,
             modified_user=user,
             modified_stream=None,
             event_time__gte=now,
             event_time__lte=now + timedelta(minutes=60),
         ).order_by("event_time").values_list("event_type", flat=True))
     self.assertEqual(
         event_types,
         [
             RealmAuditLog.USER_CREATED,
             RealmAuditLog.USER_DEACTIVATED,
             RealmAuditLog.USER_ACTIVATED,
             RealmAuditLog.USER_DEACTIVATED,
             RealmAuditLog.USER_REACTIVATED,
         ],
     )
     for event in RealmAuditLog.objects.filter(
             realm=realm,
             acting_user=user,
             modified_user=user,
             modified_stream=None,
             event_time__gte=now,
             event_time__lte=now + timedelta(minutes=60),
     ):
         extra_data = orjson.loads(event.extra_data)
         self.check_role_count_schema(extra_data[RealmAuditLog.ROLE_COUNT])
         self.assertNotIn(RealmAuditLog.OLD_VALUE, extra_data)
Beispiel #53
0
    def handle(self, **options: Any) -> None:
        string_id = "realm{:02}".format(
            Realm.objects.filter(string_id__startswith="realm").count())
        realm = do_create_realm(string_id, string_id)

        name = "{:02}-user".format(
            UserProfile.objects.filter(email__contains="user@").count())
        user = do_create_user(
            f"{name}@{string_id}.zulip.com",
            "password",
            realm,
            name,
            role=UserProfile.ROLE_REALM_ADMINISTRATOR,
            acting_user=None,
        )
        assert realm.signup_notifications_stream is not None
        bulk_add_subscriptions(realm, [realm.signup_notifications_stream],
                               [user])

        send_initial_realm_messages(realm)
Beispiel #54
0
    def get_or_create_user(self, username, ldap_user):
        # type: (str, _LDAPUser) -> Tuple[UserProfile, bool]
        try:
            if settings.LDAP_EMAIL_ATTR is not None:
                # Get email from ldap attributes.
                if settings.LDAP_EMAIL_ATTR not in ldap_user.attrs:
                    raise ZulipLDAPException(
                        "LDAP user doesn't have the needed %s attribute" %
                        (settings.LDAP_EMAIL_ATTR, ))

                username = ldap_user.attrs[settings.LDAP_EMAIL_ATTR][0]

            user_profile = get_user_profile_by_email(username)
            if not user_profile.is_active or user_profile.realm.deactivated:
                raise ZulipLDAPException("Realm has been deactivated")
            if not ldap_auth_enabled(user_profile.realm):
                raise ZulipLDAPException("LDAP Authentication is not enabled")
            return user_profile, False
        except UserProfile.DoesNotExist:
            if self._realm is None:
                raise ZulipLDAPConfigurationError("Realm is None",
                                                  self.REALM_IS_NONE_ERROR)
            # No need to check for an inactive user since they don't exist yet
            if self._realm.deactivated:
                raise ZulipLDAPException("Realm has been deactivated")

            full_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["full_name"]
            short_name = full_name = ldap_user.attrs[full_name_attr][0]
            try:
                full_name = check_full_name(full_name)
            except JsonableError as e:
                raise ZulipLDAPException(e.msg)
            if "short_name" in settings.AUTH_LDAP_USER_ATTR_MAP:
                short_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP[
                    "short_name"]
                short_name = ldap_user.attrs[short_name_attr][0]

            user_profile = do_create_user(username, None, self._realm,
                                          full_name, short_name)

            return user_profile, True
Beispiel #55
0
    def get_or_create_user(self, username, ldap_user):
        try:
            user_profile = get_user_profile_by_email(username)
            if not user_profile.is_active or user_profile.realm.deactivated:
                raise ZulipLDAPException("Realm has been deactivated")
            return user_profile, False
        except UserProfile.DoesNotExist:
            domain = resolve_email_to_domain(username)
            realm = get_realm(domain)
            # No need to check for an inactive user since they don't exist yet
            if realm.deactivated:
                raise ZulipLDAPException("Realm has been deactivated")

            full_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["full_name"]
            short_name = full_name = ldap_user.attrs[full_name_attr][0]
            if "short_name" in settings.AUTH_LDAP_USER_ATTR_MAP:
                short_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["short_name"]
                short_name = ldap_user.attrs[short_name_attr][0]

            user_profile = do_create_user(username, None, realm, full_name, short_name)
            return user_profile, False
Beispiel #56
0
 def create_test_bot(self,
                     email: Text,
                     user_profile: UserProfile,
                     full_name: Text,
                     short_name: Text,
                     bot_type: int,
                     service_name: str = None) -> UserProfile:
     bot_profile = do_create_user(email=email,
                                  password='',
                                  realm=user_profile.realm,
                                  full_name=full_name,
                                  short_name=short_name,
                                  bot_type=bot_type,
                                  bot_owner=user_profile)
     if bot_type in (UserProfile.OUTGOING_WEBHOOK_BOT,
                     UserProfile.EMBEDDED_BOT):
         add_service(name=service_name,
                     user_profile=bot_profile,
                     base_url='',
                     interface=Service.GENERIC,
                     token='abcdef')
     return bot_profile
Beispiel #57
0
    def get_or_create_user(self, username, ldap_user):
        # type: (str, _LDAPUser) -> Tuple[UserProfile, bool]
        try:
            user_profile = get_user_profile_by_email(username)
            if not user_profile.is_active or user_profile.realm.deactivated:
                raise ZulipLDAPException("Realm has been deactivated")
            if not ldap_auth_enabled(user_profile.realm):
                raise ZulipLDAPException("LDAP Authentication is not enabled")
            return user_profile, False
        except UserProfile.DoesNotExist:
            # No need to check for an inactive user since they don't exist yet
            if self._realm.deactivated:
                raise ZulipLDAPException("Realm has been deactivated")

            full_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["full_name"]
            short_name = full_name = ldap_user.attrs[full_name_attr][0]
            if "short_name" in settings.AUTH_LDAP_USER_ATTR_MAP:
                short_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["short_name"]
                short_name = ldap_user.attrs[short_name_attr][0]

            user_profile = do_create_user(username, None, self._realm, full_name, short_name)
            return user_profile, True
Beispiel #58
0
def add_bot_backend(request,
                    user_profile,
                    full_name=REQ(),
                    short_name=REQ(),
                    default_sending_stream_name=REQ('default_sending_stream',
                                                    default=None),
                    default_events_register_stream_name=REQ(
                        'default_events_register_stream', default=None),
                    default_all_public_streams=REQ(validator=check_bool,
                                                   default=None)):
    # type: (HttpRequest, UserProfile, text_type, text_type, Optional[text_type], Optional[text_type], Optional[bool]) -> HttpResponse
    short_name += "-bot"
    email = short_name + "@" + user_profile.realm.domain
    form = CreateUserForm({'full_name': full_name, 'email': email})
    if not form.is_valid():
        # We validate client-side as well
        return json_error(_('Bad name or username'))

    try:
        get_user_profile_by_email(email)
        return json_error(_("Username already in use"))
    except UserProfile.DoesNotExist:
        pass

    if len(request.FILES) == 0:
        avatar_source = UserProfile.AVATAR_FROM_GRAVATAR
    elif len(request.FILES) != 1:
        return json_error(_("You may only upload one file at a time"))
    else:
        user_file = list(request.FILES.values())[0]
        upload_avatar_image(user_file, user_profile, email)
        avatar_source = UserProfile.AVATAR_FROM_USER

    default_sending_stream = None
    if default_sending_stream_name is not None:
        default_sending_stream = stream_or_none(default_sending_stream_name,
                                                user_profile.realm)
    if (default_sending_stream and not default_sending_stream.is_public() and
            not subscribed_to_stream(user_profile, default_sending_stream)):
        return json_error(_('Insufficient permission'))

    default_events_register_stream = None
    if default_events_register_stream_name is not None:
        default_events_register_stream = stream_or_none(
            default_events_register_stream_name, user_profile.realm)
    if (default_events_register_stream
            and not default_events_register_stream.is_public()
            and not subscribed_to_stream(user_profile,
                                         default_events_register_stream)):
        return json_error(_('Insufficient permission'))

    bot_profile = do_create_user(
        email=email,
        password='',
        realm=user_profile.realm,
        full_name=full_name,
        short_name=short_name,
        active=True,
        bot_type=UserProfile.DEFAULT_BOT,
        bot_owner=user_profile,
        avatar_source=avatar_source,
        default_sending_stream=default_sending_stream,
        default_events_register_stream=default_events_register_stream,
        default_all_public_streams=default_all_public_streams)
    json_result = dict(
        api_key=bot_profile.api_key,
        avatar_url=avatar_url(bot_profile),
        default_sending_stream=get_stream_name(
            bot_profile.default_sending_stream),
        default_events_register_stream=get_stream_name(
            bot_profile.default_events_register_stream),
        default_all_public_streams=bot_profile.default_all_public_streams,
    )
    return json_success(json_result)
Beispiel #59
0
def add_bot_backend(
    request: HttpRequest,
    user_profile: UserProfile,
    full_name_raw: str = REQ("full_name"),
    short_name_raw: str = REQ("short_name"),
    bot_type: int = REQ(validator=check_int, default=UserProfile.DEFAULT_BOT),
    payload_url: Optional[str] = REQ(validator=check_url, default=""),
    service_name: Optional[str] = REQ(default=None),
    config_data: Dict[str, str] = REQ(
        default={}, validator=check_dict(value_validator=check_string)),
    interface_type: int = REQ(validator=check_int, default=Service.GENERIC),
    default_sending_stream_name: Optional[str] = REQ('default_sending_stream',
                                                     default=None),
    default_events_register_stream_name: Optional[str] = REQ(
        'default_events_register_stream', default=None),
    default_all_public_streams: Optional[bool] = REQ(validator=check_bool,
                                                     default=None)
) -> HttpResponse:
    short_name = check_short_name(short_name_raw)
    if bot_type != UserProfile.INCOMING_WEBHOOK_BOT:
        service_name = service_name or short_name
    short_name += "-bot"
    full_name = check_full_name(full_name_raw)
    try:
        email = '%s@%s' % (short_name, user_profile.realm.get_bot_domain())
    except InvalidFakeEmailDomain:
        return json_error(
            _("Can't create bots until FAKE_EMAIL_DOMAIN is correctly configured.\n"
              "Please contact your server administrator."))
    form = CreateUserForm({'full_name': full_name, 'email': email})

    if bot_type == UserProfile.EMBEDDED_BOT:
        if not settings.EMBEDDED_BOTS_ENABLED:
            return json_error(_("Embedded bots are not enabled."))
        if service_name not in [bot.name for bot in EMBEDDED_BOTS]:
            return json_error(_("Invalid embedded bot name."))

    if not form.is_valid():
        # We validate client-side as well
        return json_error(_('Bad name or username'))
    try:
        get_user_by_delivery_email(email, user_profile.realm)
        return json_error(_("Username already in use"))
    except UserProfile.DoesNotExist:
        pass

    check_bot_name_available(
        realm_id=user_profile.realm_id,
        full_name=full_name,
    )

    check_bot_creation_policy(user_profile, bot_type)
    check_valid_bot_type(user_profile, bot_type)
    check_valid_interface_type(interface_type)

    if len(request.FILES) == 0:
        avatar_source = UserProfile.AVATAR_FROM_GRAVATAR
    elif len(request.FILES) != 1:
        return json_error(_("You may only upload one file at a time"))
    else:
        avatar_source = UserProfile.AVATAR_FROM_USER

    default_sending_stream = None
    if default_sending_stream_name is not None:
        (default_sending_stream, ignored_rec,
         ignored_sub) = access_stream_by_name(user_profile,
                                              default_sending_stream_name)

    default_events_register_stream = None
    if default_events_register_stream_name is not None:
        (default_events_register_stream, ignored_rec,
         ignored_sub) = access_stream_by_name(
             user_profile, default_events_register_stream_name)

    if bot_type in (UserProfile.INCOMING_WEBHOOK_BOT,
                    UserProfile.EMBEDDED_BOT) and service_name:
        check_valid_bot_config(bot_type, service_name, config_data)

    bot_profile = do_create_user(
        email=email,
        password='',
        realm=user_profile.realm,
        full_name=full_name,
        short_name=short_name,
        bot_type=bot_type,
        bot_owner=user_profile,
        avatar_source=avatar_source,
        default_sending_stream=default_sending_stream,
        default_events_register_stream=default_events_register_stream,
        default_all_public_streams=default_all_public_streams)
    if len(request.FILES) == 1:
        user_file = list(request.FILES.values())[0]
        upload_avatar_image(user_file, user_profile, bot_profile)

    if bot_type in (UserProfile.OUTGOING_WEBHOOK_BOT,
                    UserProfile.EMBEDDED_BOT):
        assert (isinstance(service_name, str))
        add_service(name=service_name,
                    user_profile=bot_profile,
                    base_url=payload_url,
                    interface=interface_type,
                    token=generate_api_key())

    if bot_type == UserProfile.INCOMING_WEBHOOK_BOT and service_name:
        set_bot_config(bot_profile, "integration_id", service_name)

    if bot_type in (UserProfile.INCOMING_WEBHOOK_BOT,
                    UserProfile.EMBEDDED_BOT):
        for key, value in config_data.items():
            set_bot_config(bot_profile, key, value)

    notify_created_bot(bot_profile)

    api_key = get_api_key(bot_profile)

    json_result = dict(
        api_key=api_key,
        avatar_url=avatar_url(bot_profile),
        default_sending_stream=get_stream_name(
            bot_profile.default_sending_stream),
        default_events_register_stream=get_stream_name(
            bot_profile.default_events_register_stream),
        default_all_public_streams=bot_profile.default_all_public_streams,
    )
    return json_success(json_result)