Files
WP-LIT-MCP/src/Access.php
T
janniclas.loosenandClaude Opus 5.5 f69efcb953 fix: guard allowedRoles() against corrupt filtered results
The lit_mcp_allowed_roles filter could return a non-array, causing
array_filter() to throw TypeError in PHP 8.1+. Now fallback to
['administrator'] if filter result is not an array.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-25 15:23:56 +02:00

84 lines
2.0 KiB
PHP

<?php
declare(strict_types=1);
namespace LIT\MCP;
use WP_User;
/**
* Role gate: only users whose role is allowed get the lit_mcp_use capability.
*
* The capability is granted dynamically via user_has_cap, so no role objects
* in the database are modified.
*/
final class Access
{
public const CAPABILITY = 'lit_mcp_use';
public const OPTION = 'lit_mcp_allowed_roles';
private const DEFAULT_ROLES = ['administrator'];
private const ADAPTER_META_TOOLS = [
'discover_abilities',
'get_ability_info',
'execute_ability',
];
public function register(): void
{
add_filter('user_has_cap', [$this, 'grantCapability'], 10, 4);
foreach (self::ADAPTER_META_TOOLS as $tool) {
add_filter(
"mcp_adapter_{$tool}_capability",
static fn (): string => self::CAPABILITY
);
}
}
/**
* @return list<string>
*/
public function allowedRoles(): array
{
$roles = get_option(self::OPTION, self::DEFAULT_ROLES);
if (! is_array($roles)) {
$roles = self::DEFAULT_ROLES;
}
$roles = apply_filters('lit_mcp_allowed_roles', $roles);
if (! is_array($roles)) {
$roles = self::DEFAULT_ROLES;
}
return array_values(array_filter($roles, 'is_string'));
}
/**
* @param array<string, bool> $allcaps
* @param list<string> $caps
* @param array<int, mixed> $args
* @return array<string, bool>
*/
public function grantCapability(
array $allcaps,
array $caps,
array $args,
WP_User $user
): array {
if (! in_array(self::CAPABILITY, $caps, true)) {
return $allcaps;
}
if (array_intersect($user->roles, $this->allowedRoles()) !== []) {
$allcaps[self::CAPABILITY] = true;
}
return $allcaps;
}
public static function currentUserMayUse(): bool
{
return current_user_can(self::CAPABILITY);
}
}