From b0a84cd7ab395147ec77fac893c8fa4bf4652a1d Mon Sep 17 00:00:00 2001 From: Greg Price Date: Wed, 13 Feb 2019 17:01:42 -0800 Subject: [PATCH] message: Add an O(1)-query variant of bulk_access_messages. We'll use this in the push-notifications code, in a context where there should definitely already be UserMessage rows if everything's gone normally... but explicitly checking at the top seems like the right pattern from a secure-coding perspective. --- zerver/lib/message.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/zerver/lib/message.py b/zerver/lib/message.py index 349eac84a3..9809208369 100644 --- a/zerver/lib/message.py +++ b/zerver/lib/message.py @@ -555,6 +555,26 @@ def bulk_access_messages(user_profile: UserProfile, messages: Sequence[Message]) filtered_messages.append(message) return filtered_messages +def bulk_access_messages_expect_usermessage( + user_profile_id: int, message_ids: Sequence[int]) -> List[int]: + ''' + Like bulk_access_messages, but faster and potentially stricter. + + Returns a subset of `message_ids` containing only messages the + user can access. Makes O(1) database queries. + + Use this function only when the user is expected to have a + UserMessage row for every message in `message_ids`. If a + UserMessage row is missing, the message will be omitted even if + the user has access (e.g. because it went to a public stream.) + + See also: `access_message`, `bulk_access_messages`. + ''' + return UserMessage.objects.filter( + user_profile_id=user_profile_id, + message_id__in=message_ids, + ).values_list('message_id', flat=True) + def render_markdown(message: Message, content: str, realm: Optional[Realm]=None,