mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-30 19:43:47 +00:00 
			
		
		
		
	export: Fix get_consented_user_ids to also account for bots.
Now that we severely limited the way that non-consenting users get exported, we need to start to consider bots as consenting when appropriate - otherwise the exported bot accounts will be unusable after importing.
This commit is contained in:
		
				
					committed by
					
						 Tim Abbott
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							e57b6719fa
						
					
				
				
					commit
					3c1fae1707
				
			| @@ -25,10 +25,12 @@ from urllib.parse import urlsplit | |||||||
| import orjson | import orjson | ||||||
| from django.apps import apps | from django.apps import apps | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
|  | from django.db import connection | ||||||
| from django.db.models import Exists, Model, OuterRef, Q | from django.db.models import Exists, Model, OuterRef, Q | ||||||
| from django.forms.models import model_to_dict | from django.forms.models import model_to_dict | ||||||
| from django.utils.timezone import is_naive as timezone_is_naive | from django.utils.timezone import is_naive as timezone_is_naive | ||||||
| from django.utils.timezone import now as timezone_now | from django.utils.timezone import now as timezone_now | ||||||
|  | from psycopg2 import sql | ||||||
|  |  | ||||||
| import zerver.lib.upload | import zerver.lib.upload | ||||||
| from analytics.models import RealmCount, StreamCount, UserCount | from analytics.models import RealmCount, StreamCount, UserCount | ||||||
| @@ -2707,11 +2709,38 @@ def get_analytics_config() -> Config: | |||||||
|  |  | ||||||
|  |  | ||||||
| def get_consented_user_ids(realm: Realm) -> set[int]: | def get_consented_user_ids(realm: Realm) -> set[int]: | ||||||
|     return set( |     # A UserProfile is consenting to private data export if either: | ||||||
|         UserProfile.objects.filter( |     # 1) It is an active, human account and enabled allow_private_data_export. | ||||||
|             realm=realm, is_active=True, is_bot=False, allow_private_data_export=True |     # 2) It is an active, bot account with allow_private_data_export toggled on. | ||||||
|         ).values_list("id", flat=True) |     # 3) It is a bot whose owner is (1). | ||||||
|     ) |     # Note: A bot of type (3) can be inactive - it's fine because (1) ensures | ||||||
|  |     # the owner has not been deactivated. | ||||||
|  |  | ||||||
|  |     query = sql.SQL(""" | ||||||
|  |         WITH consenting_humans AS ( | ||||||
|  |             SELECT id | ||||||
|  |             FROM zerver_userprofile | ||||||
|  |             WHERE allow_private_data_export | ||||||
|  |               AND is_active | ||||||
|  |               AND NOT is_bot | ||||||
|  |               AND realm_id = {realm_id} | ||||||
|  |         ) | ||||||
|  |         SELECT id | ||||||
|  |         FROM zerver_userprofile | ||||||
|  |         WHERE | ||||||
|  |             (id IN (SELECT id FROM consenting_humans)) | ||||||
|  |             OR (allow_private_data_export AND is_active AND is_bot AND realm_id = {realm_id}) | ||||||
|  |             OR ( | ||||||
|  |                 bot_owner_id IN (SELECT id FROM consenting_humans) | ||||||
|  |                 AND is_bot | ||||||
|  |                 AND realm_id = {realm_id} | ||||||
|  |             ) | ||||||
|  |     """).format(realm_id=sql.Literal(realm.id)) | ||||||
|  |  | ||||||
|  |     with connection.cursor() as cursor: | ||||||
|  |         cursor.execute(query) | ||||||
|  |         rows = cursor.fetchall() | ||||||
|  |     return {row[0] for row in rows} | ||||||
|  |  | ||||||
|  |  | ||||||
| def export_realm_wrapper( | def export_realm_wrapper( | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user