Skip to content

Commit 639d3a8

Browse files
Merge pull request #387 from JLG-WOCFR-DEV/codex/add-user-capability-checks-to-link-update-functions
Add fix-links capability guard and tests
2 parents 4670d24 + 2683243 commit 639d3a8

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

liens-morts-detector-jlg/includes/class-blc-links-list-table.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,17 @@ protected function process_bulk_action() {
14631463
return;
14641464
}
14651465

1466+
if (!function_exists('blc_current_user_can_fix_links') || !blc_current_user_can_fix_links()) {
1467+
$notice = [
1468+
'message' => __('Permissions insuffisantes pour effectuer cette action groupée.', 'liens-morts-detector-jlg'),
1469+
'type' => 'error',
1470+
'announcement' => __('Action groupée annulée : permissions insuffisantes.', 'liens-morts-detector-jlg'),
1471+
];
1472+
1473+
$this->redirect_after_bulk($notice);
1474+
return;
1475+
}
1476+
14661477
$ids = $this->get_requested_bulk_ids();
14671478

14681479
check_admin_referer('bulk-' . $this->_args['plural']);

liens-morts-detector-jlg/liens-morts-detector-jlg.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,10 @@ function blc_require_post_params(array $required_params) {
462462
* @return array|WP_Error
463463
*/
464464
function blc_perform_link_update(array $args) {
465+
if (!function_exists('blc_current_user_can_fix_links') || !blc_current_user_can_fix_links()) {
466+
return new WP_Error('blc_forbidden', __('Permissions insuffisantes.', 'liens-morts-detector-jlg'), ['status' => BLC_HTTP_FORBIDDEN]);
467+
}
468+
465469
global $wpdb;
466470

467471
$defaults = [
@@ -1272,6 +1276,10 @@ function blc_ajax_apply_detected_redirect_callback() {
12721276
// Gère la dissociation d'un lien
12731277
add_action('wp_ajax_blc_unlink', 'blc_ajax_unlink_callback');
12741278
function blc_ajax_unlink_callback() {
1279+
if (!function_exists('blc_current_user_can_fix_links') || !blc_current_user_can_fix_links()) {
1280+
wp_send_json_error(['message' => __('Permissions insuffisantes.', 'liens-morts-detector-jlg')], BLC_HTTP_FORBIDDEN);
1281+
}
1282+
12751283
check_ajax_referer('blc_unlink_nonce');
12761284

12771285
$params = blc_require_post_params(['post_id', 'row_id', 'url_to_unlink']);
@@ -1401,6 +1409,10 @@ function blc_ajax_unlink_callback() {
14011409

14021410
add_action('wp_ajax_blc_ignore_link', 'blc_ajax_ignore_link_callback');
14031411
function blc_ajax_ignore_link_callback() {
1412+
if (!function_exists('blc_current_user_can_fix_links') || !blc_current_user_can_fix_links()) {
1413+
wp_send_json_error(['message' => __('Permissions insuffisantes.', 'liens-morts-detector-jlg')], BLC_HTTP_FORBIDDEN);
1414+
}
1415+
14041416
check_ajax_referer('blc_ignore_link_nonce');
14051417

14061418
$params = blc_require_post_params(['post_id', 'row_id', 'mode']);
@@ -1529,6 +1541,10 @@ function blc_ajax_ignore_link_callback() {
15291541

15301542
add_action('wp_ajax_blc_recheck_link', 'blc_ajax_recheck_link_callback');
15311543
function blc_ajax_recheck_link_callback() {
1544+
if (!function_exists('blc_current_user_can_fix_links') || !blc_current_user_can_fix_links()) {
1545+
wp_send_json_error(['message' => __('Permissions insuffisantes.', 'liens-morts-detector-jlg')], BLC_HTTP_FORBIDDEN);
1546+
}
1547+
15321548
check_ajax_referer('blc_recheck_link_nonce');
15331549

15341550
$params = blc_require_post_params(['post_id', 'row_id']);

tests/BlcAjaxCallbacksTest.php

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,42 @@
11
<?php
22

33
namespace {
4+
if (!class_exists('WP_Error')) {
5+
class WP_Error
6+
{
7+
/** @var string */
8+
private $code;
9+
10+
/** @var string */
11+
private $message;
12+
13+
/** @var mixed */
14+
private $data;
15+
16+
public function __construct($code = '', $message = '', $data = null)
17+
{
18+
$this->code = (string) $code;
19+
$this->message = (string) $message;
20+
$this->data = $data;
21+
}
22+
23+
public function get_error_code()
24+
{
25+
return $this->code;
26+
}
27+
28+
public function get_error_message()
29+
{
30+
return $this->message;
31+
}
32+
33+
public function get_error_data()
34+
{
35+
return $this->data;
36+
}
37+
}
38+
}
39+
440
if (!function_exists('__')) {
541
function __($text, $domain = null)
642
{
@@ -396,6 +432,33 @@ public function test_edit_link_returns_error_when_required_param_is_missing(arra
396432
blc_ajax_edit_link_callback();
397433
}
398434

435+
public function test_perform_link_update_requires_fix_links_capability_even_if_user_can_edit_post(): void
436+
{
437+
Functions\when('blc_current_user_can_fix_links')->justReturn(false);
438+
Functions\when('current_user_can')->alias(static function ($capability) {
439+
return $capability === 'edit_post';
440+
});
441+
442+
global $wpdb;
443+
$wpdb = (object) ['prefix' => 'wp_'];
444+
445+
Functions\when('get_post')->justReturn(null);
446+
447+
$result = \blc_perform_link_update([
448+
'post_id' => 21,
449+
'row_id' => 21,
450+
'row' => ['url' => 'http://example.com'],
451+
'old_url' => 'http://example.com',
452+
'new_url' => 'http://example.org',
453+
]);
454+
455+
$this->assertInstanceOf(\WP_Error::class, $result);
456+
$this->assertSame('blc_forbidden', $result->get_error_code());
457+
$data = $result->get_error_data('blc_forbidden');
458+
$this->assertIsArray($data);
459+
$this->assertSame(BLC_HTTP_FORBIDDEN, $data['status'] ?? null);
460+
}
461+
399462
public function unlinkMissingParamProvider(): array
400463
{
401464
return [
@@ -456,6 +519,23 @@ public function test_unlink_returns_error_when_required_param_is_missing(array $
456519
blc_ajax_unlink_callback();
457520
}
458521

522+
public function test_ajax_unlink_requires_fix_links_capability_even_if_user_can_edit_post(): void
523+
{
524+
Functions\when('blc_current_user_can_fix_links')->justReturn(false);
525+
Functions\when('current_user_can')->alias(static function ($capability) {
526+
return $capability === 'edit_post';
527+
});
528+
Functions\when('check_ajax_referer')->justReturn(true);
529+
Functions\expect('wp_send_json_error')->once()->with([
530+
'message' => 'Permissions insuffisantes.',
531+
], BLC_HTTP_FORBIDDEN)->andReturnUsing(static function () {
532+
throw new \RuntimeException('unlink-forbidden');
533+
});
534+
535+
$this->expectExceptionMessage('unlink-forbidden');
536+
blc_ajax_unlink_callback();
537+
}
538+
459539
public function test_edit_link_denied_for_user_without_permission(): void
460540
{
461541
$_POST['post_id'] = 1;
@@ -2153,6 +2233,40 @@ public function test_unlink_scheme_relative_url_updates_content_and_database():
21532233
$this->assertSame(['id' => 8], $wpdb->delete_args[1]);
21542234
$this->assertSame(['%d'], $wpdb->delete_args[2]);
21552235
}
2236+
2237+
public function test_ajax_ignore_requires_fix_links_capability_even_if_user_can_edit_post(): void
2238+
{
2239+
Functions\when('blc_current_user_can_fix_links')->justReturn(false);
2240+
Functions\when('current_user_can')->alias(static function ($capability) {
2241+
return $capability === 'edit_post';
2242+
});
2243+
Functions\when('check_ajax_referer')->justReturn(true);
2244+
Functions\expect('wp_send_json_error')->once()->with([
2245+
'message' => 'Permissions insuffisantes.',
2246+
], BLC_HTTP_FORBIDDEN)->andReturnUsing(static function () {
2247+
throw new \RuntimeException('ignore-forbidden');
2248+
});
2249+
2250+
$this->expectExceptionMessage('ignore-forbidden');
2251+
blc_ajax_ignore_link_callback();
2252+
}
2253+
2254+
public function test_ajax_recheck_requires_fix_links_capability_even_if_user_can_edit_post(): void
2255+
{
2256+
Functions\when('blc_current_user_can_fix_links')->justReturn(false);
2257+
Functions\when('current_user_can')->alias(static function ($capability) {
2258+
return $capability === 'edit_post';
2259+
});
2260+
Functions\when('check_ajax_referer')->justReturn(true);
2261+
Functions\expect('wp_send_json_error')->once()->with([
2262+
'message' => 'Permissions insuffisantes.',
2263+
], BLC_HTTP_FORBIDDEN)->andReturnUsing(static function () {
2264+
throw new \RuntimeException('recheck-forbidden');
2265+
});
2266+
2267+
$this->expectExceptionMessage('recheck-forbidden');
2268+
blc_ajax_recheck_link_callback();
2269+
}
21562270
}
21572271

21582272
}

0 commit comments

Comments
 (0)