mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 16:14:02 +00:00
export: Don't export real email of users unless accessible to admins.
An administrator shouldn't be able to bypass a user's setting to hide their email address from everyone, including admins. Therefore, we should overwrite the delivery_email for such users during export - unless the user consented to have their private data exported. The notable consequence of this is that such user accounts will become completely inaccessible after importing this data to a new server, due to not having a functional email address on record. These accounts will only be possible to reclaim via a manual intervention to change the email address on the `UserProfile` by server administrators.
This commit is contained in:
committed by
Tim Abbott
parent
13303fd916
commit
9da4eeaa94
@@ -10,12 +10,14 @@ import glob
|
||||
import hashlib
|
||||
import logging
|
||||
import os
|
||||
import secrets
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
from collections.abc import Callable, Iterable, Mapping
|
||||
from contextlib import suppress
|
||||
from datetime import datetime
|
||||
from email.headerregistry import Address
|
||||
from functools import cache
|
||||
from typing import TYPE_CHECKING, Any, Optional, TypeAlias, TypedDict, cast
|
||||
from urllib.parse import urlsplit
|
||||
@@ -81,7 +83,7 @@ from zerver.models import (
|
||||
)
|
||||
from zerver.models.presence import PresenceSequence
|
||||
from zerver.models.realm_audit_logs import AuditLogEventType
|
||||
from zerver.models.realms import get_realm
|
||||
from zerver.models.realms import get_fake_email_domain, get_realm
|
||||
from zerver.models.saved_snippets import SavedSnippet
|
||||
from zerver.models.users import get_system_bot, get_user_profile_by_id
|
||||
|
||||
@@ -1182,6 +1184,13 @@ def add_user_profile_child_configs(user_profile_config: Config) -> None:
|
||||
EXCLUDED_USER_PROFILE_FIELDS = ["api_key", "password", "uuid"]
|
||||
|
||||
|
||||
def get_randomized_exported_user_dummy_email_address(realm: Realm) -> str:
|
||||
random_token = secrets.token_hex(16)
|
||||
return Address(
|
||||
username=f"exported-user-{random_token}", domain=get_fake_email_domain(realm.host)
|
||||
).addr_spec
|
||||
|
||||
|
||||
def custom_fetch_user_profile(response: TableData, context: Context) -> None:
|
||||
realm = context["realm"]
|
||||
exportable_user_ids = context["exportable_user_ids"]
|
||||
@@ -1209,7 +1218,18 @@ def custom_fetch_user_profile(response: TableData, context: Context) -> None:
|
||||
# inactive is_mirror_dummy users.
|
||||
row["is_mirror_dummy"] = True
|
||||
row["is_active"] = False
|
||||
if row["email_address_visibility"] == UserProfile.EMAIL_ADDRESS_VISIBILITY_NOBODY:
|
||||
# The user chose not to make their email address visible even to the realm administrators.
|
||||
# Generate a dummy email address for them so that this preference can't be bypassed
|
||||
# through the export feature.
|
||||
row["delivery_email"] = get_randomized_exported_user_dummy_email_address(realm)
|
||||
|
||||
for settings_name in RealmUserDefault.property_types:
|
||||
if settings_name == "email_address_visibility":
|
||||
# We should respect users' preference for whether to show their email
|
||||
# address to others across the export->import cycle.
|
||||
continue
|
||||
|
||||
value = getattr(realm_user_default, settings_name)
|
||||
row[settings_name] = value
|
||||
|
||||
|
Reference in New Issue
Block a user