Improve error handling in controllers/repositories
This commit is contained in:
@@ -15,6 +15,7 @@ use React\Socket\SocketServer;
|
||||
use SlotDb\SlotDb\Bus\MessageBus;
|
||||
use SlotDb\SlotDb\Data\Database;
|
||||
use SlotDb\SlotDb\Data\Group\Group;
|
||||
use SlotDb\SlotDb\Data\Schema\Schema;
|
||||
use SlotDb\SlotDb\Data\Slot\Slot;
|
||||
use SlotDb\SlotDb\Data\Slot\SlotRepository;
|
||||
|
||||
@@ -59,6 +60,7 @@ class Daemon
|
||||
$routes = new RouteCollection();
|
||||
$routes->addController(new Http\Controller\SlotsController($em->getRepository(Slot::class), $this->messageBus));
|
||||
$routes->addController(new Http\Controller\GroupsController($em->getRepository(Group::class), $em->getRepository(Slot::class)));
|
||||
$routes->addController(new Http\Controller\SchemassController($em->getRepository(Schema::class)));
|
||||
|
||||
$this->server = new HttpServer(
|
||||
new Http\Middleware\LoggingMiddleware($httpLogger ?? $logger),
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace SlotDb\SlotDb\Data\Group;
|
||||
|
||||
|
||||
class GroupNotFoundException extends \RuntimeException
|
||||
{}
|
||||
@@ -43,6 +43,3 @@ class GroupRepository extends EntityRepository
|
||||
$this->getEntityManager()->clear();
|
||||
}
|
||||
}
|
||||
|
||||
class GroupNotFoundException extends \RuntimeException
|
||||
{}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace SlotDb\SlotDb\Data\Slot;
|
||||
|
||||
class SlotNotFoundException extends \RuntimeException
|
||||
{}
|
||||
@@ -91,6 +91,3 @@ class SlotRepository extends EntityRepository
|
||||
$this->getEntityManager()->clear();
|
||||
}
|
||||
}
|
||||
|
||||
class SlotNotFoundException extends \RuntimeException
|
||||
{}
|
||||
@@ -6,6 +6,7 @@ use NoccyLabs\React\Http\Attributes\Route;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use React\Http\Message\Response;
|
||||
use SlotDb\SlotDb\Data\Group\Group;
|
||||
use SlotDb\SlotDb\Data\Group\GroupNotFoundException;
|
||||
use SlotDb\SlotDb\Data\Group\GroupRepository;
|
||||
use SlotDb\SlotDb\Data\Slot\Slot;
|
||||
use SlotDb\SlotDb\Data\Slot\SlotRepository;
|
||||
@@ -45,7 +46,11 @@ class GroupsController extends Controller
|
||||
#[Route(path:"/api/slotdb/v1/group/:group", methods:["GET"])]
|
||||
public function queryGroup(ServerRequestInterface $request, string $group)
|
||||
{
|
||||
$groupObj = $this->groups->findGroup($group);
|
||||
try {
|
||||
$groupObj = $this->groups->findGroup($group);
|
||||
} catch (GroupNotFoundException $e) {
|
||||
return Response::json([ 'error'=>"Group not found" ])->withStatus(404);
|
||||
}
|
||||
|
||||
$groupProps = $groupObj->getProperties();
|
||||
|
||||
@@ -63,7 +68,11 @@ class GroupsController extends Controller
|
||||
#[Route(path:"/api/slotdb/v1/group/:group/members", methods:["GET"])]
|
||||
public function queryGroupMembers(ServerRequestInterface $request, string $group)
|
||||
{
|
||||
$groupObj = $this->groups->findGroup($group);
|
||||
try {
|
||||
$groupObj = $this->groups->findGroup($group);
|
||||
} catch (GroupNotFoundException $e) {
|
||||
return Response::json([ 'error'=>"Group not found" ])->withStatus(404);
|
||||
}
|
||||
|
||||
return Response::json(iterator_to_array($groupObj->getSlots()));
|
||||
}
|
||||
@@ -71,7 +80,11 @@ class GroupsController extends Controller
|
||||
#[Route(path:"/api/slotdb/v1/group/:group", methods:["POST"])]
|
||||
public function updateGroup(ServerRequestInterface $request, string $group)
|
||||
{
|
||||
$groupObj = $this->groups->findGroup($group);
|
||||
try {
|
||||
$groupObj = $this->groups->findGroup($group);
|
||||
} catch (GroupNotFoundException $e) {
|
||||
return Response::json([ 'error'=>"Group not found" ])->withStatus(404);
|
||||
}
|
||||
|
||||
$groupProps = $groupObj->getProperties();
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace SlotDb\SlotDb\Http\Controller;
|
||||
|
||||
use NoccyLabs\React\Http\Attributes\Route;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use React\Http\Message\Response;
|
||||
use SlotDb\SlotDb\Data\Group\Group;
|
||||
use SlotDb\SlotDb\Data\Group\GroupRepository;
|
||||
use SlotDb\SlotDb\Data\Schema\SchemaRepository;
|
||||
use SlotDb\SlotDb\Data\Slot\Slot;
|
||||
use SlotDb\SlotDb\Data\Slot\SlotRepository;
|
||||
|
||||
class SchemassController extends Controller
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private readonly SchemaRepository $schemas
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#[Route(path:"/api/slotdb/v1/schemas", methods:["GET"])]
|
||||
public function listSchemas(ServerRequestInterface $request)
|
||||
{
|
||||
$slots = $this->schemas->findGroups();
|
||||
return Response::json($slots);
|
||||
}
|
||||
|
||||
#[Route(path:"/api/slotdb/v1/schema/:schema", methods:["GET"])]
|
||||
public function getSchema(ServerRequestInterface $request, string $schema)
|
||||
{
|
||||
return Response::json(true);
|
||||
}
|
||||
|
||||
#[Route(path:"/api/slotdb/v1/schema/:schema", methods:["POST"])]
|
||||
public function createSchema(ServerRequestInterface $request, string $schema)
|
||||
{
|
||||
return Response::json(true);
|
||||
}
|
||||
|
||||
#[Route(path:"/api/slotdb/v1/schema/:schema", methods:["PUT"])]
|
||||
public function updateSchema(ServerRequestInterface $request, string $schema)
|
||||
{
|
||||
return Response::json(true);
|
||||
}
|
||||
|
||||
#[Route(path:"/api/slotdb/v1/schema/:schema", methods:["DELETE"])]
|
||||
public function deleteSchema(ServerRequestInterface $request, string $schema)
|
||||
{
|
||||
return Response::json(true);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ use Psr\Http\Message\ServerRequestInterface;
|
||||
use React\Http\Message\Response;
|
||||
use SlotDb\SlotDb\Bus\MessageBus;
|
||||
use SlotDb\SlotDb\Data\Slot\Slot;
|
||||
use SlotDb\SlotDb\Data\Slot\SlotNotFoundException;
|
||||
use SlotDb\SlotDb\Data\Slot\SlotRepository;
|
||||
|
||||
|
||||
@@ -80,7 +81,11 @@ class SlotsController extends Controller
|
||||
#[Route(path:"/api/slotdb/v1/slot/:slot", methods:["GET"])]
|
||||
public function querySlot(ServerRequestInterface $request, string $slot)
|
||||
{
|
||||
$slotObj = $this->slots->findOneBy(['slotId' => $slot]);
|
||||
try {
|
||||
$slotObj = $this->slots->findSlot($slot);
|
||||
} catch (SlotNotFoundException $e) {
|
||||
return Response::json([ 'error'=>"Slot not found" ])->withStatus(404);
|
||||
}
|
||||
|
||||
return Response::json($slotObj);
|
||||
}
|
||||
@@ -88,7 +93,12 @@ class SlotsController extends Controller
|
||||
#[Route(path:"/api/slotdb/v1/slot/:slot", methods:["POST"])]
|
||||
public function updateSlot(ServerRequestInterface $request, string $slot)
|
||||
{
|
||||
$slotObj = $this->slots->findOneBy(['slotId' => $slot]);
|
||||
try {
|
||||
$slotObj = $this->slots->findSlot($slot);
|
||||
} catch (SlotNotFoundException $e) {
|
||||
return Response::json([ 'error'=>"Slot not found" ])->withStatus(404);
|
||||
}
|
||||
|
||||
$slotProps = $slotObj->getProperties();
|
||||
|
||||
$posted = json_decode($request->getBody());
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace SlotDb\SlotDb\Security;
|
||||
|
||||
use SlotDb\SlotDb\Data\Slot\Slot;
|
||||
|
||||
class AccessChecker
|
||||
{
|
||||
/** @var array<string,AceMatcher> */
|
||||
private $aclCache = [];
|
||||
|
||||
/**
|
||||
* Check if any of the ACL rules match the slot and property
|
||||
*
|
||||
* @param Slot $slot
|
||||
* @param string $prop
|
||||
* @param array<string> $acl
|
||||
* @return bool
|
||||
*/
|
||||
public function checkAccess(Slot $slot, string $prop, array $acl, string $access): bool
|
||||
{
|
||||
$groupId = $slot->getGroup() ? $slot->getGroup()->getGroupId() : null;
|
||||
$slotId = $slot->getSlotId();
|
||||
|
||||
foreach ($acl as $ace) {
|
||||
$matcher = $this->getCompiledMatcher($ace);
|
||||
if ($matcher->matches($slotId, $groupId, $prop, $access)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getCompiledMatcher(string $ace): AceMatcher
|
||||
{
|
||||
if (!isset($this->aclCache[$ace])) {
|
||||
$this->aclCache[$ace] = new AceMatcher($ace);
|
||||
}
|
||||
return $this->aclCache[$ace];
|
||||
}
|
||||
}
|
||||
|
||||
class AceMatcher
|
||||
{
|
||||
public function __construct(
|
||||
private readonly string $ace
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
public function matches(string $slot, string $group, string $prop, string $access): bool
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function getAce(): string
|
||||
{
|
||||
return $this->ace;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user