mirror of https://github.com/zulip/zulip.git
message: Support avoiding database queries in has_message_access.
If the caller has already fetched the Stream or subscription details for the user, those can be passed to has_message_access to avoid extra database queries.
This commit is contained in:
parent
44fddcc9c1
commit
b15941610d
|
@ -677,8 +677,21 @@ def access_message(
|
|||
|
||||
|
||||
def has_message_access(
|
||||
user_profile: UserProfile, message: Message, user_message: Optional[UserMessage]
|
||||
user_profile: UserProfile,
|
||||
message: Message,
|
||||
user_message: Optional[UserMessage],
|
||||
*,
|
||||
stream: Optional[Stream] = None,
|
||||
is_subscribed: Optional[bool] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Returns whether a user has access to a given message.
|
||||
|
||||
* The user_message parameter must be provded if the user has a UserMessage
|
||||
row for the target message.
|
||||
* The optional stream parameter is validated; is_subscribed is not.
|
||||
"""
|
||||
|
||||
# If you have a user_message object, you have access.
|
||||
if user_message is not None:
|
||||
return True
|
||||
|
@ -687,7 +700,11 @@ def has_message_access(
|
|||
# You can't access private messages you didn't receive
|
||||
return False
|
||||
|
||||
stream = Stream.objects.get(id=message.recipient.type_id)
|
||||
if stream is None:
|
||||
stream = Stream.objects.get(id=message.recipient.type_id)
|
||||
else:
|
||||
assert stream.recipient_id == message.recipient_id
|
||||
|
||||
if stream.realm != user_profile.realm:
|
||||
# You can't access public stream messages in other realms
|
||||
return False
|
||||
|
@ -701,6 +718,9 @@ def has_message_access(
|
|||
return True
|
||||
|
||||
# is_history_public_to_subscribers, so check if you're subscribed
|
||||
if is_subscribed is not None:
|
||||
return is_subscribed
|
||||
|
||||
return Subscription.objects.filter(
|
||||
user_profile=user_profile, active=True, recipient=message.recipient
|
||||
).exists()
|
||||
|
|
|
@ -1363,6 +1363,12 @@ class EditMessageTest(ZulipTestCase):
|
|||
has_message_access(guest_user, Message.objects.get(id=msg_id_to_test_acesss), None),
|
||||
True,
|
||||
)
|
||||
self.assertEqual(
|
||||
has_message_access(
|
||||
guest_user, Message.objects.get(id=msg_id_to_test_acesss), None, stream=old_stream
|
||||
),
|
||||
True,
|
||||
)
|
||||
self.assertEqual(
|
||||
has_message_access(non_guest_user, Message.objects.get(id=msg_id_to_test_acesss), None),
|
||||
True,
|
||||
|
@ -1387,6 +1393,32 @@ class EditMessageTest(ZulipTestCase):
|
|||
has_message_access(non_guest_user, Message.objects.get(id=msg_id_to_test_acesss), None),
|
||||
True,
|
||||
)
|
||||
self.assertEqual(
|
||||
# If the guest user were subscribed to the new stream,
|
||||
# they'd have access; has_message_access does not validate
|
||||
# the is_subscribed parameter.
|
||||
has_message_access(
|
||||
guest_user,
|
||||
Message.objects.get(id=msg_id_to_test_acesss),
|
||||
None,
|
||||
stream=new_stream,
|
||||
is_subscribed=True,
|
||||
),
|
||||
True,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
has_message_access(
|
||||
guest_user, Message.objects.get(id=msg_id_to_test_acesss), None, stream=new_stream
|
||||
),
|
||||
False,
|
||||
)
|
||||
with self.assertRaises(AssertionError):
|
||||
# Raises assertion if you pass an invalid stream.
|
||||
has_message_access(
|
||||
guest_user, Message.objects.get(id=msg_id_to_test_acesss), None, stream=old_stream
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
UserMessage.objects.filter(
|
||||
user_profile_id=non_guest_user.id,
|
||||
|
|
Loading…
Reference in New Issue