From 06d446aec13663b2dc2bc7532d41aed99ba26777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Mudr=C3=A1k?= Date: Mon, 27 Feb 2023 18:26:41 +0100 Subject: [PATCH] MDL-74586 rss: Make rss_get_userid_from_token() use table index Due to missing `AND k.script = 'rss'` condition, the query did not make use of the existing script-value compound index defined for the table. So it had to perform the full sequential scan for all rows when searching for the token. This had serious performance issues on sites with many users, especially in case on non-existing token / key. --- lib/rsslib.php | 13 +++++++++---- lib/tests/rsslib_test.php | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/rsslib.php b/lib/rsslib.php index 7141fd71996..cb2a3890df8 100644 --- a/lib/rsslib.php +++ b/lib/rsslib.php @@ -413,10 +413,15 @@ function rss_geterrorxmlfile($errortype = 'rsserror') { function rss_get_userid_from_token($token) { global $DB; - $sql = 'SELECT u.id FROM {user} u - JOIN {user_private_key} k ON u.id = k.userid - WHERE u.deleted = 0 AND u.confirmed = 1 - AND u.suspended = 0 AND k.value = ?'; + $sql = "SELECT u.id + FROM {user} u + JOIN {user_private_key} k ON u.id = k.userid + WHERE u.deleted = 0 + AND u.confirmed = 1 + AND u.suspended = 0 + AND k.script = 'rss' + AND k.value = ?"; + return $DB->get_field_sql($sql, array($token), IGNORE_MISSING); } diff --git a/lib/tests/rsslib_test.php b/lib/tests/rsslib_test.php index ff0674595b8..3585601018e 100644 --- a/lib/tests/rsslib_test.php +++ b/lib/tests/rsslib_test.php @@ -20,7 +20,7 @@ defined('MOODLE_INTERNAL') || die(); global $CFG; require_once($CFG->libdir.'/simplepie/moodle_simplepie.php'); - +require_once($CFG->libdir . '/rsslib.php'); /** * These tests rely on the rsstest.xml file on download.moodle.org, @@ -140,4 +140,19 @@ EOD; $this->assertSame('Moodle News', $feed->get_title()); $this->assertSame('http://moodle.org/mod/forum/view.php?f=1', $feed->get_link()); } + + /** + * Test that we can get the right user ID based on the provided private key (token). + * + * @covers ::rss_get_userid_from_token + */ + public function test_rss_get_userid_from_token() { + global $USER; + + $this->resetAfterTest(); + $this->setGuestUser(); + + $key = rss_get_token($USER->id); + $this->assertSame(rss_get_userid_from_token($key), $USER->id); + } }