From 5a33a141af42eab89204415da7908c1f10aaab4c Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 21 Jun 2020 15:11:24 +0700 Subject: [PATCH] [ticket/16533] Add autologin keys management UCP module events PHPBB3-16533 --- phpBB/docs/events.md | 56 +++++++++++++++++++ phpBB/includes/ucp/ucp_profile.php | 47 ++++++++++++---- .../template/ucp_profile_autologin_keys.html | 11 +++- tests/functional/ucp_profile_test.php | 33 +++++++++++ .../phpbb_functional_test_case.php | 6 +- 5 files changed, 141 insertions(+), 12 deletions(-) diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index ccc5b146f2..d58cb07477 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -2730,6 +2730,62 @@ ucp_prefs_view_select_menu_prepend * Purpose: Add options to the top of the drop-down lists block of the Edit Display Options screen +ucp_profile_autologin_keys_tbody_key_after +=== +* Locations: + + styles/prosilver/template/ucp_profile_autologin_keys.html +* Since: 3.3.2-RC1 +* Purpose: Add table column after the first column. + +ucp_profile_autologin_keys_tbody_key_before +=== +* Locations: + + styles/prosilver/template/ucp_profile_autologin_keys.html +* Since: 3.3.2-RC1 +* Purpose: Add table column before the first column. + +ucp_profile_autologin_keys_tbody_mark_after +=== +* Locations: + + styles/prosilver/template/ucp_profile_autologin_keys.html +* Since: 3.3.2-RC1 +* Purpose: Add table column after the last column. + +ucp_profile_autologin_keys_tbody_mark_before +=== +* Locations: + + styles/prosilver/template/ucp_profile_autologin_keys.html +* Since: 3.3.2-RC1 +* Purpose: Add table column before the last column. + +ucp_profile_autologin_keys_thead_key_after +=== +* Locations: + + styles/prosilver/template/ucp_profile_autologin_keys.html +* Since: 3.3.2-RC1 +* Purpose: Add table header content after the first column. + +ucp_profile_autologin_keys_thead_key_before +=== +* Locations: + + styles/prosilver/template/ucp_profile_autologin_keys.html +* Since: 3.3.2-RC1 +* Purpose: Add table header content before the first column. + +ucp_profile_autologin_keys_thead_mark_after +=== +* Locations: + + styles/prosilver/template/ucp_profile_autologin_keys.html +* Since: 3.3.2-RC1 +* Purpose: Add table header content after the last column. + +ucp_profile_autologin_keys_thead_mark_before +=== +* Locations: + + styles/prosilver/template/ucp_profile_autologin_keys.html +* Since: 3.3.2-RC1 +* Purpose: Add table header content before the last column. + ucp_profile_profile_info_after === * Locations: diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index dca7e7eeb7..53a042f173 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -810,23 +810,50 @@ class ucp_profile $error = array_map(array($user, 'lang'), $error); } - $sql = 'SELECT key_id, last_ip, last_login - FROM ' . SESSIONS_KEYS_TABLE . ' - WHERE user_id = ' . (int) $user->data['user_id'] . ' - ORDER BY last_login ASC'; + $sql_ary = [ + 'SELECT' => 'sk.key_id, sk.last_ip, sk.last_login', + 'FROM' => [SESSIONS_KEYS_TABLE => 'sk'], + 'WHERE' => 'sk.user_id = ' . (int) $user->data['user_id'], + 'ORDER_BY' => 'sk.last_login ASC', + ]; - $result = $db->sql_query($sql); + /** + * Event allows changing SQL query for autologin keys + * + * @event core.ucp_profile_autologin_keys_sql + * @var array sql_ary Array with autologin keys SQL query + * @since 3.3.2-RC1 + */ + $vars = ['sql_ary']; + extract($phpbb_dispatcher->trigger_event('core.ucp_profile_autologin_keys_sql', compact($vars))); - while ($row = $db->sql_fetchrow($result)) + $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary)); + $sessions = (array) $db->sql_fetchrowset($result); + $db->sql_freeresult($result); + + $template_vars = []; + foreach ($sessions as $row) { - $template->assign_block_vars('sessions', array( - 'KEY' => substr($row['key_id'], 0, 8), + $key = substr($row['key_id'], 0, 8); + $template_vars[$key] = [ + 'KEY' => $key, 'IP' => $row['last_ip'], 'LOGIN_TIME' => $user->format_date($row['last_login']), - )); + ]; } - $db->sql_freeresult($result); + /** + * Event allows changing template variables + * + * @event core.ucp_profile_autologin_keys_template_vars + * @var array sessions Array with session keys data + * @var array template_vars Array with template variables + * @since 3.3.2-RC1 + */ + $vars = ['sessions', 'template_vars']; + extract($phpbb_dispatcher->trigger_event('core.ucp_profile_autologin_keys_template_vars', compact($vars))); + + $template->assign_block_vars_array('sessions', $template_vars); break; } diff --git a/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html b/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html index 65909b7068..d61c185eab 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html +++ b/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html @@ -7,25 +7,34 @@

{L_PROFILE_AUTOLOGIN_KEYS}

{ERROR}

+ {% DEFINE COLSPAN = 4 %} + {% EVENT ucp_profile_autologin_keys_thead_key_before %} + {% EVENT ucp_profile_autologin_keys_thead_key_after %} + {% EVENT ucp_profile_autologin_keys_thead_mark_before %} + {% EVENT ucp_profile_autologin_keys_thead_mark_after %} + {% EVENT ucp_profile_autologin_keys_tbody_key_before %} + {% EVENT ucp_profile_autologin_keys_tbody_key_after %} + {% EVENT ucp_profile_autologin_keys_tbody_mark_before %} + {% EVENT ucp_profile_autologin_keys_tbody_mark_after %} - +
{L_LOGIN_KEY}{L_IP} {L_LOGIN_TIME}{L_MARK}
{sessions.IP} {sessions.LOGIN_TIME}
{L_PROFILE_NO_AUTOLOGIN_KEYS}
{L_PROFILE_NO_AUTOLOGIN_KEYS}
diff --git a/tests/functional/ucp_profile_test.php b/tests/functional/ucp_profile_test.php index 2d68704162..8b92cdf243 100644 --- a/tests/functional/ucp_profile_test.php +++ b/tests/functional/ucp_profile_test.php @@ -44,4 +44,37 @@ class phpbb_functional_ucp_profile_test extends phpbb_functional_test_case $this->assertEquals('phpbb_twitter', $form->get('pf_phpbb_twitter')->getValue()); $this->assertEquals('phpbb.youtube', $form->get('pf_phpbb_youtube')->getValue()); } + + public function test_autologin_keys_manage() + { + $this->add_lang('ucp'); + $this->login('admin', true); + $db = $this->get_db(); + + $crawler = self::request('GET', 'ucp.php?i=ucp_profile&mode=autologin_keys'); + $this->assertContainsLang('UCP_PROFILE_AUTOLOGIN_KEYS', $crawler->filter('#cp-main h2')->text()); + + $profile_url = $crawler->filter('a[title="Profile"]')->attr('href'); + $user_id = $this->get_parameter_from_link($profile_url, 'u'); + + $sql_ary = [ + 'SELECT' => 'sk.key_id', + 'FROM' => [SESSIONS_KEYS_TABLE => 'sk'], + 'WHERE' => 'sk.user_id = ' . (int) $user_id, + 'ORDER_BY' => 'sk.last_login ASC', + ]; + $result = $db->sql_query_limit($db->sql_build_query('SELECT', $sql_ary), 1); + $key_id = substr($db->sql_fetchfield('key_id'), 0, 8); + $db->sql_freeresult($result); + + $this->assertContains($key_id, $crawler->filter('label[for="' . $key_id . '"]')->text()); + + $form = $crawler->selectButton('submit')->form(); + $form['keys'][0]->tick(); + $crawler = self::submit($form); + $this->assertContains($this->lang('AUTOLOGIN_SESSION_KEYS_DELETED'), $crawler->filter('html')->text()); + + $crawler = self::request('GET', 'ucp.php?i=ucp_profile&mode=autologin_keys'); + $this->assertContains($this->lang('PROFILE_NO_AUTOLOGIN_KEYS'), $crawler->filter('tbody > tr > td[class="bg1"]')->text()); + } } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 94a7d4e7af..b55f4c8b05 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -788,7 +788,7 @@ class phpbb_functional_test_case extends phpbb_test_case return group_user_add($group_id, false, $usernames, $group_name, $default, $leader); } - protected function login($username = 'admin') + protected function login($username = 'admin', $autologin = false) { $this->add_lang('ucp'); @@ -796,6 +796,10 @@ class phpbb_functional_test_case extends phpbb_test_case $this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), $crawler->filter('html')->text()); $form = $crawler->selectButton($this->lang('LOGIN'))->form(); + if ($autologin) + { + $form['autologin']->tick(); + } $crawler = self::submit($form, array('username' => $username, 'password' => $username . $username)); $this->assertNotContains($this->lang('LOGIN'), $crawler->filter('.navbar')->text());