mirror of https://github.com/zulip/zulip.git
Add realm-level settings to control inline image and url preview.
This gives users more control in case they don't want previews, especially for the "previews of linked websites" feature. Fixes: #2640.
This commit is contained in:
parent
a27f8f2f30
commit
bddcfb1c96
|
@ -381,6 +381,10 @@ function _setup_page() {
|
||||||
realm_restricted_to_domain: page_params.realm_restricted_to_domain,
|
realm_restricted_to_domain: page_params.realm_restricted_to_domain,
|
||||||
realm_invite_required: page_params.realm_invite_required,
|
realm_invite_required: page_params.realm_invite_required,
|
||||||
realm_invite_by_admins_only: page_params.realm_invite_by_admins_only,
|
realm_invite_by_admins_only: page_params.realm_invite_by_admins_only,
|
||||||
|
realm_inline_image_preview: page_params.realm_inline_image_preview,
|
||||||
|
server_inline_image_preview: page_params.server_inline_image_preview,
|
||||||
|
realm_inline_url_embed_preview: page_params.realm_inline_url_embed_preview,
|
||||||
|
server_inline_url_embed_preview: page_params.server_inline_url_embed_preview,
|
||||||
realm_authentication_methods: page_params.realm_authentication_methods,
|
realm_authentication_methods: page_params.realm_authentication_methods,
|
||||||
realm_create_stream_by_admins_only: page_params.realm_create_stream_by_admins_only,
|
realm_create_stream_by_admins_only: page_params.realm_create_stream_by_admins_only,
|
||||||
realm_name_changes_disabled: page_params.realm_name_changes_disabled,
|
realm_name_changes_disabled: page_params.realm_name_changes_disabled,
|
||||||
|
@ -623,6 +627,8 @@ function _setup_page() {
|
||||||
var restricted_to_domain_status = $("#admin-realm-restricted-to-domain-status").expectOne();
|
var restricted_to_domain_status = $("#admin-realm-restricted-to-domain-status").expectOne();
|
||||||
var invite_required_status = $("#admin-realm-invite-required-status").expectOne();
|
var invite_required_status = $("#admin-realm-invite-required-status").expectOne();
|
||||||
var invite_by_admins_only_status = $("#admin-realm-invite-by-admins-only-status").expectOne();
|
var invite_by_admins_only_status = $("#admin-realm-invite-by-admins-only-status").expectOne();
|
||||||
|
var inline_image_preview_status = $("#admin-realm-inline-image-preview-status").expectOne();
|
||||||
|
var inline_url_embed_preview_status = $("#admin-realm-inline-url-embed-preview-status").expectOne();
|
||||||
var authentication_methods_status = $("#admin-realm-authentication-methods-status").expectOne();
|
var authentication_methods_status = $("#admin-realm-authentication-methods-status").expectOne();
|
||||||
var create_stream_by_admins_only_status = $("#admin-realm-create-stream-by-admins-only-status").expectOne();
|
var create_stream_by_admins_only_status = $("#admin-realm-create-stream-by-admins-only-status").expectOne();
|
||||||
var name_changes_disabled_status = $("#admin-realm-name-changes-disabled-status").expectOne();
|
var name_changes_disabled_status = $("#admin-realm-name-changes-disabled-status").expectOne();
|
||||||
|
@ -636,6 +642,8 @@ function _setup_page() {
|
||||||
restricted_to_domain_status.hide();
|
restricted_to_domain_status.hide();
|
||||||
invite_required_status.hide();
|
invite_required_status.hide();
|
||||||
invite_by_admins_only_status.hide();
|
invite_by_admins_only_status.hide();
|
||||||
|
inline_image_preview_status.hide();
|
||||||
|
inline_url_embed_preview_status.hide();
|
||||||
authentication_methods_status.hide();
|
authentication_methods_status.hide();
|
||||||
create_stream_by_admins_only_status.hide();
|
create_stream_by_admins_only_status.hide();
|
||||||
name_changes_disabled_status.hide();
|
name_changes_disabled_status.hide();
|
||||||
|
@ -653,6 +661,8 @@ function _setup_page() {
|
||||||
var new_restricted = $("#id_realm_restricted_to_domain").prop("checked");
|
var new_restricted = $("#id_realm_restricted_to_domain").prop("checked");
|
||||||
var new_invite = $("#id_realm_invite_required").prop("checked");
|
var new_invite = $("#id_realm_invite_required").prop("checked");
|
||||||
var new_invite_by_admins_only = $("#id_realm_invite_by_admins_only").prop("checked");
|
var new_invite_by_admins_only = $("#id_realm_invite_by_admins_only").prop("checked");
|
||||||
|
var new_inline_image_preview = $("#id_realm_inline_image_preview").prop("checked");
|
||||||
|
var new_inline_url_embed_preview = $("#id_realm_inline_url_embed_preview").prop("checked");
|
||||||
var new_create_stream_by_admins_only = $("#id_realm_create_stream_by_admins_only").prop("checked");
|
var new_create_stream_by_admins_only = $("#id_realm_create_stream_by_admins_only").prop("checked");
|
||||||
var new_name_changes_disabled = $("#id_realm_name_changes_disabled").prop("checked");
|
var new_name_changes_disabled = $("#id_realm_name_changes_disabled").prop("checked");
|
||||||
var new_email_changes_disabled = $("#id_realm_email_changes_disabled").prop("checked");
|
var new_email_changes_disabled = $("#id_realm_email_changes_disabled").prop("checked");
|
||||||
|
@ -685,6 +695,8 @@ function _setup_page() {
|
||||||
restricted_to_domain: JSON.stringify(new_restricted),
|
restricted_to_domain: JSON.stringify(new_restricted),
|
||||||
invite_required: JSON.stringify(new_invite),
|
invite_required: JSON.stringify(new_invite),
|
||||||
invite_by_admins_only: JSON.stringify(new_invite_by_admins_only),
|
invite_by_admins_only: JSON.stringify(new_invite_by_admins_only),
|
||||||
|
inline_image_preview: JSON.stringify(new_inline_image_preview),
|
||||||
|
inline_url_embed_preview: JSON.stringify(new_inline_url_embed_preview),
|
||||||
authentication_methods: JSON.stringify(new_auth_methods),
|
authentication_methods: JSON.stringify(new_auth_methods),
|
||||||
create_stream_by_admins_only: JSON.stringify(new_create_stream_by_admins_only),
|
create_stream_by_admins_only: JSON.stringify(new_create_stream_by_admins_only),
|
||||||
name_changes_disabled: JSON.stringify(new_name_changes_disabled),
|
name_changes_disabled: JSON.stringify(new_name_changes_disabled),
|
||||||
|
@ -728,6 +740,20 @@ function _setup_page() {
|
||||||
ui_report.success(i18n.t("Any user may now invite new users!"), invite_by_admins_only_status);
|
ui_report.success(i18n.t("Any user may now invite new users!"), invite_by_admins_only_status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (response_data.inline_image_preview !== undefined) {
|
||||||
|
if (response_data.inline_image_preview) {
|
||||||
|
ui.report_success(i18n.t("Previews of uploaded and linked images will be shown!"), inline_image_preview_status);
|
||||||
|
} else {
|
||||||
|
ui.report_success(i18n.t("Previews of uploaded and linked images will not be shown!"), inline_image_preview_status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (response_data.inline_url_embed_preview !== undefined) {
|
||||||
|
if (response_data.inline_url_embed_preview) {
|
||||||
|
ui.report_success(i18n.t("Previews for linked websites will be shown!"), inline_url_embed_preview_status);
|
||||||
|
} else {
|
||||||
|
ui.report_success(i18n.t("Previews for linked websites will not be shown!"), inline_url_embed_preview_status);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (response_data.create_stream_by_admins_only !== undefined) {
|
if (response_data.create_stream_by_admins_only !== undefined) {
|
||||||
if (response_data.create_stream_by_admins_only) {
|
if (response_data.create_stream_by_admins_only) {
|
||||||
ui_report.success(i18n.t("Only administrators may now create new streams!"), create_stream_by_admins_only_status);
|
ui_report.success(i18n.t("Only administrators may now create new streams!"), create_stream_by_admins_only_status);
|
||||||
|
|
|
@ -62,6 +62,10 @@ function dispatch_normal_event(event) {
|
||||||
page_params.realm_invite_required = event.value;
|
page_params.realm_invite_required = event.value;
|
||||||
} else if (event.op === 'update' && event.property === 'invite_by_admins_only') {
|
} else if (event.op === 'update' && event.property === 'invite_by_admins_only') {
|
||||||
page_params.realm_invite_by_admins_only = event.value;
|
page_params.realm_invite_by_admins_only = event.value;
|
||||||
|
} else if (event.op === 'update' && event.property === 'inline_image_preview') {
|
||||||
|
page_params.realm_inline_image_preview = event.value;
|
||||||
|
} else if (event.op === 'update' && event.property === 'inline_url_embed_preview') {
|
||||||
|
page_params.realm_inline_url_embed_preview = event.value;
|
||||||
} else if (event.op === 'update' && event.property === 'create_stream_by_admins_only') {
|
} else if (event.op === 'update' && event.property === 'create_stream_by_admins_only') {
|
||||||
page_params.realm_create_stream_by_admins_only = event.value;
|
page_params.realm_create_stream_by_admins_only = event.value;
|
||||||
if (!page_params.is_admin) {
|
if (!page_params.is_admin) {
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
<div class="alert" id="admin-realm-restricted-to-domain-status"></div>
|
<div class="alert" id="admin-realm-restricted-to-domain-status"></div>
|
||||||
<div class="alert" id="admin-realm-invite-required-status"></div>
|
<div class="alert" id="admin-realm-invite-required-status"></div>
|
||||||
<div class="alert" id="admin-realm-invite-by-admins-only-status"></div>
|
<div class="alert" id="admin-realm-invite-by-admins-only-status"></div>
|
||||||
|
<div class="alert" id="admin-realm-inline-image-preview-status"></div>
|
||||||
|
<div class="alert" id="admin-realm-inline-url-embed-preview-status"></div>
|
||||||
<div class="alert" id="admin-realm-create-stream-by-admins-only-status"></div>
|
<div class="alert" id="admin-realm-create-stream-by-admins-only-status"></div>
|
||||||
<div class="alert" id="admin-realm-add-emoji-by-admins-only-status"></div>
|
<div class="alert" id="admin-realm-add-emoji-by-admins-only-status"></div>
|
||||||
<div class="alert" id="admin-realm-message-editing-status"></div>
|
<div class="alert" id="admin-realm-message-editing-status"></div>
|
||||||
|
@ -55,6 +57,30 @@
|
||||||
{{t "Only admins may invite" }}
|
{{t "Only admins may invite" }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
{{#if server_inline_image_preview}}
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="checkbox" class="inline-block" id="id_realm_inline_image_preview" name="realm_inline_image_preview"
|
||||||
|
{{#if realm_inline_image_preview}}checked="checked"{{/if}} />
|
||||||
|
<label for="id_realm_inline_image_preview"
|
||||||
|
id="id_realm_inline_image_preview_label"
|
||||||
|
title="{{t 'If checked, image previews will be shown.' }}"
|
||||||
|
class="inline-block" style="width:initial">
|
||||||
|
{{t "Show previews of uploaded and linked images" }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if server_inline_url_embed_preview}}
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="checkbox" class="inline-block" id="id_realm_inline_url_embed_preview" name="realm_inline_url_embed_preview"
|
||||||
|
{{#if realm_inline_url_embed_preview}}checked="checked"{{/if}} />
|
||||||
|
<label for="id_realm_inline_url_embed_preview"
|
||||||
|
id="id_realm_inline_url_embed_preview_label"
|
||||||
|
title="{{t 'If checked, previews of linked websites will be shown.' }}"
|
||||||
|
class="inline-block">
|
||||||
|
{{t "Show previews of linked websites" }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="checkbox" class="inline-block" id="id_realm_create_stream_by_admins_only"
|
<input type="checkbox" class="inline-block" id="id_realm_create_stream_by_admins_only"
|
||||||
name="realm_create_stream_by_admins_only"
|
name="realm_create_stream_by_admins_only"
|
||||||
|
|
|
@ -12,7 +12,8 @@ from django.core import validators
|
||||||
from analytics.lib.counts import COUNT_STATS, do_increment_logging_stat
|
from analytics.lib.counts import COUNT_STATS, do_increment_logging_stat
|
||||||
from zerver.lib.bugdown import (
|
from zerver.lib.bugdown import (
|
||||||
BugdownRenderingException,
|
BugdownRenderingException,
|
||||||
version as bugdown_version
|
version as bugdown_version,
|
||||||
|
url_embed_preview_enabled_for_realm
|
||||||
)
|
)
|
||||||
from zerver.lib.cache import (
|
from zerver.lib.cache import (
|
||||||
to_dict_cache_key,
|
to_dict_cache_key,
|
||||||
|
@ -479,6 +480,30 @@ def do_set_realm_invite_by_admins_only(realm, invite_by_admins_only):
|
||||||
)
|
)
|
||||||
send_event(event, active_user_ids(realm))
|
send_event(event, active_user_ids(realm))
|
||||||
|
|
||||||
|
def do_set_realm_inline_image_preview(realm, inline_image_preview):
|
||||||
|
# type: (Realm, bool) -> None
|
||||||
|
realm.inline_image_preview = inline_image_preview
|
||||||
|
realm.save(update_fields=['inline_image_preview'])
|
||||||
|
event = dict(
|
||||||
|
type="realm",
|
||||||
|
op="update",
|
||||||
|
property='inline_image_preview',
|
||||||
|
value=inline_image_preview,
|
||||||
|
)
|
||||||
|
send_event(event, active_user_ids(realm))
|
||||||
|
|
||||||
|
def do_set_realm_inline_url_embed_preview(realm, inline_url_embed_preview):
|
||||||
|
# type: (Realm, bool) -> None
|
||||||
|
realm.inline_url_embed_preview = inline_url_embed_preview
|
||||||
|
realm.save(update_fields=['inline_url_embed_preview'])
|
||||||
|
event = dict(
|
||||||
|
type="realm",
|
||||||
|
op="update",
|
||||||
|
property='inline_url_embed_preview',
|
||||||
|
value=inline_url_embed_preview,
|
||||||
|
)
|
||||||
|
send_event(event, active_user_ids(realm))
|
||||||
|
|
||||||
def do_set_realm_authentication_methods(realm, authentication_methods):
|
def do_set_realm_authentication_methods(realm, authentication_methods):
|
||||||
# type: (Realm, Dict[str, bool]) -> None
|
# type: (Realm, Dict[str, bool]) -> None
|
||||||
for key, value in list(authentication_methods.items()):
|
for key, value in list(authentication_methods.items()):
|
||||||
|
@ -924,7 +949,7 @@ def do_send_messages(messages_maybe_none):
|
||||||
event['sender_queue_id'] = message['sender_queue_id']
|
event['sender_queue_id'] = message['sender_queue_id']
|
||||||
send_event(event, users)
|
send_event(event, users)
|
||||||
|
|
||||||
if settings.INLINE_URL_EMBED_PREVIEW and links_for_embed:
|
if url_embed_preview_enabled_for_realm(message['message']) and links_for_embed:
|
||||||
event_data = {
|
event_data = {
|
||||||
'message_id': message['message'].id,
|
'message_id': message['message'].id,
|
||||||
'message_content': message['message'].content,
|
'message_content': message['message'].content,
|
||||||
|
|
|
@ -63,6 +63,32 @@ if False:
|
||||||
class BugdownRenderingException(Exception):
|
class BugdownRenderingException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def url_embed_preview_enabled_for_realm(message):
|
||||||
|
# type: (Message) -> bool
|
||||||
|
if message is not None:
|
||||||
|
realm = message.get_realm()
|
||||||
|
else:
|
||||||
|
realm = None
|
||||||
|
|
||||||
|
if not settings.INLINE_URL_EMBED_PREVIEW:
|
||||||
|
return False
|
||||||
|
if realm is None:
|
||||||
|
return True
|
||||||
|
return realm.inline_url_embed_preview
|
||||||
|
|
||||||
|
def image_preview_enabled_for_realm():
|
||||||
|
# type: () -> bool
|
||||||
|
global current_message
|
||||||
|
if current_message is not None:
|
||||||
|
realm = current_message.get_realm()
|
||||||
|
else:
|
||||||
|
realm = None
|
||||||
|
if not settings.INLINE_IMAGE_PREVIEW:
|
||||||
|
return False
|
||||||
|
if realm is None:
|
||||||
|
return True
|
||||||
|
return realm.inline_image_preview
|
||||||
|
|
||||||
def unescape(s):
|
def unescape(s):
|
||||||
# type: (Text) -> (Text)
|
# type: (Text) -> (Text)
|
||||||
if six.PY2:
|
if six.PY2:
|
||||||
|
@ -327,7 +353,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
|
||||||
|
|
||||||
def is_image(self, url):
|
def is_image(self, url):
|
||||||
# type: (Text) -> bool
|
# type: (Text) -> bool
|
||||||
if not settings.INLINE_IMAGE_PREVIEW:
|
if not image_preview_enabled_for_realm():
|
||||||
return False
|
return False
|
||||||
parsed_url = urllib.parse.urlparse(url)
|
parsed_url = urllib.parse.urlparse(url)
|
||||||
# List from http://support.google.com/chromeos/bin/answer.py?hl=en&answer=183093
|
# List from http://support.google.com/chromeos/bin/answer.py?hl=en&answer=183093
|
||||||
|
@ -384,7 +410,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
|
||||||
|
|
||||||
def youtube_id(self, url):
|
def youtube_id(self, url):
|
||||||
# type: (Text) -> Optional[Text]
|
# type: (Text) -> Optional[Text]
|
||||||
if not settings.INLINE_IMAGE_PREVIEW:
|
if not image_preview_enabled_for_realm():
|
||||||
return None
|
return None
|
||||||
# Youtube video id extraction regular expression from http://pastebin.com/KyKAFv1s
|
# Youtube video id extraction regular expression from http://pastebin.com/KyKAFv1s
|
||||||
# If it matches, match.group(2) is the video id.
|
# If it matches, match.group(2) is the video id.
|
||||||
|
@ -620,7 +646,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
|
||||||
if db_data and db_data['sent_by_bot']:
|
if db_data and db_data['sent_by_bot']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if current_message is None or not settings.INLINE_URL_EMBED_PREVIEW:
|
if current_message is None or not url_embed_preview_enabled_for_realm(current_message):
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
extracted_data = link_preview.link_embed_data_from_cache(url)
|
extracted_data = link_preview.link_embed_data_from_cache(url)
|
||||||
|
|
|
@ -97,6 +97,8 @@ def fetch_initial_state_data(user_profile, event_types, queue_id,
|
||||||
state['realm_restricted_to_domain'] = user_profile.realm.restricted_to_domain
|
state['realm_restricted_to_domain'] = user_profile.realm.restricted_to_domain
|
||||||
state['realm_invite_required'] = user_profile.realm.invite_required
|
state['realm_invite_required'] = user_profile.realm.invite_required
|
||||||
state['realm_invite_by_admins_only'] = user_profile.realm.invite_by_admins_only
|
state['realm_invite_by_admins_only'] = user_profile.realm.invite_by_admins_only
|
||||||
|
state['realm_inline_image_preview'] = user_profile.realm.inline_image_preview
|
||||||
|
state['realm_inline_url_embed_preview'] = user_profile.realm.inline_url_embed_preview
|
||||||
state['realm_authentication_methods'] = user_profile.realm.authentication_methods_dict()
|
state['realm_authentication_methods'] = user_profile.realm.authentication_methods_dict()
|
||||||
state['realm_create_stream_by_admins_only'] = user_profile.realm.create_stream_by_admins_only
|
state['realm_create_stream_by_admins_only'] = user_profile.realm.create_stream_by_admins_only
|
||||||
state['realm_add_emoji_by_admins_only'] = user_profile.realm.add_emoji_by_admins_only
|
state['realm_add_emoji_by_admins_only'] = user_profile.realm.add_emoji_by_admins_only
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-21 15:56
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('zerver', '0064_sync_uploads_filesize_with_db'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='realm',
|
||||||
|
name='inline_image_preview',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-21 15:58
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('zerver', '0065_realm_inline_image_preview'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='realm',
|
||||||
|
name='inline_url_embed_preview',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -116,6 +116,8 @@ class Realm(ModelReprMixin, models.Model):
|
||||||
restricted_to_domain = models.BooleanField(default=False) # type: bool
|
restricted_to_domain = models.BooleanField(default=False) # type: bool
|
||||||
invite_required = models.BooleanField(default=True) # type: bool
|
invite_required = models.BooleanField(default=True) # type: bool
|
||||||
invite_by_admins_only = models.BooleanField(default=False) # type: bool
|
invite_by_admins_only = models.BooleanField(default=False) # type: bool
|
||||||
|
inline_image_preview = models.BooleanField(default=True) # type: bool
|
||||||
|
inline_url_embed_preview = models.BooleanField(default=True) # type: bool
|
||||||
create_stream_by_admins_only = models.BooleanField(default=False) # type: bool
|
create_stream_by_admins_only = models.BooleanField(default=False) # type: bool
|
||||||
add_emoji_by_admins_only = models.BooleanField(default=False) # type: bool
|
add_emoji_by_admins_only = models.BooleanField(default=False) # type: bool
|
||||||
mandatory_topics = models.BooleanField(default=False) # type: bool
|
mandatory_topics = models.BooleanField(default=False) # type: bool
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.test import TestCase
|
from django.test import TestCase, override_settings
|
||||||
|
|
||||||
from zerver.lib import bugdown
|
from zerver.lib import bugdown
|
||||||
from zerver.lib.actions import (
|
from zerver.lib.actions import (
|
||||||
|
@ -37,6 +37,7 @@ from zerver.models import (
|
||||||
Recipient,
|
Recipient,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import copy
|
||||||
import mock
|
import mock
|
||||||
import os
|
import os
|
||||||
import ujson
|
import ujson
|
||||||
|
@ -229,6 +230,65 @@ class BugdownTest(TestCase):
|
||||||
|
|
||||||
self.assertEqual(converted, '<p>Check out the debate: <a href="http://www.youtube.com/watch?v=hx1mjT73xYE" target="_blank" title="http://www.youtube.com/watch?v=hx1mjT73xYE">http://www.youtube.com/watch?v=hx1mjT73xYE</a></p>\n<div class="youtube-video message_inline_image"><a data-id="hx1mjT73xYE" href="http://www.youtube.com/watch?v=hx1mjT73xYE" target="_blank" title="http://www.youtube.com/watch?v=hx1mjT73xYE"><img src="https://i.ytimg.com/vi/hx1mjT73xYE/default.jpg"></a></div>')
|
self.assertEqual(converted, '<p>Check out the debate: <a href="http://www.youtube.com/watch?v=hx1mjT73xYE" target="_blank" title="http://www.youtube.com/watch?v=hx1mjT73xYE">http://www.youtube.com/watch?v=hx1mjT73xYE</a></p>\n<div class="youtube-video message_inline_image"><a data-id="hx1mjT73xYE" href="http://www.youtube.com/watch?v=hx1mjT73xYE" target="_blank" title="http://www.youtube.com/watch?v=hx1mjT73xYE"><img src="https://i.ytimg.com/vi/hx1mjT73xYE/default.jpg"></a></div>')
|
||||||
|
|
||||||
|
@override_settings(INLINE_IMAGE_PREVIEW=True)
|
||||||
|
def test_inline_image_preview(self):
|
||||||
|
# type: () -> None
|
||||||
|
with_preview = '<p><a href="http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg" target="_blank" title="http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg">http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg</a></p>\n<div class="message_inline_image"><a href="http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg" target="_blank" title="http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg"><img src="https://external-content.zulipcdn.net/389b5d7148a0cbc7475ed564e1b03ceb476bdacb/687474703a2f2f63646e2e77616c6c70617065727361666172692e636f6d2f31332f362f313665566a782e6a706567"></a></div>'
|
||||||
|
without_preview = '<p><a href="http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg" target="_blank" title="http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg">http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg</a></p>'
|
||||||
|
content = 'http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg'
|
||||||
|
|
||||||
|
sender_user_profile = get_user_profile_by_email("othello@zulip.com")
|
||||||
|
msg = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
||||||
|
converted = render_markdown(msg, content)
|
||||||
|
self.assertEqual(converted, with_preview)
|
||||||
|
|
||||||
|
realm = msg.get_realm()
|
||||||
|
setattr(realm, 'inline_image_preview', False)
|
||||||
|
realm.save()
|
||||||
|
|
||||||
|
sender_user_profile = get_user_profile_by_email("othello@zulip.com")
|
||||||
|
msg = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
||||||
|
converted = render_markdown(msg, content)
|
||||||
|
self.assertEqual(converted, without_preview)
|
||||||
|
|
||||||
|
@override_settings(INLINE_IMAGE_PREVIEW=False)
|
||||||
|
def test_image_preview_enabled_for_realm(self):
|
||||||
|
# type: () -> None
|
||||||
|
ret = bugdown.image_preview_enabled_for_realm()
|
||||||
|
self.assertEqual(ret, False)
|
||||||
|
|
||||||
|
settings.INLINE_IMAGE_PREVIEW = True
|
||||||
|
|
||||||
|
sender_user_profile = get_user_profile_by_email("othello@zulip.com")
|
||||||
|
bugdown.current_message = copy.deepcopy(Message(sender=sender_user_profile, sending_client=get_client("test")))
|
||||||
|
realm = bugdown.current_message.get_realm()
|
||||||
|
|
||||||
|
ret = bugdown.image_preview_enabled_for_realm()
|
||||||
|
self.assertEqual(ret, realm.inline_image_preview)
|
||||||
|
|
||||||
|
bugdown.current_message = None
|
||||||
|
ret = bugdown.image_preview_enabled_for_realm()
|
||||||
|
self.assertEqual(ret, True)
|
||||||
|
|
||||||
|
@override_settings(INLINE_URL_EMBED_PREVIEW=False)
|
||||||
|
def test_url_embed_preview_enabled_for_realm(self):
|
||||||
|
# type: () -> None
|
||||||
|
sender_user_profile = get_user_profile_by_email("othello@zulip.com")
|
||||||
|
message = copy.deepcopy(Message(sender=sender_user_profile, sending_client=get_client("test")))
|
||||||
|
realm = message.get_realm()
|
||||||
|
|
||||||
|
ret = bugdown.url_embed_preview_enabled_for_realm(message)
|
||||||
|
self.assertEqual(ret, False)
|
||||||
|
|
||||||
|
settings.INLINE_URL_EMBED_PREVIEW = True
|
||||||
|
|
||||||
|
ret = bugdown.url_embed_preview_enabled_for_realm(message)
|
||||||
|
self.assertEqual(ret, realm.inline_image_preview)
|
||||||
|
|
||||||
|
message = None
|
||||||
|
ret = bugdown.url_embed_preview_enabled_for_realm(message)
|
||||||
|
self.assertEqual(ret, True)
|
||||||
|
|
||||||
def test_inline_dropbox(self):
|
def test_inline_dropbox(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
msg = 'Look at how hilarious our old office was: https://www.dropbox.com/s/ymdijjcg67hv2ta/IMG_0923.JPG'
|
msg = 'Look at how hilarious our old office was: https://www.dropbox.com/s/ymdijjcg67hv2ta/IMG_0923.JPG'
|
||||||
|
|
|
@ -51,6 +51,8 @@ from zerver.lib.actions import (
|
||||||
do_set_realm_invite_by_admins_only,
|
do_set_realm_invite_by_admins_only,
|
||||||
do_set_name_changes_disabled,
|
do_set_name_changes_disabled,
|
||||||
do_set_email_changes_disabled,
|
do_set_email_changes_disabled,
|
||||||
|
do_set_realm_inline_image_preview,
|
||||||
|
do_set_realm_inline_url_embed_preview,
|
||||||
do_set_realm_message_editing,
|
do_set_realm_message_editing,
|
||||||
do_set_realm_default_language,
|
do_set_realm_default_language,
|
||||||
do_set_realm_authentication_methods,
|
do_set_realm_authentication_methods,
|
||||||
|
@ -711,6 +713,34 @@ class EventsRegisterTest(ZulipTestCase):
|
||||||
error = schema_checker('events[0]', events[0])
|
error = schema_checker('events[0]', events[0])
|
||||||
self.assert_on_error(error)
|
self.assert_on_error(error)
|
||||||
|
|
||||||
|
def test_change_realm_inline_image_preview(self):
|
||||||
|
# type: () -> None
|
||||||
|
schema_checker = check_dict([
|
||||||
|
('type', equals('realm')),
|
||||||
|
('op', equals('update')),
|
||||||
|
('property', equals('inline_image_preview')),
|
||||||
|
('value', check_bool),
|
||||||
|
])
|
||||||
|
do_set_realm_inline_image_preview(self.user_profile.realm, inline_image_preview=False)
|
||||||
|
for inline_image_preview in (True, False):
|
||||||
|
events = self.do_test(lambda: do_set_realm_inline_image_preview(self.user_profile.realm, inline_image_preview))
|
||||||
|
error = schema_checker('events[0]', events[0])
|
||||||
|
self.assert_on_error(error)
|
||||||
|
|
||||||
|
def test_change_realm_inline_url_embed_preview(self):
|
||||||
|
# type: () -> None
|
||||||
|
schema_checker = check_dict([
|
||||||
|
('type', equals('realm')),
|
||||||
|
('op', equals('update')),
|
||||||
|
('property', equals('inline_url_embed_preview')),
|
||||||
|
('value', check_bool),
|
||||||
|
])
|
||||||
|
do_set_realm_inline_url_embed_preview(self.user_profile.realm, inline_url_embed_preview=False)
|
||||||
|
for inline_url_embed_preview in (True, False):
|
||||||
|
events = self.do_test(lambda: do_set_realm_inline_url_embed_preview(self.user_profile.realm, inline_url_embed_preview))
|
||||||
|
error = schema_checker('events[0]', events[0])
|
||||||
|
self.assert_on_error(error)
|
||||||
|
|
||||||
def test_change_realm_default_language(self):
|
def test_change_realm_default_language(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
schema_checker = check_dict([
|
schema_checker = check_dict([
|
||||||
|
|
|
@ -105,6 +105,8 @@ class HomeTest(ZulipTestCase):
|
||||||
"realm_filters",
|
"realm_filters",
|
||||||
"realm_icon_source",
|
"realm_icon_source",
|
||||||
"realm_icon_url",
|
"realm_icon_url",
|
||||||
|
"realm_inline_image_preview",
|
||||||
|
"realm_inline_url_embed_preview",
|
||||||
"realm_invite_by_admins_only",
|
"realm_invite_by_admins_only",
|
||||||
"realm_invite_required",
|
"realm_invite_required",
|
||||||
"realm_message_content_edit_limit_seconds",
|
"realm_message_content_edit_limit_seconds",
|
||||||
|
@ -117,6 +119,8 @@ class HomeTest(ZulipTestCase):
|
||||||
"referrals",
|
"referrals",
|
||||||
"save_stacktraces",
|
"save_stacktraces",
|
||||||
"server_generation",
|
"server_generation",
|
||||||
|
"server_inline_image_preview",
|
||||||
|
"server_inline_url_embed_preview",
|
||||||
"server_uri",
|
"server_uri",
|
||||||
"share_the_love",
|
"share_the_love",
|
||||||
"show_digest_email",
|
"show_digest_email",
|
||||||
|
|
|
@ -256,6 +256,20 @@ class PreviewTestCase(ZulipTestCase):
|
||||||
msg = self._send_message_with_test_org_url(sender_email='prospero@zulip.com')
|
msg = self._send_message_with_test_org_url(sender_email='prospero@zulip.com')
|
||||||
self.assertIn(embedded_link, msg.rendered_content)
|
self.assertIn(embedded_link, msg.rendered_content)
|
||||||
|
|
||||||
|
def test_inline_url_embed_preview(self):
|
||||||
|
# type: () -> None
|
||||||
|
with_preview = '<p><a href="http://test.org/" target="_blank" title="http://test.org/">http://test.org/</a></p>\n<div class="message_embed"><a class="message_embed_image" href="http://test.org/" style="background-image: url(http://ia.media-imdb.com/images/rock.jpg)" target="_blank"></a><div class="data-container"><div class="message_embed_title"><a href="http://test.org/" target="_blank" title="The Rock">The Rock</a></div><div class="message_embed_description">Description text</div></div></div>'
|
||||||
|
without_preview = '<p><a href="http://test.org/" target="_blank" title="http://test.org/">http://test.org/</a></p>'
|
||||||
|
msg = self._send_message_with_test_org_url(sender_email='hamlet@zulip.com')
|
||||||
|
self.assertEqual(msg.rendered_content, with_preview)
|
||||||
|
|
||||||
|
realm = msg.get_realm()
|
||||||
|
setattr(realm, 'inline_url_embed_preview', False)
|
||||||
|
realm.save()
|
||||||
|
|
||||||
|
msg = self._send_message_with_test_org_url(sender_email='prospero@zulip.com', queue_should_run=False)
|
||||||
|
self.assertEqual(msg.rendered_content, without_preview)
|
||||||
|
|
||||||
def test_http_error_get_data(self):
|
def test_http_error_get_data(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
url = 'http://test.org/'
|
url = 'http://test.org/'
|
||||||
|
|
|
@ -135,6 +135,20 @@ class RealmTest(ZulipTestCase):
|
||||||
realm = update_with_api(invite_by_admins_only=False)
|
realm = update_with_api(invite_by_admins_only=False)
|
||||||
self.assertEqual(realm.invite_by_admins_only, False)
|
self.assertEqual(realm.invite_by_admins_only, False)
|
||||||
|
|
||||||
|
# inline_image_preview
|
||||||
|
set_up_db('inline_image_preview', True)
|
||||||
|
realm = update_with_api(inline_image_preview=False)
|
||||||
|
self.assertEqual(realm.inline_image_preview, False)
|
||||||
|
realm = update_with_api(inline_image_preview=True)
|
||||||
|
self.assertEqual(realm.inline_image_preview, True)
|
||||||
|
|
||||||
|
# inline_url_embed_preview
|
||||||
|
set_up_db('inline_url_embed_preview', False)
|
||||||
|
realm = update_with_api(inline_url_embed_preview=True)
|
||||||
|
self.assertEqual(realm.inline_url_embed_preview, True)
|
||||||
|
realm = update_with_api(inline_url_embed_preview=False)
|
||||||
|
self.assertEqual(realm.inline_url_embed_preview, False)
|
||||||
|
|
||||||
# create_stream_by_admins_only
|
# create_stream_by_admins_only
|
||||||
set_up_db('create_stream_by_admins_only', False)
|
set_up_db('create_stream_by_admins_only', False)
|
||||||
realm = update_with_api(create_stream_by_admins_only=True)
|
realm = update_with_api(create_stream_by_admins_only=True)
|
||||||
|
|
|
@ -206,6 +206,8 @@ def home_real(request):
|
||||||
server_generation = settings.SERVER_GENERATION,
|
server_generation = settings.SERVER_GENERATION,
|
||||||
use_websockets = settings.USE_WEBSOCKETS,
|
use_websockets = settings.USE_WEBSOCKETS,
|
||||||
save_stacktraces = settings.SAVE_FRONTEND_STACKTRACES,
|
save_stacktraces = settings.SAVE_FRONTEND_STACKTRACES,
|
||||||
|
server_inline_image_preview = settings.INLINE_IMAGE_PREVIEW,
|
||||||
|
server_inline_url_embed_preview = settings.INLINE_URL_EMBED_PREVIEW,
|
||||||
|
|
||||||
# realm data.
|
# realm data.
|
||||||
# TODO: Move all of these data to register_ret and pull from there
|
# TODO: Move all of these data to register_ret and pull from there
|
||||||
|
@ -299,6 +301,8 @@ def home_real(request):
|
||||||
'realm_icon_source',
|
'realm_icon_source',
|
||||||
'realm_icon_url',
|
'realm_icon_url',
|
||||||
'realm_invite_by_admins_only',
|
'realm_invite_by_admins_only',
|
||||||
|
'realm_inline_image_preview',
|
||||||
|
'realm_inline_url_embed_preview',
|
||||||
'realm_invite_required',
|
'realm_invite_required',
|
||||||
'realm_message_content_edit_limit_seconds',
|
'realm_message_content_edit_limit_seconds',
|
||||||
'realm_name',
|
'realm_name',
|
||||||
|
|
|
@ -972,6 +972,7 @@ def update_message_backend(request, user_profile,
|
||||||
message, ignored_user_message = access_message(user_profile, message_id)
|
message, ignored_user_message = access_message(user_profile, message_id)
|
||||||
|
|
||||||
# You only have permission to edit a message if:
|
# You only have permission to edit a message if:
|
||||||
|
# you change this value also change those two parameters in message_edit.js.
|
||||||
# 1. You sent it, OR:
|
# 1. You sent it, OR:
|
||||||
# 2. This is a topic-only edit for a (no topic) message, OR:
|
# 2. This is a topic-only edit for a (no topic) message, OR:
|
||||||
# 3. This is a topic-only edit and you are an admin.
|
# 3. This is a topic-only edit and you are an admin.
|
||||||
|
@ -1034,7 +1035,7 @@ def update_message_backend(request, user_profile,
|
||||||
propagate_mode, content, rendered_content)
|
propagate_mode, content, rendered_content)
|
||||||
# Include the number of messages changed in the logs
|
# Include the number of messages changed in the logs
|
||||||
request._log_data['extra'] = "[%s]" % (number_changed,)
|
request._log_data['extra'] = "[%s]" % (number_changed,)
|
||||||
if links_for_embed and getattr(settings, 'INLINE_URL_EMBED_PREVIEW', None):
|
if links_for_embed and bugdown.url_embed_preview_enabled_for_realm(message):
|
||||||
event_data = {
|
event_data = {
|
||||||
'message_id': message.id,
|
'message_id': message.id,
|
||||||
'message_content': message.content,
|
'message_content': message.content,
|
||||||
|
|
|
@ -12,6 +12,8 @@ from zerver.lib.actions import (
|
||||||
do_set_realm_invite_by_admins_only,
|
do_set_realm_invite_by_admins_only,
|
||||||
do_set_name_changes_disabled,
|
do_set_name_changes_disabled,
|
||||||
do_set_email_changes_disabled,
|
do_set_email_changes_disabled,
|
||||||
|
do_set_realm_inline_image_preview,
|
||||||
|
do_set_realm_inline_url_embed_preview,
|
||||||
do_set_realm_add_emoji_by_admins_only,
|
do_set_realm_add_emoji_by_admins_only,
|
||||||
do_set_realm_invite_required,
|
do_set_realm_invite_required,
|
||||||
do_set_realm_message_editing,
|
do_set_realm_message_editing,
|
||||||
|
@ -35,6 +37,8 @@ def update_realm(request, user_profile, name=REQ(validator=check_string, default
|
||||||
invite_by_admins_only=REQ(validator=check_bool, default=None),
|
invite_by_admins_only=REQ(validator=check_bool, default=None),
|
||||||
name_changes_disabled=REQ(validator=check_bool, default=None),
|
name_changes_disabled=REQ(validator=check_bool, default=None),
|
||||||
email_changes_disabled=REQ(validator=check_bool, default=None),
|
email_changes_disabled=REQ(validator=check_bool, default=None),
|
||||||
|
inline_image_preview=REQ(validator=check_bool, default=None),
|
||||||
|
inline_url_embed_preview=REQ(validator=check_bool, default=None),
|
||||||
create_stream_by_admins_only=REQ(validator=check_bool, default=None),
|
create_stream_by_admins_only=REQ(validator=check_bool, default=None),
|
||||||
add_emoji_by_admins_only=REQ(validator=check_bool, default=None),
|
add_emoji_by_admins_only=REQ(validator=check_bool, default=None),
|
||||||
allow_message_editing=REQ(validator=check_bool, default=None),
|
allow_message_editing=REQ(validator=check_bool, default=None),
|
||||||
|
@ -42,7 +46,7 @@ def update_realm(request, user_profile, name=REQ(validator=check_string, default
|
||||||
default_language=REQ(validator=check_string, default=None),
|
default_language=REQ(validator=check_string, default=None),
|
||||||
waiting_period_threshold=REQ(converter=to_non_negative_int, default=None),
|
waiting_period_threshold=REQ(converter=to_non_negative_int, default=None),
|
||||||
authentication_methods=REQ(validator=check_dict([]), default=None)):
|
authentication_methods=REQ(validator=check_dict([]), default=None)):
|
||||||
# type: (HttpRequest, UserProfile, Optional[str], Optional[str], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[int], Optional[str], Optional[int], Optional[dict]) -> HttpResponse
|
# type: (HttpRequest, UserProfile, Optional[str], Optional[str], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[int], Optional[str], Optional[int], Optional[dict]) -> HttpResponse
|
||||||
# Validation for default_language
|
# Validation for default_language
|
||||||
if default_language is not None and default_language not in get_available_language_codes():
|
if default_language is not None and default_language not in get_available_language_codes():
|
||||||
raise JsonableError(_("Invalid language '%s'" % (default_language,)))
|
raise JsonableError(_("Invalid language '%s'" % (default_language,)))
|
||||||
|
@ -71,6 +75,12 @@ def update_realm(request, user_profile, name=REQ(validator=check_string, default
|
||||||
if email_changes_disabled is not None and realm.email_changes_disabled != email_changes_disabled:
|
if email_changes_disabled is not None and realm.email_changes_disabled != email_changes_disabled:
|
||||||
do_set_email_changes_disabled(realm, email_changes_disabled)
|
do_set_email_changes_disabled(realm, email_changes_disabled)
|
||||||
data['email_changes_disabled'] = email_changes_disabled
|
data['email_changes_disabled'] = email_changes_disabled
|
||||||
|
if inline_image_preview is not None and realm.inline_image_preview != inline_image_preview:
|
||||||
|
do_set_realm_inline_image_preview(realm, inline_image_preview)
|
||||||
|
data['inline_image_preview'] = inline_image_preview
|
||||||
|
if inline_url_embed_preview is not None and realm.inline_url_embed_preview != inline_url_embed_preview:
|
||||||
|
do_set_realm_inline_url_embed_preview(realm, inline_url_embed_preview)
|
||||||
|
data['inline_url_embed_preview'] = inline_url_embed_preview
|
||||||
if authentication_methods is not None and realm.authentication_methods_dict() != authentication_methods:
|
if authentication_methods is not None and realm.authentication_methods_dict() != authentication_methods:
|
||||||
if True not in list(authentication_methods.values()):
|
if True not in list(authentication_methods.values()):
|
||||||
return json_error(_("At least one authentication method must be enabled."),
|
return json_error(_("At least one authentication method must be enabled."),
|
||||||
|
|
Loading…
Reference in New Issue