def test_delete(self) -> None: user_profile = self.example_user('iago') realm = user_profile.realm field = CustomProfileField.objects.get(name="Phone number", realm=realm) data = [{'id': field.id, 'value': u'123456'}] # type: List[Dict[str, Union[int, Text]]] do_update_user_custom_profile_data(user_profile, data) self.assertEqual(len(custom_profile_fields_for_realm(realm.id)), 3) self.assertEqual(user_profile.customprofilefieldvalue_set.count(), 3) do_remove_realm_custom_profile_field(realm, field) self.assertEqual(len(custom_profile_fields_for_realm(realm.id)), 2) self.assertEqual(user_profile.customprofilefieldvalue_set.count(), 2)
def test_delete(self) -> None: user_profile = self.example_user('iago') realm = user_profile.realm field = try_add_realm_custom_profile_field( realm, u"Phone", CustomProfileField.SHORT_TEXT ) data = [{'id': field.id, 'value': u'123456'}] # type: List[Dict[str, Union[int, Text]]] do_update_user_custom_profile_data(user_profile, data) self.assertEqual(len(custom_profile_fields_for_realm(realm.id)), 1) self.assertEqual(user_profile.customprofilefieldvalue_set.count(), 1) do_remove_realm_custom_profile_field(realm, field) self.assertEqual(len(custom_profile_fields_for_realm(realm.id)), 0) self.assertEqual(user_profile.customprofilefieldvalue_set.count(), 0)
def test_delete(self) -> None: user_profile = self.example_user('iago') realm = user_profile.realm field = try_add_realm_custom_profile_field( realm, u"Phone", CustomProfileField.SHORT_TEXT) data = [{ 'id': field.id, 'value': u'123456' }] # type: List[Dict[str, Union[int, Text]]] do_update_user_custom_profile_data(user_profile, data) self.assertEqual(len(custom_profile_fields_for_realm(realm.id)), 1) self.assertEqual(user_profile.customprofilefieldvalue_set.count(), 1) do_remove_realm_custom_profile_field(realm, field) self.assertEqual(len(custom_profile_fields_for_realm(realm.id)), 0) self.assertEqual(user_profile.customprofilefieldvalue_set.count(), 0)
def sync_custom_profile_fields_from_ldap(self, user_profile: UserProfile, ldap_user: _LDAPUser) -> None: values_by_var_name = {} # type: Dict[str, Union[int, str, List[int]]] for attr, ldap_attr in settings.AUTH_LDAP_USER_ATTR_MAP.items(): if not attr.startswith('custom_profile_field__'): continue var_name = attr.split('custom_profile_field__')[1] try: value = ldap_user.attrs[ldap_attr][0] except KeyError: # If this user doesn't have this field set then ignore this # field and continue syncing other fields. `django-auth-ldap` # automatically logs error about missing field. continue values_by_var_name[var_name] = value fields_by_var_name = {} # type: Dict[str, CustomProfileField] custom_profile_fields = custom_profile_fields_for_realm( user_profile.realm.id) for field in custom_profile_fields: var_name = '_'.join(field.name.lower().split(' ')) fields_by_var_name[var_name] = field existing_values = {} for data in user_profile.profile_data: var_name = '_'.join(data['name'].lower().split( ' ')) # type: ignore # data field values can also be int existing_values[var_name] = data['value'] profile_data = [] # type: List[Dict[str, Union[int, str, List[int]]]] for var_name, value in values_by_var_name.items(): try: field = fields_by_var_name[var_name] except KeyError: raise ZulipLDAPException( 'Custom profile field with name %s not found.' % (var_name, )) if existing_values.get(var_name) == value: continue result = validate_user_custom_profile_field( user_profile.realm.id, field, value) if result is not None: raise ZulipLDAPException('Invalid data for %s field: %s' % (var_name, result)) profile_data.append({ 'id': field.id, 'value': value, }) do_update_user_custom_profile_data(user_profile, profile_data)
def sync_custom_profile_fields_from_ldap(self, user_profile: UserProfile, ldap_user: _LDAPUser) -> None: values_by_var_name = {} # type: Dict[str, Union[int, str, List[int]]] for attr, ldap_attr in settings.AUTH_LDAP_USER_ATTR_MAP.items(): if not attr.startswith('custom_profile_field__'): continue var_name = attr.split('custom_profile_field__')[1] try: value = ldap_user.attrs[ldap_attr][0] except KeyError: # If this user doesn't have this field set then ignore this # field and continue syncing other fields. `django-auth-ldap` # automatically logs error about missing field. continue values_by_var_name[var_name] = value fields_by_var_name = {} # type: Dict[str, CustomProfileField] custom_profile_fields = custom_profile_fields_for_realm(user_profile.realm.id) for field in custom_profile_fields: var_name = '_'.join(field.name.lower().split(' ')) fields_by_var_name[var_name] = field existing_values = {} for data in user_profile.profile_data: var_name = '_'.join(data['name'].lower().split(' ')) # type: ignore # data field values can also be int existing_values[var_name] = data['value'] profile_data = [] # type: List[Dict[str, Union[int, str, List[int]]]] for var_name, value in values_by_var_name.items(): try: field = fields_by_var_name[var_name] except KeyError: raise ZulipLDAPException('Custom profile field with name %s not found.' % (var_name,)) if existing_values.get(var_name) == value: continue result = validate_user_custom_profile_field(user_profile.realm.id, field, value) if result is not None: raise ZulipLDAPException('Invalid data for %s field: %s' % (var_name, result)) profile_data.append({ 'id': field.id, 'value': value, }) do_update_user_custom_profile_data(user_profile, profile_data)
def list_realm_custom_profile_fields(request, user_profile): # type: (HttpRequest, UserProfile) -> HttpResponse fields = custom_profile_fields_for_realm(user_profile.realm_id) return json_success({'custom_fields': [f.as_dict() for f in fields]})
def fetch_initial_state_data(user_profile: UserProfile, event_types: Optional[Iterable[str]], queue_id: str, client_gravatar: bool, include_subscribers: bool = True) -> Dict[str, Any]: state = {'queue_id': queue_id} # type: Dict[str, Any] realm = user_profile.realm if event_types is None: # return True always want = always_want # type: Callable[[str], bool] else: want = set(event_types).__contains__ if want('alert_words'): state['alert_words'] = user_alert_words(user_profile) if want('custom_profile_fields'): fields = custom_profile_fields_for_realm(realm.id) state['custom_profile_fields'] = [f.as_dict() for f in fields] state['custom_profile_field_types'] = CustomProfileField.FIELD_TYPE_CHOICES_DICT if want('hotspots'): state['hotspots'] = get_next_hotspots(user_profile) if want('message'): # The client should use get_messages() to fetch messages # starting with the max_message_id. They will get messages # newer than that ID via get_events() messages = Message.objects.filter(usermessage__user_profile=user_profile).order_by('-id')[:1] if messages: state['max_message_id'] = messages[0].id else: state['max_message_id'] = -1 if want('muted_topics'): state['muted_topics'] = get_topic_mutes(user_profile) if want('pointer'): state['pointer'] = user_profile.pointer if want('presence'): state['presences'] = get_status_dict(user_profile) if want('realm'): for property_name in Realm.property_types: state['realm_' + property_name] = getattr(realm, property_name) # Most state is handled via the property_types framework; # these manual entries are for those realm settings that don't # fit into that framework. state['realm_authentication_methods'] = realm.authentication_methods_dict() state['realm_allow_message_editing'] = realm.allow_message_editing state['realm_allow_community_topic_editing'] = realm.allow_community_topic_editing state['realm_allow_message_deleting'] = realm.allow_message_deleting state['realm_message_content_edit_limit_seconds'] = realm.message_content_edit_limit_seconds state['realm_message_content_delete_limit_seconds'] = realm.message_content_delete_limit_seconds state['realm_icon_url'] = realm_icon_url(realm) state['realm_icon_source'] = realm.icon_source state['max_icon_file_size'] = settings.MAX_ICON_FILE_SIZE state['realm_logo_url'] = realm_logo_url(realm) state['realm_logo_source'] = realm.logo_source state['max_logo_file_size'] = settings.MAX_LOGO_FILE_SIZE state['realm_bot_domain'] = realm.get_bot_domain() state['realm_uri'] = realm.uri state['realm_available_video_chat_providers'] = realm.VIDEO_CHAT_PROVIDERS state['realm_presence_disabled'] = realm.presence_disabled state['realm_digest_emails_enabled'] = realm.digest_emails_enabled and settings.SEND_DIGEST_EMAILS state['realm_is_zephyr_mirror_realm'] = realm.is_zephyr_mirror_realm state['realm_email_auth_enabled'] = email_auth_enabled(realm) state['realm_password_auth_enabled'] = password_auth_enabled(realm) state['realm_push_notifications_enabled'] = push_notifications_enabled() if realm.notifications_stream and not realm.notifications_stream.deactivated: notifications_stream = realm.notifications_stream state['realm_notifications_stream_id'] = notifications_stream.id else: state['realm_notifications_stream_id'] = -1 signup_notifications_stream = realm.get_signup_notifications_stream() if signup_notifications_stream: state['realm_signup_notifications_stream_id'] = signup_notifications_stream.id else: state['realm_signup_notifications_stream_id'] = -1 if want('realm_domains'): state['realm_domains'] = get_realm_domains(realm) if want('realm_emoji'): state['realm_emoji'] = realm.get_emoji() if want('realm_filters'): state['realm_filters'] = realm_filters_for_realm(realm.id) if want('realm_user_groups'): state['realm_user_groups'] = user_groups_in_realm_serialized(realm) if want('realm_user'): state['raw_users'] = get_raw_user_data( realm_id=realm.id, client_gravatar=client_gravatar, ) # For the user's own avatar URL, we force # client_gravatar=False, since that saves some unnecessary # client-side code for handing medium-size avatars. See #8253 # for details. state['avatar_source'] = user_profile.avatar_source state['avatar_url_medium'] = avatar_url( user_profile, medium=True, client_gravatar=False, ) state['avatar_url'] = avatar_url( user_profile, medium=False, client_gravatar=False, ) state['can_create_streams'] = user_profile.can_create_streams() state['can_subscribe_other_users'] = user_profile.can_subscribe_other_users() state['cross_realm_bots'] = list(get_cross_realm_dicts()) state['is_admin'] = user_profile.is_realm_admin state['is_guest'] = user_profile.is_guest state['user_id'] = user_profile.id state['enter_sends'] = user_profile.enter_sends state['email'] = user_profile.email state['delivery_email'] = user_profile.delivery_email state['full_name'] = user_profile.full_name if want('realm_bot'): state['realm_bots'] = get_owned_bot_dicts(user_profile) # This does not yet have an apply_event counterpart, since currently, # new entries for EMBEDDED_BOTS can only be added directly in the codebase. if want('realm_embedded_bots'): realm_embedded_bots = [] for bot in EMBEDDED_BOTS: realm_embedded_bots.append({'name': bot.name, 'config': load_bot_config_template(bot.name)}) state['realm_embedded_bots'] = realm_embedded_bots if want('subscription'): subscriptions, unsubscribed, never_subscribed = gather_subscriptions_helper( user_profile, include_subscribers=include_subscribers) state['subscriptions'] = subscriptions state['unsubscribed'] = unsubscribed state['never_subscribed'] = never_subscribed if want('update_message_flags') and want('message'): # Keeping unread_msgs updated requires both message flag updates and # message updates. This is due to the fact that new messages will not # generate a flag update so we need to use the flags field in the # message event. state['raw_unread_msgs'] = get_raw_unread_data(user_profile) if want('starred_messages'): state['starred_messages'] = get_starred_message_ids(user_profile) if want('stream'): state['streams'] = do_get_streams(user_profile) state['stream_name_max_length'] = Stream.MAX_NAME_LENGTH state['stream_description_max_length'] = Stream.MAX_DESCRIPTION_LENGTH if want('default_streams'): state['realm_default_streams'] = streams_to_dicts_sorted( get_default_streams_for_realm(realm.id)) if want('default_stream_groups'): state['realm_default_stream_groups'] = default_stream_groups_to_dicts_sorted( get_default_stream_groups(realm)) if want('update_display_settings'): for prop in UserProfile.property_types: state[prop] = getattr(user_profile, prop) state['emojiset_choices'] = user_profile.emojiset_choices() if want('update_global_notifications'): for notification in UserProfile.notification_setting_types: state[notification] = getattr(user_profile, notification) state['available_notification_sounds'] = get_available_notification_sounds() if want('user_status'): state['away_user_ids'] = sorted(list(get_away_user_ids(realm_id=realm.id))) if want('zulip_version'): state['zulip_version'] = ZULIP_VERSION return state
def fetch_initial_state_data(user_profile, event_types, queue_id, include_subscribers=True): # type: (UserProfile, Optional[Iterable[str]], str, bool) -> Dict[str, Any] state = {'queue_id': queue_id} # type: Dict[str, Any] if event_types is None: want = lambda msg_type: True else: want = set(event_types).__contains__ if want('alert_words'): state['alert_words'] = user_alert_words(user_profile) if want('custom_profile_fields'): fields = custom_profile_fields_for_realm(user_profile.realm.id) state['custom_profile_fields'] = [f.as_dict() for f in fields] if want('attachments'): state['attachments'] = user_attachments(user_profile) if want('hotspots'): state['hotspots'] = get_next_hotspots(user_profile) if want('message'): # The client should use get_messages() to fetch messages # starting with the max_message_id. They will get messages # newer than that ID via get_events() messages = Message.objects.filter( usermessage__user_profile=user_profile).order_by('-id')[:1] if messages: state['max_message_id'] = messages[0].id else: state['max_message_id'] = -1 if want('muted_topics'): state['muted_topics'] = ujson.loads(user_profile.muted_topics) if want('pointer'): state['pointer'] = user_profile.pointer if want('presence'): state['presences'] = get_status_dict(user_profile) if want('realm'): for property_name in Realm.property_types: state['realm_' + property_name] = getattr(user_profile.realm, property_name) # Most state is handled via the property_types framework; # these manual entries are for those realm settings that don't # fit into that framework. state[ 'realm_authentication_methods'] = user_profile.realm.authentication_methods_dict( ) state[ 'realm_allow_message_editing'] = user_profile.realm.allow_message_editing state[ 'realm_message_content_edit_limit_seconds'] = user_profile.realm.message_content_edit_limit_seconds state['realm_icon_url'] = realm_icon_url(user_profile.realm) state['realm_icon_source'] = user_profile.realm.icon_source state['max_icon_file_size'] = settings.MAX_ICON_FILE_SIZE state['realm_bot_domain'] = user_profile.realm.get_bot_domain() state['realm_uri'] = user_profile.realm.uri state['realm_presence_disabled'] = user_profile.realm.presence_disabled state['realm_show_digest_email'] = user_profile.realm.show_digest_email state[ 'realm_is_zephyr_mirror_realm'] = user_profile.realm.is_zephyr_mirror_realm state['realm_password_auth_enabled'] = password_auth_enabled( user_profile.realm) if user_profile.realm.notifications_stream and not user_profile.realm.notifications_stream.deactivated: notifications_stream = user_profile.realm.notifications_stream state['realm_notifications_stream_id'] = notifications_stream.id else: state['realm_notifications_stream_id'] = -1 if want('realm_domains'): state['realm_domains'] = get_realm_domains(user_profile.realm) if want('realm_emoji'): state['realm_emoji'] = user_profile.realm.get_emoji() if want('realm_filters'): state['realm_filters'] = realm_filters_for_realm(user_profile.realm_id) if want('realm_user'): state['realm_users'] = get_realm_user_dicts(user_profile) state['avatar_source'] = user_profile.avatar_source state['avatar_url_medium'] = avatar_url(user_profile, medium=True) state['avatar_url'] = avatar_url(user_profile) state['can_create_streams'] = user_profile.can_create_streams() state['cross_realm_bots'] = list(get_cross_realm_dicts()) state['is_admin'] = user_profile.is_realm_admin state['user_id'] = user_profile.id state['enter_sends'] = user_profile.enter_sends state['email'] = user_profile.email state['full_name'] = user_profile.full_name if want('realm_bot'): state['realm_bots'] = get_owned_bot_dicts(user_profile) if want('subscription'): subscriptions, unsubscribed, never_subscribed = gather_subscriptions_helper( user_profile, include_subscribers=include_subscribers) state['subscriptions'] = subscriptions state['unsubscribed'] = unsubscribed state['never_subscribed'] = never_subscribed if want('update_message_flags') and want('message'): # Keeping unread_msgs updated requires both message flag updates and # message updates. This is due to the fact that new messages will not # generate a flag update so we need to use the flags field in the # message event. state['unread_msgs'] = get_unread_message_ids_per_recipient( user_profile) if want('stream'): state['streams'] = do_get_streams(user_profile) if want('default_streams'): state['realm_default_streams'] = streams_to_dicts_sorted( get_default_streams_for_realm(user_profile.realm)) if want('update_display_settings'): for prop in UserProfile.property_types: state[prop] = getattr(user_profile, prop) state['emojiset_choices'] = user_profile.emojiset_choices() state['autoscroll_forever'] = user_profile.autoscroll_forever if want('update_global_notifications'): for notification in UserProfile.notification_setting_types: state[notification] = getattr(user_profile, notification) state[ 'default_desktop_notifications'] = user_profile.default_desktop_notifications if want('zulip_version'): state['zulip_version'] = ZULIP_VERSION return state
def custom_field_exists_in_realm(self, field_id: int) -> bool: fields = custom_profile_fields_for_realm(self.realm.id) field_ids = [field.id for field in fields] return (field_id in field_ids)
def setUp(self) -> None: self.realm = get_realm("zulip") self.original_count = len(custom_profile_fields_for_realm(self.realm.id))
def fetch_initial_state_data( user_profile: UserProfile, event_types: Optional[Iterable[str]], queue_id: str, client_gravatar: bool, user_avatar_url_field_optional: bool, slim_presence: bool = False, include_subscribers: bool = True) -> Dict[str, Any]: state: Dict[str, Any] = {'queue_id': queue_id} realm = user_profile.realm if event_types is None: # return True always want: Callable[[str], bool] = always_want else: want = set(event_types).__contains__ # Show the version info unconditionally. state['zulip_version'] = ZULIP_VERSION state['zulip_feature_level'] = API_FEATURE_LEVEL if want('alert_words'): state['alert_words'] = user_alert_words(user_profile) if want('custom_profile_fields'): fields = custom_profile_fields_for_realm(realm.id) state['custom_profile_fields'] = [f.as_dict() for f in fields] state[ 'custom_profile_field_types'] = CustomProfileField.FIELD_TYPE_CHOICES_DICT if want('hotspots'): state['hotspots'] = get_next_hotspots(user_profile) if want('message'): # The client should use get_messages() to fetch messages # starting with the max_message_id. They will get messages # newer than that ID via get_events() user_messages = UserMessage.objects \ .filter(user_profile=user_profile) \ .order_by('-message_id') \ .values('message_id')[:1] if user_messages: state['max_message_id'] = user_messages[0]['message_id'] else: state['max_message_id'] = -1 if want('muted_topics'): state['muted_topics'] = get_topic_mutes(user_profile) if want('presence'): state['presences'] = get_presences_for_realm(realm, user_profile, slim_presence) if want('realm'): for property_name in Realm.property_types: state['realm_' + property_name] = getattr(realm, property_name) # Most state is handled via the property_types framework; # these manual entries are for those realm settings that don't # fit into that framework. state[ 'realm_authentication_methods'] = realm.authentication_methods_dict( ) state['realm_allow_message_editing'] = realm.allow_message_editing state[ 'realm_allow_community_topic_editing'] = realm.allow_community_topic_editing state['realm_allow_message_deleting'] = realm.allow_message_deleting state[ 'realm_message_content_edit_limit_seconds'] = realm.message_content_edit_limit_seconds state[ 'realm_message_content_delete_limit_seconds'] = realm.message_content_delete_limit_seconds state['realm_community_topic_editing_limit_seconds'] = \ Realm.DEFAULT_COMMUNITY_TOPIC_EDITING_LIMIT_SECONDS state['realm_icon_url'] = realm_icon_url(realm) state['realm_icon_source'] = realm.icon_source state['max_icon_file_size'] = settings.MAX_ICON_FILE_SIZE add_realm_logo_fields(state, realm) state['realm_bot_domain'] = realm.get_bot_domain() state['realm_uri'] = realm.uri state[ 'realm_available_video_chat_providers'] = realm.VIDEO_CHAT_PROVIDERS state['realm_presence_disabled'] = realm.presence_disabled state['settings_send_digest_emails'] = settings.SEND_DIGEST_EMAILS state[ 'realm_digest_emails_enabled'] = realm.digest_emails_enabled and settings.SEND_DIGEST_EMAILS state['realm_is_zephyr_mirror_realm'] = realm.is_zephyr_mirror_realm state['realm_email_auth_enabled'] = email_auth_enabled(realm) state['realm_password_auth_enabled'] = password_auth_enabled(realm) state['realm_push_notifications_enabled'] = push_notifications_enabled( ) state['realm_upload_quota'] = realm.upload_quota_bytes() state['realm_plan_type'] = realm.plan_type state['zulip_plan_is_not_limited'] = realm.plan_type != Realm.LIMITED state['upgrade_text_for_wide_organization_logo'] = str( Realm.UPGRADE_TEXT_STANDARD) state['realm_default_external_accounts'] = DEFAULT_EXTERNAL_ACCOUNTS state['jitsi_server_url'] = settings.JITSI_SERVER_URL state['development_environment'] = settings.DEVELOPMENT state['server_generation'] = settings.SERVER_GENERATION state['password_min_length'] = settings.PASSWORD_MIN_LENGTH state['password_min_guesses'] = settings.PASSWORD_MIN_GUESSES state['max_file_upload_size_mib'] = settings.MAX_FILE_UPLOAD_SIZE state['max_avatar_file_size_mib'] = settings.MAX_AVATAR_FILE_SIZE state['server_inline_image_preview'] = settings.INLINE_IMAGE_PREVIEW state[ 'server_inline_url_embed_preview'] = settings.INLINE_URL_EMBED_PREVIEW state[ 'server_avatar_changes_disabled'] = settings.AVATAR_CHANGES_DISABLED state['server_name_changes_disabled'] = settings.NAME_CHANGES_DISABLED if realm.notifications_stream and not realm.notifications_stream.deactivated: notifications_stream = realm.notifications_stream state['realm_notifications_stream_id'] = notifications_stream.id else: state['realm_notifications_stream_id'] = -1 signup_notifications_stream = realm.get_signup_notifications_stream() if signup_notifications_stream: state[ 'realm_signup_notifications_stream_id'] = signup_notifications_stream.id else: state['realm_signup_notifications_stream_id'] = -1 if want('realm_domains'): state['realm_domains'] = get_realm_domains(realm) if want('realm_emoji'): state['realm_emoji'] = realm.get_emoji() if want('realm_filters'): state['realm_filters'] = realm_filters_for_realm(realm.id) if want('realm_user_groups'): state['realm_user_groups'] = user_groups_in_realm_serialized(realm) if want('realm_filtered_user'): state['filtered_users'] = get_filtered_user_data( realm, user_profile, client_gravatar=client_gravatar, user_avatar_url_field_optional=user_avatar_url_field_optional) # For the user's own avatar URL, we force # client_gravatar=False, since that saves some unnecessary # client-side code for handing medium-size avatars. See #8253 # for details. state['avatar_source'] = user_profile.avatar_source state['avatar_url_medium'] = avatar_url( user_profile, medium=True, client_gravatar=False, ) state['avatar_url'] = avatar_url( user_profile, medium=False, client_gravatar=False, ) state['can_create_streams'] = user_profile.can_create_streams() state[ 'can_subscribe_other_users'] = user_profile.can_subscribe_other_users( ) state['cross_realm_bots'] = list(get_cross_realm_dicts()) state['is_admin'] = user_profile.is_realm_admin state['is_owner'] = user_profile.is_realm_owner state['is_guest'] = user_profile.is_guest state['user_id'] = user_profile.id state['enter_sends'] = user_profile.enter_sends state['email'] = user_profile.email state['delivery_email'] = user_profile.delivery_email state['full_name'] = user_profile.full_name if want('realm_user'): state['raw_users'] = get_raw_user_data( realm, user_profile, client_gravatar=client_gravatar, user_avatar_url_field_optional=user_avatar_url_field_optional) # For the user's own avatar URL, we force # client_gravatar=False, since that saves some unnecessary # client-side code for handing medium-size avatars. See #8253 # for details. state['avatar_source'] = user_profile.avatar_source state['avatar_url_medium'] = avatar_url( user_profile, medium=True, client_gravatar=False, ) state['avatar_url'] = avatar_url( user_profile, medium=False, client_gravatar=False, ) state['can_create_streams'] = user_profile.can_create_streams() state[ 'can_subscribe_other_users'] = user_profile.can_subscribe_other_users( ) state['cross_realm_bots'] = list(get_cross_realm_dicts()) state['is_admin'] = user_profile.is_realm_admin state['is_owner'] = user_profile.is_realm_owner state['is_guest'] = user_profile.is_guest state['user_id'] = user_profile.id state['enter_sends'] = user_profile.enter_sends state['email'] = user_profile.email state['delivery_email'] = user_profile.delivery_email state['full_name'] = user_profile.full_name if want('realm_bot'): state['realm_bots'] = get_owned_bot_dicts(user_profile) # This does not yet have an apply_event counterpart, since currently, # new entries for EMBEDDED_BOTS can only be added directly in the codebase. if want('realm_embedded_bots'): realm_embedded_bots = [] for bot in EMBEDDED_BOTS: realm_embedded_bots.append({ 'name': bot.name, 'config': load_bot_config_template(bot.name) }) state['realm_embedded_bots'] = realm_embedded_bots # This does not have an apply_events counterpart either since # this data is mostly static. if want('realm_incoming_webhook_bots'): realm_incoming_webhook_bots = [] for integration in WEBHOOK_INTEGRATIONS: realm_incoming_webhook_bots.append({ 'name': integration.name, 'config': {c[1]: c[0] for c in integration.config_options}, }) state['realm_incoming_webhook_bots'] = realm_incoming_webhook_bots if want('recent_private_conversations'): # A data structure containing records of this form: # # [{'max_message_id': 700175, 'user_ids': [801]}] # # for all recent private message conversations, ordered by the # highest message ID in the conversation. The user_ids list # is the list of users other than the current user in the # private message conversation (so it is [] for PMs to self). # Note that raw_recent_private_conversations is an # intermediate form as a dictionary keyed by recipient_id, # which is more efficient to update, and is rewritten to the # final format in post_process_state. state[ 'raw_recent_private_conversations'] = get_recent_private_conversations( user_profile) if want('subscription'): subscriptions, unsubscribed, never_subscribed = gather_subscriptions_helper( user_profile, include_subscribers=include_subscribers) state['subscriptions'] = subscriptions state['unsubscribed'] = unsubscribed state['never_subscribed'] = never_subscribed if want('update_message_flags') and want('message'): # Keeping unread_msgs updated requires both message flag updates and # message updates. This is due to the fact that new messages will not # generate a flag update so we need to use the flags field in the # message event. state['raw_unread_msgs'] = get_raw_unread_data(user_profile) if want('starred_messages'): state['starred_messages'] = get_starred_message_ids(user_profile) if want('stream'): state['streams'] = do_get_streams(user_profile) state['stream_name_max_length'] = Stream.MAX_NAME_LENGTH state['stream_description_max_length'] = Stream.MAX_DESCRIPTION_LENGTH if want('default_streams'): if user_profile.is_guest: state['realm_default_streams'] = [] else: state['realm_default_streams'] = streams_to_dicts_sorted( get_default_streams_for_realm(realm.id)) if want('default_stream_groups'): if user_profile.is_guest: state['realm_default_stream_groups'] = [] else: state[ 'realm_default_stream_groups'] = default_stream_groups_to_dicts_sorted( get_default_stream_groups(realm)) if want('stop_words'): state['stop_words'] = read_stop_words() if want('update_display_settings'): for prop in UserProfile.property_types: state[prop] = getattr(user_profile, prop) state['emojiset_choices'] = user_profile.emojiset_choices() if want('update_global_notifications'): for notification in UserProfile.notification_setting_types: state[notification] = getattr(user_profile, notification) state[ 'available_notification_sounds'] = get_available_notification_sounds( ) if want('user_status'): state['user_status'] = get_user_info_dict(realm_id=realm.id) if want('video_calls'): state['has_zoom_token'] = user_profile.zoom_token is not None return state
def setUp(self) -> None: super().setUp() self.realm = get_realm("zulip") self.original_count = len( custom_profile_fields_for_realm(self.realm.id))
def fetch_initial_state_data(user_profile, event_types, queue_id, include_subscribers=True): # type: (UserProfile, Optional[Iterable[str]], str, bool) -> Dict[str, Any] state = {'queue_id': queue_id} # type: Dict[str, Any] if event_types is None: want = lambda msg_type: True else: want = set(event_types).__contains__ if want('alert_words'): state['alert_words'] = user_alert_words(user_profile) if want('custom_profile_fields'): fields = custom_profile_fields_for_realm(user_profile.realm.id) state['custom_profile_fields'] = [f.as_dict() for f in fields] if want('attachments'): state['attachments'] = user_attachments(user_profile) if want('hotspots'): state['hotspots'] = get_next_hotspots(user_profile) if want('message'): # The client should use get_messages() to fetch messages # starting with the max_message_id. They will get messages # newer than that ID via get_events() messages = Message.objects.filter(usermessage__user_profile=user_profile).order_by('-id')[:1] if messages: state['max_message_id'] = messages[0].id else: state['max_message_id'] = -1 if want('muted_topics'): state['muted_topics'] = ujson.loads(user_profile.muted_topics) if want('pointer'): state['pointer'] = user_profile.pointer if want('presence'): state['presences'] = get_status_dict(user_profile) if want('realm'): for property_name in Realm.property_types: state['realm_' + property_name] = getattr(user_profile.realm, property_name) # Most state is handled via the property_types framework; # these manual entries are for those realm settings that don't # fit into that framework. state['realm_authentication_methods'] = user_profile.realm.authentication_methods_dict() state['realm_allow_message_editing'] = user_profile.realm.allow_message_editing state['realm_message_content_edit_limit_seconds'] = user_profile.realm.message_content_edit_limit_seconds state['realm_icon_url'] = realm_icon_url(user_profile.realm) state['realm_icon_source'] = user_profile.realm.icon_source state['max_icon_file_size'] = settings.MAX_ICON_FILE_SIZE state['realm_bot_domain'] = user_profile.realm.get_bot_domain() state['realm_uri'] = user_profile.realm.uri state['realm_presence_disabled'] = user_profile.realm.presence_disabled state['realm_show_digest_email'] = user_profile.realm.show_digest_email state['realm_is_zephyr_mirror_realm'] = user_profile.realm.is_zephyr_mirror_realm state['realm_password_auth_enabled'] = password_auth_enabled(user_profile.realm) if user_profile.realm.notifications_stream and not user_profile.realm.notifications_stream.deactivated: notifications_stream = user_profile.realm.notifications_stream state['realm_notifications_stream_id'] = notifications_stream.id else: state['realm_notifications_stream_id'] = -1 if want('realm_domains'): state['realm_domains'] = get_realm_domains(user_profile.realm) if want('realm_emoji'): state['realm_emoji'] = user_profile.realm.get_emoji() if want('realm_filters'): state['realm_filters'] = realm_filters_for_realm(user_profile.realm_id) if want('realm_user'): state['realm_users'] = get_realm_user_dicts(user_profile) state['avatar_source'] = user_profile.avatar_source state['avatar_url_medium'] = avatar_url(user_profile, medium=True) state['avatar_url'] = avatar_url(user_profile) state['can_create_streams'] = user_profile.can_create_streams() state['cross_realm_bots'] = list(get_cross_realm_dicts()) state['is_admin'] = user_profile.is_realm_admin state['user_id'] = user_profile.id state['enter_sends'] = user_profile.enter_sends state['email'] = user_profile.email state['full_name'] = user_profile.full_name if want('realm_bot'): state['realm_bots'] = get_owned_bot_dicts(user_profile) if want('subscription'): subscriptions, unsubscribed, never_subscribed = gather_subscriptions_helper( user_profile, include_subscribers=include_subscribers) state['subscriptions'] = subscriptions state['unsubscribed'] = unsubscribed state['never_subscribed'] = never_subscribed if want('update_message_flags') and want('message'): # Keeping unread_msgs updated requires both message flag updates and # message updates. This is due to the fact that new messages will not # generate a flag update so we need to use the flags field in the # message event. state['unread_msgs'] = get_unread_message_ids_per_recipient(user_profile) if want('stream'): state['streams'] = do_get_streams(user_profile) if want('default_streams'): state['realm_default_streams'] = streams_to_dicts_sorted(get_default_streams_for_realm(user_profile.realm)) if want('update_display_settings'): for prop in UserProfile.property_types: state[prop] = getattr(user_profile, prop) state['emojiset_choices'] = user_profile.emojiset_choices() state['autoscroll_forever'] = user_profile.autoscroll_forever if want('update_global_notifications'): for notification in UserProfile.notification_setting_types: state[notification] = getattr(user_profile, notification) state['default_desktop_notifications'] = user_profile.default_desktop_notifications if want('zulip_version'): state['zulip_version'] = ZULIP_VERSION return state
def notify_realm_custom_profile_fields(realm: Realm) -> None: fields = custom_profile_fields_for_realm(realm.id) event = dict(type="custom_profile_fields", fields=[f.as_dict() for f in fields]) send_event(realm, event, active_user_ids(realm.id))
def fetch_initial_state_data(user_profile, event_types, queue_id, include_subscribers=True): # type: (UserProfile, Optional[Iterable[str]], str, bool) -> Dict[str, Any] state = {'queue_id': queue_id} # type: Dict[str, Any] if event_types is None: want = lambda msg_type: True else: want = set(event_types).__contains__ if want('alert_words'): state['alert_words'] = user_alert_words(user_profile) if want('custom_profile_fields'): fields = custom_profile_fields_for_realm(user_profile.realm.id) state['custom_profile_fields'] = [f.as_dict() for f in fields] if want('attachments'): state['attachments'] = user_attachments(user_profile) if want('hotspots'): state['hotspots'] = get_next_hotspots(user_profile) if want('message'): # The client should use get_messages() to fetch messages # starting with the max_message_id. They will get messages # newer than that ID via get_events() messages = Message.objects.filter(usermessage__user_profile=user_profile).order_by('-id')[:1] if messages: state['max_message_id'] = messages[0].id else: state['max_message_id'] = -1 if want('muted_topics'): state['muted_topics'] = ujson.loads(user_profile.muted_topics) if want('pointer'): state['pointer'] = user_profile.pointer if want('presence'): state['presences'] = get_status_dict(user_profile) if want('realm'): for property_name in Realm.property_types: state['realm_' + property_name] = getattr(user_profile.realm, property_name) state['realm_authentication_methods'] = user_profile.realm.authentication_methods_dict() state['realm_allow_message_editing'] = user_profile.realm.allow_message_editing state['realm_message_content_edit_limit_seconds'] = user_profile.realm.message_content_edit_limit_seconds state['realm_icon_url'] = realm_icon_url(user_profile.realm) state['realm_icon_source'] = user_profile.realm.icon_source state['max_icon_file_size'] = settings.MAX_ICON_FILE_SIZE state['realm_bot_domain'] = user_profile.realm.get_bot_domain() state['realm_uri'] = user_profile.realm.uri state['realm_presence_disabled'] = user_profile.realm.presence_disabled state['realm_mandatory_topics'] = user_profile.realm.mandatory_topics state['realm_show_digest_email'] = user_profile.realm.show_digest_email state['realm_is_zephyr_mirror_realm'] = user_profile.realm.is_zephyr_mirror_realm state['realm_password_auth_enabled'] = password_auth_enabled(user_profile.realm) if user_profile.realm.notifications_stream and not user_profile.realm.notifications_stream.deactivated: notifications_stream = user_profile.realm.notifications_stream state['realm_notifications_stream_id'] = notifications_stream.id else: state['realm_notifications_stream_id'] = -1 if want('realm_domains'): state['realm_domains'] = get_realm_domains(user_profile.realm) if want('realm_emoji'): state['realm_emoji'] = user_profile.realm.get_emoji() if want('realm_filters'): state['realm_filters'] = realm_filters_for_realm(user_profile.realm_id) if want('realm_user'): state['realm_users'] = get_realm_user_dicts(user_profile) state['avatar_source'] = user_profile.avatar_source state['avatar_url_medium'] = avatar_url(user_profile, medium=True) state['avatar_url'] = avatar_url(user_profile) state['can_create_streams'] = user_profile.can_create_streams() state['cross_realm_bots'] = list(get_cross_realm_dicts()) state['is_admin'] = user_profile.is_realm_admin state['user_id'] = user_profile.id state['enter_sends'] = user_profile.enter_sends state['email'] = user_profile.email state['full_name'] = user_profile.full_name if want('realm_bot'): state['realm_bots'] = get_owned_bot_dicts(user_profile) if want('referral'): state['referrals'] = {'granted': user_profile.invites_granted, 'used': user_profile.invites_used} if want('subscription'): subscriptions, unsubscribed, never_subscribed = gather_subscriptions_helper( user_profile, include_subscribers=include_subscribers) state['subscriptions'] = subscriptions state['unsubscribed'] = unsubscribed state['never_subscribed'] = never_subscribed if want('update_message_flags'): # There's no initial data for message flag updates, client will # get any updates during a session from get_events() pass if want('stream'): state['streams'] = do_get_streams(user_profile) if want('default_streams'): state['realm_default_streams'] = streams_to_dicts_sorted(get_default_streams_for_realm(user_profile.realm)) if want('update_display_settings'): state['twenty_four_hour_time'] = user_profile.twenty_four_hour_time state['left_side_userlist'] = user_profile.left_side_userlist state['emoji_alt_code'] = user_profile.emoji_alt_code state['emojiset'] = user_profile.emojiset state['emojiset_choices'] = user_profile.emojiset_choices() state['timezone'] = user_profile.timezone state['default_language'] = user_profile.default_language state['autoscroll_forever'] = user_profile.autoscroll_forever if want('update_global_notifications'): state['default_desktop_notifications'] = user_profile.default_desktop_notifications state['enable_stream_desktop_notifications'] = user_profile.enable_stream_desktop_notifications state['enable_stream_sounds'] = user_profile.enable_stream_sounds state['enable_desktop_notifications'] = user_profile.enable_desktop_notifications state['enable_sounds'] = user_profile.enable_sounds state['enable_offline_email_notifications'] = user_profile.enable_offline_email_notifications state['enable_offline_push_notifications'] = user_profile.enable_offline_push_notifications state['enable_online_push_notifications'] = user_profile.enable_online_push_notifications state['enable_digest_emails'] = user_profile.enable_digest_emails state['pm_content_in_desktop_notifications'] = user_profile.pm_content_in_desktop_notifications if want('zulip_version'): state['zulip_version'] = ZULIP_VERSION return state
def setUp(self) -> None: self.original_count = len( custom_profile_fields_for_realm(get_realm("zulip").id))
def fetch_initial_state_data( user_profile: Optional[UserProfile], *, realm: Optional[Realm] = None, event_types: Optional[Iterable[str]] = None, queue_id: Optional[str] = "", client_gravatar: bool = False, user_avatar_url_field_optional: bool = False, slim_presence: bool = False, include_subscribers: bool = True, include_streams: bool = True, ) -> Dict[str, Any]: """When `event_types` is None, fetches the core data powering the webapp's `page_params` and `/api/v1/register` (for mobile/terminal apps). Can also fetch a subset as determined by `event_types`. The user_profile=None code path is used for logged-out public access to streams with is_web_public=True. Whenever you add new code to this function, you should also add corresponding events for changes in the data structures and new code to apply_events (and add a test in test_events.py). """ if realm is None: assert user_profile is not None realm = user_profile.realm state: Dict[str, Any] = {'queue_id': queue_id} if event_types is None: # return True always want: Callable[[str], bool] = always_want else: want = set(event_types).__contains__ # Show the version info unconditionally. state['zulip_version'] = ZULIP_VERSION state['zulip_feature_level'] = API_FEATURE_LEVEL if want('alert_words'): state['alert_words'] = [] if user_profile is None else user_alert_words(user_profile) if want('custom_profile_fields'): fields = custom_profile_fields_for_realm(realm.id) state['custom_profile_fields'] = [f.as_dict() for f in fields] state['custom_profile_field_types'] = { item[4]: {"id": item[0], "name": str(item[1])} for item in CustomProfileField.ALL_FIELD_TYPES } if want('hotspots'): # Even if we offered special hotspots for guests without an # account, we'd maybe need to store their state using cookies # or local storage, rather than in the database. state['hotspots'] = [] if user_profile is None else get_next_hotspots(user_profile) if want('message'): # Since the introduction of `anchor="latest"` in the API, # `max_message_id` is primarily used for generating `local_id` # values that are higher than this. We likely can eventually # remove this parameter from the API. user_messages = [] if user_profile is not None: user_messages = UserMessage.objects \ .filter(user_profile=user_profile) \ .order_by('-message_id') \ .values('message_id')[:1] if user_messages: state['max_message_id'] = user_messages[0]['message_id'] else: state['max_message_id'] = -1 if want('muted_topics'): state['muted_topics'] = [] if user_profile is None else get_topic_mutes(user_profile) if want('presence'): state['presences'] = {} if user_profile is None else get_presences_for_realm(realm, slim_presence) if want('realm'): for property_name in Realm.property_types: state['realm_' + property_name] = getattr(realm, property_name) # Most state is handled via the property_types framework; # these manual entries are for those realm settings that don't # fit into that framework. state['realm_authentication_methods'] = realm.authentication_methods_dict() # We pretend these features are disabled because guests can't # access them. In the future, we may want to move this logic # to the frontends, so that we can correctly display what # these fields are in the settings. state['realm_allow_message_editing'] = False if user_profile is None else realm.allow_message_editing state['realm_allow_community_topic_editing'] = False if user_profile is None else realm.allow_community_topic_editing state['realm_allow_message_deleting'] = False if user_profile is None else realm.allow_message_deleting state['realm_message_content_edit_limit_seconds'] = realm.message_content_edit_limit_seconds state['realm_message_content_delete_limit_seconds'] = realm.message_content_delete_limit_seconds state['realm_community_topic_editing_limit_seconds'] = \ Realm.DEFAULT_COMMUNITY_TOPIC_EDITING_LIMIT_SECONDS # This setting determines whether to send presence and also # whether to display of users list in the right sidebar; we # want both behaviors for logged-out users. We may in the # future choose to move this logic to the frontend. state['realm_presence_disabled'] = True if user_profile is None else realm.presence_disabled state['realm_icon_url'] = realm_icon_url(realm) state['realm_icon_source'] = realm.icon_source state['max_icon_file_size'] = settings.MAX_ICON_FILE_SIZE add_realm_logo_fields(state, realm) state['realm_bot_domain'] = realm.get_bot_domain() state['realm_uri'] = realm.uri state['realm_available_video_chat_providers'] = realm.VIDEO_CHAT_PROVIDERS state['settings_send_digest_emails'] = settings.SEND_DIGEST_EMAILS state['realm_digest_emails_enabled'] = realm.digest_emails_enabled and settings.SEND_DIGEST_EMAILS state['realm_is_zephyr_mirror_realm'] = realm.is_zephyr_mirror_realm state['realm_email_auth_enabled'] = email_auth_enabled(realm) state['realm_password_auth_enabled'] = password_auth_enabled(realm) state['realm_push_notifications_enabled'] = push_notifications_enabled() state['realm_upload_quota'] = realm.upload_quota_bytes() state['realm_plan_type'] = realm.plan_type state['zulip_plan_is_not_limited'] = realm.plan_type != Realm.LIMITED state['upgrade_text_for_wide_organization_logo'] = str(Realm.UPGRADE_TEXT_STANDARD) state['realm_default_external_accounts'] = DEFAULT_EXTERNAL_ACCOUNTS state['jitsi_server_url'] = settings.JITSI_SERVER_URL.rstrip('/') state['development_environment'] = settings.DEVELOPMENT state['server_generation'] = settings.SERVER_GENERATION state['password_min_length'] = settings.PASSWORD_MIN_LENGTH state['password_min_guesses'] = settings.PASSWORD_MIN_GUESSES state['max_file_upload_size_mib'] = settings.MAX_FILE_UPLOAD_SIZE state['max_avatar_file_size_mib'] = settings.MAX_AVATAR_FILE_SIZE state['server_inline_image_preview'] = settings.INLINE_IMAGE_PREVIEW state['server_inline_url_embed_preview'] = settings.INLINE_URL_EMBED_PREVIEW state['server_avatar_changes_disabled'] = settings.AVATAR_CHANGES_DISABLED state['server_name_changes_disabled'] = settings.NAME_CHANGES_DISABLED if realm.notifications_stream and not realm.notifications_stream.deactivated: notifications_stream = realm.notifications_stream state['realm_notifications_stream_id'] = notifications_stream.id else: state['realm_notifications_stream_id'] = -1 signup_notifications_stream = realm.get_signup_notifications_stream() if signup_notifications_stream: state['realm_signup_notifications_stream_id'] = signup_notifications_stream.id else: state['realm_signup_notifications_stream_id'] = -1 if want('realm_domains'): state['realm_domains'] = get_realm_domains(realm) if want('realm_emoji'): state['realm_emoji'] = realm.get_emoji() if want('realm_filters'): state['realm_filters'] = realm_filters_for_realm(realm.id) if want('realm_user_groups'): state['realm_user_groups'] = user_groups_in_realm_serialized(realm) if user_profile is not None: settings_user = user_profile else: # When UserProfile=None, we want to serve the values for various # settings as the defaults. Instead of copying the default values # from models.py here, we access these default values from a # temporary UserProfile object that will not be saved to the database. # # We also can set various fields to avoid duplicating code # unnecessarily. settings_user = UserProfile( full_name="Anonymous User", email="*****@*****.**", delivery_email="*****@*****.**", realm=realm, # We tag logged-out users as guests because most guest # restrictions apply to these users as well, and it lets # us avoid unnecessary conditionals. role=UserProfile.ROLE_GUEST, avatar_source=UserProfile.AVATAR_FROM_GRAVATAR, # ID=0 is not used in real Zulip databases, ensuring this is unique. id=0, ) if want('realm_user'): state['raw_users'] = get_raw_user_data(realm, user_profile, client_gravatar=client_gravatar, user_avatar_url_field_optional=user_avatar_url_field_optional) state['cross_realm_bots'] = list(get_cross_realm_dicts()) # For the user's own avatar URL, we force # client_gravatar=False, since that saves some unnecessary # client-side code for handing medium-size avatars. See #8253 # for details. state['avatar_source'] = settings_user.avatar_source state['avatar_url_medium'] = avatar_url( settings_user, medium=True, client_gravatar=False, ) state['avatar_url'] = avatar_url( settings_user, medium=False, client_gravatar=False, ) state['can_create_streams'] = settings_user.can_create_streams() state['can_subscribe_other_users'] = settings_user.can_subscribe_other_users() state['is_admin'] = settings_user.is_realm_admin state['is_owner'] = settings_user.is_realm_owner state['is_guest'] = settings_user.is_guest state['user_id'] = settings_user.id state['enter_sends'] = settings_user.enter_sends state['email'] = settings_user.email state['delivery_email'] = settings_user.delivery_email state['full_name'] = settings_user.full_name if want('realm_bot'): state['realm_bots'] = [] if user_profile is None else get_owned_bot_dicts(user_profile) # This does not yet have an apply_event counterpart, since currently, # new entries for EMBEDDED_BOTS can only be added directly in the codebase. if want('realm_embedded_bots'): realm_embedded_bots = [] for bot in EMBEDDED_BOTS: realm_embedded_bots.append({'name': bot.name, 'config': load_bot_config_template(bot.name)}) state['realm_embedded_bots'] = realm_embedded_bots # This does not have an apply_events counterpart either since # this data is mostly static. if want('realm_incoming_webhook_bots'): realm_incoming_webhook_bots = [] for integration in WEBHOOK_INTEGRATIONS: realm_incoming_webhook_bots.append({ 'name': integration.name, 'config': {c[1]: c[0] for c in integration.config_options}, }) state['realm_incoming_webhook_bots'] = realm_incoming_webhook_bots if want('recent_private_conversations'): # A data structure containing records of this form: # # [{'max_message_id': 700175, 'user_ids': [801]}] # # for all recent private message conversations, ordered by the # highest message ID in the conversation. The user_ids list # is the list of users other than the current user in the # private message conversation (so it is [] for PMs to self). # Note that raw_recent_private_conversations is an # intermediate form as a dictionary keyed by recipient_id, # which is more efficient to update, and is rewritten to the # final format in post_process_state. state['raw_recent_private_conversations'] = {} if user_profile is None else get_recent_private_conversations(user_profile) if want('subscription'): if user_profile is not None: sub_info = gather_subscriptions_helper( user_profile, include_subscribers=include_subscribers, ) else: sub_info = get_web_public_subs(realm) state['subscriptions'] = sub_info.subscriptions state['unsubscribed'] = sub_info.unsubscribed state['never_subscribed'] = sub_info.never_subscribed if want('update_message_flags') and want('message'): # Keeping unread_msgs updated requires both message flag updates and # message updates. This is due to the fact that new messages will not # generate a flag update so we need to use the flags field in the # message event. if user_profile is not None: state['raw_unread_msgs'] = get_raw_unread_data(user_profile) else: # For logged-out visitors, we treat all messages as read; # calling this helper lets us return empty objects in the # appropriate format. state['raw_unread_msgs'] = extract_unread_data_from_um_rows([], user_profile) if want('starred_messages'): state['starred_messages'] = [] if user_profile is None else get_starred_message_ids(user_profile) if want('stream'): if include_streams: # The webapp doesn't use the data from here; instead, # it uses data from state["subscriptions"] and other # places. if user_profile is not None: state['streams'] = do_get_streams(user_profile) else: # TODO: This line isn't used by the webapp because it # gets these data via the `subscriptions` key; it will # be used when the mobile apps support logged-out # access. state['streams'] = get_web_public_streams(realm) # nocoverage state['stream_name_max_length'] = Stream.MAX_NAME_LENGTH state['stream_description_max_length'] = Stream.MAX_DESCRIPTION_LENGTH if want('default_streams'): if settings_user.is_guest: # Guest users and logged-out users don't have access to # all default streams, so we pretend the organization # doesn't have any. state['realm_default_streams'] = [] else: state['realm_default_streams'] = streams_to_dicts_sorted( get_default_streams_for_realm(realm.id)) if want('default_stream_groups'): if settings_user.is_guest: state['realm_default_stream_groups'] = [] else: state['realm_default_stream_groups'] = default_stream_groups_to_dicts_sorted( get_default_stream_groups(realm)) if want('stop_words'): state['stop_words'] = read_stop_words() if want('update_display_settings'): for prop in UserProfile.property_types: state[prop] = getattr(settings_user, prop) state['emojiset_choices'] = UserProfile.emojiset_choices() if want('update_global_notifications'): for notification in UserProfile.notification_setting_types: state[notification] = getattr(settings_user, notification) state['available_notification_sounds'] = get_available_notification_sounds() if want('user_status'): # We require creating an account to access statuses. state['user_status'] = {} if user_profile is None else get_user_info_dict(realm_id=realm.id) if want('video_calls'): state['has_zoom_token'] = settings_user.zoom_token is not None return state
def custom_field_exists_in_realm(self, field_id: int) -> bool: fields = custom_profile_fields_for_realm(self.realm.id) field_ids = [field.id for field in fields] return field_id in field_ids
def list_realm_custom_profile_fields(request: HttpRequest, user_profile: UserProfile) -> HttpResponse: fields = custom_profile_fields_for_realm(user_profile.realm_id) return json_success({'custom_fields': [f.as_dict() for f in fields]})
def fetch_initial_state_data( user_profile: UserProfile, event_types: Optional[Iterable[str]], queue_id: str, client_gravatar: bool, include_subscribers: bool = True) -> Dict[str, Any]: state = {'queue_id': queue_id} # type: Dict[str, Any] realm = user_profile.realm if event_types is None: # return True always want = always_want # type: Callable[[str], bool] else: want = set(event_types).__contains__ if want('alert_words'): state['alert_words'] = user_alert_words(user_profile) if want('custom_profile_fields'): fields = custom_profile_fields_for_realm(realm.id) state['custom_profile_fields'] = [f.as_dict() for f in fields] state[ 'custom_profile_field_types'] = CustomProfileField.FIELD_TYPE_CHOICES if want('hotspots'): state['hotspots'] = get_next_hotspots(user_profile) if want('message'): # The client should use get_messages() to fetch messages # starting with the max_message_id. They will get messages # newer than that ID via get_events() messages = Message.objects.filter( usermessage__user_profile=user_profile).order_by('-id')[:1] if messages: state['max_message_id'] = messages[0].id else: state['max_message_id'] = -1 if want('muted_topics'): state['muted_topics'] = get_topic_mutes(user_profile) if want('pointer'): state['pointer'] = user_profile.pointer if want('presence'): state['presences'] = get_status_dict(user_profile) if want('realm'): for property_name in Realm.property_types: state['realm_' + property_name] = getattr(realm, property_name) # Most state is handled via the property_types framework; # these manual entries are for those realm settings that don't # fit into that framework. state[ 'realm_authentication_methods'] = realm.authentication_methods_dict( ) state['realm_allow_message_editing'] = realm.allow_message_editing state[ 'realm_allow_community_topic_editing'] = realm.allow_community_topic_editing state['realm_allow_message_deleting'] = realm.allow_message_deleting state[ 'realm_message_content_edit_limit_seconds'] = realm.message_content_edit_limit_seconds state[ 'realm_message_content_delete_limit_seconds'] = realm.message_content_delete_limit_seconds state['realm_icon_url'] = realm_icon_url(realm) state['realm_icon_source'] = realm.icon_source state['max_icon_file_size'] = settings.MAX_ICON_FILE_SIZE state['realm_bot_domain'] = realm.get_bot_domain() state['realm_uri'] = realm.uri state[ 'realm_available_video_chat_providers'] = realm.VIDEO_CHAT_PROVIDERS state['realm_presence_disabled'] = realm.presence_disabled state[ 'realm_digest_emails_enabled'] = realm.digest_emails_enabled and settings.SEND_DIGEST_EMAILS state['realm_is_zephyr_mirror_realm'] = realm.is_zephyr_mirror_realm state['realm_email_auth_enabled'] = email_auth_enabled(realm) state['realm_password_auth_enabled'] = password_auth_enabled(realm) state['realm_push_notifications_enabled'] = push_notifications_enabled( ) if realm.notifications_stream and not realm.notifications_stream.deactivated: notifications_stream = realm.notifications_stream state['realm_notifications_stream_id'] = notifications_stream.id else: state['realm_notifications_stream_id'] = -1 signup_notifications_stream = realm.get_signup_notifications_stream() if signup_notifications_stream: state[ 'realm_signup_notifications_stream_id'] = signup_notifications_stream.id else: state['realm_signup_notifications_stream_id'] = -1 if want('realm_domains'): state['realm_domains'] = get_realm_domains(realm) if want('realm_emoji'): state['realm_emoji'] = realm.get_emoji() if want('realm_filters'): state['realm_filters'] = realm_filters_for_realm(realm.id) if want('realm_user_groups'): state['realm_user_groups'] = user_groups_in_realm_serialized(realm) if want('realm_user'): state['raw_users'] = get_raw_user_data( realm_id=realm.id, client_gravatar=client_gravatar, ) # For the user's own avatar URL, we force # client_gravatar=False, since that saves some unnecessary # client-side code for handing medium-size avatars. See #8253 # for details. state['avatar_source'] = user_profile.avatar_source state['avatar_url_medium'] = avatar_url( user_profile, medium=True, client_gravatar=False, ) state['avatar_url'] = avatar_url( user_profile, medium=False, client_gravatar=False, ) state['can_create_streams'] = user_profile.can_create_streams() state['cross_realm_bots'] = list(get_cross_realm_dicts()) state['is_admin'] = user_profile.is_realm_admin state['is_guest'] = user_profile.is_guest state['user_id'] = user_profile.id state['enter_sends'] = user_profile.enter_sends state['email'] = user_profile.email state['delivery_email'] = user_profile.delivery_email state['full_name'] = user_profile.full_name if want('realm_bot'): state['realm_bots'] = get_owned_bot_dicts(user_profile) # This does not yet have an apply_event counterpart, since currently, # new entries for EMBEDDED_BOTS can only be added directly in the codebase. if want('realm_embedded_bots'): realm_embedded_bots = [] for bot in EMBEDDED_BOTS: realm_embedded_bots.append({ 'name': bot.name, 'config': load_bot_config_template(bot.name) }) state['realm_embedded_bots'] = realm_embedded_bots if want('subscription'): subscriptions, unsubscribed, never_subscribed = gather_subscriptions_helper( user_profile, include_subscribers=include_subscribers) state['subscriptions'] = subscriptions state['unsubscribed'] = unsubscribed state['never_subscribed'] = never_subscribed if want('update_message_flags') and want('message'): # Keeping unread_msgs updated requires both message flag updates and # message updates. This is due to the fact that new messages will not # generate a flag update so we need to use the flags field in the # message event. state['raw_unread_msgs'] = get_raw_unread_data(user_profile) if want('stream'): state['streams'] = do_get_streams(user_profile) state['stream_name_max_length'] = Stream.MAX_NAME_LENGTH state['stream_description_max_length'] = Stream.MAX_DESCRIPTION_LENGTH if want('default_streams'): state['realm_default_streams'] = streams_to_dicts_sorted( get_default_streams_for_realm(realm.id)) if want('default_stream_groups'): state[ 'realm_default_stream_groups'] = default_stream_groups_to_dicts_sorted( get_default_stream_groups(realm)) if want('update_display_settings'): for prop in UserProfile.property_types: state[prop] = getattr(user_profile, prop) state['emojiset_choices'] = user_profile.emojiset_choices() if want('update_global_notifications'): for notification in UserProfile.notification_setting_types: state[notification] = getattr(user_profile, notification) if want('zulip_version'): state['zulip_version'] = ZULIP_VERSION return state
def list_realm_custom_profile_fields( request: HttpRequest, user_profile: UserProfile) -> HttpResponse: fields = custom_profile_fields_for_realm(user_profile.realm_id) return json_success({"custom_fields": [f.as_dict() for f in fields]})