auth = $auth; $this->authRequired = $authRequired; $this->isEntryPoint = $isEntryPoint; $this->showDialog = $showDialog; } protected function resolve() { $this->isResolved = true; } protected function resolveUseNoAuth() { $this->resolve(); $this->isResolvedUseNoAuth = true; } public function isResolved() : bool { return $this->isResolved; } public function isResolvedUseNoAuth() : bool { return $this->isResolvedUseNoAuth; } public function process(Request $request, Response $response) { $httpMethod = $request->getMethod(); $username = null; $password = null; if ($request->hasHeader('PHP_AUTH_USER')) { $username = $request->getHeader('PHP_AUTH_USER'); } if ($request->hasHeader('PHP_AUTH_PW')) { $password = $request->getHeader('PHP_AUTH_PW'); } $authenticationMethod = null; if ($request->hasHeader('Http-Espo-Authorization')) { $espoAuthorizationHeader = $request->getHeader('Http-Espo-Authorization'); list($username, $password) = explode(':', base64_decode($espoAuthorizationHeader), 2); } else { if ($request->hasHeader('X-Hmac-Authorization')) { $hmacAuthorizationHeader = $request->getHeader('X-Hmac-Authorization'); $authenticationMethod = 'Hmac'; list($username, $password) = explode(':', base64_decode($hmacAuthorizationHeader), 2); } else { $apiKeyHeader = $request->getHeader('X-Api-Key'); if ($apiKeyHeader) { $authenticationMethod = 'ApiKey'; $username = $apiKeyHeader; $password = null; } } } if (!isset($username)) { if ($request->getCookieParam('auth-username') && $request->getCookieParam('auth-token')) { $username = $request->getCookieParam('auth-username'); $password = $request->getCookieParam('auth-token'); } } if (!isset($username) && !isset($password)) { $espoCgiAuth = $request->getHeader('Http-Espo-Cgi-Auth'); if (!$espoCgiAuth) { $espoCgiAuth = $request->getHeader('Redirect-Http-Espo-Cgi-Auth'); } else { list($username, $password) = explode(':' , base64_decode(substr($espoCgiAuth, 6))); } } if (!$this->authRequired) { if (!$this->isEntryPoint) { if ($username && $password) { try { $isAuthenticated = $this->auth->login($username, $password); } catch (\Exception $e) { $this->processException($response, $e); return; } if ($isAuthenticated) { $this->resolve(); return; } } } $this->resolveUseNoAuth(); return; } if ($username) { try { $authResult = $this->auth->login($username, $password, $authenticationMethod); } catch (\Exception $e) { $this->processException($response, $e); } if ($authResult) { $this->handleAuthResult($response, $authResult); } else { $this->processUnauthorized($response); } } else { if (!$this->isXMLHttpRequest($request)) { $this->showDialog = true; } $this->processUnauthorized($response); } } protected function handleAuthResult(Response $response, array $authResult) { $status = $authResult['status']; if ($status === AuthUtil::STATUS_SUCCESS) { $this->resolve(); return; } if ($status === AuthUtil::STATUS_SECOND_STEP_REQUIRED) { $response->setStatus(401); $response->setHeader('X-Status-Reason', 'second-step-required'); $bodyData = [ 'status' => $status, 'message' => $authResult['message'] ?? null, 'view' => $authResult['view'] ?? null, 'token' => $authResult['token'] ?? null, ]; $response->writeBody(json_encode($bodyData)); } return; } protected function processException(Response $response, \Exception $e) { $reason = $e->getMessage(); if ($reason) { $response->setHeader('X-Status-Reason', $e->getMessage()); } $response->setStatus($e->getCode(), $reason); } protected function processUnauthorized(Response $response) { if ($this->showDialog) { $response->setHeader('WWW-Authenticate', 'Basic realm=""'); } $response->setStatus(401); } protected function isXMLHttpRequest(Request $request) { if (strtolower($request->getHeader('Http-X-Requested-With') ?? '') == 'xmlhttprequest') { return true; } return false; } }