diff --git a/application/Espo/Core/Api/Auth.php b/application/Espo/Core/Api/Auth.php index cff30b6fa7..5407098f09 100644 --- a/application/Espo/Core/Api/Auth.php +++ b/application/Espo/Core/Api/Auth.php @@ -55,15 +55,23 @@ class Auth protected $authRequired; + protected $isEntryPoint = false; + private $isResolved = false; private $isResolvedUseNoAuth = false; - public function __construct(Authentication $authentication, bool $authRequired = true, bool $isEntryPoint = false) + public function __construct(Authentication $authentication, bool $authRequired = true) { $this->authentication = $authentication; $this->authRequired = $authRequired; - $this->isEntryPoint = $isEntryPoint; + } + + public function createForEntryPoint(Authentication $authentication, bool $authRequired = true) + { + $instance = new Auth($authentication, $authRequired); + $instance->isEntryPoint = true; + return $instance; } protected function resolve() diff --git a/application/Espo/Core/Api/EntryPoint.php b/application/Espo/Core/Api/EntryPoint.php new file mode 100644 index 0000000000..74064e5cb9 --- /dev/null +++ b/application/Espo/Core/Api/EntryPoint.php @@ -0,0 +1,95 @@ +entryPointManager = $entryPointManager; + $this->applicationUser = $applicationUser; + $this->authRequired = $authRequired; + $this->authNotStrict = $authNotStrict; + $this->entryPoint = $entryPoint; + $this->data = $data; + } + + public function process(string $entryPoint, Request $request, Response $response, ?StdClass $data) + { + $authentication = $this->injectableFactory->createWith(Authentication::class, [ + 'allowAnyAccess' => $this->authNotStrict, + ]); + + $apiAuth = ApiAuth::createForEntryPoint($authentication, $this->authRequired); + + $apiAuth->process($request, $response); + + if (!$apiAuth->isResolved()) { + return; + } + if ($apiAuth->isResolvedUseNoAuth()) { + $this->applicationUser->setupSystemUser(); + } + + ob_start(); + $this->entryPointManager->run($entryPoint, $request, $response, $data); + $contents = ob_get_clean(); + + if ($contents) { + $response->writeBody($contents); + } + } +} diff --git a/application/Espo/Core/ApplicationRunners/EntryPoint.php b/application/Espo/Core/ApplicationRunners/EntryPoint.php index 761e50654e..0f5fcf8174 100644 --- a/application/Espo/Core/ApplicationRunners/EntryPoint.php +++ b/application/Espo/Core/ApplicationRunners/EntryPoint.php @@ -66,14 +66,20 @@ use StdClass; class EntryPoint implements ApplicationRunner { protected $injectableFactory; + protected $entryPointManager; protected $entityManager; protected $clientManager; protected $applicationUser; public function __construct( - InjectableFactory $injectableFactory, EntityManager $entityManager, ClientManager $clientManager, ApplicationUser $applicationUser + InjectableFactory $injectableFactory, + EntryPointManager $entryPointManager, + EntityManager $entityManager, + ClientManager $clientManager, + ApplicationUser $applicationUser ) { $this->injectableFactory = $injectableFactory; + $this->entryPointManager = $entryPointManager; $this->entityManager = $entityManager; $this->clientManager = $clientManager; $this->applicationUser = $applicationUser; @@ -88,22 +94,17 @@ class EntryPoint implements ApplicationRunner $final = $params->final ?? false; $data = $params->data ?? null; - if (!$entryPoint) throw new Error(); + if (!$entryPoint) { + throw new Error(); + } - $entryPointManager = $this->injectableFactory->create(EntryPointManager::class); - - $authRequired = $entryPointManager->checkAuthRequired($entryPoint); - $authNotStrict = $entryPointManager->checkNotStrictAuth($entryPoint); + $authRequired = $this->entryPointManager->checkAuthRequired($entryPoint); + $authNotStrict = $this->entryPointManager->checkNotStrictAuth($entryPoint); if ($authRequired && !$authNotStrict && !$final) { - if ($portalId = $this->detectPortalId()) { - $app = new PortalApplication($portalId); - $app->setClientBasePath($this->clientManager->getBasePath()); - $app->run(EntryPoint::class, (object) [ - 'entryPoint' => $entryPoint, - 'data' => $data, - 'final' => true, - ]); + $portalId = $this->detectPortalId(); + if ($portalId) { + $this->runThroughPortal($portalId, $entryPoint, $data); return; } } @@ -113,37 +114,12 @@ class EntryPoint implements ApplicationRunner $slim->add( function (Psr7Request $request, Psr7RequestHandler $handler) use ( - $entryPointManager, $entryPoint, $data, $authRequired, $authNotStrict, $slim + $entryPoint, $data, $authRequired, $authNotStrict, $slim ) : Psr7Response { $requestWrapped = new RequestWrapper($request, $slim->getBasePath()); $responseWrapped = new ResponseWrapper($handler->handle($request)); - try { - $authentication = $this->injectableFactory->createWith(Authentication::class, [ - 'allowAnyAccess' => $authNotStrict, - ]); - - $apiAuth = new ApiAuth($authentication, $authRequired, true); - - $apiAuth->process($requestWrapped, $responseWrapped); - - if (!$apiAuth->isResolved()) { - return $responseWrapped->getResponse(); - } - if ($apiAuth->isResolvedUseNoAuth()) { - $this->applicationUser->setupSystemUser(); - } - - ob_start(); - $entryPointManager->run($entryPoint, $requestWrapped, $responseWrapped, $data); - $contents = ob_get_clean(); - - if ($contents) { - $responseWrapped->writeBody($contents); - } - } catch (\Exception $e) { - (new ApiErrorOutput($requestWrapped))->process($responseWrapped, $e, true); - } + $this->processRequest($entryPoint, $requestWrapped, $responseWrapped, $data, $authRequired, $authNotStrict); return $responseWrapped->getResponse(); } @@ -156,6 +132,43 @@ class EntryPoint implements ApplicationRunner $slim->run(); } + protected function processRequest( + string $entryPoint, + RequestWrapper $requestWrapped, + ResponseWrapper $responseWrapped, + ?StdClass $data, + bool $authRequired, + bool $authNotStrict + ) { + try { + $authentication = $this->injectableFactory->createWith(Authentication::class, [ + 'allowAnyAccess' => $authNotStrict, + ]); + + $apiAuth = ApiAuth::createForEntryPoint($authentication, $authRequired); + + $apiAuth->process($requestWrapped, $responseWrapped); + + if (!$apiAuth->isResolved()) { + return; + } + + if ($apiAuth->isResolvedUseNoAuth()) { + $this->applicationUser->setupSystemUser(); + } + + ob_start(); + $this->entryPointManager->run($entryPoint, $requestWrapped, $responseWrapped, $data); + $contents = ob_get_clean(); + + if ($contents) { + $responseWrapped->writeBody($contents); + } + } catch (\Exception $e) { + (new ApiErrorOutput($requestWrapped))->process($responseWrapped, $e, true); + } + } + protected function detectPortalId() : ?string { if (!empty($_GET['portalId'])) { @@ -170,4 +183,15 @@ class EntryPoint implements ApplicationRunner } return null; } + + protected function runThroughPortal(string $portalId, string $entryPoint, ?StdClass $data) + { + $app = new PortalApplication($portalId); + $app->setClientBasePath($this->clientManager->getBasePath()); + $app->run(EntryPoint::class, (object) [ + 'entryPoint' => $entryPoint, + 'data' => $data, + 'final' => true, + ]); + } } diff --git a/application/Espo/Resources/metadata/app/containerServices.json b/application/Espo/Resources/metadata/app/containerServices.json index 4108059286..a50bde5a22 100644 --- a/application/Espo/Resources/metadata/app/containerServices.json +++ b/application/Espo/Resources/metadata/app/containerServices.json @@ -50,6 +50,9 @@ "hookManager": { "className": "Espo\\Core\\HookManager" }, + "entryPointManager": { + "className": "Espo\\Core\\EntryPointManager" + }, "notificatorFactory": { "className": "Espo\\Core\\NotificatorFactory" },