diff --git a/zerver/lib/import_realm.py b/zerver/lib/import_realm.py index 84e74c9fa4..acb8363e68 100644 --- a/zerver/lib/import_realm.py +++ b/zerver/lib/import_realm.py @@ -1059,6 +1059,7 @@ def do_import_realm(import_dir: Path, subdomain: str, processes: int = 1) -> Rea validate_email(user_profile.delivery_email) validate_email(user_profile.email) user_profile.set_unusable_password() + user_profile.tos_version = UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN UserProfile.objects.bulk_create(user_profiles) re_map_foreign_keys(data, "zerver_defaultstream", "stream", related_table="stream") diff --git a/zerver/lib/scim.py b/zerver/lib/scim.py index d06a916652..ffdc3cae13 100644 --- a/zerver/lib/scim.py +++ b/zerver/lib/scim.py @@ -270,6 +270,7 @@ class ZulipSCIMUser(SCIMUser): password, realm, full_name_new_value, + tos_version=UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN, acting_user=None, ) return diff --git a/zerver/management/commands/create_realm.py b/zerver/management/commands/create_realm.py index 05c9865d63..62f9448365 100644 --- a/zerver/management/commands/create_realm.py +++ b/zerver/management/commands/create_realm.py @@ -53,12 +53,14 @@ workflow as `./manage.py create_user`. create_user_params.password, realm, create_user_params.full_name, - # Explicitly set tos_version=None. For servers that - # have configured Terms of Service, this means that - # users created via this mechanism will be prompted to - # accept the Terms of Service on first login. + # Explicitly set tos_version=-1. This means that users + # created via this mechanism would be prompted to set + # the email_address_visibility setting on first login. + # For servers that have configured Terms of Service, + # users will also be prompted to accept the Terms of + # Service on first login. role=UserProfile.ROLE_REALM_OWNER, realm_creation=True, - tos_version=None, + tos_version=UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN, acting_user=None, ) diff --git a/zerver/management/commands/create_user.py b/zerver/management/commands/create_user.py index d09f3eadac..b97fb2b6ef 100644 --- a/zerver/management/commands/create_user.py +++ b/zerver/management/commands/create_user.py @@ -6,6 +6,7 @@ from django.db.utils import IntegrityError from zerver.actions.create_user import do_create_user from zerver.lib.management import ZulipBaseCommand +from zerver.models import UserProfile class Command(ZulipBaseCommand): @@ -38,11 +39,13 @@ prompted to accept the Terms of Service the first time they login. create_user_params.password, realm, create_user_params.full_name, - # Explicitly set tos_version=None. For servers that - # have configured Terms of Service, this means that - # users created via this mechanism will be prompted to - # accept the Terms of Service on first login. - tos_version=None, + # Explicitly set tos_version=-1. This means that users + # created via this mechanism would be prompted to set + # the email_address_visibility setting on first login. + # For servers that have configured Terms of Service, + # users will also be prompted to accept the Terms of + # Service on first login. + tos_version=UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN, acting_user=None, ) except IntegrityError: diff --git a/zerver/management/commands/send_custom_email.py b/zerver/management/commands/send_custom_email.py index 22d82a80ce..7fd04aa2e7 100644 --- a/zerver/management/commands/send_custom_email.py +++ b/zerver/management/commands/send_custom_email.py @@ -3,6 +3,7 @@ from typing import Any, Collection, List from django.conf import settings from django.core.management.base import CommandError +from django.db.models import Q from zerver.lib.management import ZulipBaseCommand from zerver.lib.send_email import send_custom_email @@ -130,7 +131,9 @@ class Command(ZulipBaseCommand): users = ( UserProfile.objects.select_related() .filter(id__in=[u.id for u in users]) - .exclude(tos_version=None) + .exclude( + Q(tos_version=None) | Q(tos_version=UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN) + ) ) send_custom_email(users, target_emails=target_emails, options=options) diff --git a/zerver/models.py b/zerver/models.py index bd52f88e04..25670875c3 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -1814,6 +1814,13 @@ class UserProfile(AbstractBaseUser, PermissionsMixin, UserBaseSettings): # type full_name = models.CharField(max_length=MAX_NAME_LENGTH) date_joined = models.DateTimeField(default=timezone_now) + + # Terms of Service version number that this user has accepted. We + # use the special value TOS_VERSION_BEFORE_FIRST_LOGIN for users + # whose account was created without direct user interaction (via + # the API or a data import), and null for users whose account is + # fully created on servers that do not have a configured ToS. + TOS_VERSION_BEFORE_FIRST_LOGIN = "-1" tos_version = models.CharField(null=True, max_length=10) api_key = models.CharField(max_length=API_KEY_LENGTH) diff --git a/zerver/tests/test_home.py b/zerver/tests/test_home.py index 4593d89efa..f47ede8025 100644 --- a/zerver/tests/test_home.py +++ b/zerver/tests/test_home.py @@ -499,7 +499,7 @@ class HomeTest(ZulipTestCase): user = self.example_user("hamlet") self.login_user(user) - for user_tos_version in [None, "1.1", "2.0.3.4"]: + for user_tos_version in [None, "-1", "1.1", "2.0.3.4"]: user.tos_version = user_tos_version user.save() @@ -536,7 +536,7 @@ class HomeTest(ZulipTestCase): user = self.example_user("hamlet") self.login_user(user) - user.tos_version = None + user.tos_version = UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN user.save() with self.settings( diff --git a/zerver/tests/test_users.py b/zerver/tests/test_users.py index 88e21a82e6..7ddfb6637c 100644 --- a/zerver/tests/test_users.py +++ b/zerver/tests/test_users.py @@ -957,6 +957,7 @@ class AdminCreateUserTest(ZulipTestCase): result = orjson.loads(result.content) self.assertEqual(new_user.full_name, "Romeo Montague") self.assertEqual(new_user.id, result["user_id"]) + self.assertEqual(new_user.tos_version, UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN) # Make sure the recipient field is set correctly. self.assertEqual( diff --git a/zerver/views/home.py b/zerver/views/home.py index 117145314b..1a7bf91009 100644 --- a/zerver/views/home.py +++ b/zerver/views/home.py @@ -54,7 +54,7 @@ def accounts_accept_terms(request: HttpRequest) -> HttpResponse: } if ( - request.user.tos_version is None + request.user.tos_version == UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN and settings.FIRST_TIME_TERMS_OF_SERVICE_TEMPLATE is not None ): context[ diff --git a/zerver/views/users.py b/zerver/views/users.py index 84ab329cfe..2ac69c54b9 100644 --- a/zerver/views/users.py +++ b/zerver/views/users.py @@ -721,11 +721,13 @@ def create_user_backend( password, realm, full_name, - # Explicitly set tos_version=None. For servers that have - # configured Terms of Service, this means that users created - # via this mechanism will be prompted to accept the Terms of + # Explicitly set tos_version=-1. This means that users + # created via this mechanism would be prompted to set + # the email_address_visibility setting on first login. + # For servers that have configured Terms of Service, + # users will also be prompted to accept the Terms of # Service on first login. - tos_version=None, + tos_version=UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN, acting_user=user_profile, ) return json_success(request, data={"user_id": target_user.id}) diff --git a/zproject/backends.py b/zproject/backends.py index 2556a53877..fcf6ed113c 100644 --- a/zproject/backends.py +++ b/zproject/backends.py @@ -1047,7 +1047,13 @@ class ZulipLDAPAuthBackend(ZulipLDAPAuthBackendBase): opts["default_stream_groups"] = [] user_profile = do_create_user( - username, None, self._realm, full_name, acting_user=None, **opts + username, + None, + self._realm, + full_name, + tos_version=UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN, + acting_user=None, + **opts, ) self.sync_avatar_from_ldap(user_profile, ldap_user) self.sync_custom_profile_fields_from_ldap(user_profile, ldap_user)