refactor: migrate to scoped execution contexts

Signed-off-by: Sebastian <krupinski01@gmail.com>
This commit is contained in:
2026-07-27 00:50:43 -04:00
parent 9d48710d02
commit 3a68d03114
6 changed files with 60 additions and 60 deletions
+5 -5
View File
@@ -5,7 +5,7 @@ declare(strict_types=1);
namespace KTXM\ServiceDav\Auth; namespace KTXM\ServiceDav\Auth;
use KTXC\Service\SecurityService; use KTXC\Service\SecurityService;
use KTXC\SessionIdentity; use KTXC\Context\IdentityContext;
use Sabre\DAV\Auth\Backend\AbstractBasic; use Sabre\DAV\Auth\Backend\AbstractBasic;
use Sabre\HTTP\RequestInterface; use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface; use Sabre\HTTP\ResponseInterface;
@@ -15,7 +15,7 @@ class DavAuthBackend extends AbstractBasic
public const PRINCIPAL_PREFIX = 'principals/'; public const PRINCIPAL_PREFIX = 'principals/';
public function __construct( public function __construct(
private readonly SessionIdentity $identity, private readonly IdentityContext $identityContext,
private readonly SecurityService $securityService, private readonly SecurityService $securityService,
string $realm = 'KTXC DAV', string $realm = 'KTXC DAV',
) { ) {
@@ -24,8 +24,8 @@ class DavAuthBackend extends AbstractBasic
public function check(RequestInterface $request, ResponseInterface $response): array public function check(RequestInterface $request, ResponseInterface $response): array
{ {
if ($this->identity->identity() !== null) { if ($this->identityContext->identity() !== null) {
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
return [true, self::PRINCIPAL_PREFIX . $userId]; return [true, self::PRINCIPAL_PREFIX . $userId];
} }
@@ -39,7 +39,7 @@ class DavAuthBackend extends AbstractBasic
return false; return false;
} }
$this->identity->initialize($user, false); $this->identityContext->initialize($user);
return true; return true;
} }
} }
+15 -15
View File
@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace KTXM\ServiceDav\Backends; namespace KTXM\ServiceDav\Backends;
use KTXC\SessionIdentity; use KTXC\Context\IdentityContextInterface;
use KTXC\SessionTenant; use KTXC\Context\TenantContextInterface;
use KTXF\Chrono\Entity\JournalObject; use KTXF\Chrono\Entity\JournalObject;
use KTXF\Chrono\Entity\TaskObject; use KTXF\Chrono\Entity\TaskObject;
use KTXM\ChronoManager\Conversion\IcalDecoder; use KTXM\ChronoManager\Conversion\IcalDecoder;
@@ -39,8 +39,8 @@ class CalDavBackend extends AbstractBackend
public function __construct( public function __construct(
private readonly ChronoManager $manager, private readonly ChronoManager $manager,
private readonly SessionIdentity $identity, private readonly IdentityContextInterface $identityContext,
private readonly SessionTenant $tenant, private readonly TenantContextInterface $tenantContext,
private readonly DavUriMap $uriMap, private readonly DavUriMap $uriMap,
private readonly IcalEncoder $encoder, private readonly IcalEncoder $encoder,
private readonly IcalDecoder $decoder, private readonly IcalDecoder $decoder,
@@ -50,7 +50,7 @@ class CalDavBackend extends AbstractBackend
{ {
$result = []; $result = [];
$allCollections = $this->manager->collectionList($this->tenant->identifier(), $this->identity->identifier()); $allCollections = $this->manager->collectionList($this->tenantContext->identifier(), $this->identityContext->identifier());
foreach ($allCollections as $providerId => $providerServices) { foreach ($allCollections as $providerId => $providerServices) {
foreach ($providerServices as $serviceId => $collections) { foreach ($providerServices as $serviceId => $collections) {
@@ -93,8 +93,8 @@ class CalDavBackend extends AbstractBackend
public function getCalendarObjects($calendarId): array public function getCalendarObjects($calendarId): array
{ {
[$providerId, $serviceId, $collectionId] = $this->parseId($calendarId); [$providerId, $serviceId, $collectionId] = $this->parseId($calendarId);
$tenantId = $this->tenant->identifier(); $tenantId = $this->tenantContext->identifier();
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$targets = ResourceIdentifiers::fromArray([$calendarId]); $targets = ResourceIdentifiers::fromArray([$calendarId]);
$all = $this->manager->entityListBulk($tenantId, $userId, $targets); $all = $this->manager->entityListBulk($tenantId, $userId, $targets);
@@ -127,8 +127,8 @@ class CalDavBackend extends AbstractBackend
public function getCalendarObject($calendarId, $objectUri): ?array public function getCalendarObject($calendarId, $objectUri): ?array
{ {
[$providerId, $serviceId, $collectionId] = $this->parseId($calendarId); [$providerId, $serviceId, $collectionId] = $this->parseId($calendarId);
$tenantId = $this->tenant->identifier(); $tenantId = $this->tenantContext->identifier();
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $calendarId); $mapId = $this->mapId($tenantId, $userId, $calendarId);
// Resolve URI => entityId via the map; fall back to treating stripped URI as entityId // Resolve URI => entityId via the map; fall back to treating stripped URI as entityId
@@ -167,8 +167,8 @@ class CalDavBackend extends AbstractBackend
public function createCalendarObject($calendarId, $objectUri, $calendarData): ?string public function createCalendarObject($calendarId, $objectUri, $calendarData): ?string
{ {
[$providerId, $serviceId, $collectionId] = $this->parseId($calendarId); [$providerId, $serviceId, $collectionId] = $this->parseId($calendarId);
$tenantId = $this->tenant->identifier(); $tenantId = $this->tenantContext->identifier();
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$vcal = Reader::read($calendarData); $vcal = Reader::read($calendarData);
$props = $this->icalToEntityProps($vcal); $props = $this->icalToEntityProps($vcal);
@@ -190,8 +190,8 @@ class CalDavBackend extends AbstractBackend
public function updateCalendarObject($calendarId, $objectUri, $calendarData): ?string public function updateCalendarObject($calendarId, $objectUri, $calendarData): ?string
{ {
[$providerId, $serviceId, $collectionId] = $this->parseId($calendarId); [$providerId, $serviceId, $collectionId] = $this->parseId($calendarId);
$tenantId = $this->tenant->identifier(); $tenantId = $this->tenantContext->identifier();
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $calendarId); $mapId = $this->mapId($tenantId, $userId, $calendarId);
$entityId = $this->uriMap->getEntityId($mapId, $objectUri) $entityId = $this->uriMap->getEntityId($mapId, $objectUri)
@@ -210,8 +210,8 @@ class CalDavBackend extends AbstractBackend
public function deleteCalendarObject($calendarId, $objectUri): void public function deleteCalendarObject($calendarId, $objectUri): void
{ {
[$providerId, $serviceId, $collectionId] = $this->parseId($calendarId); [$providerId, $serviceId, $collectionId] = $this->parseId($calendarId);
$tenantId = $this->tenant->identifier(); $tenantId = $this->tenantContext->identifier();
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $calendarId); $mapId = $this->mapId($tenantId, $userId, $calendarId);
$entityId = $this->uriMap->getEntityId($mapId, $objectUri) $entityId = $this->uriMap->getEntityId($mapId, $objectUri)
+15 -15
View File
@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace KTXM\ServiceDav\Backends; namespace KTXM\ServiceDav\Backends;
use KTXC\SessionIdentity; use KTXC\Context\IdentityContextInterface;
use KTXC\SessionTenant; use KTXC\Context\TenantContextInterface;
use KTXF\Resource\Identifier\CollectionIdentifier; use KTXF\Resource\Identifier\CollectionIdentifier;
use KTXF\Resource\Identifier\EntityIdentifier; use KTXF\Resource\Identifier\EntityIdentifier;
use KTXF\Resource\Identifier\ResourceIdentifiers; use KTXF\Resource\Identifier\ResourceIdentifiers;
@@ -32,8 +32,8 @@ class CardDavBackend extends AbstractBackend
public function __construct( public function __construct(
private readonly PeopleManager $manager, private readonly PeopleManager $manager,
private readonly SessionIdentity $identity, private readonly IdentityContextInterface $identityContext,
private readonly SessionTenant $tenant, private readonly TenantContextInterface $tenantContext,
private readonly DavUriMap $uriMap, private readonly DavUriMap $uriMap,
) {} ) {}
@@ -46,7 +46,7 @@ class CardDavBackend extends AbstractBackend
$result = []; $result = [];
// collectionList returns [providerId][serviceId][collectionId] => CollectionBaseInterface // collectionList returns [providerId][serviceId][collectionId] => CollectionBaseInterface
$allCollections = $this->manager->collectionList($this->tenant->identifier(), $this->identity->identifier()); $allCollections = $this->manager->collectionList($this->tenantContext->identifier(), $this->identityContext->identifier());
foreach ($allCollections as $providerId => $providerServices) { foreach ($allCollections as $providerId => $providerServices) {
foreach ($providerServices as $serviceId => $collections) { foreach ($providerServices as $serviceId => $collections) {
@@ -94,8 +94,8 @@ class CardDavBackend extends AbstractBackend
public function getCards($addressBookId): array public function getCards($addressBookId): array
{ {
$tenantId = $this->tenant->identifier(); $tenantId = $this->tenantContext->identifier();
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$targets = ResourceIdentifiers::fromArray([$addressBookId]); $targets = ResourceIdentifiers::fromArray([$addressBookId]);
@@ -134,8 +134,8 @@ class CardDavBackend extends AbstractBackend
public function getCard($addressBookId, $cardUri): ?array public function getCard($addressBookId, $cardUri): ?array
{ {
[$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId); [$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId);
$tenantId = $this->tenant->identifier(); $tenantId = $this->tenantContext->identifier();
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $addressBookId); $mapId = $this->mapId($tenantId, $userId, $addressBookId);
$entityId = $this->uriMap->getEntityId($mapId, $cardUri) $entityId = $this->uriMap->getEntityId($mapId, $cardUri)
@@ -172,8 +172,8 @@ class CardDavBackend extends AbstractBackend
public function createCard($addressBookId, $cardUri, $cardData): ?string public function createCard($addressBookId, $cardUri, $cardData): ?string
{ {
[$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId); [$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId);
$tenantId = $this->tenant->identifier(); $tenantId = $this->tenantContext->identifier();
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$vcard = Reader::read($cardData); $vcard = Reader::read($cardData);
$props = $this->vcardToEntityProps($vcard); $props = $this->vcardToEntityProps($vcard);
@@ -192,8 +192,8 @@ class CardDavBackend extends AbstractBackend
public function updateCard($addressBookId, $cardUri, $cardData): ?string public function updateCard($addressBookId, $cardUri, $cardData): ?string
{ {
[$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId); [$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId);
$tenantId = $this->tenant->identifier(); $tenantId = $this->tenantContext->identifier();
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $addressBookId); $mapId = $this->mapId($tenantId, $userId, $addressBookId);
$entityId = $this->uriMap->getEntityId($mapId, $cardUri) $entityId = $this->uriMap->getEntityId($mapId, $cardUri)
@@ -210,8 +210,8 @@ class CardDavBackend extends AbstractBackend
public function deleteCard($addressBookId, $cardUri): bool public function deleteCard($addressBookId, $cardUri): bool
{ {
[$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId); [$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId);
$tenantId = $this->tenant->identifier(); $tenantId = $this->tenantContext->identifier();
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $addressBookId); $mapId = $this->mapId($tenantId, $userId, $addressBookId);
$entityId = $this->uriMap->getEntityId($mapId, $cardUri) $entityId = $this->uriMap->getEntityId($mapId, $cardUri)
+5 -5
View File
@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace KTXM\ServiceDav\Backends; namespace KTXM\ServiceDav\Backends;
use KTXC\SessionIdentity; use KTXC\Context\IdentityContextInterface;
use KTXC\SessionTenant; use KTXC\Context\TenantContextInterface;
use KTXM\DocumentsManager\Manager as DocumentsManager; use KTXM\DocumentsManager\Manager as DocumentsManager;
use Sabre\DAV\Collection; use Sabre\DAV\Collection;
use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\Forbidden;
@@ -23,8 +23,8 @@ class FilesRootNode extends Collection
{ {
public function __construct( public function __construct(
private readonly DocumentsManager $manager, private readonly DocumentsManager $manager,
private readonly SessionIdentity $identity, private readonly IdentityContextInterface $identityContext,
private readonly SessionTenant $tenant, private readonly TenantContextInterface $tenantContext,
) {} ) {}
public function getName(): string public function getName(): string
@@ -36,7 +36,7 @@ class FilesRootNode extends Collection
public function getChildren(): array public function getChildren(): array
{ {
$nodes = []; $nodes = [];
$services = $this->manager->serviceList($this->tenant->identifier(), $this->identity->identifier()); $services = $this->manager->serviceList($this->tenantContext->identifier(), $this->identityContext->identifier());
foreach ($services as $providerId => $providerServices) { foreach ($services as $providerId => $providerServices) {
foreach ($providerServices as $serviceId => $service) { foreach ($providerServices as $serviceId => $service) {
+10 -10
View File
@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace KTXM\ServiceDav\Backends; namespace KTXM\ServiceDav\Backends;
use KTXC\SessionIdentity; use KTXC\Context\IdentityContextInterface;
use KTXC\SessionTenant; use KTXC\Context\TenantContextInterface;
use KTXM\ServiceDav\DavProperties; use KTXM\ServiceDav\DavProperties;
use Sabre\DAVACL\PrincipalBackend\BackendInterface; use Sabre\DAVACL\PrincipalBackend\BackendInterface;
@@ -17,8 +17,8 @@ class PrincipalBackend implements BackendInterface
public const PRINCIPAL_PREFIX = 'principals'; public const PRINCIPAL_PREFIX = 'principals';
public function __construct( public function __construct(
private readonly SessionIdentity $identity, private readonly IdentityContextInterface $identityContext,
private readonly SessionTenant $tenant, private readonly TenantContextInterface $tenantContext,
) {} ) {}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@@ -27,7 +27,7 @@ class PrincipalBackend implements BackendInterface
public function getPrincipalsByPrefix($prefixPath): array public function getPrincipalsByPrefix($prefixPath): array
{ {
if ($prefixPath !== self::PRINCIPAL_PREFIX || $this->identity->identity() === null) { if ($prefixPath !== self::PRINCIPAL_PREFIX || $this->identityContext->identity() === null) {
return []; return [];
} }
@@ -36,11 +36,11 @@ class PrincipalBackend implements BackendInterface
public function getPrincipalByPath($path): ?array public function getPrincipalByPath($path): ?array
{ {
if ($this->identity->identity() === null) { if ($this->identityContext->identity() === null) {
return null; return null;
} }
$expected = self::PRINCIPAL_PREFIX . '/' . $this->identity->identifier(); $expected = self::PRINCIPAL_PREFIX . '/' . $this->identityContext->identifier();
if ($path !== $expected) { if ($path !== $expected) {
return null; return null;
} }
@@ -84,9 +84,9 @@ class PrincipalBackend implements BackendInterface
private function buildPrincipal(): array private function buildPrincipal(): array
{ {
$userId = $this->identity->identifier(); $userId = $this->identityContext->identifier();
$label = $this->identity->label() ?? $userId; $label = $this->identityContext->label() ?? $userId;
$email = $this->identity->mailAddress() ?? ''; $email = $this->identityContext->mailAddress() ?? '';
return [ return [
DavProperties::URI => self::PRINCIPAL_PREFIX . '/' . $userId, DavProperties::URI => self::PRINCIPAL_PREFIX . '/' . $userId,
+10 -10
View File
@@ -9,8 +9,8 @@ use KTXC\Http\Request\Request;
use KTXC\Http\Response\Response; use KTXC\Http\Response\Response;
use KTXC\Http\Response\StreamedResponse; use KTXC\Http\Response\StreamedResponse;
use KTXC\Service\SecurityService; use KTXC\Service\SecurityService;
use KTXC\SessionIdentity; use KTXC\Context\IdentityContextInterface;
use KTXC\SessionTenant; use KTXC\Context\TenantContextInterface;
use KTXM\ChronoManager\Conversion\IcalDecoder; use KTXM\ChronoManager\Conversion\IcalDecoder;
use KTXM\ChronoManager\Conversion\IcalEncoder; use KTXM\ChronoManager\Conversion\IcalEncoder;
use KTXM\ChronoManager\Manager as ChronoManager; use KTXM\ChronoManager\Manager as ChronoManager;
@@ -41,8 +41,8 @@ class DavServer
private const BASE_URI = '/dav/'; private const BASE_URI = '/dav/';
public function __construct( public function __construct(
private readonly SessionTenant $tenant, private readonly TenantContextInterface $tenantContext,
private readonly SessionIdentity $identity, private readonly IdentityContextInterface $identityContext,
private readonly SecurityService $securityService, private readonly SecurityService $securityService,
private readonly DocumentsManager $documentsManager, private readonly DocumentsManager $documentsManager,
private readonly ChronoManager $chronoManager, private readonly ChronoManager $chronoManager,
@@ -99,26 +99,26 @@ class DavServer
private function buildServer(): Server private function buildServer(): Server
{ {
$principalBackend = new PrincipalBackend($this->identity, $this->tenant); $principalBackend = new PrincipalBackend($this->identityContext, $this->tenantContext);
$calDavBackend = new CalDavBackend($this->chronoManager, $this->identity, $this->tenant, $this->uriMap, new IcalEncoder(), new IcalDecoder()); $calDavBackend = new CalDavBackend($this->chronoManager, $this->identityContext, $this->tenantContext, $this->uriMap, new IcalEncoder(), new IcalDecoder());
$cardDavBackend = new CardDavBackend($this->peopleManager, $this->identity, $this->tenant, $this->uriMap); $cardDavBackend = new CardDavBackend($this->peopleManager, $this->identityContext, $this->tenantContext, $this->uriMap);
$server = new Server([ $server = new Server([
new PrincipalCollection($principalBackend, PrincipalBackend::PRINCIPAL_PREFIX), new PrincipalCollection($principalBackend, PrincipalBackend::PRINCIPAL_PREFIX),
new CalendarRoot($principalBackend, $calDavBackend), new CalendarRoot($principalBackend, $calDavBackend),
new AddressBookRoot($principalBackend, $cardDavBackend), new AddressBookRoot($principalBackend, $cardDavBackend),
new FilesRootNode($this->documentsManager, $this->identity, $this->tenant), new FilesRootNode($this->documentsManager, $this->identityContext, $this->tenantContext),
]); ]);
$server->setBaseUri(self::BASE_URI); $server->setBaseUri(self::BASE_URI);
$server->debugExceptions = $this->debug; $server->debugExceptions = $this->debug;
// Authentication plugin — short-circuits when JWT/Bearer already populated // Authentication plugin — short-circuits when JWT/Bearer already populated
$authBackend = new DavAuthBackend($this->identity, $this->securityService); $authBackend = new DavAuthBackend($this->identityContext, $this->securityService);
$server->addPlugin(new AuthPlugin($authBackend)); $server->addPlugin(new AuthPlugin($authBackend));
// DAVACL — required for CalDAV / CardDAV principal resolution // DAVACL — required for CalDAV / CardDAV principal resolution
$aclPlugin = new DavACLPlugin(); $aclPlugin = new DavACLPlugin();
$userId = (string) ($this->identity->identifier() ?? 'anonymous'); $userId = (string) ($this->identityContext->identifier() ?? 'anonymous');
$aclPlugin->adminPrincipals = [PrincipalBackend::PRINCIPAL_PREFIX . '/' . $userId]; $aclPlugin->adminPrincipals = [PrincipalBackend::PRINCIPAL_PREFIX . '/' . $userId];
$server->addPlugin($aclPlugin); $server->addPlugin($aclPlugin);