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;
use KTXC\Service\SecurityService;
use KTXC\SessionIdentity;
use KTXC\Context\IdentityContext;
use Sabre\DAV\Auth\Backend\AbstractBasic;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
@@ -15,7 +15,7 @@ class DavAuthBackend extends AbstractBasic
public const PRINCIPAL_PREFIX = 'principals/';
public function __construct(
private readonly SessionIdentity $identity,
private readonly IdentityContext $identityContext,
private readonly SecurityService $securityService,
string $realm = 'KTXC DAV',
) {
@@ -24,8 +24,8 @@ class DavAuthBackend extends AbstractBasic
public function check(RequestInterface $request, ResponseInterface $response): array
{
if ($this->identity->identity() !== null) {
$userId = $this->identity->identifier();
if ($this->identityContext->identity() !== null) {
$userId = $this->identityContext->identifier();
return [true, self::PRINCIPAL_PREFIX . $userId];
}
@@ -39,7 +39,7 @@ class DavAuthBackend extends AbstractBasic
return false;
}
$this->identity->initialize($user, false);
$this->identityContext->initialize($user);
return true;
}
}
+15 -15
View File
@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace KTXM\ServiceDav\Backends;
use KTXC\SessionIdentity;
use KTXC\SessionTenant;
use KTXC\Context\IdentityContextInterface;
use KTXC\Context\TenantContextInterface;
use KTXF\Chrono\Entity\JournalObject;
use KTXF\Chrono\Entity\TaskObject;
use KTXM\ChronoManager\Conversion\IcalDecoder;
@@ -39,8 +39,8 @@ class CalDavBackend extends AbstractBackend
public function __construct(
private readonly ChronoManager $manager,
private readonly SessionIdentity $identity,
private readonly SessionTenant $tenant,
private readonly IdentityContextInterface $identityContext,
private readonly TenantContextInterface $tenantContext,
private readonly DavUriMap $uriMap,
private readonly IcalEncoder $encoder,
private readonly IcalDecoder $decoder,
@@ -50,7 +50,7 @@ class CalDavBackend extends AbstractBackend
{
$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 ($providerServices as $serviceId => $collections) {
@@ -93,8 +93,8 @@ class CalDavBackend extends AbstractBackend
public function getCalendarObjects($calendarId): array
{
[$providerId, $serviceId, $collectionId] = $this->parseId($calendarId);
$tenantId = $this->tenant->identifier();
$userId = $this->identity->identifier();
$tenantId = $this->tenantContext->identifier();
$userId = $this->identityContext->identifier();
$targets = ResourceIdentifiers::fromArray([$calendarId]);
$all = $this->manager->entityListBulk($tenantId, $userId, $targets);
@@ -127,8 +127,8 @@ class CalDavBackend extends AbstractBackend
public function getCalendarObject($calendarId, $objectUri): ?array
{
[$providerId, $serviceId, $collectionId] = $this->parseId($calendarId);
$tenantId = $this->tenant->identifier();
$userId = $this->identity->identifier();
$tenantId = $this->tenantContext->identifier();
$userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $calendarId);
// 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
{
[$providerId, $serviceId, $collectionId] = $this->parseId($calendarId);
$tenantId = $this->tenant->identifier();
$userId = $this->identity->identifier();
$tenantId = $this->tenantContext->identifier();
$userId = $this->identityContext->identifier();
$vcal = Reader::read($calendarData);
$props = $this->icalToEntityProps($vcal);
@@ -190,8 +190,8 @@ class CalDavBackend extends AbstractBackend
public function updateCalendarObject($calendarId, $objectUri, $calendarData): ?string
{
[$providerId, $serviceId, $collectionId] = $this->parseId($calendarId);
$tenantId = $this->tenant->identifier();
$userId = $this->identity->identifier();
$tenantId = $this->tenantContext->identifier();
$userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $calendarId);
$entityId = $this->uriMap->getEntityId($mapId, $objectUri)
@@ -210,8 +210,8 @@ class CalDavBackend extends AbstractBackend
public function deleteCalendarObject($calendarId, $objectUri): void
{
[$providerId, $serviceId, $collectionId] = $this->parseId($calendarId);
$tenantId = $this->tenant->identifier();
$userId = $this->identity->identifier();
$tenantId = $this->tenantContext->identifier();
$userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $calendarId);
$entityId = $this->uriMap->getEntityId($mapId, $objectUri)
+15 -15
View File
@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace KTXM\ServiceDav\Backends;
use KTXC\SessionIdentity;
use KTXC\SessionTenant;
use KTXC\Context\IdentityContextInterface;
use KTXC\Context\TenantContextInterface;
use KTXF\Resource\Identifier\CollectionIdentifier;
use KTXF\Resource\Identifier\EntityIdentifier;
use KTXF\Resource\Identifier\ResourceIdentifiers;
@@ -32,8 +32,8 @@ class CardDavBackend extends AbstractBackend
public function __construct(
private readonly PeopleManager $manager,
private readonly SessionIdentity $identity,
private readonly SessionTenant $tenant,
private readonly IdentityContextInterface $identityContext,
private readonly TenantContextInterface $tenantContext,
private readonly DavUriMap $uriMap,
) {}
@@ -46,7 +46,7 @@ class CardDavBackend extends AbstractBackend
$result = [];
// 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 ($providerServices as $serviceId => $collections) {
@@ -94,8 +94,8 @@ class CardDavBackend extends AbstractBackend
public function getCards($addressBookId): array
{
$tenantId = $this->tenant->identifier();
$userId = $this->identity->identifier();
$tenantId = $this->tenantContext->identifier();
$userId = $this->identityContext->identifier();
$targets = ResourceIdentifiers::fromArray([$addressBookId]);
@@ -134,8 +134,8 @@ class CardDavBackend extends AbstractBackend
public function getCard($addressBookId, $cardUri): ?array
{
[$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId);
$tenantId = $this->tenant->identifier();
$userId = $this->identity->identifier();
$tenantId = $this->tenantContext->identifier();
$userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $addressBookId);
$entityId = $this->uriMap->getEntityId($mapId, $cardUri)
@@ -172,8 +172,8 @@ class CardDavBackend extends AbstractBackend
public function createCard($addressBookId, $cardUri, $cardData): ?string
{
[$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId);
$tenantId = $this->tenant->identifier();
$userId = $this->identity->identifier();
$tenantId = $this->tenantContext->identifier();
$userId = $this->identityContext->identifier();
$vcard = Reader::read($cardData);
$props = $this->vcardToEntityProps($vcard);
@@ -192,8 +192,8 @@ class CardDavBackend extends AbstractBackend
public function updateCard($addressBookId, $cardUri, $cardData): ?string
{
[$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId);
$tenantId = $this->tenant->identifier();
$userId = $this->identity->identifier();
$tenantId = $this->tenantContext->identifier();
$userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $addressBookId);
$entityId = $this->uriMap->getEntityId($mapId, $cardUri)
@@ -210,8 +210,8 @@ class CardDavBackend extends AbstractBackend
public function deleteCard($addressBookId, $cardUri): bool
{
[$providerId, $serviceId, $collectionId] = $this->parseId($addressBookId);
$tenantId = $this->tenant->identifier();
$userId = $this->identity->identifier();
$tenantId = $this->tenantContext->identifier();
$userId = $this->identityContext->identifier();
$mapId = $this->mapId($tenantId, $userId, $addressBookId);
$entityId = $this->uriMap->getEntityId($mapId, $cardUri)
+5 -5
View File
@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace KTXM\ServiceDav\Backends;
use KTXC\SessionIdentity;
use KTXC\SessionTenant;
use KTXC\Context\IdentityContextInterface;
use KTXC\Context\TenantContextInterface;
use KTXM\DocumentsManager\Manager as DocumentsManager;
use Sabre\DAV\Collection;
use Sabre\DAV\Exception\Forbidden;
@@ -23,8 +23,8 @@ class FilesRootNode extends Collection
{
public function __construct(
private readonly DocumentsManager $manager,
private readonly SessionIdentity $identity,
private readonly SessionTenant $tenant,
private readonly IdentityContextInterface $identityContext,
private readonly TenantContextInterface $tenantContext,
) {}
public function getName(): string
@@ -36,7 +36,7 @@ class FilesRootNode extends Collection
public function getChildren(): array
{
$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 ($providerServices as $serviceId => $service) {
+10 -10
View File
@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace KTXM\ServiceDav\Backends;
use KTXC\SessionIdentity;
use KTXC\SessionTenant;
use KTXC\Context\IdentityContextInterface;
use KTXC\Context\TenantContextInterface;
use KTXM\ServiceDav\DavProperties;
use Sabre\DAVACL\PrincipalBackend\BackendInterface;
@@ -17,8 +17,8 @@ class PrincipalBackend implements BackendInterface
public const PRINCIPAL_PREFIX = 'principals';
public function __construct(
private readonly SessionIdentity $identity,
private readonly SessionTenant $tenant,
private readonly IdentityContextInterface $identityContext,
private readonly TenantContextInterface $tenantContext,
) {}
// -------------------------------------------------------------------------
@@ -27,7 +27,7 @@ class PrincipalBackend implements BackendInterface
public function getPrincipalsByPrefix($prefixPath): array
{
if ($prefixPath !== self::PRINCIPAL_PREFIX || $this->identity->identity() === null) {
if ($prefixPath !== self::PRINCIPAL_PREFIX || $this->identityContext->identity() === null) {
return [];
}
@@ -36,11 +36,11 @@ class PrincipalBackend implements BackendInterface
public function getPrincipalByPath($path): ?array
{
if ($this->identity->identity() === null) {
if ($this->identityContext->identity() === null) {
return null;
}
$expected = self::PRINCIPAL_PREFIX . '/' . $this->identity->identifier();
$expected = self::PRINCIPAL_PREFIX . '/' . $this->identityContext->identifier();
if ($path !== $expected) {
return null;
}
@@ -84,9 +84,9 @@ class PrincipalBackend implements BackendInterface
private function buildPrincipal(): array
{
$userId = $this->identity->identifier();
$label = $this->identity->label() ?? $userId;
$email = $this->identity->mailAddress() ?? '';
$userId = $this->identityContext->identifier();
$label = $this->identityContext->label() ?? $userId;
$email = $this->identityContext->mailAddress() ?? '';
return [
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\StreamedResponse;
use KTXC\Service\SecurityService;
use KTXC\SessionIdentity;
use KTXC\SessionTenant;
use KTXC\Context\IdentityContextInterface;
use KTXC\Context\TenantContextInterface;
use KTXM\ChronoManager\Conversion\IcalDecoder;
use KTXM\ChronoManager\Conversion\IcalEncoder;
use KTXM\ChronoManager\Manager as ChronoManager;
@@ -41,8 +41,8 @@ class DavServer
private const BASE_URI = '/dav/';
public function __construct(
private readonly SessionTenant $tenant,
private readonly SessionIdentity $identity,
private readonly TenantContextInterface $tenantContext,
private readonly IdentityContextInterface $identityContext,
private readonly SecurityService $securityService,
private readonly DocumentsManager $documentsManager,
private readonly ChronoManager $chronoManager,
@@ -99,26 +99,26 @@ class DavServer
private function buildServer(): Server
{
$principalBackend = new PrincipalBackend($this->identity, $this->tenant);
$calDavBackend = new CalDavBackend($this->chronoManager, $this->identity, $this->tenant, $this->uriMap, new IcalEncoder(), new IcalDecoder());
$cardDavBackend = new CardDavBackend($this->peopleManager, $this->identity, $this->tenant, $this->uriMap);
$principalBackend = new PrincipalBackend($this->identityContext, $this->tenantContext);
$calDavBackend = new CalDavBackend($this->chronoManager, $this->identityContext, $this->tenantContext, $this->uriMap, new IcalEncoder(), new IcalDecoder());
$cardDavBackend = new CardDavBackend($this->peopleManager, $this->identityContext, $this->tenantContext, $this->uriMap);
$server = new Server([
new PrincipalCollection($principalBackend, PrincipalBackend::PRINCIPAL_PREFIX),
new CalendarRoot($principalBackend, $calDavBackend),
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->debugExceptions = $this->debug;
// 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));
// DAVACL — required for CalDAV / CardDAV principal resolution
$aclPlugin = new DavACLPlugin();
$userId = (string) ($this->identity->identifier() ?? 'anonymous');
$userId = (string) ($this->identityContext->identifier() ?? 'anonymous');
$aclPlugin->adminPrincipals = [PrincipalBackend::PRINCIPAL_PREFIX . '/' . $userId];
$server->addPlugin($aclPlugin);