Add bot_type field to UserProfile.

This is intended to support creating different types of bots with
potentially limited permissions.
This commit is contained in:
Tomasz Kolek
2016-05-18 20:23:03 +02:00
committed by Tim Abbott
parent 06bc1007fd
commit 8c18b8947f
10 changed files with 54 additions and 26 deletions

View File

@@ -252,7 +252,7 @@ def notify_created_bot(user_profile):
send_event(event, bot_owner_userids(user_profile))
def do_create_user(email, password, realm, full_name, short_name,
active=True, bot=False, bot_owner=None,
active=True, bot_type=None, bot_owner=None,
avatar_source=UserProfile.AVATAR_FROM_GRAVATAR,
default_sending_stream=None, default_events_register_stream=None,
default_all_public_streams=None, prereg_user=None,
@@ -263,21 +263,21 @@ def do_create_user(email, password, realm, full_name, short_name,
'short_name': short_name,
'user': email,
'domain': realm.domain,
'bot': bot}
if bot:
'bot': bool(bot_type)}
if bot_type:
event['bot_owner'] = bot_owner.email
log_event(event)
user_profile = create_user(email=email, password=password, realm=realm,
full_name=full_name, short_name=short_name,
active=active, bot=bot, bot_owner=bot_owner,
active=active, bot_type=bot_type, bot_owner=bot_owner,
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)
notify_created_user(user_profile)
if bot:
if bot_type:
notify_created_bot(user_profile)
else:
process_new_human_user(user_profile, prereg_user=prereg_user,
@@ -1629,6 +1629,10 @@ def do_change_is_admin(user_profile, value, permission='administer'):
is_admin=value))
send_event(event, active_user_ids(user_profile.realm))
def do_change_bot_type(user_profile, value):
user_profile.bot_type = value
user_profile.save()
def do_make_stream_public(user_profile, realm, stream_name):
stream_name = stream_name.strip()
stream = get_stream(stream_name, realm)

View File

@@ -15,7 +15,7 @@ def bulk_create_realms(realm_list):
existing_realms.add(domain)
Realm.objects.bulk_create(realms_to_create)
def bulk_create_users(realms, users_raw, bot=False):
def bulk_create_users(realms, users_raw, bot_type=None):
"""
Creates and saves a UserProfile with the given email.
Has some code based off of UserManage.create_user, but doesn't .save()
@@ -34,7 +34,7 @@ def bulk_create_users(realms, users_raw, bot=False):
for (email, full_name, short_name, active) in users:
domain = resolve_email_to_domain(email)
profile = create_user_profile(realms[domain], email,
initial_password(email), active, bot,
initial_password(email), active, bot_type,
full_name, short_name, None, False)
profiles_to_create.append(profile)
UserProfile.objects.bulk_create(profiles_to_create)

View File

@@ -21,7 +21,7 @@ def random_api_key():
# Only use this for bulk_create -- for normal usage one should use
# create_user (below) which will also make the Subscription and
# Recipient objects
def create_user_profile(realm, email, password, active, bot, full_name,
def create_user_profile(realm, email, password, active, bot_type, full_name,
short_name, bot_owner, is_mirror_dummy):
now = timezone.now()
email = UserManager.normalize_email(email)
@@ -31,12 +31,12 @@ def create_user_profile(realm, email, password, active, bot, full_name,
user_profile = UserProfile(email=email, is_staff=False, is_active=active,
full_name=full_name, short_name=short_name,
last_login=now, date_joined=now, realm=realm,
pointer=-1, is_bot=bot, bot_owner=bot_owner,
is_mirror_dummy=is_mirror_dummy,
pointer=-1, is_bot=bool(bot_type), bot_type=bot_type,
bot_owner=bot_owner, is_mirror_dummy=is_mirror_dummy,
enable_stream_desktop_notifications=enable_stream_desktop_notifications,
onboarding_steps=ujson.dumps([]))
if bot or not active:
if bot_type or not active:
password = None
user_profile.set_password(password)
@@ -45,12 +45,12 @@ def create_user_profile(realm, email, password, active, bot, full_name,
return user_profile
def create_user(email, password, realm, full_name, short_name,
active=True, bot=False, bot_owner=None,
active=True, bot_type=None, bot_owner=None,
avatar_source=UserProfile.AVATAR_FROM_GRAVATAR,
is_mirror_dummy=False, default_sending_stream=None,
default_events_register_stream=None,
default_all_public_streams=None, user_profile_id=None):
user_profile = create_user_profile(realm, email, password, active, bot,
user_profile = create_user_profile(realm, email, password, active, bot_type,
full_name, short_name, bot_owner,
is_mirror_dummy)

View File

@@ -13,7 +13,7 @@ from optparse import make_option
settings.TORNADO_SERVER = None
def create_users(name_list, bot=False):
def create_users(name_list, bot_type=None):
realms = {}
for realm in Realm.objects.all():
realms[realm.domain] = realm
@@ -22,7 +22,7 @@ def create_users(name_list, bot=False):
for full_name, email in name_list:
short_name = email_to_username(email)
user_set.add((email, full_name, short_name, True))
bulk_create_users(realms, user_set, bot)
bulk_create_users(realms, user_set, bot_type)
class Command(BaseCommand):
help = "Populate an initial database for Zulip Voyager"
@@ -39,14 +39,14 @@ class Command(BaseCommand):
Realm.objects.create(domain="zulip.com")
names = [(settings.FEEDBACK_BOT_NAME, settings.FEEDBACK_BOT)]
create_users(names, bot=True)
create_users(names, bot_type=UserProfile.DEFAULT_BOT)
get_client("website")
get_client("API")
internal_bots = [(bot['name'], bot['email_template'] % (settings.INTERNAL_BOT_DOMAIN,))
for bot in settings.INTERNAL_BOTS]
create_users(internal_bots, bot=True)
create_users(internal_bots, bot_type=UserProfile.DEFAULT_BOT)
# Set the owners for these bots to the bots themselves
bots = UserProfile.objects.filter(email__in=[bot_info[1] for bot_info in internal_bots])
for bot in bots:

View File

@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('zerver', '0016_realm_create_stream_by_admins_only'),
]
operations = [
migrations.AddField(
model_name='userprofile',
name='bot_type',
field=models.PositiveSmallIntegerField(null=True, db_index=True),
),
]

View File

@@ -299,6 +299,8 @@ post_save.connect(flush_realm_filter, sender=RealmFilter)
post_delete.connect(flush_realm_filter, sender=RealmFilter)
class UserProfile(AbstractBaseUser, PermissionsMixin):
DEFAULT_BOT = 1
# Fields from models.AbstractUser minus last_name and first_name,
# which we don't use; email is modified to make it indexed and unique.
email = models.EmailField(blank=False, db_index=True, unique=True)
@@ -306,6 +308,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
is_active = models.BooleanField(default=True, db_index=True)
is_realm_admin = models.BooleanField(default=False, db_index=True)
is_bot = models.BooleanField(default=False, db_index=True)
bot_type = models.PositiveSmallIntegerField(null=True, db_index=True)
is_api_super_user = models.BooleanField(default=False, db_index=True)
date_joined = models.DateTimeField(default=timezone.now)
is_mirror_dummy = models.BooleanField(default=False)

View File

@@ -4,7 +4,7 @@ from django.test import TestCase
from zerver.models import (
get_client, get_realm, get_stream, get_user_profile_by_email,
Message, Recipient,
Message, Recipient, UserProfile
)
from zerver.lib.actions import (
@@ -201,7 +201,7 @@ class EventsRegisterTest(AuthedTestCase):
def create_bot(self, email):
return do_create_user(email, '123',
get_realm('zulip.com'), 'Test Bot', 'test',
bot=True, bot_owner=self.user_profile)
bot_type=UserProfile.DEFAULT_BOT, bot_owner=self.user_profile)
def realm_bot_schema(self, field_name, check):
return check_dict([

View File

@@ -1486,7 +1486,7 @@ class CheckMessageTest(AuthedTestCase):
full_name='',
short_name='',
active=True,
bot=True,
bot_type=UserProfile.DEFAULT_BOT,
bot_owner=parent
)
bot.last_reminder = None

View File

@@ -206,7 +206,8 @@ def add_bot_backend(request, user_profile, full_name=REQ, short_name=REQ,
bot_profile = do_create_user(email=email, password='',
realm=user_profile.realm, full_name=full_name,
short_name=short_name, active=True, bot=True,
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,

View File

@@ -11,7 +11,8 @@ from zerver.models import Message, UserProfile, Stream, Recipient, Client, \
get_huddle_hash, clear_database, get_client, get_user_profile_by_id, \
split_email_to_domain, email_to_username
from zerver.lib.actions import do_send_message, set_default_streams, \
do_activate_user, do_deactivate_user, do_change_password, do_change_is_admin
do_activate_user, do_deactivate_user, do_change_password, do_change_is_admin,\
do_change_bot_type
from zerver.lib.parallel import run_parallel
from django.db.models import Count
from django.conf import settings
@@ -34,12 +35,12 @@ from typing import Any, Dict, Set, Tuple
settings.TORNADO_SERVER = None
def create_users(realms, name_list, bot=False):
def create_users(realms, name_list, bot_type=None):
user_set = set()
for full_name, email in name_list:
short_name = email_to_username(email)
user_set.add((email, full_name, short_name, True))
bulk_create_users(realms, user_set, bot)
bulk_create_users(realms, user_set, bot_type)
def create_streams(realms, realm, stream_list):
stream_set = set()
@@ -206,7 +207,7 @@ class Command(BaseCommand):
("Zulip Error Bot", "error-bot@zulip.com"),
]
zulip_realm_bots.extend(all_realm_bots)
create_users(realms, zulip_realm_bots, bot=True)
create_users(realms, zulip_realm_bots, bot_type=UserProfile.DEFAULT_BOT)
if not options["test_suite"]:
# Initialize the email gateway bot as an API Super User
@@ -245,7 +246,7 @@ class Command(BaseCommand):
("Zulip Nagios Bot", "nagios-bot@zulip.com"),
("Zulip Feedback Bot", "feedback@zulip.com"),
]
create_users(realms, internal_zulip_users_nosubs, bot=True)
create_users(realms, internal_zulip_users_nosubs, bot_type=UserProfile.DEFAULT_BOT)
# Mark all messages as read
UserMessage.objects.all().update(flags=UserMessage.flags.read)