Refactored out claim check logic to its own class
This commit is contained in:
@ -3,6 +3,7 @@
|
||||
namespace NoccyLabs\Mercureact\Http\Middleware;
|
||||
|
||||
use NoccyLabs\Mercureact\Broker\Message;
|
||||
use NoccyLabs\Mercureact\Broker\Security\ClaimChecker;
|
||||
use NoccyLabs\Mercureact\Broker\Subscriber\SseSubscriber;
|
||||
use NoccyLabs\Mercureact\Broker\TopicManager;
|
||||
use NoccyLabs\Mercureact\Configuration;
|
||||
@ -27,6 +28,8 @@ class MercureHandler
|
||||
|
||||
private int $seenIdHistorySize = 100;
|
||||
|
||||
private ClaimChecker $claimChecker;
|
||||
|
||||
public function __construct(
|
||||
private Configuration $config,
|
||||
private TopicManager $topicManager,
|
||||
@ -35,6 +38,7 @@ class MercureHandler
|
||||
{
|
||||
$this->loop = $loop ?? Loop::get();
|
||||
$this->seenIdHistorySize = $this->config->getDuplicateIdHistorySize();
|
||||
$this->claimChecker = new ClaimChecker();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,7 +98,7 @@ class MercureHandler
|
||||
// Grab the JWT token from the requests authorization attribute
|
||||
if ($request->getAttribute('authorized')) {
|
||||
$claims = $request->getAttribute('mercure.subscribe');
|
||||
if (!$this->checkTopicClaims($topics, $claims)) {
|
||||
if (!$this->claimChecker->matchAll($topics, $claims)) {
|
||||
throw new SecurityException(
|
||||
message: "Insufficient permissions for subscribe",
|
||||
code: SecurityException::ERR_NO_PERMISSION
|
||||
@ -112,6 +116,7 @@ class MercureHandler
|
||||
}
|
||||
|
||||
$this->topicManager->subscribe($subscriber, $topics);
|
||||
|
||||
$responseStream->on('close', function () use ($subscriber, $topics) {
|
||||
$this->topicManager->unsubscribe($subscriber, $topics);
|
||||
});
|
||||
@ -156,7 +161,7 @@ class MercureHandler
|
||||
if ($request->getAttribute('authorized')) {
|
||||
$claims = $request->getAttribute('mercure.publish');
|
||||
// check topic against publishClaims
|
||||
if (!$this->checkTopicClaims($data['topic']??[], $claims)) {
|
||||
if (!$this->claimChecker->matchAll($data['topic']??[], $claims)) {
|
||||
throw new SecurityException(
|
||||
message: "Insufficient permissions for publish",
|
||||
code: SecurityException::ERR_NO_PERMISSION
|
||||
@ -195,23 +200,4 @@ class MercureHandler
|
||||
return Response::plaintext($message->id."\n");
|
||||
}
|
||||
|
||||
private function checkTopicClaims(string|array $topic, array $claims): bool
|
||||
{
|
||||
$matched = 0;
|
||||
foreach ((array)$topic as $match) {
|
||||
foreach ($claims as $claim) {
|
||||
if (($claim === "*") || ($claim === $match)) {
|
||||
$matched++;
|
||||
break;
|
||||
}
|
||||
// TODO make sure that UriTemplate parsing works
|
||||
if ((new UriTemplate())->extract($claim, $match, true)) {
|
||||
$matched++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ($matched == count($topic));
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user