Added anonymous/private logic
This commit is contained in:
@ -94,9 +94,23 @@ class MercureHandler
|
||||
);
|
||||
[ $name, $value ] = array_map('urldecode', explode("=", $param, 2));
|
||||
if ($name === 'topic') $topics[] = $value;
|
||||
// TODO check claims for access
|
||||
}
|
||||
|
||||
// Grab the JWT token from the requests authorization attribute
|
||||
$tok = $request->getAttribute('authorization');
|
||||
if ($tok instanceof JWTToken) {
|
||||
$claims = $tok->claims->getAll();
|
||||
if (isset($claims['mercure']['subscribe'])) {
|
||||
$subscribeClaims = $claims['mercure']['subscribe'];
|
||||
// TODO check topic against publishClaims
|
||||
if (!$this->checkTopicClaims($topics, $subscribeClaims)) {
|
||||
throw new SecurityException("Insufficient permissions for subscribe", SecurityException::ERR_NO_PERMISSION);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// TODO add option to allow/disallow anonymous acess. should still respect
|
||||
}
|
||||
|
||||
$this->topicManager->subscribe($subscriber, $topics);
|
||||
//$this->eventClients->attach($responseStream, $request);
|
||||
$responseStream->on('close', function () use ($subscriber, $topics) {
|
||||
@ -142,13 +156,17 @@ class MercureHandler
|
||||
$claims = $tok->claims->getAll();
|
||||
if (isset($claims['mercure']['publish'])) {
|
||||
$publishClaims = $claims['mercure']['publish'];
|
||||
// TODO check topic against publishClaims
|
||||
// check topic against publishClaims
|
||||
if (!$this->checkTopicClaims($data['topic']??[], $publishClaims)) {
|
||||
throw new SecurityException("Insufficient permissions for publish", SecurityException::ERR_NO_PERMISSION);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// FIXME reject if access denied
|
||||
// reject if access denied
|
||||
throw new SecurityException(
|
||||
message: "Access denied",
|
||||
code: SecurityException::ERR_ACCESS_DENIED
|
||||
);
|
||||
}
|
||||
|
||||
// Put an id in there if none already
|
||||
@ -167,17 +185,19 @@ class MercureHandler
|
||||
return Response::plaintext("urn:uuid:".$message->id."\n");
|
||||
}
|
||||
|
||||
private function checkTopicClaims(string|array $topic, array $claims, bool $all=false): bool
|
||||
private function checkTopicClaims(string|array $topic, array $claims): bool
|
||||
{
|
||||
// TODO match all topics if $all, reject on mismatch
|
||||
$matched = 0;
|
||||
foreach ((array)$topic as $match) {
|
||||
foreach ($claims as $claim) {
|
||||
if ($claim === "*") return true;
|
||||
if ($claim === $match) return true;
|
||||
// TODO implement full matching
|
||||
// TODO implement matching of URI Templates
|
||||
if (($claim === "*") || ($claim === $match)) {
|
||||
$matched++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return ($matched == count($topic));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user