mirror of https://github.com/zulip/zulip.git
events: Check last_event_id for validity.
This verifies that the client passed a last_event_id that actually came from the queue instead of making up an ID from the future. It turns out one of our tests was making up such an ID, but legitimate clients are expected not to do so. Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
This commit is contained in:
parent
bbbea9ec87
commit
e00d4be6d5
|
@ -117,7 +117,7 @@ class EventsTestCase(TornadoWebTestCase):
|
|||
event_queue_id = self.create_queue()
|
||||
data = {
|
||||
'queue_id': event_queue_id,
|
||||
'last_event_id': 0,
|
||||
'last_event_id': -1,
|
||||
}
|
||||
|
||||
path = '/json/events?{}'.format(urllib.parse.urlencode(data))
|
||||
|
|
|
@ -240,6 +240,7 @@ class EventQueue:
|
|||
def __init__(self, id: str) -> None:
|
||||
self.queue = deque() # type: ignore # Should be Deque[Dict[str, Any]], but Deque isn't available in Python 3.4
|
||||
self.next_event_id = 0 # type: int
|
||||
self.newest_pruned_id = -1 # type: int
|
||||
self.id = id # type: str
|
||||
self.virtual_events = {} # type: Dict[str, Dict[str, Any]]
|
||||
|
||||
|
@ -295,6 +296,7 @@ class EventQueue:
|
|||
# See the comment on pop; that applies here as well
|
||||
def prune(self, through_id: int) -> None:
|
||||
while len(self.queue) != 0 and self.queue[0]['id'] <= through_id:
|
||||
self.newest_pruned_id = self.queue[0]['id']
|
||||
self.pop()
|
||||
|
||||
def contents(self) -> List[Dict[str, Any]]:
|
||||
|
@ -522,7 +524,11 @@ def fetch_events(query: Mapping[str, Any]) -> Dict[str, Any]:
|
|||
raise BadEventQueueIdError(queue_id)
|
||||
if user_profile_id != client.user_profile_id:
|
||||
raise JsonableError(_("You are not authorized to get events from this queue"))
|
||||
if last_event_id < client.event_queue.newest_pruned_id:
|
||||
raise JsonableError(_("An event newer than %s has already been pruned!") % (last_event_id,))
|
||||
client.event_queue.prune(last_event_id)
|
||||
if last_event_id != client.event_queue.newest_pruned_id:
|
||||
raise JsonableError(_("Event %s was not in this queue") % (last_event_id,))
|
||||
was_connected = client.finish_current_handler()
|
||||
|
||||
if not client.event_queue.empty() or dont_block:
|
||||
|
|
Loading…
Reference in New Issue