mirror of https://github.com/zulip/zulip.git
python: Migrate most json_error => JsonableError.
JsonableError has two major benefits over json_error: * It can be raised from anywhere in the codebase, rather than being a return value, which is much more convenient for refactoring, as one doesn't potentially need to change error handling style when extracting a bit of view code to a function. * It is guaranteed to contain the `code` property, which is helpful for API consistency. Various stragglers are not updated because JsonableError requires subclassing in order to specify custom data or HTTP status codes.
This commit is contained in:
parent
322a9b0346
commit
dcbb2a78ca
|
@ -25,8 +25,8 @@ from zerver.lib.actions import (
|
||||||
do_scrub_realm,
|
do_scrub_realm,
|
||||||
do_send_realm_reactivation_email,
|
do_send_realm_reactivation_email,
|
||||||
)
|
)
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.realm_icon import realm_icon_url
|
from zerver.lib.realm_icon import realm_icon_url
|
||||||
from zerver.lib.response import json_error
|
|
||||||
from zerver.lib.subdomains import get_subdomain_from_hostname
|
from zerver.lib.subdomains import get_subdomain_from_hostname
|
||||||
from zerver.models import MultiuseInvite, PreregistrationUser, Realm, UserProfile, get_realm
|
from zerver.models import MultiuseInvite, PreregistrationUser, Realm, UserProfile, get_realm
|
||||||
from zerver.views.invite import get_invitee_emails_set
|
from zerver.views.invite import get_invitee_emails_set
|
||||||
|
@ -110,7 +110,7 @@ def support(request: HttpRequest) -> HttpResponse:
|
||||||
if "csrfmiddlewaretoken" in keys:
|
if "csrfmiddlewaretoken" in keys:
|
||||||
keys.remove("csrfmiddlewaretoken")
|
keys.remove("csrfmiddlewaretoken")
|
||||||
if len(keys) != 2:
|
if len(keys) != 2:
|
||||||
return json_error(_("Invalid parameters"))
|
raise JsonableError(_("Invalid parameters"))
|
||||||
|
|
||||||
realm_id = request.POST.get("realm_id")
|
realm_id = request.POST.get("realm_id")
|
||||||
realm = Realm.objects.get(id=realm_id)
|
realm = Realm.objects.get(id=realm_id)
|
||||||
|
|
|
@ -47,6 +47,7 @@ from zerver.decorator import (
|
||||||
zulip_login_required,
|
zulip_login_required,
|
||||||
)
|
)
|
||||||
from zerver.lib.actions import do_make_user_billing_admin
|
from zerver.lib.actions import do_make_user_billing_admin
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_error, json_success
|
||||||
from zerver.lib.send_email import FromAddress, send_email
|
from zerver.lib.send_email import FromAddress, send_email
|
||||||
|
@ -372,12 +373,12 @@ def update_plan(
|
||||||
|
|
||||||
new_plan, last_ledger_entry = make_end_of_cycle_updates_if_needed(plan, timezone_now())
|
new_plan, last_ledger_entry = make_end_of_cycle_updates_if_needed(plan, timezone_now())
|
||||||
if new_plan is not None:
|
if new_plan is not None:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Unable to update the plan. The plan has been expired and replaced with a new plan.")
|
_("Unable to update the plan. The plan has been expired and replaced with a new plan.")
|
||||||
)
|
)
|
||||||
|
|
||||||
if last_ledger_entry is None:
|
if last_ledger_entry is None:
|
||||||
return json_error(_("Unable to update the plan. The plan has ended."))
|
raise JsonableError(_("Unable to update the plan. The plan has ended."))
|
||||||
|
|
||||||
if status is not None:
|
if status is not None:
|
||||||
if status == CustomerPlan.ACTIVE:
|
if status == CustomerPlan.ACTIVE:
|
||||||
|
@ -398,19 +399,19 @@ def update_plan(
|
||||||
|
|
||||||
if licenses is not None:
|
if licenses is not None:
|
||||||
if plan.automanage_licenses:
|
if plan.automanage_licenses:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_(
|
_(
|
||||||
"Unable to update licenses manually. Your plan is on automatic license management."
|
"Unable to update licenses manually. Your plan is on automatic license management."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if last_ledger_entry.licenses == licenses:
|
if last_ledger_entry.licenses == licenses:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_(
|
_(
|
||||||
"Your plan is already on {licenses} licenses in the current billing period."
|
"Your plan is already on {licenses} licenses in the current billing period."
|
||||||
).format(licenses=licenses)
|
).format(licenses=licenses)
|
||||||
)
|
)
|
||||||
if last_ledger_entry.licenses > licenses:
|
if last_ledger_entry.licenses > licenses:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("You cannot decrease the licenses in the current billing period.").format(
|
_("You cannot decrease the licenses in the current billing period.").format(
|
||||||
licenses=licenses
|
licenses=licenses
|
||||||
)
|
)
|
||||||
|
@ -426,13 +427,13 @@ def update_plan(
|
||||||
|
|
||||||
if licenses_at_next_renewal is not None:
|
if licenses_at_next_renewal is not None:
|
||||||
if plan.automanage_licenses:
|
if plan.automanage_licenses:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_(
|
_(
|
||||||
"Unable to update licenses manually. Your plan is on automatic license management."
|
"Unable to update licenses manually. Your plan is on automatic license management."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if last_ledger_entry.licenses_at_next_renewal == licenses_at_next_renewal:
|
if last_ledger_entry.licenses_at_next_renewal == licenses_at_next_renewal:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_(
|
_(
|
||||||
"Your plan is already scheduled to renew with {licenses_at_next_renewal} licenses."
|
"Your plan is already scheduled to renew with {licenses_at_next_renewal} licenses."
|
||||||
).format(licenses_at_next_renewal=licenses_at_next_renewal)
|
).format(licenses_at_next_renewal=licenses_at_next_renewal)
|
||||||
|
@ -450,7 +451,7 @@ def update_plan(
|
||||||
)
|
)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
return json_error(_("Nothing to change."))
|
raise JsonableError(_("Nothing to change."))
|
||||||
|
|
||||||
|
|
||||||
@require_billing_access
|
@require_billing_access
|
||||||
|
|
|
@ -452,7 +452,7 @@ def human_users_only(view_func: ViewFuncT) -> ViewFuncT:
|
||||||
@wraps(view_func)
|
@wraps(view_func)
|
||||||
def _wrapped_view_func(request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse:
|
def _wrapped_view_func(request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse:
|
||||||
if request.user.is_bot:
|
if request.user.is_bot:
|
||||||
return json_error(_("This endpoint does not accept bot requests."))
|
raise JsonableError(_("This endpoint does not accept bot requests."))
|
||||||
return view_func(request, *args, **kwargs)
|
return view_func(request, *args, **kwargs)
|
||||||
|
|
||||||
return cast(ViewFuncT, _wrapped_view_func) # https://github.com/python/mypy/issues/1927
|
return cast(ViewFuncT, _wrapped_view_func) # https://github.com/python/mypy/issues/1927
|
||||||
|
@ -549,7 +549,7 @@ def require_member_or_admin(view_func: ViewFuncT) -> ViewFuncT:
|
||||||
if user_profile.is_guest:
|
if user_profile.is_guest:
|
||||||
raise JsonableError(_("Not allowed for guest users"))
|
raise JsonableError(_("Not allowed for guest users"))
|
||||||
if user_profile.is_bot:
|
if user_profile.is_bot:
|
||||||
return json_error(_("This endpoint does not accept bot requests."))
|
raise JsonableError(_("This endpoint does not accept bot requests."))
|
||||||
return view_func(request, user_profile, *args, **kwargs)
|
return view_func(request, user_profile, *args, **kwargs)
|
||||||
|
|
||||||
return cast(ViewFuncT, _wrapped_view_func) # https://github.com/python/mypy/issues/1927
|
return cast(ViewFuncT, _wrapped_view_func) # https://github.com/python/mypy/issues/1927
|
||||||
|
@ -624,7 +624,7 @@ def authenticated_rest_api_view(
|
||||||
auth_type, credentials = request.META["HTTP_AUTHORIZATION"].split()
|
auth_type, credentials = request.META["HTTP_AUTHORIZATION"].split()
|
||||||
# case insensitive per RFC 1945
|
# case insensitive per RFC 1945
|
||||||
if auth_type.lower() != "basic":
|
if auth_type.lower() != "basic":
|
||||||
return json_error(_("This endpoint requires HTTP basic authentication."))
|
raise JsonableError(_("This endpoint requires HTTP basic authentication."))
|
||||||
role, api_key = base64.b64decode(credentials).decode("utf-8").split(":")
|
role, api_key = base64.b64decode(credentials).decode("utf-8").split(":")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return json_unauthorized(_("Invalid authorization header for basic auth"))
|
return json_unauthorized(_("Invalid authorization header for basic auth"))
|
||||||
|
|
|
@ -9,7 +9,8 @@ from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.filters import clean_data_from_query_parameters
|
from zerver.filters import clean_data_from_query_parameters
|
||||||
from zerver.lib.actions import internal_send_stream_message
|
from zerver.lib.actions import internal_send_stream_message
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.response import json_success
|
||||||
from zerver.models import get_stream, get_system_bot
|
from zerver.models import get_stream, get_system_bot
|
||||||
|
|
||||||
|
|
||||||
|
@ -199,5 +200,5 @@ def do_report_error(type: str, report: Dict[str, Any]) -> HttpResponse:
|
||||||
elif type == "server":
|
elif type == "server":
|
||||||
notify_server_error(report)
|
notify_server_error(report)
|
||||||
else:
|
else:
|
||||||
return json_error(_("Invalid type parameter"))
|
raise JsonableError(_("Invalid type parameter"))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -220,6 +220,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
||||||
"message": {
|
"message": {
|
||||||
"msg": "Unknown WordPress webhook action: WordPress action",
|
"msg": "Unknown WordPress webhook action: WordPress action",
|
||||||
"result": "error",
|
"result": "error",
|
||||||
|
"code": "BAD_REQUEST",
|
||||||
},
|
},
|
||||||
"fixture_name": "user_register.txt",
|
"fixture_name": "user_register.txt",
|
||||||
"status_code": 400,
|
"status_code": 400,
|
||||||
|
@ -228,6 +229,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
||||||
"message": {
|
"message": {
|
||||||
"msg": "Unknown WordPress webhook action: WordPress action",
|
"msg": "Unknown WordPress webhook action: WordPress action",
|
||||||
"result": "error",
|
"result": "error",
|
||||||
|
"code": "BAD_REQUEST",
|
||||||
},
|
},
|
||||||
"fixture_name": "publish_post_no_data_provided.txt",
|
"fixture_name": "publish_post_no_data_provided.txt",
|
||||||
"status_code": 400,
|
"status_code": 400,
|
||||||
|
@ -236,6 +238,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
||||||
"message": {
|
"message": {
|
||||||
"msg": "Unknown WordPress webhook action: WordPress action",
|
"msg": "Unknown WordPress webhook action: WordPress action",
|
||||||
"result": "error",
|
"result": "error",
|
||||||
|
"code": "BAD_REQUEST",
|
||||||
},
|
},
|
||||||
"fixture_name": "unknown_action_no_data.txt",
|
"fixture_name": "unknown_action_no_data.txt",
|
||||||
"status_code": 400,
|
"status_code": 400,
|
||||||
|
@ -244,6 +247,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
||||||
"message": {
|
"message": {
|
||||||
"msg": "Unknown WordPress webhook action: WordPress action",
|
"msg": "Unknown WordPress webhook action: WordPress action",
|
||||||
"result": "error",
|
"result": "error",
|
||||||
|
"code": "BAD_REQUEST",
|
||||||
},
|
},
|
||||||
"fixture_name": "publish_page.txt",
|
"fixture_name": "publish_page.txt",
|
||||||
"status_code": 400,
|
"status_code": 400,
|
||||||
|
@ -252,6 +256,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
||||||
"message": {
|
"message": {
|
||||||
"msg": "Unknown WordPress webhook action: WordPress action",
|
"msg": "Unknown WordPress webhook action: WordPress action",
|
||||||
"result": "error",
|
"result": "error",
|
||||||
|
"code": "BAD_REQUEST",
|
||||||
},
|
},
|
||||||
"fixture_name": "unknown_action_no_hook_provided.txt",
|
"fixture_name": "unknown_action_no_hook_provided.txt",
|
||||||
"status_code": 400,
|
"status_code": 400,
|
||||||
|
@ -260,6 +265,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
||||||
"message": {
|
"message": {
|
||||||
"msg": "Unknown WordPress webhook action: WordPress action",
|
"msg": "Unknown WordPress webhook action: WordPress action",
|
||||||
"result": "error",
|
"result": "error",
|
||||||
|
"code": "BAD_REQUEST",
|
||||||
},
|
},
|
||||||
"fixture_name": "publish_post_type_not_provided.txt",
|
"fixture_name": "publish_post_type_not_provided.txt",
|
||||||
"status_code": 400,
|
"status_code": 400,
|
||||||
|
@ -268,6 +274,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
||||||
"message": {
|
"message": {
|
||||||
"msg": "Unknown WordPress webhook action: WordPress action",
|
"msg": "Unknown WordPress webhook action: WordPress action",
|
||||||
"result": "error",
|
"result": "error",
|
||||||
|
"code": "BAD_REQUEST",
|
||||||
},
|
},
|
||||||
"fixture_name": "wp_login.txt",
|
"fixture_name": "wp_login.txt",
|
||||||
"status_code": 400,
|
"status_code": 400,
|
||||||
|
@ -276,6 +283,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
|
||||||
"message": {
|
"message": {
|
||||||
"msg": "Unknown WordPress webhook action: WordPress action",
|
"msg": "Unknown WordPress webhook action: WordPress action",
|
||||||
"result": "error",
|
"result": "error",
|
||||||
|
"code": "BAD_REQUEST",
|
||||||
},
|
},
|
||||||
"fixture_name": "publish_post.txt",
|
"fixture_name": "publish_post.txt",
|
||||||
"status_code": 400,
|
"status_code": 400,
|
||||||
|
|
|
@ -184,8 +184,9 @@ class RealmExportTest(ZulipTestCase):
|
||||||
)
|
)
|
||||||
RealmAuditLog.objects.bulk_create(exports)
|
RealmAuditLog.objects.bulk_create(exports)
|
||||||
|
|
||||||
result = export_realm(self.client_post, admin)
|
with self.assertRaises(JsonableError) as error:
|
||||||
self.assert_json_error(result, "Exceeded rate limit.")
|
export_realm(self.client_post, admin)
|
||||||
|
self.assertEqual(str(error.exception), "Exceeded rate limit.")
|
||||||
|
|
||||||
def test_upload_and_message_limit(self) -> None:
|
def test_upload_and_message_limit(self) -> None:
|
||||||
admin = self.example_user("iago")
|
admin = self.example_user("iago")
|
||||||
|
|
|
@ -6,7 +6,8 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import REQ, has_request_variables, internal_notify_view, process_client
|
from zerver.decorator import REQ, has_request_variables, internal_notify_view, process_client
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.validator import (
|
from zerver.lib.validator import (
|
||||||
check_bool,
|
check_bool,
|
||||||
check_int,
|
check_int,
|
||||||
|
@ -34,7 +35,7 @@ def cleanup_event_queue(
|
||||||
if client is None:
|
if client is None:
|
||||||
raise BadEventQueueIdError(queue_id)
|
raise BadEventQueueIdError(queue_id)
|
||||||
if user_profile.id != client.user_profile_id:
|
if user_profile.id != client.user_profile_id:
|
||||||
return json_error(_("You are not authorized to access this queue"))
|
raise JsonableError(_("You are not authorized to access this queue"))
|
||||||
request._log_data["extra"] = f"[{queue_id}]"
|
request._log_data["extra"] = f"[{queue_id}]"
|
||||||
client.cleanup()
|
client.cleanup()
|
||||||
return json_success()
|
return json_success()
|
||||||
|
@ -102,7 +103,7 @@ def get_events_backend(
|
||||||
),
|
),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if all_public_streams and not user_profile.can_access_public_streams():
|
if all_public_streams and not user_profile.can_access_public_streams():
|
||||||
return json_error(_("User not authorized for this query"))
|
raise JsonableError(_("User not authorized for this query"))
|
||||||
|
|
||||||
# Extract the Tornado handler from the request
|
# Extract the Tornado handler from the request
|
||||||
handler: AsyncDjangoHandler = request._tornado_handler
|
handler: AsyncDjangoHandler = request._tornado_handler
|
||||||
|
|
|
@ -822,7 +822,7 @@ def api_fetch_api_key(
|
||||||
|
|
||||||
realm = get_realm_from_request(request)
|
realm = get_realm_from_request(request)
|
||||||
if realm is None:
|
if realm is None:
|
||||||
return json_error(_("Invalid subdomain"))
|
raise JsonableError(_("Invalid subdomain"))
|
||||||
|
|
||||||
if not ldap_auth_enabled(realm=realm):
|
if not ldap_auth_enabled(realm=realm):
|
||||||
# In case we don't authenticate against LDAP, check for a valid
|
# In case we don't authenticate against LDAP, check for a valid
|
||||||
|
@ -945,12 +945,12 @@ def json_fetch_api_key(
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
realm = get_realm_from_request(request)
|
realm = get_realm_from_request(request)
|
||||||
if realm is None:
|
if realm is None:
|
||||||
return json_error(_("Invalid subdomain"))
|
raise JsonableError(_("Invalid subdomain"))
|
||||||
if password_auth_enabled(user_profile.realm):
|
if password_auth_enabled(user_profile.realm):
|
||||||
if not authenticate(
|
if not authenticate(
|
||||||
request=request, username=user_profile.delivery_email, password=password, realm=realm
|
request=request, username=user_profile.delivery_email, password=password, realm=realm
|
||||||
):
|
):
|
||||||
return json_error(_("Your username or password is incorrect."))
|
raise JsonableError(_("Your username or password is incorrect."))
|
||||||
|
|
||||||
api_key = get_api_key(user_profile)
|
api_key = get_api_key(user_profile)
|
||||||
return json_success({"api_key": api_key, "email": user_profile.delivery_email})
|
return json_success({"api_key": api_key, "email": user_profile.delivery_email})
|
||||||
|
|
|
@ -2,7 +2,8 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.lib.compatibility import find_mobile_os, version_lt
|
from zerver.lib.compatibility import find_mobile_os, version_lt
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.user_agent import parse_user_agent
|
from zerver.lib.user_agent import parse_user_agent
|
||||||
|
|
||||||
# Zulip Mobile release 16.2.96 was made 2018-08-22. It fixed a
|
# Zulip Mobile release 16.2.96 was made 2018-08-22. It fixed a
|
||||||
|
@ -14,16 +15,16 @@ android_min_app_version = "16.2.96"
|
||||||
|
|
||||||
def check_global_compatibility(request: HttpRequest) -> HttpResponse:
|
def check_global_compatibility(request: HttpRequest) -> HttpResponse:
|
||||||
if request.META.get("HTTP_USER_AGENT") is None:
|
if request.META.get("HTTP_USER_AGENT") is None:
|
||||||
return json_error(_("User-Agent header missing from request"))
|
raise JsonableError(_("User-Agent header missing from request"))
|
||||||
|
|
||||||
# This string should not be tagged for translation, since old
|
# This string should not be tagged for translation, since old
|
||||||
# clients are checking for an extra string.
|
# clients are checking for an extra string.
|
||||||
legacy_compatibility_error_message = "Client is too old"
|
legacy_compatibility_error_message = "Client is too old"
|
||||||
user_agent = parse_user_agent(request.META["HTTP_USER_AGENT"])
|
user_agent = parse_user_agent(request.META["HTTP_USER_AGENT"])
|
||||||
if user_agent["name"] == "ZulipInvalid":
|
if user_agent["name"] == "ZulipInvalid":
|
||||||
return json_error(legacy_compatibility_error_message)
|
raise JsonableError(legacy_compatibility_error_message)
|
||||||
if user_agent["name"] == "ZulipMobile":
|
if user_agent["name"] == "ZulipMobile":
|
||||||
user_os = find_mobile_os(request.META["HTTP_USER_AGENT"])
|
user_os = find_mobile_os(request.META["HTTP_USER_AGENT"])
|
||||||
if user_os == "android" and version_lt(user_agent["version"], android_min_app_version):
|
if user_os == "android" and version_lt(user_agent["version"], android_min_app_version):
|
||||||
return json_error(legacy_compatibility_error_message)
|
raise JsonableError(legacy_compatibility_error_message)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -19,7 +19,7 @@ from zerver.lib.actions import (
|
||||||
from zerver.lib.exceptions import JsonableError
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.external_accounts import validate_external_account_field_data
|
from zerver.lib.external_accounts import validate_external_account_field_data
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.types import ProfileFieldData
|
from zerver.lib.types import ProfileFieldData
|
||||||
from zerver.lib.users import validate_user_custom_profile_data
|
from zerver.lib.users import validate_user_custom_profile_data
|
||||||
from zerver.lib.validator import (
|
from zerver.lib.validator import (
|
||||||
|
@ -124,7 +124,7 @@ def create_realm_custom_profile_field(
|
||||||
)
|
)
|
||||||
return json_success({"id": field.id})
|
return json_success({"id": field.id})
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
return json_error(_("A field with that label already exists."))
|
raise JsonableError(_("A field with that label already exists."))
|
||||||
|
|
||||||
|
|
||||||
@require_realm_admin
|
@require_realm_admin
|
||||||
|
@ -134,7 +134,7 @@ def delete_realm_custom_profile_field(
|
||||||
try:
|
try:
|
||||||
field = CustomProfileField.objects.get(id=field_id)
|
field = CustomProfileField.objects.get(id=field_id)
|
||||||
except CustomProfileField.DoesNotExist:
|
except CustomProfileField.DoesNotExist:
|
||||||
return json_error(_("Field id {id} not found.").format(id=field_id))
|
raise JsonableError(_("Field id {id} not found.").format(id=field_id))
|
||||||
|
|
||||||
do_remove_realm_custom_profile_field(realm=user_profile.realm, field=field)
|
do_remove_realm_custom_profile_field(realm=user_profile.realm, field=field)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
@ -154,17 +154,17 @@ def update_realm_custom_profile_field(
|
||||||
try:
|
try:
|
||||||
field = CustomProfileField.objects.get(realm=realm, id=field_id)
|
field = CustomProfileField.objects.get(realm=realm, id=field_id)
|
||||||
except CustomProfileField.DoesNotExist:
|
except CustomProfileField.DoesNotExist:
|
||||||
return json_error(_("Field id {id} not found.").format(id=field_id))
|
raise JsonableError(_("Field id {id} not found.").format(id=field_id))
|
||||||
|
|
||||||
if field.field_type == CustomProfileField.EXTERNAL_ACCOUNT:
|
if field.field_type == CustomProfileField.EXTERNAL_ACCOUNT:
|
||||||
if is_default_external_field(field.field_type, orjson.loads(field.field_data)):
|
if is_default_external_field(field.field_type, orjson.loads(field.field_data)):
|
||||||
return json_error(_("Default custom field cannot be updated."))
|
raise JsonableError(_("Default custom field cannot be updated."))
|
||||||
|
|
||||||
validate_custom_profile_field(name, hint, field.field_type, field_data)
|
validate_custom_profile_field(name, hint, field.field_type, field_data)
|
||||||
try:
|
try:
|
||||||
try_update_realm_custom_profile_field(realm, field, name, hint=hint, field_data=field_data)
|
try_update_realm_custom_profile_field(realm, field, name, hint=hint, field_data=field_data)
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
return json_error(_("A field with that label already exists."))
|
raise JsonableError(_("A field with that label already exists."))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ def api_dev_fetch_api_key(request: HttpRequest, username: str = REQ()) -> HttpRe
|
||||||
validate_login_email(username)
|
validate_login_email(username)
|
||||||
realm = get_realm_from_request(request)
|
realm = get_realm_from_request(request)
|
||||||
if realm is None:
|
if realm is None:
|
||||||
return json_error(_("Invalid subdomain"))
|
raise JsonableError(_("Invalid subdomain"))
|
||||||
return_data: Dict[str, bool] = {}
|
return_data: Dict[str, bool] = {}
|
||||||
user_profile = authenticate(dev_auth_username=username, realm=realm, return_data=return_data)
|
user_profile = authenticate(dev_auth_username=username, realm=realm, return_data=return_data)
|
||||||
if return_data.get("inactive_realm"):
|
if return_data.get("inactive_realm"):
|
||||||
|
|
|
@ -6,6 +6,7 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.test import Client
|
from django.test import Client
|
||||||
|
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.integrations import WEBHOOK_INTEGRATIONS
|
from zerver.lib.integrations import WEBHOOK_INTEGRATIONS
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_error, json_success
|
||||||
|
@ -104,7 +105,7 @@ def check_send_webhook_fixture_message(
|
||||||
try:
|
try:
|
||||||
custom_headers_dict = orjson.loads(custom_headers)
|
custom_headers_dict = orjson.loads(custom_headers)
|
||||||
except orjson.JSONDecodeError as ve:
|
except orjson.JSONDecodeError as ve:
|
||||||
return json_error(f"Custom HTTP headers are not in a valid JSON format. {ve}") # nolint
|
raise JsonableError(f"Custom HTTP headers are not in a valid JSON format. {ve}") # nolint
|
||||||
|
|
||||||
response = send_webhook_fixture_message(url, body, is_json, custom_headers_dict)
|
response = send_webhook_fixture_message(url, body, is_json, custom_headers_dict)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
|
|
|
@ -2,8 +2,9 @@ from django.http import HttpRequest, HttpResponse
|
||||||
|
|
||||||
from zerver.decorator import internal_notify_view
|
from zerver.decorator import internal_notify_view
|
||||||
from zerver.lib.email_mirror import mirror_email_message
|
from zerver.lib.email_mirror import mirror_email_message
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
|
|
||||||
|
|
||||||
@internal_notify_view(False)
|
@internal_notify_view(False)
|
||||||
|
@ -15,5 +16,5 @@ def email_mirror_message(
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
result = mirror_email_message(rcpt_to, msg_base64)
|
result = mirror_email_message(rcpt_to, msg_base64)
|
||||||
if result["status"] == "error":
|
if result["status"] == "error":
|
||||||
return json_error(result["msg"])
|
raise JsonableError(result["msg"])
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -4,8 +4,9 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.lib.events import do_events_register
|
from zerver.lib.events import do_events_register
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.validator import check_bool, check_dict, check_list, check_string
|
from zerver.lib.validator import check_bool, check_dict, check_list, check_string
|
||||||
from zerver.models import Stream, UserProfile
|
from zerver.models import Stream, UserProfile
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ def events_register_backend(
|
||||||
queue_lifespan_secs: int = REQ(converter=int, default=0, documentation_pending=True),
|
queue_lifespan_secs: int = REQ(converter=int, default=0, documentation_pending=True),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if all_public_streams and not user_profile.can_access_public_streams():
|
if all_public_streams and not user_profile.can_access_public_streams():
|
||||||
return json_error(_("User not authorized for this query"))
|
raise JsonableError(_("User not authorized for this query"))
|
||||||
|
|
||||||
all_public_streams = _default_all_public_streams(user_profile, all_public_streams)
|
all_public_streams = _default_all_public_streams(user_profile, all_public_streams)
|
||||||
narrow = _default_narrow(user_profile, narrow)
|
narrow = _default_narrow(user_profile, narrow)
|
||||||
|
|
|
@ -3,9 +3,10 @@ from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import human_users_only
|
from zerver.decorator import human_users_only
|
||||||
from zerver.lib.actions import do_mark_hotspot_as_read
|
from zerver.lib.actions import do_mark_hotspot_as_read
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.hotspots import ALL_HOTSPOTS
|
from zerver.lib.hotspots import ALL_HOTSPOTS
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +16,6 @@ def mark_hotspot_as_read(
|
||||||
request: HttpRequest, user: UserProfile, hotspot: str = REQ()
|
request: HttpRequest, user: UserProfile, hotspot: str = REQ()
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if hotspot not in ALL_HOTSPOTS:
|
if hotspot not in ALL_HOTSPOTS:
|
||||||
return json_error(_("Unknown hotspot: {}").format(hotspot))
|
raise JsonableError(_("Unknown hotspot: {}").format(hotspot))
|
||||||
do_mark_hotspot_as_read(user, hotspot)
|
do_mark_hotspot_as_read(user, hotspot)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -15,7 +15,7 @@ from zerver.lib.actions import (
|
||||||
)
|
)
|
||||||
from zerver.lib.exceptions import OrganizationOwnerRequired
|
from zerver.lib.exceptions import OrganizationOwnerRequired
|
||||||
from zerver.lib.request import REQ, JsonableError, has_request_variables
|
from zerver.lib.request import REQ, JsonableError, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.streams import access_stream_by_id
|
from zerver.lib.streams import access_stream_by_id
|
||||||
from zerver.lib.validator import check_int, check_list
|
from zerver.lib.validator import check_int, check_list
|
||||||
from zerver.models import MultiuseInvite, PreregistrationUser, Stream, UserProfile
|
from zerver.models import MultiuseInvite, PreregistrationUser, Stream, UserProfile
|
||||||
|
@ -44,7 +44,7 @@ def invite_users_backend(
|
||||||
# be handled by the decorator above.
|
# be handled by the decorator above.
|
||||||
raise JsonableError(_("Insufficient permission"))
|
raise JsonableError(_("Insufficient permission"))
|
||||||
if invite_as not in PreregistrationUser.INVITE_AS.values():
|
if invite_as not in PreregistrationUser.INVITE_AS.values():
|
||||||
return json_error(_("Must be invited as an valid type of user"))
|
raise JsonableError(_("Must be invited as an valid type of user"))
|
||||||
check_if_owner_required(invite_as, user_profile)
|
check_if_owner_required(invite_as, user_profile)
|
||||||
if (
|
if (
|
||||||
invite_as
|
invite_as
|
||||||
|
@ -54,11 +54,11 @@ def invite_users_backend(
|
||||||
]
|
]
|
||||||
and not user_profile.is_realm_admin
|
and not user_profile.is_realm_admin
|
||||||
):
|
):
|
||||||
return json_error(_("Must be an organization administrator"))
|
raise JsonableError(_("Must be an organization administrator"))
|
||||||
if not invitee_emails_raw:
|
if not invitee_emails_raw:
|
||||||
return json_error(_("You must specify at least one email address."))
|
raise JsonableError(_("You must specify at least one email address."))
|
||||||
if not stream_ids:
|
if not stream_ids:
|
||||||
return json_error(_("You must specify at least one stream for invitees to join."))
|
raise JsonableError(_("You must specify at least one stream for invitees to join."))
|
||||||
|
|
||||||
invitee_emails = get_invitee_emails_set(invitee_emails_raw)
|
invitee_emails = get_invitee_emails_set(invitee_emails_raw)
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ def invite_users_backend(
|
||||||
try:
|
try:
|
||||||
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
||||||
except JsonableError:
|
except JsonableError:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Stream does not exist with id: {}. No invites were sent.").format(stream_id)
|
_("Stream does not exist with id: {}. No invites were sent.").format(stream_id)
|
||||||
)
|
)
|
||||||
streams.append(stream)
|
streams.append(stream)
|
||||||
|
@ -174,7 +174,7 @@ def generate_multiuse_invite_backend(
|
||||||
try:
|
try:
|
||||||
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
||||||
except JsonableError:
|
except JsonableError:
|
||||||
return json_error(_("Invalid stream id {}. No invites were sent.").format(stream_id))
|
raise JsonableError(_("Invalid stream id {}. No invites were sent.").format(stream_id))
|
||||||
streams.append(stream)
|
streams.append(stream)
|
||||||
|
|
||||||
invite_link = do_create_multiuse_invite_link(user_profile, invite_as, streams)
|
invite_link = do_create_multiuse_invite_link(user_profile, invite_as, streams)
|
||||||
|
|
|
@ -12,7 +12,7 @@ from zerver.lib.actions import check_update_message, do_delete_messages
|
||||||
from zerver.lib.exceptions import JsonableError
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.html_diff import highlight_html_differences
|
from zerver.lib.html_diff import highlight_html_differences
|
||||||
from zerver.lib.message import access_message
|
from zerver.lib.message import access_message
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.timestamp import datetime_to_timestamp
|
from zerver.lib.timestamp import datetime_to_timestamp
|
||||||
from zerver.lib.topic import LEGACY_PREV_TOPIC, REQ_topic
|
from zerver.lib.topic import LEGACY_PREV_TOPIC, REQ_topic
|
||||||
from zerver.lib.validator import check_bool, check_string_in, to_non_negative_int
|
from zerver.lib.validator import check_bool, check_string_in, to_non_negative_int
|
||||||
|
@ -74,7 +74,7 @@ def get_message_edit_history(
|
||||||
message_id: int = REQ(converter=to_non_negative_int, path_only=True),
|
message_id: int = REQ(converter=to_non_negative_int, path_only=True),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if not user_profile.realm.allow_edit_history:
|
if not user_profile.realm.allow_edit_history:
|
||||||
return json_error(_("Message edit history is disabled in this organization"))
|
raise JsonableError(_("Message edit history is disabled in this organization"))
|
||||||
message, ignored_user_message = access_message(user_profile, message_id)
|
message, ignored_user_message = access_message(user_profile, message_id)
|
||||||
|
|
||||||
# Extract the message edit history from the message
|
# Extract the message edit history from the message
|
||||||
|
|
|
@ -38,7 +38,7 @@ from zerver.lib.addressee import get_user_profiles, get_user_profiles_by_ids
|
||||||
from zerver.lib.exceptions import ErrorCode, JsonableError, MissingAuthenticationError
|
from zerver.lib.exceptions import ErrorCode, JsonableError, MissingAuthenticationError
|
||||||
from zerver.lib.message import get_first_visible_message_id, messages_for_ids
|
from zerver.lib.message import get_first_visible_message_id, messages_for_ids
|
||||||
from zerver.lib.narrow import is_web_public_compatible, is_web_public_narrow
|
from zerver.lib.narrow import is_web_public_compatible, is_web_public_narrow
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.sqlalchemy_utils import get_sqlalchemy_connection
|
from zerver.lib.sqlalchemy_utils import get_sqlalchemy_connection
|
||||||
from zerver.lib.streams import (
|
from zerver.lib.streams import (
|
||||||
can_access_stream_history_by_id,
|
can_access_stream_history_by_id,
|
||||||
|
@ -946,7 +946,7 @@ def get_messages_backend(
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
anchor = parse_anchor_value(anchor_val, use_first_unread_anchor_val)
|
anchor = parse_anchor_value(anchor_val, use_first_unread_anchor_val)
|
||||||
if num_before + num_after > MAX_MESSAGES_PER_FETCH:
|
if num_before + num_after > MAX_MESSAGES_PER_FETCH:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Too many messages requested (maximum {}).").format(
|
_("Too many messages requested (maximum {}).").format(
|
||||||
MAX_MESSAGES_PER_FETCH,
|
MAX_MESSAGES_PER_FETCH,
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,8 +18,9 @@ from zerver.lib.actions import (
|
||||||
extract_private_recipients,
|
extract_private_recipients,
|
||||||
extract_stream_indicator,
|
extract_stream_indicator,
|
||||||
)
|
)
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.message import render_markdown
|
from zerver.lib.message import render_markdown
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.timestamp import convert_to_UTC
|
from zerver.lib.timestamp import convert_to_UTC
|
||||||
from zerver.lib.topic import REQ_topic
|
from zerver.lib.topic import REQ_topic
|
||||||
from zerver.lib.zcommand import process_zcommands
|
from zerver.lib.zcommand import process_zcommands
|
||||||
|
@ -151,7 +152,7 @@ def handle_deferred_message(
|
||||||
try:
|
try:
|
||||||
deliver_at = dateparser(defer_until)
|
deliver_at = dateparser(defer_until)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return json_error(_("Invalid time format"))
|
raise JsonableError(_("Invalid time format"))
|
||||||
|
|
||||||
deliver_at_usertz = deliver_at
|
deliver_at_usertz = deliver_at
|
||||||
if deliver_at_usertz.tzinfo is None:
|
if deliver_at_usertz.tzinfo is None:
|
||||||
|
@ -160,7 +161,7 @@ def handle_deferred_message(
|
||||||
deliver_at = convert_to_UTC(deliver_at_usertz)
|
deliver_at = convert_to_UTC(deliver_at_usertz)
|
||||||
|
|
||||||
if deliver_at <= timezone_now():
|
if deliver_at <= timezone_now():
|
||||||
return json_error(_("Time must be in the future."))
|
raise JsonableError(_("Time must be in the future."))
|
||||||
|
|
||||||
check_schedule_message(
|
check_schedule_message(
|
||||||
sender,
|
sender,
|
||||||
|
@ -223,13 +224,13 @@ def send_message_backend(
|
||||||
client = request.client
|
client = request.client
|
||||||
can_forge_sender = request.user.can_forge_sender
|
can_forge_sender = request.user.can_forge_sender
|
||||||
if forged and not can_forge_sender:
|
if forged and not can_forge_sender:
|
||||||
return json_error(_("User not authorized for this query"))
|
raise JsonableError(_("User not authorized for this query"))
|
||||||
|
|
||||||
realm = None
|
realm = None
|
||||||
if realm_str and realm_str != user_profile.realm.string_id:
|
if realm_str and realm_str != user_profile.realm.string_id:
|
||||||
# The realm_str parameter does nothing, because it has to match
|
# The realm_str parameter does nothing, because it has to match
|
||||||
# the user's realm - but we keep it around for backward compatibility.
|
# the user's realm - but we keep it around for backward compatibility.
|
||||||
return json_error(_("User not authorized for this query"))
|
raise JsonableError(_("User not authorized for this query"))
|
||||||
|
|
||||||
if client.name in ["zephyr_mirror", "irc_mirror", "jabber_mirror", "JabberMirror"]:
|
if client.name in ["zephyr_mirror", "irc_mirror", "jabber_mirror", "JabberMirror"]:
|
||||||
# Here's how security works for mirroring:
|
# Here's how security works for mirroring:
|
||||||
|
@ -246,14 +247,14 @@ def send_message_backend(
|
||||||
# `create_mirrored_message_users` below, which checks the
|
# `create_mirrored_message_users` below, which checks the
|
||||||
# same-realm constraint.
|
# same-realm constraint.
|
||||||
if "sender" not in request.POST:
|
if "sender" not in request.POST:
|
||||||
return json_error(_("Missing sender"))
|
raise JsonableError(_("Missing sender"))
|
||||||
if message_type_name != "private" and not can_forge_sender:
|
if message_type_name != "private" and not can_forge_sender:
|
||||||
return json_error(_("User not authorized for this query"))
|
raise JsonableError(_("User not authorized for this query"))
|
||||||
|
|
||||||
# For now, mirroring only works with recipient emails, not for
|
# For now, mirroring only works with recipient emails, not for
|
||||||
# recipient user IDs.
|
# recipient user IDs.
|
||||||
if not all(isinstance(to_item, str) for to_item in message_to):
|
if not all(isinstance(to_item, str) for to_item in message_to):
|
||||||
return json_error(_("Mirroring not allowed with recipient user IDs"))
|
raise JsonableError(_("Mirroring not allowed with recipient user IDs"))
|
||||||
|
|
||||||
# We need this manual cast so that mypy doesn't complain about
|
# We need this manual cast so that mypy doesn't complain about
|
||||||
# create_mirrored_message_users not being able to accept a Sequence[int]
|
# create_mirrored_message_users not being able to accept a Sequence[int]
|
||||||
|
@ -263,18 +264,18 @@ def send_message_backend(
|
||||||
try:
|
try:
|
||||||
mirror_sender = create_mirrored_message_users(request, user_profile, message_to)
|
mirror_sender = create_mirrored_message_users(request, user_profile, message_to)
|
||||||
except InvalidMirrorInput:
|
except InvalidMirrorInput:
|
||||||
return json_error(_("Invalid mirrored message"))
|
raise JsonableError(_("Invalid mirrored message"))
|
||||||
|
|
||||||
if client.name == "zephyr_mirror" and not user_profile.realm.is_zephyr_mirror_realm:
|
if client.name == "zephyr_mirror" and not user_profile.realm.is_zephyr_mirror_realm:
|
||||||
return json_error(_("Zephyr mirroring is not allowed in this organization"))
|
raise JsonableError(_("Zephyr mirroring is not allowed in this organization"))
|
||||||
sender = mirror_sender
|
sender = mirror_sender
|
||||||
else:
|
else:
|
||||||
if "sender" in request.POST:
|
if "sender" in request.POST:
|
||||||
return json_error(_("Invalid mirrored message"))
|
raise JsonableError(_("Invalid mirrored message"))
|
||||||
sender = user_profile
|
sender = user_profile
|
||||||
|
|
||||||
if (delivery_type == "send_later" or delivery_type == "remind") and defer_until is None:
|
if (delivery_type == "send_later" or delivery_type == "remind") and defer_until is None:
|
||||||
return json_error(_("Missing deliver_at in a request for delayed message delivery"))
|
raise JsonableError(_("Missing deliver_at in a request for delayed message delivery"))
|
||||||
|
|
||||||
if (delivery_type == "send_later" or delivery_type == "remind") and defer_until is not None:
|
if (delivery_type == "send_later" or delivery_type == "remind") and defer_until is not None:
|
||||||
return handle_deferred_message(
|
return handle_deferred_message(
|
||||||
|
|
|
@ -6,8 +6,9 @@ from django.utils.timezone import now as timezone_now
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.lib.actions import do_mute_topic, do_mute_user, do_unmute_topic, do_unmute_user
|
from zerver.lib.actions import do_mute_topic, do_mute_user, do_unmute_topic, do_unmute_user
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.streams import (
|
from zerver.lib.streams import (
|
||||||
access_stream_by_id,
|
access_stream_by_id,
|
||||||
access_stream_by_name,
|
access_stream_by_name,
|
||||||
|
@ -36,7 +37,7 @@ def mute_topic(
|
||||||
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
||||||
|
|
||||||
if topic_is_muted(user_profile, stream.id, topic_name):
|
if topic_is_muted(user_profile, stream.id, topic_name):
|
||||||
return json_error(_("Topic already muted"))
|
raise JsonableError(_("Topic already muted"))
|
||||||
|
|
||||||
do_mute_topic(user_profile, stream, topic_name, date_muted)
|
do_mute_topic(user_profile, stream, topic_name, date_muted)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
@ -54,7 +55,7 @@ def unmute_topic(
|
||||||
stream = access_stream_for_unmute_topic_by_id(user_profile, stream_id, error)
|
stream = access_stream_for_unmute_topic_by_id(user_profile, stream_id, error)
|
||||||
|
|
||||||
if not topic_is_muted(user_profile, stream.id, topic_name):
|
if not topic_is_muted(user_profile, stream.id, topic_name):
|
||||||
return json_error(error)
|
raise JsonableError(error)
|
||||||
|
|
||||||
do_unmute_topic(user_profile, stream, topic_name)
|
do_unmute_topic(user_profile, stream, topic_name)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
@ -91,13 +92,13 @@ def update_muted_topic(
|
||||||
|
|
||||||
def mute_user(request: HttpRequest, user_profile: UserProfile, muted_user_id: int) -> HttpResponse:
|
def mute_user(request: HttpRequest, user_profile: UserProfile, muted_user_id: int) -> HttpResponse:
|
||||||
if user_profile.id == muted_user_id:
|
if user_profile.id == muted_user_id:
|
||||||
return json_error(_("Cannot mute self"))
|
raise JsonableError(_("Cannot mute self"))
|
||||||
|
|
||||||
muted_user = access_user_by_id(user_profile, muted_user_id, allow_bots=False, for_admin=False)
|
muted_user = access_user_by_id(user_profile, muted_user_id, allow_bots=False, for_admin=False)
|
||||||
date_muted = timezone_now()
|
date_muted = timezone_now()
|
||||||
|
|
||||||
if get_mute_object(user_profile, muted_user) is not None:
|
if get_mute_object(user_profile, muted_user) is not None:
|
||||||
return json_error(_("User already muted"))
|
raise JsonableError(_("User already muted"))
|
||||||
|
|
||||||
do_mute_user(user_profile, muted_user, date_muted)
|
do_mute_user(user_profile, muted_user, date_muted)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
@ -110,7 +111,7 @@ def unmute_user(
|
||||||
mute_object = get_mute_object(user_profile, muted_user)
|
mute_object = get_mute_object(user_profile, muted_user)
|
||||||
|
|
||||||
if mute_object is None:
|
if mute_object is None:
|
||||||
return json_error(_("User is not muted"))
|
raise JsonableError(_("User is not muted"))
|
||||||
|
|
||||||
do_unmute_user(mute_object)
|
do_unmute_user(mute_object)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -10,7 +10,7 @@ from zerver.decorator import human_users_only
|
||||||
from zerver.lib.actions import do_update_user_status, update_user_presence
|
from zerver.lib.actions import do_update_user_status, update_user_presence
|
||||||
from zerver.lib.presence import get_presence_for_user, get_presence_response
|
from zerver.lib.presence import get_presence_for_user, get_presence_response
|
||||||
from zerver.lib.request import REQ, JsonableError, has_request_variables
|
from zerver.lib.request import REQ, JsonableError, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.timestamp import datetime_to_timestamp
|
from zerver.lib.timestamp import datetime_to_timestamp
|
||||||
from zerver.lib.validator import check_bool, check_capped_string
|
from zerver.lib.validator import check_bool, check_capped_string
|
||||||
from zerver.models import (
|
from zerver.models import (
|
||||||
|
@ -37,14 +37,14 @@ def get_presence_backend(
|
||||||
email = user_id_or_email
|
email = user_id_or_email
|
||||||
target = get_active_user(email, user_profile.realm)
|
target = get_active_user(email, user_profile.realm)
|
||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
return json_error(_("No such user"))
|
raise JsonableError(_("No such user"))
|
||||||
|
|
||||||
if target.is_bot:
|
if target.is_bot:
|
||||||
return json_error(_("Presence is not supported for bot users."))
|
raise JsonableError(_("Presence is not supported for bot users."))
|
||||||
|
|
||||||
presence_dict = get_presence_for_user(target.id)
|
presence_dict = get_presence_for_user(target.id)
|
||||||
if len(presence_dict) == 0:
|
if len(presence_dict) == 0:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("No presence data for {user_id_or_email}").format(user_id_or_email=user_id_or_email)
|
_("No presence data for {user_id_or_email}").format(user_id_or_email=user_id_or_email)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ def update_user_status_backend(
|
||||||
status_text = status_text.strip()
|
status_text = status_text.strip()
|
||||||
|
|
||||||
if (away is None) and (status_text is None):
|
if (away is None) and (status_text is None):
|
||||||
return json_error(_("Client did not pass any new values."))
|
raise JsonableError(_("Client did not pass any new values."))
|
||||||
|
|
||||||
do_update_user_status(
|
do_update_user_status(
|
||||||
user_profile=user_profile,
|
user_profile=user_profile,
|
||||||
|
|
|
@ -21,7 +21,7 @@ from zerver.lib.actions import (
|
||||||
from zerver.lib.exceptions import OrganizationOwnerRequired
|
from zerver.lib.exceptions import OrganizationOwnerRequired
|
||||||
from zerver.lib.i18n import get_available_language_codes
|
from zerver.lib.i18n import get_available_language_codes
|
||||||
from zerver.lib.request import REQ, JsonableError, has_request_variables
|
from zerver.lib.request import REQ, JsonableError, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.retention import parse_message_retention_days
|
from zerver.lib.retention import parse_message_retention_days
|
||||||
from zerver.lib.streams import access_stream_by_id
|
from zerver.lib.streams import access_stream_by_id
|
||||||
from zerver.lib.validator import (
|
from zerver.lib.validator import (
|
||||||
|
@ -131,15 +131,15 @@ def update_realm(
|
||||||
if not user_profile.is_realm_owner:
|
if not user_profile.is_realm_owner:
|
||||||
raise OrganizationOwnerRequired()
|
raise OrganizationOwnerRequired()
|
||||||
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."))
|
raise JsonableError(_("At least one authentication method must be enabled."))
|
||||||
if video_chat_provider is not None and video_chat_provider not in {
|
if video_chat_provider is not None and video_chat_provider not in {
|
||||||
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))
|
raise JsonableError(_("Invalid video_chat_provider {}").format(video_chat_provider))
|
||||||
if giphy_rating is not None and giphy_rating not in {
|
if giphy_rating is not None and giphy_rating not in {
|
||||||
p["id"] for p in Realm.GIPHY_RATING_OPTIONS.values()
|
p["id"] for p in Realm.GIPHY_RATING_OPTIONS.values()
|
||||||
}:
|
}:
|
||||||
return json_error(_("Invalid giphy_rating {}").format(giphy_rating))
|
raise JsonableError(_("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:
|
||||||
|
|
|
@ -5,8 +5,9 @@ from django.utils.translation import gettext as _
|
||||||
from zerver.decorator import require_realm_admin
|
from zerver.decorator import require_realm_admin
|
||||||
from zerver.lib.actions import do_add_realm_domain, do_change_realm_domain, do_remove_realm_domain
|
from zerver.lib.actions import do_add_realm_domain, do_change_realm_domain, do_remove_realm_domain
|
||||||
from zerver.lib.domains import validate_domain
|
from zerver.lib.domains import validate_domain
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.validator import check_bool
|
from zerver.lib.validator import check_bool
|
||||||
from zerver.models import RealmDomain, UserProfile, get_realm_domains
|
from zerver.models import RealmDomain, UserProfile, get_realm_domains
|
||||||
|
|
||||||
|
@ -28,9 +29,9 @@ def create_realm_domain(
|
||||||
try:
|
try:
|
||||||
validate_domain(domain)
|
validate_domain(domain)
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
return json_error(_("Invalid domain: {}").format(e.messages[0]))
|
raise JsonableError(_("Invalid domain: {}").format(e.messages[0]))
|
||||||
if RealmDomain.objects.filter(realm=user_profile.realm, domain=domain).exists():
|
if RealmDomain.objects.filter(realm=user_profile.realm, domain=domain).exists():
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("The domain {domain} is already a part of your organization.").format(domain=domain)
|
_("The domain {domain} is already a part of your organization.").format(domain=domain)
|
||||||
)
|
)
|
||||||
realm_domain = do_add_realm_domain(user_profile.realm, domain, allow_subdomains)
|
realm_domain = do_add_realm_domain(user_profile.realm, domain, allow_subdomains)
|
||||||
|
@ -49,7 +50,7 @@ def patch_realm_domain(
|
||||||
realm_domain = RealmDomain.objects.get(realm=user_profile.realm, domain=domain)
|
realm_domain = RealmDomain.objects.get(realm=user_profile.realm, domain=domain)
|
||||||
do_change_realm_domain(realm_domain, allow_subdomains)
|
do_change_realm_domain(realm_domain, allow_subdomains)
|
||||||
except RealmDomain.DoesNotExist:
|
except RealmDomain.DoesNotExist:
|
||||||
return json_error(_("No entry found for domain {domain}.").format(domain=domain))
|
raise JsonableError(_("No entry found for domain {domain}.").format(domain=domain))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,5 +63,5 @@ def delete_realm_domain(
|
||||||
realm_domain = RealmDomain.objects.get(realm=user_profile.realm, domain=domain)
|
realm_domain = RealmDomain.objects.get(realm=user_profile.realm, domain=domain)
|
||||||
do_remove_realm_domain(realm_domain, acting_user=user_profile)
|
do_remove_realm_domain(realm_domain, acting_user=user_profile)
|
||||||
except RealmDomain.DoesNotExist:
|
except RealmDomain.DoesNotExist:
|
||||||
return json_error(_("No entry found for domain {domain}.").format(domain=domain))
|
raise JsonableError(_("No entry found for domain {domain}.").format(domain=domain))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -6,7 +6,7 @@ from zerver.decorator import require_member_or_admin
|
||||||
from zerver.lib.actions import check_add_realm_emoji, do_remove_realm_emoji
|
from zerver.lib.actions import check_add_realm_emoji, do_remove_realm_emoji
|
||||||
from zerver.lib.emoji import check_emoji_admin, check_valid_emoji_name
|
from zerver.lib.emoji import check_emoji_admin, check_valid_emoji_name
|
||||||
from zerver.lib.request import REQ, JsonableError, has_request_variables
|
from zerver.lib.request import REQ, JsonableError, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.models import RealmEmoji, UserProfile
|
from zerver.models import RealmEmoji, UserProfile
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,12 +28,12 @@ def upload_emoji(
|
||||||
if RealmEmoji.objects.filter(
|
if RealmEmoji.objects.filter(
|
||||||
realm=user_profile.realm, name=emoji_name, deactivated=False
|
realm=user_profile.realm, name=emoji_name, deactivated=False
|
||||||
).exists():
|
).exists():
|
||||||
return json_error(_("A custom emoji with this name already exists."))
|
raise JsonableError(_("A custom emoji with this name already exists."))
|
||||||
if len(request.FILES) != 1:
|
if len(request.FILES) != 1:
|
||||||
return json_error(_("You must upload exactly one file."))
|
raise JsonableError(_("You must upload exactly one file."))
|
||||||
emoji_file = list(request.FILES.values())[0]
|
emoji_file = list(request.FILES.values())[0]
|
||||||
if (settings.MAX_EMOJI_FILE_SIZE_MIB * 1024 * 1024) < emoji_file.size:
|
if (settings.MAX_EMOJI_FILE_SIZE_MIB * 1024 * 1024) < emoji_file.size:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
||||||
settings.MAX_EMOJI_FILE_SIZE_MIB,
|
settings.MAX_EMOJI_FILE_SIZE_MIB,
|
||||||
)
|
)
|
||||||
|
@ -41,7 +41,7 @@ def upload_emoji(
|
||||||
|
|
||||||
realm_emoji = check_add_realm_emoji(user_profile.realm, emoji_name, user_profile, emoji_file)
|
realm_emoji = check_add_realm_emoji(user_profile.realm, emoji_name, user_profile, emoji_file)
|
||||||
if realm_emoji is None:
|
if realm_emoji is None:
|
||||||
return json_error(_("Image file upload failed."))
|
raise JsonableError(_("Image file upload failed."))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,10 @@ from django.utils.translation import gettext as _
|
||||||
from analytics.models import RealmCount
|
from analytics.models import RealmCount
|
||||||
from zerver.decorator import require_realm_admin
|
from zerver.decorator import require_realm_admin
|
||||||
from zerver.lib.actions import do_delete_realm_export, notify_realm_export
|
from zerver.lib.actions import do_delete_realm_export, notify_realm_export
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.export import get_realm_exports_serialized
|
from zerver.lib.export import get_realm_exports_serialized
|
||||||
from zerver.lib.queue import queue_json_publish
|
from zerver.lib.queue import queue_json_publish
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.models import RealmAuditLog, UserProfile
|
from zerver.models import RealmAuditLog, UserProfile
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ def export_realm(request: HttpRequest, user: UserProfile) -> HttpResponse:
|
||||||
realm=realm, event_type=event_type, event_time__gte=event_time_delta
|
realm=realm, event_type=event_type, event_time__gte=event_time_delta
|
||||||
)
|
)
|
||||||
if len(limit_check) >= EXPORT_LIMIT:
|
if len(limit_check) >= EXPORT_LIMIT:
|
||||||
return json_error(_("Exceeded rate limit."))
|
raise JsonableError(_("Exceeded rate limit."))
|
||||||
|
|
||||||
total_messages = sum(
|
total_messages = sum(
|
||||||
realm_count.value
|
realm_count.value
|
||||||
|
@ -48,7 +49,7 @@ def export_realm(request: HttpRequest, user: UserProfile) -> HttpResponse:
|
||||||
total_messages > MAX_MESSAGE_HISTORY
|
total_messages > MAX_MESSAGE_HISTORY
|
||||||
or user.realm.currently_used_upload_space_bytes() > MAX_UPLOAD_QUOTA
|
or user.realm.currently_used_upload_space_bytes() > MAX_UPLOAD_QUOTA
|
||||||
):
|
):
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Please request a manual export from {email}.").format(
|
_("Please request a manual export from {email}.").format(
|
||||||
email=settings.ZULIP_ADMINISTRATOR,
|
email=settings.ZULIP_ADMINISTRATOR,
|
||||||
)
|
)
|
||||||
|
@ -87,10 +88,10 @@ def delete_realm_export(request: HttpRequest, user: UserProfile, export_id: int)
|
||||||
id=export_id, realm=user.realm, event_type=RealmAuditLog.REALM_EXPORTED
|
id=export_id, realm=user.realm, event_type=RealmAuditLog.REALM_EXPORTED
|
||||||
)
|
)
|
||||||
except RealmAuditLog.DoesNotExist:
|
except RealmAuditLog.DoesNotExist:
|
||||||
return json_error(_("Invalid data export ID"))
|
raise JsonableError(_("Invalid data export ID"))
|
||||||
|
|
||||||
export_data = orjson.loads(audit_log_entry.extra_data)
|
export_data = orjson.loads(audit_log_entry.extra_data)
|
||||||
if "deleted_timestamp" in export_data:
|
if "deleted_timestamp" in export_data:
|
||||||
return json_error(_("Export already deleted"))
|
raise JsonableError(_("Export already deleted"))
|
||||||
do_delete_realm_export(user, audit_log_entry)
|
do_delete_realm_export(user, audit_log_entry)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -5,8 +5,9 @@ from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import require_realm_admin
|
from zerver.decorator import require_realm_admin
|
||||||
from zerver.lib.actions import do_change_icon_source
|
from zerver.lib.actions import do_change_icon_source
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.realm_icon import realm_icon_url
|
from zerver.lib.realm_icon import realm_icon_url
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.upload import upload_icon_image
|
from zerver.lib.upload import upload_icon_image
|
||||||
from zerver.lib.url_encoding import add_query_arg_to_redirect_url
|
from zerver.lib.url_encoding import add_query_arg_to_redirect_url
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
@ -16,11 +17,11 @@ from zerver.models import UserProfile
|
||||||
def upload_icon(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
def upload_icon(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
||||||
|
|
||||||
if len(request.FILES) != 1:
|
if len(request.FILES) != 1:
|
||||||
return json_error(_("You must upload exactly one icon."))
|
raise JsonableError(_("You must upload exactly one icon."))
|
||||||
|
|
||||||
icon_file = list(request.FILES.values())[0]
|
icon_file = list(request.FILES.values())[0]
|
||||||
if (settings.MAX_ICON_FILE_SIZE_MIB * 1024 * 1024) < icon_file.size:
|
if (settings.MAX_ICON_FILE_SIZE_MIB * 1024 * 1024) < icon_file.size:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
||||||
settings.MAX_ICON_FILE_SIZE_MIB,
|
settings.MAX_ICON_FILE_SIZE_MIB,
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,6 +4,7 @@ from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import require_realm_admin
|
from zerver.decorator import require_realm_admin
|
||||||
from zerver.lib.actions import do_add_linkifier, do_remove_linkifier, do_update_linkifier
|
from zerver.lib.actions import do_add_linkifier, do_remove_linkifier, do_update_linkifier
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_error, json_success
|
||||||
from zerver.models import RealmFilter, UserProfile, linkifiers_for_realm
|
from zerver.models import RealmFilter, UserProfile, linkifiers_for_realm
|
||||||
|
@ -41,7 +42,7 @@ def delete_linkifier(
|
||||||
try:
|
try:
|
||||||
do_remove_linkifier(realm=user_profile.realm, id=filter_id)
|
do_remove_linkifier(realm=user_profile.realm, id=filter_id)
|
||||||
except RealmFilter.DoesNotExist:
|
except RealmFilter.DoesNotExist:
|
||||||
return json_error(_("Linkifier not found."))
|
raise JsonableError(_("Linkifier not found."))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,6 +64,6 @@ def update_linkifier(
|
||||||
)
|
)
|
||||||
return json_success()
|
return json_success()
|
||||||
except RealmFilter.DoesNotExist:
|
except RealmFilter.DoesNotExist:
|
||||||
return json_error(_("Linkifier not found."))
|
raise JsonableError(_("Linkifier not found."))
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
return json_error(e.messages[0], data={"errors": dict(e)})
|
return json_error(e.messages[0], data={"errors": dict(e)})
|
||||||
|
|
|
@ -5,9 +5,10 @@ from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import require_realm_admin
|
from zerver.decorator import require_realm_admin
|
||||||
from zerver.lib.actions import do_change_logo_source
|
from zerver.lib.actions import do_change_logo_source
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.realm_logo import get_realm_logo_url
|
from zerver.lib.realm_logo import get_realm_logo_url
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.upload import upload_logo_image
|
from zerver.lib.upload import upload_logo_image
|
||||||
from zerver.lib.url_encoding import add_query_arg_to_redirect_url
|
from zerver.lib.url_encoding import add_query_arg_to_redirect_url
|
||||||
from zerver.lib.validator import check_bool
|
from zerver.lib.validator import check_bool
|
||||||
|
@ -22,10 +23,10 @@ def upload_logo(
|
||||||
user_profile.realm.ensure_not_on_limited_plan()
|
user_profile.realm.ensure_not_on_limited_plan()
|
||||||
|
|
||||||
if len(request.FILES) != 1:
|
if len(request.FILES) != 1:
|
||||||
return json_error(_("You must upload exactly one logo."))
|
raise JsonableError(_("You must upload exactly one logo."))
|
||||||
logo_file = list(request.FILES.values())[0]
|
logo_file = list(request.FILES.values())[0]
|
||||||
if (settings.MAX_LOGO_FILE_SIZE_MIB * 1024 * 1024) < logo_file.size:
|
if (settings.MAX_LOGO_FILE_SIZE_MIB * 1024 * 1024) < logo_file.size:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
||||||
settings.MAX_LOGO_FILE_SIZE_MIB,
|
settings.MAX_LOGO_FILE_SIZE_MIB,
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,7 +10,8 @@ from zerver.lib.bot_storage import (
|
||||||
remove_bot_storage,
|
remove_bot_storage,
|
||||||
set_bot_storage,
|
set_bot_storage,
|
||||||
)
|
)
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.validator import check_dict, check_list, check_string
|
from zerver.lib.validator import check_dict, check_list, check_string
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ def update_storage(
|
||||||
try:
|
try:
|
||||||
set_bot_storage(user_profile, list(storage.items()))
|
set_bot_storage(user_profile, list(storage.items()))
|
||||||
except StateError as e: # nocoverage
|
except StateError as e: # nocoverage
|
||||||
return json_error(str(e))
|
raise JsonableError(str(e))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ def get_storage(
|
||||||
try:
|
try:
|
||||||
storage = {key: get_bot_storage(user_profile, key) for key in keys}
|
storage = {key: get_bot_storage(user_profile, key) for key in keys}
|
||||||
except StateError as e:
|
except StateError as e:
|
||||||
return json_error(str(e))
|
raise JsonableError(str(e))
|
||||||
return json_success({"storage": storage})
|
return json_success({"storage": storage})
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,5 +55,5 @@ def remove_storage(
|
||||||
try:
|
try:
|
||||||
remove_bot_storage(user_profile, keys)
|
remove_bot_storage(user_profile, keys)
|
||||||
except StateError as e:
|
except StateError as e:
|
||||||
return json_error(str(e))
|
raise JsonableError(str(e))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -148,7 +148,7 @@ def add_default_stream(
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
||||||
if stream.invite_only:
|
if stream.invite_only:
|
||||||
return json_error(_("Private streams cannot be made default."))
|
raise JsonableError(_("Private streams cannot be made default."))
|
||||||
do_add_default_stream(stream)
|
do_add_default_stream(stream)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ def update_default_stream_group_info(
|
||||||
new_description: Optional[str] = REQ(default=None),
|
new_description: Optional[str] = REQ(default=None),
|
||||||
) -> None:
|
) -> None:
|
||||||
if not new_group_name and not new_description:
|
if not new_group_name and not new_description:
|
||||||
return json_error(_('You must pass "new_description" or "new_group_name".'))
|
raise JsonableError(_('You must pass "new_description" or "new_group_name".'))
|
||||||
|
|
||||||
group = access_default_stream_group_by_id(user_profile.realm, group_id)
|
group = access_default_stream_group_by_id(user_profile.realm, group_id)
|
||||||
if new_group_name is not None:
|
if new_group_name is not None:
|
||||||
|
@ -210,7 +210,7 @@ def update_default_stream_group_streams(
|
||||||
elif op == "remove":
|
elif op == "remove":
|
||||||
do_remove_streams_from_default_stream_group(user_profile.realm, group, streams)
|
do_remove_streams_from_default_stream_group(user_profile.realm, group, streams)
|
||||||
else:
|
else:
|
||||||
return json_error(_('Invalid value for "op". Specify one of "add" or "remove".'))
|
raise JsonableError(_('Invalid value for "op". Specify one of "add" or "remove".'))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ def update_stream_backend(
|
||||||
if new_name is not None:
|
if new_name is not None:
|
||||||
new_name = new_name.strip()
|
new_name = new_name.strip()
|
||||||
if stream.name == new_name:
|
if stream.name == new_name:
|
||||||
return json_error(_("Stream already has that name!"))
|
raise JsonableError(_("Stream already has that name!"))
|
||||||
if stream.name.lower() != new_name.lower():
|
if stream.name.lower() != new_name.lower():
|
||||||
# Check that the stream name is available (unless we are
|
# Check that the stream name is available (unless we are
|
||||||
# are only changing the casing of the stream name).
|
# are only changing the casing of the stream name).
|
||||||
|
@ -301,7 +301,7 @@ def update_stream_backend(
|
||||||
default_stream_ids = {s.id for s in get_default_streams_for_realm(stream.realm_id)}
|
default_stream_ids = {s.id for s in get_default_streams_for_realm(stream.realm_id)}
|
||||||
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
||||||
if is_private and stream.id in default_stream_ids:
|
if is_private and stream.id in default_stream_ids:
|
||||||
return json_error(_("Default streams cannot be made private."))
|
raise JsonableError(_("Default streams cannot be made private."))
|
||||||
do_change_stream_invite_only(stream, is_private, history_public_to_subscribers)
|
do_change_stream_invite_only(stream, is_private, history_public_to_subscribers)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ def update_subscriptions_backend(
|
||||||
add: Sequence[Mapping[str, str]] = REQ(json_validator=add_subscriptions_schema, default=[]),
|
add: Sequence[Mapping[str, str]] = REQ(json_validator=add_subscriptions_schema, default=[]),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if not add and not delete:
|
if not add and not delete:
|
||||||
return json_error(_('Nothing to do. Specify at least one of "add" or "delete".'))
|
raise JsonableError(_('Nothing to do. Specify at least one of "add" or "delete".'))
|
||||||
|
|
||||||
thunks = [
|
thunks = [
|
||||||
lambda: add_subscriptions_backend(request, user_profile, streams_raw=add),
|
lambda: add_subscriptions_backend(request, user_profile, streams_raw=add),
|
||||||
|
@ -498,7 +498,7 @@ def add_subscriptions_backend(
|
||||||
user_profile, existing_streams
|
user_profile, existing_streams
|
||||||
)
|
)
|
||||||
if len(unauthorized_streams) > 0 and authorization_errors_fatal:
|
if len(unauthorized_streams) > 0 and authorization_errors_fatal:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Unable to access stream ({stream_name}).").format(
|
_("Unable to access stream ({stream_name}).").format(
|
||||||
stream_name=unauthorized_streams[0].name,
|
stream_name=unauthorized_streams[0].name,
|
||||||
)
|
)
|
||||||
|
@ -508,7 +508,7 @@ def add_subscriptions_backend(
|
||||||
|
|
||||||
if len(principals) > 0:
|
if len(principals) > 0:
|
||||||
if realm.is_zephyr_mirror_realm and not all(stream.invite_only for stream in streams):
|
if realm.is_zephyr_mirror_realm and not all(stream.invite_only for stream in streams):
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("You can only invite other Zephyr mirroring users to private streams.")
|
_("You can only invite other Zephyr mirroring users to private streams.")
|
||||||
)
|
)
|
||||||
if not user_profile.can_subscribe_other_users():
|
if not user_profile.can_subscribe_other_users():
|
||||||
|
@ -865,16 +865,16 @@ def update_subscription_properties_backend(
|
||||||
value = change["value"]
|
value = change["value"]
|
||||||
|
|
||||||
if property not in property_converters:
|
if property not in property_converters:
|
||||||
return json_error(_("Unknown subscription property: {}").format(property))
|
raise JsonableError(_("Unknown subscription property: {}").format(property))
|
||||||
|
|
||||||
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
||||||
if sub is None:
|
if sub is None:
|
||||||
return json_error(_("Not subscribed to stream id {}").format(stream_id))
|
raise JsonableError(_("Not subscribed to stream id {}").format(stream_id))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
value = property_converters[property](property, value)
|
value = property_converters[property](property, value)
|
||||||
except ValidationError as error:
|
except ValidationError as error:
|
||||||
return json_error(error.message)
|
raise JsonableError(error.message)
|
||||||
|
|
||||||
do_change_subscription_property(
|
do_change_subscription_property(
|
||||||
user_profile, sub, stream, property, value, acting_user=user_profile
|
user_profile, sub, stream, property, value, acting_user=user_profile
|
||||||
|
|
|
@ -8,7 +8,7 @@ from zerver.decorator import REQ, has_request_variables
|
||||||
from zerver.lib.actions import do_add_submessage, verify_submessage_sender
|
from zerver.lib.actions import do_add_submessage, verify_submessage_sender
|
||||||
from zerver.lib.exceptions import JsonableError
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.message import access_message
|
from zerver.lib.message import access_message
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.validator import check_int, validate_poll_data, validate_todo_data
|
from zerver.lib.validator import check_int, validate_poll_data, validate_todo_data
|
||||||
from zerver.lib.widget import get_widget_type
|
from zerver.lib.widget import get_widget_type
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
@ -35,7 +35,7 @@ def process_submessage(
|
||||||
try:
|
try:
|
||||||
widget_data = orjson.loads(content)
|
widget_data = orjson.loads(content)
|
||||||
except orjson.JSONDecodeError:
|
except orjson.JSONDecodeError:
|
||||||
return json_error(_("Invalid json for submessage"))
|
raise JsonableError(_("Invalid json for submessage"))
|
||||||
|
|
||||||
widget_type = get_widget_type(message_id=message.id)
|
widget_type = get_widget_type(message_id=message.id)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import REQ, has_request_variables
|
from zerver.decorator import REQ, has_request_variables
|
||||||
from zerver.lib.actions import check_send_typing_notification, do_send_stream_typing_notification
|
from zerver.lib.actions import check_send_typing_notification, do_send_stream_typing_notification
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.streams import access_stream_by_id, access_stream_for_send_message
|
from zerver.lib.streams import access_stream_by_id, access_stream_for_send_message
|
||||||
from zerver.lib.validator import check_int, check_list, check_string_in
|
from zerver.lib.validator import check_int, check_list, check_string_in
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
@ -28,14 +29,14 @@ def send_notification_backend(
|
||||||
to_length = len(notification_to)
|
to_length = len(notification_to)
|
||||||
|
|
||||||
if to_length == 0:
|
if to_length == 0:
|
||||||
return json_error(_("Empty 'to' list"))
|
raise JsonableError(_("Empty 'to' list"))
|
||||||
|
|
||||||
if message_type == "stream":
|
if message_type == "stream":
|
||||||
if to_length > 1:
|
if to_length > 1:
|
||||||
return json_error(_("Cannot send to multiple streams"))
|
raise JsonableError(_("Cannot send to multiple streams"))
|
||||||
|
|
||||||
if topic is None:
|
if topic is None:
|
||||||
return json_error(_("Missing topic"))
|
raise JsonableError(_("Missing topic"))
|
||||||
|
|
||||||
stream_id = notification_to[0]
|
stream_id = notification_to[0]
|
||||||
# Verify that the user has access to the stream and has
|
# Verify that the user has access to the stream and has
|
||||||
|
|
|
@ -7,7 +7,8 @@ from django.utils.cache import patch_cache_control
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django_sendfile import sendfile
|
from django_sendfile import sendfile
|
||||||
|
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.upload import (
|
from zerver.lib.upload import (
|
||||||
INLINE_MIME_TYPES,
|
INLINE_MIME_TYPES,
|
||||||
check_upload_within_quota,
|
check_upload_within_quota,
|
||||||
|
@ -104,23 +105,23 @@ def serve_file(
|
||||||
def serve_local_file_unauthed(request: HttpRequest, token: str, filename: str) -> HttpResponse:
|
def serve_local_file_unauthed(request: HttpRequest, token: str, filename: str) -> HttpResponse:
|
||||||
path_id = get_local_file_path_id_from_token(token)
|
path_id = get_local_file_path_id_from_token(token)
|
||||||
if path_id is None:
|
if path_id is None:
|
||||||
return json_error(_("Invalid token"))
|
raise JsonableError(_("Invalid token"))
|
||||||
if path_id.split("/")[-1] != filename:
|
if path_id.split("/")[-1] != filename:
|
||||||
return json_error(_("Invalid filename"))
|
raise JsonableError(_("Invalid filename"))
|
||||||
|
|
||||||
return serve_local(request, path_id, url_only=False)
|
return serve_local(request, path_id, url_only=False)
|
||||||
|
|
||||||
|
|
||||||
def upload_file_backend(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
def upload_file_backend(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
||||||
if len(request.FILES) == 0:
|
if len(request.FILES) == 0:
|
||||||
return json_error(_("You must specify a file to upload"))
|
raise JsonableError(_("You must specify a file to upload"))
|
||||||
if len(request.FILES) != 1:
|
if len(request.FILES) != 1:
|
||||||
return json_error(_("You may only upload one file at a time"))
|
raise JsonableError(_("You may only upload one file at a time"))
|
||||||
|
|
||||||
user_file = list(request.FILES.values())[0]
|
user_file = list(request.FILES.values())[0]
|
||||||
file_size = user_file.size
|
file_size = user_file.size
|
||||||
if settings.MAX_FILE_UPLOAD_SIZE * 1024 * 1024 < file_size:
|
if settings.MAX_FILE_UPLOAD_SIZE * 1024 * 1024 < file_size:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
||||||
settings.MAX_FILE_UPLOAD_SIZE,
|
settings.MAX_FILE_UPLOAD_SIZE,
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,7 +14,7 @@ from zerver.lib.actions import (
|
||||||
)
|
)
|
||||||
from zerver.lib.exceptions import JsonableError
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.user_groups import (
|
from zerver.lib.user_groups import (
|
||||||
access_user_group_by_id,
|
access_user_group_by_id,
|
||||||
get_memberships_of_users,
|
get_memberships_of_users,
|
||||||
|
@ -58,7 +58,7 @@ def edit_user_group(
|
||||||
description: str = REQ(default=""),
|
description: str = REQ(default=""),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if not (name or description):
|
if not (name or description):
|
||||||
return json_error(_("No new data supplied"))
|
raise JsonableError(_("No new data supplied"))
|
||||||
|
|
||||||
user_group = access_user_group_by_id(user_group_id, user_profile)
|
user_group = access_user_group_by_id(user_group_id, user_profile)
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ def update_user_group_backend(
|
||||||
add: Sequence[int] = REQ(json_validator=check_list(check_int), default=[]),
|
add: Sequence[int] = REQ(json_validator=check_list(check_int), default=[]),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if not add and not delete:
|
if not add and not delete:
|
||||||
return json_error(_('Nothing to do. Specify at least one of "add" or "delete".'))
|
raise JsonableError(_('Nothing to do. Specify at least one of "add" or "delete".'))
|
||||||
|
|
||||||
thunks = [
|
thunks = [
|
||||||
lambda: add_members_to_group_backend(
|
lambda: add_members_to_group_backend(
|
||||||
|
|
|
@ -39,7 +39,7 @@ from zerver.lib.email_validation import (
|
||||||
from zerver.lib.i18n import get_available_language_codes
|
from zerver.lib.i18n import get_available_language_codes
|
||||||
from zerver.lib.rate_limiter import RateLimited
|
from zerver.lib.rate_limiter import RateLimited
|
||||||
from zerver.lib.request import JsonableError
|
from zerver.lib.request import JsonableError
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.send_email import FromAddress, send_email
|
from zerver.lib.send_email import FromAddress, send_email
|
||||||
from zerver.lib.upload import upload_avatar_image
|
from zerver.lib.upload import upload_avatar_image
|
||||||
from zerver.lib.validator import check_bool, check_int, check_int_in, check_string_in
|
from zerver.lib.validator import check_bool, check_int, check_int_in, check_string_in
|
||||||
|
@ -98,12 +98,12 @@ def json_change_settings(
|
||||||
new_password: str = REQ(default=""),
|
new_password: str = REQ(default=""),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if not (full_name or new_password or email):
|
if not (full_name or new_password or email):
|
||||||
return json_error(_("Please fill out all fields."))
|
raise JsonableError(_("Please fill out all fields."))
|
||||||
|
|
||||||
if new_password != "":
|
if new_password != "":
|
||||||
return_data: Dict[str, Any] = {}
|
return_data: Dict[str, Any] = {}
|
||||||
if email_belongs_to_ldap(user_profile.realm, user_profile.delivery_email):
|
if email_belongs_to_ldap(user_profile.realm, user_profile.delivery_email):
|
||||||
return json_error(_("Your Zulip password is managed in LDAP"))
|
raise JsonableError(_("Your Zulip password is managed in LDAP"))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not authenticate(
|
if not authenticate(
|
||||||
|
@ -113,18 +113,18 @@ def json_change_settings(
|
||||||
realm=user_profile.realm,
|
realm=user_profile.realm,
|
||||||
return_data=return_data,
|
return_data=return_data,
|
||||||
):
|
):
|
||||||
return json_error(_("Wrong password!"))
|
raise JsonableError(_("Wrong password!"))
|
||||||
except RateLimited as e:
|
except RateLimited as e:
|
||||||
assert e.secs_to_freedom is not None
|
assert e.secs_to_freedom is not None
|
||||||
secs_to_freedom = int(e.secs_to_freedom)
|
secs_to_freedom = int(e.secs_to_freedom)
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("You're making too many attempts! Try again in {} seconds.").format(
|
_("You're making too many attempts! Try again in {} seconds.").format(
|
||||||
secs_to_freedom
|
secs_to_freedom
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
if not check_password_strength(new_password):
|
if not check_password_strength(new_password):
|
||||||
return json_error(_("New password is too weak!"))
|
raise JsonableError(_("New password is too weak!"))
|
||||||
|
|
||||||
do_change_password(user_profile, new_password)
|
do_change_password(user_profile, new_password)
|
||||||
# In Django 1.10, password changes invalidates sessions, see
|
# In Django 1.10, password changes invalidates sessions, see
|
||||||
|
@ -146,14 +146,14 @@ def json_change_settings(
|
||||||
new_email = email.strip()
|
new_email = email.strip()
|
||||||
if user_profile.delivery_email != new_email and new_email != "":
|
if user_profile.delivery_email != new_email and new_email != "":
|
||||||
if user_profile.realm.email_changes_disabled and not user_profile.is_realm_admin:
|
if user_profile.realm.email_changes_disabled and not user_profile.is_realm_admin:
|
||||||
return json_error(_("Email address changes are disabled in this organization."))
|
raise JsonableError(_("Email address changes are disabled in this organization."))
|
||||||
|
|
||||||
error = validate_email_is_valid(
|
error = validate_email_is_valid(
|
||||||
new_email,
|
new_email,
|
||||||
get_realm_email_validator(user_profile.realm),
|
get_realm_email_validator(user_profile.realm),
|
||||||
)
|
)
|
||||||
if error:
|
if error:
|
||||||
return json_error(error)
|
raise JsonableError(error)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
validate_email_not_already_in_realm(
|
validate_email_not_already_in_realm(
|
||||||
|
@ -162,7 +162,7 @@ def json_change_settings(
|
||||||
verbose=False,
|
verbose=False,
|
||||||
)
|
)
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
return json_error(e.message)
|
raise JsonableError(e.message)
|
||||||
|
|
||||||
do_start_email_change_process(user_profile, new_email)
|
do_start_email_change_process(user_profile, new_email)
|
||||||
result["account_email"] = _("Check your email for a confirmation link. ")
|
result["account_email"] = _("Check your email for a confirmation link. ")
|
||||||
|
@ -291,14 +291,14 @@ def json_change_notify_settings(
|
||||||
|
|
||||||
def set_avatar_backend(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
def set_avatar_backend(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
||||||
if len(request.FILES) != 1:
|
if len(request.FILES) != 1:
|
||||||
return json_error(_("You must upload exactly one avatar."))
|
raise JsonableError(_("You must upload exactly one avatar."))
|
||||||
|
|
||||||
if avatar_changes_disabled(user_profile.realm) and not user_profile.is_realm_admin:
|
if avatar_changes_disabled(user_profile.realm) and not user_profile.is_realm_admin:
|
||||||
return json_error(str(AVATAR_CHANGES_DISABLED_ERROR))
|
raise JsonableError(str(AVATAR_CHANGES_DISABLED_ERROR))
|
||||||
|
|
||||||
user_file = list(request.FILES.values())[0]
|
user_file = list(request.FILES.values())[0]
|
||||||
if (settings.MAX_AVATAR_FILE_SIZE_MIB * 1024 * 1024) < user_file.size:
|
if (settings.MAX_AVATAR_FILE_SIZE_MIB * 1024 * 1024) < user_file.size:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
||||||
settings.MAX_AVATAR_FILE_SIZE_MIB,
|
settings.MAX_AVATAR_FILE_SIZE_MIB,
|
||||||
)
|
)
|
||||||
|
@ -315,7 +315,7 @@ def set_avatar_backend(request: HttpRequest, user_profile: UserProfile) -> HttpR
|
||||||
|
|
||||||
def delete_avatar_backend(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
def delete_avatar_backend(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
||||||
if avatar_changes_disabled(user_profile.realm) and not user_profile.is_realm_admin:
|
if avatar_changes_disabled(user_profile.realm) and not user_profile.is_realm_admin:
|
||||||
return json_error(str(AVATAR_CHANGES_DISABLED_ERROR))
|
raise JsonableError(str(AVATAR_CHANGES_DISABLED_ERROR))
|
||||||
|
|
||||||
do_change_avatar_fields(
|
do_change_avatar_fields(
|
||||||
user_profile, UserProfile.AVATAR_FROM_GRAVATAR, acting_user=user_profile
|
user_profile, UserProfile.AVATAR_FROM_GRAVATAR, acting_user=user_profile
|
||||||
|
|
|
@ -32,7 +32,7 @@ from zerver.lib.email_validation import email_allowed_for_realm
|
||||||
from zerver.lib.exceptions import CannotDeactivateLastUserError, OrganizationOwnerRequired
|
from zerver.lib.exceptions import CannotDeactivateLastUserError, OrganizationOwnerRequired
|
||||||
from zerver.lib.integrations import EMBEDDED_BOTS
|
from zerver.lib.integrations import EMBEDDED_BOTS
|
||||||
from zerver.lib.request import REQ, JsonableError, has_request_variables
|
from zerver.lib.request import REQ, JsonableError, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.streams import access_stream_by_id, access_stream_by_name, subscribed_to_stream
|
from zerver.lib.streams import access_stream_by_id, access_stream_by_name, subscribed_to_stream
|
||||||
from zerver.lib.types import Validator
|
from zerver.lib.types import Validator
|
||||||
from zerver.lib.upload import upload_avatar_image
|
from zerver.lib.upload import upload_avatar_image
|
||||||
|
@ -96,7 +96,7 @@ def deactivate_user_backend(
|
||||||
if target.is_realm_owner and not user_profile.is_realm_owner:
|
if target.is_realm_owner and not user_profile.is_realm_owner:
|
||||||
raise OrganizationOwnerRequired()
|
raise OrganizationOwnerRequired()
|
||||||
if check_last_owner(target):
|
if check_last_owner(target):
|
||||||
return json_error(_("Cannot deactivate the only organization owner"))
|
raise JsonableError(_("Cannot deactivate the only organization owner"))
|
||||||
return _deactivate_user_profile_backend(request, user_profile, target)
|
return _deactivate_user_profile_backend(request, user_profile, target)
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ def update_user_backend(
|
||||||
raise OrganizationOwnerRequired()
|
raise OrganizationOwnerRequired()
|
||||||
|
|
||||||
if target.role == UserProfile.ROLE_REALM_OWNER and check_last_owner(user_profile):
|
if target.role == UserProfile.ROLE_REALM_OWNER and check_last_owner(user_profile):
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("The owner permission cannot be removed from the only organization owner.")
|
_("The owner permission cannot be removed from the only organization owner.")
|
||||||
)
|
)
|
||||||
do_change_user_role(target, role, acting_user=user_profile)
|
do_change_user_role(target, role, acting_user=user_profile)
|
||||||
|
@ -278,11 +278,11 @@ def patch_bot_backend(
|
||||||
try:
|
try:
|
||||||
owner = get_user_profile_by_id_in_realm(bot_owner_id, user_profile.realm)
|
owner = get_user_profile_by_id_in_realm(bot_owner_id, user_profile.realm)
|
||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
return json_error(_("Failed to change owner, no such user"))
|
raise JsonableError(_("Failed to change owner, no such user"))
|
||||||
if not owner.is_active:
|
if not owner.is_active:
|
||||||
return json_error(_("Failed to change owner, user is deactivated"))
|
raise JsonableError(_("Failed to change owner, user is deactivated"))
|
||||||
if owner.is_bot:
|
if owner.is_bot:
|
||||||
return json_error(_("Failed to change owner, bots can't own other bots"))
|
raise JsonableError(_("Failed to change owner, bots can't own other bots"))
|
||||||
|
|
||||||
previous_owner = bot.bot_owner
|
previous_owner = bot.bot_owner
|
||||||
if previous_owner != owner:
|
if previous_owner != owner:
|
||||||
|
@ -321,7 +321,7 @@ def patch_bot_backend(
|
||||||
avatar_source = UserProfile.AVATAR_FROM_USER
|
avatar_source = UserProfile.AVATAR_FROM_USER
|
||||||
do_change_avatar_fields(bot, avatar_source, acting_user=user_profile)
|
do_change_avatar_fields(bot, avatar_source, acting_user=user_profile)
|
||||||
else:
|
else:
|
||||||
return json_error(_("You may only upload one file at a time"))
|
raise JsonableError(_("You may only upload one file at a time"))
|
||||||
|
|
||||||
json_result = dict(
|
json_result = dict(
|
||||||
full_name=bot.full_name,
|
full_name=bot.full_name,
|
||||||
|
@ -384,7 +384,7 @@ def add_bot_backend(
|
||||||
try:
|
try:
|
||||||
email = f"{short_name}@{user_profile.realm.get_bot_domain()}"
|
email = f"{short_name}@{user_profile.realm.get_bot_domain()}"
|
||||||
except InvalidFakeEmailDomain:
|
except InvalidFakeEmailDomain:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_(
|
_(
|
||||||
"Can't create bots until FAKE_EMAIL_DOMAIN is correctly configured.\n"
|
"Can't create bots until FAKE_EMAIL_DOMAIN is correctly configured.\n"
|
||||||
"Please contact your server administrator."
|
"Please contact your server administrator."
|
||||||
|
@ -394,16 +394,16 @@ def add_bot_backend(
|
||||||
|
|
||||||
if bot_type == UserProfile.EMBEDDED_BOT:
|
if bot_type == UserProfile.EMBEDDED_BOT:
|
||||||
if not settings.EMBEDDED_BOTS_ENABLED:
|
if not settings.EMBEDDED_BOTS_ENABLED:
|
||||||
return json_error(_("Embedded bots are not enabled."))
|
raise JsonableError(_("Embedded bots are not enabled."))
|
||||||
if service_name not in [bot.name for bot in EMBEDDED_BOTS]:
|
if service_name not in [bot.name for bot in EMBEDDED_BOTS]:
|
||||||
return json_error(_("Invalid embedded bot name."))
|
raise JsonableError(_("Invalid embedded bot name."))
|
||||||
|
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
# We validate client-side as well
|
# We validate client-side as well
|
||||||
return json_error(_("Bad name or username"))
|
raise JsonableError(_("Bad name or username"))
|
||||||
try:
|
try:
|
||||||
get_user_by_delivery_email(email, user_profile.realm)
|
get_user_by_delivery_email(email, user_profile.realm)
|
||||||
return json_error(_("Username already in use"))
|
raise JsonableError(_("Username already in use"))
|
||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -419,7 +419,7 @@ def add_bot_backend(
|
||||||
if len(request.FILES) == 0:
|
if len(request.FILES) == 0:
|
||||||
avatar_source = UserProfile.AVATAR_FROM_GRAVATAR
|
avatar_source = UserProfile.AVATAR_FROM_GRAVATAR
|
||||||
elif len(request.FILES) != 1:
|
elif len(request.FILES) != 1:
|
||||||
return json_error(_("You may only upload one file at a time"))
|
raise JsonableError(_("You may only upload one file at a time"))
|
||||||
else:
|
else:
|
||||||
avatar_source = UserProfile.AVATAR_FROM_USER
|
avatar_source = UserProfile.AVATAR_FROM_USER
|
||||||
|
|
||||||
|
@ -569,12 +569,12 @@ def create_user_backend(
|
||||||
full_name_raw: str = REQ("full_name"),
|
full_name_raw: str = REQ("full_name"),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if not user_profile.can_create_users:
|
if not user_profile.can_create_users:
|
||||||
return json_error(_("User not authorized for this query"))
|
raise JsonableError(_("User not authorized for this query"))
|
||||||
|
|
||||||
full_name = check_full_name(full_name_raw)
|
full_name = check_full_name(full_name_raw)
|
||||||
form = CreateUserForm({"full_name": full_name, "email": email})
|
form = CreateUserForm({"full_name": full_name, "email": email})
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
return json_error(_("Bad name or username"))
|
raise JsonableError(_("Bad name or username"))
|
||||||
|
|
||||||
# Check that the new user's email address belongs to the admin's realm
|
# Check that the new user's email address belongs to the admin's realm
|
||||||
# (Since this is an admin API, we don't require the user to have been
|
# (Since this is an admin API, we don't require the user to have been
|
||||||
|
@ -583,24 +583,24 @@ def create_user_backend(
|
||||||
try:
|
try:
|
||||||
email_allowed_for_realm(email, user_profile.realm)
|
email_allowed_for_realm(email, user_profile.realm)
|
||||||
except DomainNotAllowedForRealmError:
|
except DomainNotAllowedForRealmError:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("Email '{email}' not allowed in this organization").format(
|
_("Email '{email}' not allowed in this organization").format(
|
||||||
email=email,
|
email=email,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except DisposableEmailError:
|
except DisposableEmailError:
|
||||||
return json_error(_("Disposable email addresses are not allowed in this organization"))
|
raise JsonableError(_("Disposable email addresses are not allowed in this organization"))
|
||||||
except EmailContainsPlusError:
|
except EmailContainsPlusError:
|
||||||
return json_error(_("Email addresses containing + are not allowed."))
|
raise JsonableError(_("Email addresses containing + are not allowed."))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
get_user_by_delivery_email(email, user_profile.realm)
|
get_user_by_delivery_email(email, user_profile.realm)
|
||||||
return json_error(_("Email '{}' already in use").format(email))
|
raise JsonableError(_("Email '{}' already in use").format(email))
|
||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if not check_password_strength(password):
|
if not check_password_strength(password):
|
||||||
return json_error(PASSWORD_TOO_WEAK_ERROR)
|
raise JsonableError(PASSWORD_TOO_WEAK_ERROR)
|
||||||
|
|
||||||
target_user = do_create_user(email, password, realm, full_name, acting_user=user_profile)
|
target_user = do_create_user(email, password, realm, full_name, acting_user=user_profile)
|
||||||
return json_success({"user_id": target_user.id})
|
return json_success({"user_id": target_user.id})
|
||||||
|
|
|
@ -25,7 +25,7 @@ from zerver.decorator import REQ, has_request_variables, zulip_login_required
|
||||||
from zerver.lib.actions import do_set_zoom_token
|
from zerver.lib.actions import do_set_zoom_token
|
||||||
from zerver.lib.exceptions import ErrorCode, JsonableError
|
from zerver.lib.exceptions import ErrorCode, JsonableError
|
||||||
from zerver.lib.pysa import mark_sanitized
|
from zerver.lib.pysa import mark_sanitized
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.subdomains import get_subdomain
|
from zerver.lib.subdomains import get_subdomain
|
||||||
from zerver.lib.url_encoding import add_query_arg_to_redirect_url, add_query_to_redirect_url
|
from zerver.lib.url_encoding import add_query_arg_to_redirect_url, add_query_to_redirect_url
|
||||||
from zerver.lib.validator import check_dict, check_string
|
from zerver.lib.validator import check_dict, check_string
|
||||||
|
@ -212,7 +212,7 @@ def join_bigbluebutton(
|
||||||
checksum: str = REQ(),
|
checksum: str = REQ(),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if settings.BIG_BLUE_BUTTON_URL is None or settings.BIG_BLUE_BUTTON_SECRET is None:
|
if settings.BIG_BLUE_BUTTON_URL is None or settings.BIG_BLUE_BUTTON_SECRET is None:
|
||||||
return json_error(_("Big Blue Button is not configured."))
|
raise JsonableError(_("Big Blue Button is not configured."))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
|
@ -230,14 +230,14 @@ def join_bigbluebutton(
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except requests.RequestException:
|
except requests.RequestException:
|
||||||
return json_error(_("Error connecting to the Big Blue Button server."))
|
raise JsonableError(_("Error connecting to the Big Blue Button server."))
|
||||||
|
|
||||||
payload = ElementTree.fromstring(response.text)
|
payload = ElementTree.fromstring(response.text)
|
||||||
if payload.find("messageKey").text == "checksumError":
|
if payload.find("messageKey").text == "checksumError":
|
||||||
return json_error(_("Error authenticating to the Big Blue Button server."))
|
raise JsonableError(_("Error authenticating to the Big Blue Button server."))
|
||||||
|
|
||||||
if payload.find("returncode").text != "SUCCESS":
|
if payload.find("returncode").text != "SUCCESS":
|
||||||
return json_error(_("Big Blue Button server returned an unexpected error."))
|
raise JsonableError(_("Big Blue Button server returned an unexpected error."))
|
||||||
|
|
||||||
join_params = urlencode( # type: ignore[type-var] # https://github.com/python/typeshed/issues/4234
|
join_params = urlencode( # type: ignore[type-var] # https://github.com/python/typeshed/issues/4234
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,9 +12,10 @@ from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import authenticated_json_view
|
from zerver.decorator import authenticated_json_view
|
||||||
from zerver.lib.ccache import make_ccache
|
from zerver.lib.ccache import make_ccache
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.pysa import mark_sanitized
|
from zerver.lib.pysa import mark_sanitized
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.users import get_api_key
|
from zerver.lib.users import get_api_key
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
@ -32,9 +33,9 @@ def webathena_kerberos_login(
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
global kerberos_alter_egos
|
global kerberos_alter_egos
|
||||||
if cred is None:
|
if cred is None:
|
||||||
return json_error(_("Could not find Kerberos credential"))
|
raise JsonableError(_("Could not find Kerberos credential"))
|
||||||
if not user_profile.realm.webathena_enabled:
|
if not user_profile.realm.webathena_enabled:
|
||||||
return json_error(_("Webathena login not enabled"))
|
raise JsonableError(_("Webathena login not enabled"))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parsed_cred = orjson.loads(cred)
|
parsed_cred = orjson.loads(cred)
|
||||||
|
@ -55,7 +56,7 @@ def webathena_kerberos_login(
|
||||||
# credential cache file.
|
# credential cache file.
|
||||||
ccache = mark_sanitized(ccache)
|
ccache = mark_sanitized(ccache)
|
||||||
except Exception:
|
except Exception:
|
||||||
return json_error(_("Invalid Kerberos cache"))
|
raise JsonableError(_("Invalid Kerberos cache"))
|
||||||
|
|
||||||
# TODO: Send these data via (say) RabbitMQ
|
# TODO: Send these data via (say) RabbitMQ
|
||||||
try:
|
try:
|
||||||
|
@ -71,6 +72,6 @@ def webathena_kerberos_login(
|
||||||
)
|
)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
logging.exception("Error updating the user's ccache", stack_info=True)
|
logging.exception("Error updating the user's ccache", stack_info=True)
|
||||||
return json_error(_("We were unable to set up mirroring for you"))
|
raise JsonableError(_("We were unable to set up mirroring for you"))
|
||||||
|
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -6,7 +6,8 @@ from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from zerver.decorator import REQ, has_request_variables, webhook_view
|
from zerver.decorator import REQ, has_request_variables, webhook_view
|
||||||
from zerver.lib.actions import send_rate_limited_pm_notification_to_bot_owner
|
from zerver.lib.actions import send_rate_limited_pm_notification_to_bot_owner
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.send_email import FromAddress
|
from zerver.lib.send_email import FromAddress
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message, get_setup_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message, get_setup_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
@ -84,7 +85,7 @@ def api_freshstatus_webhook(
|
||||||
).strip()
|
).strip()
|
||||||
send_rate_limited_pm_notification_to_bot_owner(user_profile, user_profile.realm, message)
|
send_rate_limited_pm_notification_to_bot_owner(user_profile, user_profile.realm, message)
|
||||||
|
|
||||||
return json_error(_("Invalid payload"))
|
raise JsonableError(_("Invalid payload"))
|
||||||
|
|
||||||
check_send_webhook_message(request, user_profile, subject, body)
|
check_send_webhook_message(request, user_profile, subject, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -4,8 +4,9 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import webhook_view
|
from zerver.decorator import webhook_view
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
@ -143,7 +144,7 @@ def api_front_webhook(
|
||||||
|
|
||||||
event = payload["type"]
|
event = payload["type"]
|
||||||
if event not in EVENT_FUNCTION_MAPPER:
|
if event not in EVENT_FUNCTION_MAPPER:
|
||||||
return json_error(_("Unknown webhook request"))
|
raise JsonableError(_("Unknown webhook request"))
|
||||||
|
|
||||||
topic = payload["conversation"]["id"]
|
topic = payload["conversation"]["id"]
|
||||||
body = get_body_based_on_event(event)(payload)
|
body = get_body_based_on_event(event)(payload)
|
||||||
|
|
|
@ -4,8 +4,9 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import webhook_view
|
from zerver.decorator import webhook_view
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
@ -23,10 +24,10 @@ def api_iftt_app_webhook(
|
||||||
if topic is None:
|
if topic is None:
|
||||||
topic = payload.get("subject") # Backwards-compatibility
|
topic = payload.get("subject") # Backwards-compatibility
|
||||||
if topic is None:
|
if topic is None:
|
||||||
return json_error(_("Topic can't be empty"))
|
raise JsonableError(_("Topic can't be empty"))
|
||||||
|
|
||||||
if content is None:
|
if content is None:
|
||||||
return json_error(_("Content can't be empty"))
|
raise JsonableError(_("Content can't be empty"))
|
||||||
|
|
||||||
check_send_webhook_message(request, user_profile, topic, content)
|
check_send_webhook_message(request, user_profile, topic, content)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -6,8 +6,9 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import webhook_view
|
from zerver.decorator import webhook_view
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
@ -169,7 +170,7 @@ def api_librato_webhook(
|
||||||
attachments = []
|
attachments = []
|
||||||
|
|
||||||
if not attachments and not payload:
|
if not attachments and not payload:
|
||||||
return json_error(_("Malformed JSON input"))
|
raise JsonableError(_("Malformed JSON input"))
|
||||||
|
|
||||||
message_handler = LibratoWebhookHandler(payload, attachments)
|
message_handler = LibratoWebhookHandler(payload, attachments)
|
||||||
topic = message_handler.generate_topic()
|
topic = message_handler.generate_topic()
|
||||||
|
@ -177,7 +178,7 @@ def api_librato_webhook(
|
||||||
try:
|
try:
|
||||||
content = message_handler.handle()
|
content = message_handler.handle()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return json_error(str(e))
|
raise JsonableError(str(e))
|
||||||
|
|
||||||
check_send_webhook_message(request, user_profile, topic, content)
|
check_send_webhook_message(request, user_profile, topic, content)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -5,8 +5,9 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import webhook_view
|
from zerver.decorator import webhook_view
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message, unix_milliseconds_to_timestamp
|
from zerver.lib.webhooks.common import check_send_webhook_message, unix_milliseconds_to_timestamp
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ def api_newrelic_webhook(
|
||||||
|
|
||||||
unix_time = payload.get("timestamp", None)
|
unix_time = payload.get("timestamp", None)
|
||||||
if unix_time is None:
|
if unix_time is None:
|
||||||
return json_error(_("The newrelic webhook requires timestamp in milliseconds"))
|
raise JsonableError(_("The newrelic webhook requires timestamp in milliseconds"))
|
||||||
|
|
||||||
info["iso_timestamp"] = unix_milliseconds_to_timestamp(unix_time, "newrelic")
|
info["iso_timestamp"] = unix_milliseconds_to_timestamp(unix_time, "newrelic")
|
||||||
|
|
||||||
|
@ -62,7 +63,7 @@ def api_newrelic_webhook(
|
||||||
elif "closed" in info["status"]:
|
elif "closed" in info["status"]:
|
||||||
content = DEFAULT_TEMPLATE.format(**info)
|
content = DEFAULT_TEMPLATE.format(**info)
|
||||||
else:
|
else:
|
||||||
return json_error(
|
raise JsonableError(
|
||||||
_("The newrelic webhook requires current_state be in [open|acknowledged|closed]")
|
_("The newrelic webhook requires current_state be in [open|acknowledged|closed]")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,9 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import webhook_view
|
from zerver.decorator import webhook_view
|
||||||
from zerver.lib.exceptions import UnsupportedWebhookEventType
|
from zerver.lib.exceptions import JsonableError, UnsupportedWebhookEventType
|
||||||
from zerver.lib.request import has_request_variables
|
from zerver.lib.request import has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ def api_pivotal_webhook(request: HttpRequest, user_profile: UserProfile) -> Http
|
||||||
subject, content = api_pivotal_webhook_v5(request, user_profile)
|
subject, content = api_pivotal_webhook_v5(request, user_profile)
|
||||||
|
|
||||||
if not content:
|
if not content:
|
||||||
return json_error(_("Unable to handle Pivotal payload"))
|
raise JsonableError(_("Unable to handle Pivotal payload"))
|
||||||
|
|
||||||
check_send_webhook_message(request, user_profile, subject, content)
|
check_send_webhook_message(request, user_profile, subject, content)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -3,8 +3,9 @@ from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import webhook_view
|
from zerver.decorator import webhook_view
|
||||||
from zerver.lib.actions import check_send_stream_message
|
from zerver.lib.actions import check_send_stream_message
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
ZULIP_MESSAGE_TEMPLATE = "**{message_sender}**: `{text}`"
|
ZULIP_MESSAGE_TEMPLATE = "**{message_sender}**: `{text}`"
|
||||||
|
@ -24,7 +25,7 @@ def api_slack_webhook(
|
||||||
) -> HttpRequest:
|
) -> HttpRequest:
|
||||||
|
|
||||||
if channels_map_to_topics not in list(VALID_OPTIONS.values()):
|
if channels_map_to_topics not in list(VALID_OPTIONS.values()):
|
||||||
return json_error(_("Error: channels_map_to_topics parameter other than 0 or 1"))
|
raise JsonableError(_("Error: channels_map_to_topics parameter other than 0 or 1"))
|
||||||
|
|
||||||
if channels_map_to_topics == VALID_OPTIONS["SHOULD_BE_MAPPED"]:
|
if channels_map_to_topics == VALID_OPTIONS["SHOULD_BE_MAPPED"]:
|
||||||
subject = f"channel: {channel_name}"
|
subject = f"channel: {channel_name}"
|
||||||
|
|
|
@ -5,7 +5,8 @@ from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from zerver.decorator import REQ, has_request_variables, webhook_view
|
from zerver.decorator import REQ, has_request_variables, webhook_view
|
||||||
from zerver.lib.actions import send_rate_limited_pm_notification_to_bot_owner
|
from zerver.lib.actions import send_rate_limited_pm_notification_to_bot_owner
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.send_email import FromAddress
|
from zerver.lib.send_email import FromAddress
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
@ -46,7 +47,7 @@ def api_uptimerobot_webhook(
|
||||||
).strip()
|
).strip()
|
||||||
send_rate_limited_pm_notification_to_bot_owner(user_profile, user_profile.realm, message)
|
send_rate_limited_pm_notification_to_bot_owner(user_profile, user_profile.realm, message)
|
||||||
|
|
||||||
return json_error(_("Invalid payload"))
|
raise JsonableError(_("Invalid payload"))
|
||||||
|
|
||||||
check_send_webhook_message(request, user_profile, subject, body)
|
check_send_webhook_message(request, user_profile, subject, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -3,8 +3,9 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import webhook_view
|
from zerver.decorator import webhook_view
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ def api_wordpress_webhook(
|
||||||
data = WP_LOGIN_TEMPLATE.format(name=user_login)
|
data = WP_LOGIN_TEMPLATE.format(name=user_login)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return json_error(_("Unknown WordPress webhook action: {}").format(hook))
|
raise JsonableError(_("Unknown WordPress webhook action: {}").format(hook))
|
||||||
|
|
||||||
topic = "WordPress notification"
|
topic = "WordPress notification"
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import REQ, has_request_variables, webhook_view
|
from zerver.decorator import REQ, has_request_variables, webhook_view
|
||||||
from zerver.lib.actions import send_rate_limited_pm_notification_to_bot_owner
|
from zerver.lib.actions import send_rate_limited_pm_notification_to_bot_owner
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.send_email import FromAddress
|
from zerver.lib.send_email import FromAddress
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
@ -45,7 +46,7 @@ def api_zabbix_webhook(
|
||||||
).strip()
|
).strip()
|
||||||
send_rate_limited_pm_notification_to_bot_owner(user_profile, user_profile.realm, message)
|
send_rate_limited_pm_notification_to_bot_owner(user_profile, user_profile.realm, message)
|
||||||
|
|
||||||
return json_error(_("Invalid payload"))
|
raise JsonableError(_("Invalid payload"))
|
||||||
|
|
||||||
check_send_webhook_message(request, user_profile, subject, body)
|
check_send_webhook_message(request, user_profile, subject, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -4,8 +4,9 @@ from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.decorator import webhook_view
|
from zerver.decorator import webhook_view
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
@ -35,10 +36,10 @@ def api_zapier_webhook(
|
||||||
if topic is None:
|
if topic is None:
|
||||||
topic = payload.get("subject") # Backwards-compatibility
|
topic = payload.get("subject") # Backwards-compatibility
|
||||||
if topic is None:
|
if topic is None:
|
||||||
return json_error(_("Topic can't be empty"))
|
raise JsonableError(_("Topic can't be empty"))
|
||||||
|
|
||||||
if content is None:
|
if content is None:
|
||||||
return json_error(_("Content can't be empty"))
|
raise JsonableError(_("Content can't be empty"))
|
||||||
|
|
||||||
check_send_webhook_message(request, user_profile, topic, content)
|
check_send_webhook_message(request, user_profile, topic, content)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -19,7 +19,7 @@ from zerver.lib.push_notifications import (
|
||||||
send_apple_push_notification,
|
send_apple_push_notification,
|
||||||
)
|
)
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.validator import (
|
from zerver.lib.validator import (
|
||||||
check_bool,
|
check_bool,
|
||||||
check_capped_string,
|
check_capped_string,
|
||||||
|
@ -147,7 +147,7 @@ def unregister_remote_push_device(
|
||||||
token=token, kind=token_kind, user_id=user_id, server=server
|
token=token, kind=token_kind, user_id=user_id, server=server
|
||||||
).delete()
|
).delete()
|
||||||
if deleted[0] == 0:
|
if deleted[0] == 0:
|
||||||
return json_error(err_("Token does not exist"))
|
raise JsonableError(err_("Token does not exist"))
|
||||||
|
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue