decorator: Extract OrganizationAdministratorRequired common exception.

This eliminates significant code duplication of error messages for
situations where an organization administrator is required.
This commit is contained in:
Matheus Melo
2019-11-16 11:53:56 -03:00
committed by Tim Abbott
parent 08103544cc
commit 21ed834101
5 changed files with 23 additions and 7 deletions

View File

@@ -23,7 +23,8 @@ from zerver.lib.subdomains import get_subdomain, user_matches_subdomain
from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime
from zerver.lib.utils import statsd, is_remote_server from zerver.lib.utils import statsd, is_remote_server
from zerver.lib.exceptions import JsonableError, ErrorCode, \ from zerver.lib.exceptions import JsonableError, ErrorCode, \
InvalidJSONError, InvalidAPIKeyError InvalidJSONError, InvalidAPIKeyError, \
OrganizationAdministratorRequired
from zerver.lib.types import ViewFuncT from zerver.lib.types import ViewFuncT
from zerver.lib.validator import to_non_negative_int from zerver.lib.validator import to_non_negative_int
@@ -136,7 +137,7 @@ def require_realm_admin(func: ViewFuncT) -> ViewFuncT:
@wraps(func) @wraps(func)
def wrapper(request: HttpRequest, user_profile: UserProfile, *args: Any, **kwargs: Any) -> HttpResponse: def wrapper(request: HttpRequest, user_profile: UserProfile, *args: Any, **kwargs: Any) -> HttpResponse:
if not user_profile.is_realm_admin: if not user_profile.is_realm_admin:
raise JsonableError(_("Must be an organization administrator")) raise OrganizationAdministratorRequired()
return func(request, user_profile, *args, **kwargs) return func(request, user_profile, *args, **kwargs)
return wrapper # type: ignore # https://github.com/python/mypy/issues/1927 return wrapper # type: ignore # https://github.com/python/mypy/issues/1927
@@ -540,7 +541,7 @@ def require_user_group_edit_policy(view_func: ViewFuncT) -> ViewFuncT:
realm = user_profile.realm realm = user_profile.realm
if realm.user_group_edit_policy != Realm.USER_GROUP_EDIT_POLICY_MEMBERS and \ if realm.user_group_edit_policy != Realm.USER_GROUP_EDIT_POLICY_MEMBERS and \
not user_profile.is_realm_admin: not user_profile.is_realm_admin:
raise JsonableError(_("Must be an organization administrator")) raise OrganizationAdministratorRequired()
return view_func(request, user_profile, *args, **kwargs) return view_func(request, user_profile, *args, **kwargs)
return _wrapped_view_func # type: ignore # https://github.com/python/mypy/issues/1927 return _wrapped_view_func # type: ignore # https://github.com/python/mypy/issues/1927

View File

@@ -8,6 +8,7 @@ from typing import Optional, Tuple
from zerver.lib.request import JsonableError from zerver.lib.request import JsonableError
from zerver.lib.storage import static_path from zerver.lib.storage import static_path
from zerver.lib.upload import upload_backend from zerver.lib.upload import upload_backend
from zerver.lib.exceptions import OrganizationAdministratorRequired
from zerver.models import Reaction, Realm, RealmEmoji, UserProfile from zerver.models import Reaction, Realm, RealmEmoji, UserProfile
EMOJI_PATH = static_path("generated/emoji") EMOJI_PATH = static_path("generated/emoji")
@@ -86,7 +87,7 @@ def check_emoji_admin(user_profile: UserProfile, emoji_name: Optional[str]=None)
if user_profile.is_realm_admin: if user_profile.is_realm_admin:
return return
if user_profile.realm.add_emoji_by_admins_only: if user_profile.realm.add_emoji_by_admins_only:
raise JsonableError(_("Must be an organization administrator")) raise OrganizationAdministratorRequired()
# Otherwise, normal users can add emoji # Otherwise, normal users can add emoji
if emoji_name is None: if emoji_name is None:

View File

@@ -190,6 +190,18 @@ class InvalidJSONError(JsonableError):
def msg_format() -> str: def msg_format() -> str:
return _("Malformed JSON") return _("Malformed JSON")
class OrganizationAdministratorRequired(JsonableError):
code = ErrorCode.UNAUTHORIZED_PRINCIPAL # type: ErrorCode
ADMIN_REQUIRED_MESSAGE = _("Must be an organization administrator")
def __init__(self) -> None:
super().__init__(self.ADMIN_REQUIRED_MESSAGE)
@staticmethod
def msg_format() -> str:
return OrganizationAdministratorRequired.ADMIN_REQUIRED_MESSAGE
class BugdownRenderingException(Exception): class BugdownRenderingException(Exception):
pass pass

View File

@@ -9,6 +9,7 @@ from zerver.lib.cache import generic_bulk_cached_fetch, user_profile_cache_key_i
user_profile_by_id_cache_key user_profile_by_id_cache_key
from zerver.lib.request import JsonableError from zerver.lib.request import JsonableError
from zerver.lib.avatar import avatar_url from zerver.lib.avatar import avatar_url
from zerver.lib.exceptions import OrganizationAdministratorRequired
from zerver.models import UserProfile, Service, Realm, \ from zerver.models import UserProfile, Service, Realm, \
get_user_profile_by_id_in_realm, \ get_user_profile_by_id_in_realm, \
CustomProfileField CustomProfileField
@@ -103,10 +104,10 @@ def check_bot_creation_policy(user_profile: UserProfile, bot_type: int) -> None:
if user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_EVERYONE: if user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_EVERYONE:
return return
if user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_ADMINS_ONLY: if user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_ADMINS_ONLY:
raise JsonableError(_("Must be an organization administrator")) raise OrganizationAdministratorRequired()
if user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_LIMIT_GENERIC_BOTS and \ if user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_LIMIT_GENERIC_BOTS and \
bot_type == UserProfile.DEFAULT_BOT: bot_type == UserProfile.DEFAULT_BOT:
raise JsonableError(_("Must be an organization administrator")) raise OrganizationAdministratorRequired()
def check_valid_bot_type(user_profile: UserProfile, bot_type: int) -> None: def check_valid_bot_type(user_profile: UserProfile, bot_type: int) -> None:
if bot_type not in user_profile.allowed_bot_types: if bot_type not in user_profile.allowed_bot_types:

View File

@@ -6,6 +6,7 @@ from zerver.decorator import require_realm_admin, require_member_or_admin
from zerver.lib.actions import do_invite_users, do_revoke_user_invite, \ from zerver.lib.actions import do_invite_users, do_revoke_user_invite, \
do_revoke_multi_use_invite, do_resend_user_invite_email, \ do_revoke_multi_use_invite, do_resend_user_invite_email, \
do_get_user_invites, do_create_multiuse_invite_link do_get_user_invites, do_create_multiuse_invite_link
from zerver.lib.exceptions import OrganizationAdministratorRequired
from zerver.lib.request import REQ, has_request_variables, JsonableError from zerver.lib.request import REQ, has_request_variables, JsonableError
from zerver.lib.response import json_success, json_error from zerver.lib.response import json_success, json_error
from zerver.lib.streams import access_stream_by_id from zerver.lib.streams import access_stream_by_id
@@ -24,7 +25,7 @@ def invite_users_backend(request: HttpRequest, user_profile: UserProfile,
) -> HttpResponse: ) -> HttpResponse:
if user_profile.realm.invite_by_admins_only and not user_profile.is_realm_admin: if user_profile.realm.invite_by_admins_only and not user_profile.is_realm_admin:
return json_error(_("Must be an organization administrator")) raise OrganizationAdministratorRequired()
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")) return json_error(_("Must be invited as an valid type of user"))
if invite_as == PreregistrationUser.INVITE_AS['REALM_ADMIN'] and not user_profile.is_realm_admin: if invite_as == PreregistrationUser.INVITE_AS['REALM_ADMIN'] and not user_profile.is_realm_admin: