mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 04:53:36 +00:00
widgets: Validate todo data on the backend.
This commit is contained in:
@@ -498,6 +498,37 @@ def validate_poll_data(poll_data: object, is_widget_author: bool) -> None:
|
||||
raise ValidationError(f"Unknown type for poll data: {poll_data['type']}")
|
||||
|
||||
|
||||
def validate_todo_data(todo_data: object) -> None:
|
||||
check_dict([("type", check_string)])("todo data", todo_data)
|
||||
|
||||
assert isinstance(todo_data, dict)
|
||||
|
||||
if todo_data["type"] == "new_task":
|
||||
checker = check_dict_only(
|
||||
[
|
||||
("type", check_string),
|
||||
("key", check_int),
|
||||
("task", check_string),
|
||||
("desc", check_string),
|
||||
("completed", check_bool),
|
||||
]
|
||||
)
|
||||
checker("todo data", todo_data)
|
||||
return
|
||||
|
||||
if todo_data["type"] == "strike":
|
||||
checker = check_dict_only(
|
||||
[
|
||||
("type", check_string),
|
||||
("key", check_string),
|
||||
]
|
||||
)
|
||||
checker("todo data", todo_data)
|
||||
return
|
||||
|
||||
raise ValidationError(f"Unknown type for todo data: {todo_data['type']}")
|
||||
|
||||
|
||||
# Converter functions for use with has_request_variables
|
||||
def to_non_negative_int(s: str, max_int_size: int = 2 ** 32 - 1) -> int:
|
||||
x = int(s)
|
||||
|
||||
@@ -312,6 +312,54 @@ class WidgetContentTestCase(ZulipTestCase):
|
||||
assert_success(dict(type="new_option", idx=7, option="maybe"))
|
||||
assert_success(dict(type="question", question="what's for dinner?"))
|
||||
|
||||
def test_todo_type_validation(self) -> None:
|
||||
sender = self.example_user("cordelia")
|
||||
stream_name = "Verona"
|
||||
content = "/todo"
|
||||
|
||||
payload = dict(
|
||||
type="stream",
|
||||
to=stream_name,
|
||||
client="test suite",
|
||||
topic="whatever",
|
||||
content=content,
|
||||
)
|
||||
result = self.api_post(sender, "/api/v1/messages", payload)
|
||||
self.assert_json_success(result)
|
||||
|
||||
message = self.get_last_message()
|
||||
|
||||
def post_submessage(content: str) -> HttpResponse:
|
||||
payload = dict(
|
||||
message_id=message.id,
|
||||
msg_type="widget",
|
||||
content=content,
|
||||
)
|
||||
return self.api_post(sender, "/api/v1/submessage", payload)
|
||||
|
||||
def assert_error(content: str, error: str) -> None:
|
||||
result = post_submessage(content)
|
||||
self.assert_json_error_contains(result, error)
|
||||
|
||||
assert_error('{"type": "bogus"}', "Unknown type for todo data: bogus")
|
||||
|
||||
assert_error('{"type": "new_task"}', "key is missing")
|
||||
assert_error(
|
||||
'{"type": "new_task", "key": 7, "task": 7, "desc": "", "completed": false}',
|
||||
'data["task"] is not a string',
|
||||
)
|
||||
|
||||
assert_error('{"type": "strike"}', "key is missing")
|
||||
assert_error('{"type": "strike", "key": 999}', 'data["key"] is not a string')
|
||||
|
||||
def assert_success(data: Dict[str, object]) -> None:
|
||||
content = orjson.dumps(data).decode()
|
||||
result = post_submessage(content)
|
||||
self.assert_json_success(result)
|
||||
|
||||
assert_success(dict(type="new_task", key=7, task="eat", desc="", completed=False))
|
||||
assert_success(dict(type="strike", key="5,9"))
|
||||
|
||||
def test_get_widget_type(self) -> None:
|
||||
sender = self.example_user("cordelia")
|
||||
stream_name = "Verona"
|
||||
|
||||
@@ -8,7 +8,7 @@ from zerver.lib.actions import do_add_submessage, verify_submessage_sender
|
||||
from zerver.lib.exceptions import JsonableError
|
||||
from zerver.lib.message import access_message
|
||||
from zerver.lib.response import json_error, json_success
|
||||
from zerver.lib.validator import check_int, validate_poll_data
|
||||
from zerver.lib.validator import check_int, validate_poll_data, validate_todo_data
|
||||
from zerver.lib.widget import get_widget_type
|
||||
from zerver.models import UserProfile
|
||||
|
||||
@@ -44,6 +44,12 @@ def process_submessage(
|
||||
except ValidationError as error:
|
||||
raise JsonableError(error.message)
|
||||
|
||||
if widget_type == "todo":
|
||||
try:
|
||||
validate_todo_data(todo_data=widget_data)
|
||||
except ValidationError as error:
|
||||
raise JsonableError(error.message)
|
||||
|
||||
do_add_submessage(
|
||||
realm=user_profile.realm,
|
||||
sender_id=user_profile.id,
|
||||
|
||||
Reference in New Issue
Block a user