realm: Add setting to configure GIPHY rating.

Organization admins can use this setting to restrict the maximum
rating of GIFs that will be retrieved from GIPHY. Also, there
is option to disable GIPHY too.
This commit is contained in:
Aman Agrawal 2021-03-31 11:10:46 +00:00 committed by Tim Abbott
parent f9e0ed98b8
commit 802c450b3f
11 changed files with 116 additions and 2 deletions

View File

@ -10,6 +10,12 @@ below features are supported.
## Changes in Zulip 4.0 ## Changes in Zulip 4.0
**Feature level 55**
* [`POST /register`](/api/register-queue): Added `realm_giphy_rating`
and `giphy_rating_options` fields.
* `PATCH /realm`: Added `giphy_rating` parameter.
**Feature level 54** **Feature level 54**
* `GET /realm/filters` has been removed and replace with [`GET * `GET /realm/filters` has been removed and replace with [`GET

View File

@ -30,7 +30,7 @@ DESKTOP_WARNING_VERSION = "5.2.0"
# #
# Changes should be accompanied by documentation explaining what the # Changes should be accompanied by documentation explaining what the
# new level means in templates/zerver/api/changelog.md. # new level means in templates/zerver/api/changelog.md.
API_FEATURE_LEVEL = 54 API_FEATURE_LEVEL = 55
# Bump the minor PROVISION_VERSION to indicate that folks should provision # Bump the minor PROVISION_VERSION to indicate that folks should provision
# only when going from an old version of the code to a newer version. Bump # only when going from an old version of the code to a newer version. Bump

View File

@ -240,6 +240,7 @@ def fetch_initial_state_data(
state["server_inline_url_embed_preview"] = settings.INLINE_URL_EMBED_PREVIEW state["server_inline_url_embed_preview"] = settings.INLINE_URL_EMBED_PREVIEW
state["server_avatar_changes_disabled"] = settings.AVATAR_CHANGES_DISABLED state["server_avatar_changes_disabled"] = settings.AVATAR_CHANGES_DISABLED
state["server_name_changes_disabled"] = settings.NAME_CHANGES_DISABLED state["server_name_changes_disabled"] = settings.NAME_CHANGES_DISABLED
state["giphy_rating_options"] = realm.GIPHY_RATING_OPTIONS
if realm.notifications_stream and not realm.notifications_stream.deactivated: if realm.notifications_stream and not realm.notifications_stream.deactivated:
notifications_stream = realm.notifications_stream notifications_stream = realm.notifications_stream

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-03-31 10:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("zerver", "0318_remove_realm_invite_by_admins_only"),
]
operations = [
migrations.AddField(
model_name="realm",
name="giphy_rating",
field=models.PositiveSmallIntegerField(default=2),
),
]

View File

@ -451,6 +451,37 @@ class Realm(models.Model):
default=VIDEO_CHAT_PROVIDERS["jitsi_meet"]["id"] default=VIDEO_CHAT_PROVIDERS["jitsi_meet"]["id"]
) )
GIPHY_RATING_OPTIONS = {
"disabled": {
"name": "GIPHY integration disabled",
"id": 0,
},
# Source: https://github.com/Giphy/giphy-js/blob/master/packages/fetch-api/README.md#shared-options
"y": {
"name": "Y - Very young audience",
"id": 1,
},
"g": {
"name": "G - General audience",
"id": 2,
},
"pg": {
"name": "PG - Parental guidence",
"id": 3,
},
"pg-13": {
"name": "PG13 - Parental guidence (under 13)",
"id": 4,
},
"r": {
"name": "R - Restricted",
"id": 5,
},
}
# maximum rating of the GIFs that will be retrieved from GIPHY
giphy_rating: int = models.PositiveSmallIntegerField(default=GIPHY_RATING_OPTIONS["g"]["id"])
default_code_block_language: Optional[str] = models.TextField(null=True, default=None) default_code_block_language: Optional[str] = models.TextField(null=True, default=None)
# Define the types of the various automatically managed properties # Define the types of the various automatically managed properties
@ -468,6 +499,7 @@ class Realm(models.Model):
disallow_disposable_email_addresses=bool, disallow_disposable_email_addresses=bool,
email_address_visibility=int, email_address_visibility=int,
email_changes_disabled=bool, email_changes_disabled=bool,
giphy_rating=int,
invite_required=bool, invite_required=bool,
invite_to_realm_policy=int, invite_to_realm_policy=int,
inline_image_preview=bool, inline_image_preview=bool,

View File

@ -3053,6 +3053,12 @@ paths:
type: string type: string
description: | description: |
The description of the organization, used on login and registration pages. The description of the organization, used on login and registration pages.
realm_giphy_rating:
type: integer
description: |
Maximum rating of the GIFs that will be retrieved from GIPHY.
**Changes**: New in Zulip 4.0 (feature level 55).
digest_emails_enabled: digest_emails_enabled:
type: boolean type: boolean
description: | description: |
@ -7513,6 +7519,8 @@ paths:
Developers of clients should also read the Developers of clients should also read the
[GIPHY API TOS](https://support.giphy.com/hc/en-us/articles/360028134111-GIPHY-API-Terms-of-Service-) [GIPHY API TOS](https://support.giphy.com/hc/en-us/articles/360028134111-GIPHY-API-Terms-of-Service-)
before using this API key. before using this API key.
**Changes**: Added in Zulip 4.0 (feature level 47).
enable_desktop_notifications: enable_desktop_notifications:
type: boolean type: boolean
description: | description: |
@ -8035,6 +8043,14 @@ paths:
Present if `realm` is present in `fetch_event_types`. Present if `realm` is present in `fetch_event_types`.
The configured video call provider for the organization. The configured video call provider for the organization.
realm_giphy_rating:
type: integer
description: |
Present if `realm` is present in `fetch_event_types`.
The configured GIPHY rating for the organization.
**Changes**: New in Zulip 4.0 (feature level 55).
realm_waiting_period_threshold: realm_waiting_period_threshold:
type: integer type: integer
description: | description: |
@ -8406,6 +8422,31 @@ paths:
This Zulip server's configured minimum `zxcvbn` minimum guesses. This Zulip server's configured minimum `zxcvbn` minimum guesses.
Necessary for password change UI to show whether the password Necessary for password change UI to show whether the password
will be accepted. will be accepted.
giphy_rating_options:
type: object
description: |
Dictionary where each entry describes a valid rating
that is configured on this server and could be selected by an
organization administrator.
Useful for administrative settings UI that allows changing the
allowed rating of GIFs.
additionalProperties:
description: |
`{rating_name}`: Dictionary containing the details of the
rating with the name of the rating as
the key.
type: object
additionalProperties: false
properties:
name:
type: string
description: |
The description of the rating option.
id:
type: integer
description: |
The ID of the rating option.
max_file_upload_size_mib: max_file_upload_size_mib:
type: integer type: integer
description: | description: |

View File

@ -1893,6 +1893,9 @@ class RealmPropertyActionTest(BaseAction):
video_chat_provider=[ video_chat_provider=[
Realm.VIDEO_CHAT_PROVIDERS["jitsi_meet"]["id"], Realm.VIDEO_CHAT_PROVIDERS["jitsi_meet"]["id"],
], ],
giphy_rating=[
Realm.GIPHY_RATING_OPTIONS["disabled"]["id"],
],
default_code_block_language=["python", "javascript"], default_code_block_language=["python", "javascript"],
message_content_delete_limit_seconds=[1000, 1100, 1200], message_content_delete_limit_seconds=[1000, 1100, 1200],
invite_to_realm_policy=[4, 3, 2, 1], invite_to_realm_policy=[4, 3, 2, 1],

View File

@ -85,6 +85,7 @@ class HomeTest(ZulipTestCase):
"full_name", "full_name",
"furthest_read_time", "furthest_read_time",
"giphy_api_key", "giphy_api_key",
"giphy_rating_options",
"has_mobile_devices", "has_mobile_devices",
"has_zoom_token", "has_zoom_token",
"high_contrast_mode", "high_contrast_mode",
@ -158,6 +159,7 @@ class HomeTest(ZulipTestCase):
"realm_embedded_bots", "realm_embedded_bots",
"realm_emoji", "realm_emoji",
"realm_filters", "realm_filters",
"realm_giphy_rating",
"realm_icon_source", "realm_icon_source",
"realm_icon_url", "realm_icon_url",
"realm_incoming_webhook_bots", "realm_incoming_webhook_bots",

View File

@ -616,6 +616,7 @@ class RealmTest(ZulipTestCase):
email_address_visibility=10, email_address_visibility=10,
message_retention_days=10, message_retention_days=10,
video_chat_provider=10, video_chat_provider=10,
giphy_rating=10,
waiting_period_threshold=-10, waiting_period_threshold=-10,
digest_weekday=10, digest_weekday=10,
user_group_edit_policy=10, user_group_edit_policy=10,
@ -890,6 +891,10 @@ class RealmAPITest(ZulipTestCase):
).decode(), ).decode(),
), ),
], ],
giphy_rating=[
Realm.GIPHY_RATING_OPTIONS["y"]["id"],
Realm.GIPHY_RATING_OPTIONS["r"]["id"],
],
message_content_delete_limit_seconds=[1000, 1100, 1200], message_content_delete_limit_seconds=[1000, 1100, 1200],
invite_to_realm_policy=[ invite_to_realm_policy=[
Realm.POLICY_ADMINS_ONLY, Realm.POLICY_ADMINS_ONLY,

View File

@ -243,7 +243,8 @@ def home_real(request: HttpRequest) -> HttpResponse:
"embedded": narrow_stream is not None, "embedded": narrow_stream is not None,
"invite_as": PreregistrationUser.INVITE_AS, "invite_as": PreregistrationUser.INVITE_AS,
"max_file_upload_size_mib": settings.MAX_FILE_UPLOAD_SIZE, "max_file_upload_size_mib": settings.MAX_FILE_UPLOAD_SIZE,
"giphy_api_available": bool(page_params["giphy_api_key"]), "giphy_api_available": bool(page_params["giphy_api_key"])
and (page_params["realm_giphy_rating"] != 0),
}, },
) )
patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True) patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)

View File

@ -110,6 +110,7 @@ def update_realm(
), ),
default_twenty_four_hour_time: Optional[bool] = REQ(json_validator=check_bool, default=None), default_twenty_four_hour_time: Optional[bool] = REQ(json_validator=check_bool, default=None),
video_chat_provider: Optional[int] = REQ(json_validator=check_int, default=None), video_chat_provider: Optional[int] = REQ(json_validator=check_int, default=None),
giphy_rating: Optional[int] = REQ(json_validator=check_int, default=None),
default_code_block_language: Optional[str] = REQ(default=None), default_code_block_language: Optional[str] = REQ(default=None),
digest_weekday: Optional[int] = REQ( digest_weekday: Optional[int] = REQ(
json_validator=check_int_in(Realm.DIGEST_WEEKDAY_VALUES), default=None json_validator=check_int_in(Realm.DIGEST_WEEKDAY_VALUES), default=None
@ -130,6 +131,10 @@ def update_realm(
p["id"] for p in Realm.VIDEO_CHAT_PROVIDERS.values() p["id"] for p in Realm.VIDEO_CHAT_PROVIDERS.values()
}: }:
return json_error(_("Invalid video_chat_provider {}").format(video_chat_provider)) return json_error(_("Invalid video_chat_provider {}").format(video_chat_provider))
if giphy_rating is not None and giphy_rating not in {
p["id"] for p in Realm.GIPHY_RATING_OPTIONS.values()
}:
return json_error(_("Invalid giphy_rating {}").format(giphy_rating))
message_retention_days: Optional[int] = None message_retention_days: Optional[int] = None
if message_retention_days_raw is not None: if message_retention_days_raw is not None: