*/ class Db extends AbstractDb { const TYPE = 'db'; protected $type = self::TYPE; /** * @var callable */ protected $credentialPreprocessor; /** * @return \ZfcUser\Entity\UserInterface|null */ protected function fetchUserObject(): ?UserInterface { $identity = $this->event->getRequest()->getPost()->get('identity'); /** @var UserInterface|null $userObject */ $userObject = null; // Cycle through the configured identity sources and test each $fields = $this->moduleOptions->getAuthIdentityFields(); while (!is_object($userObject) && count($fields) > 0) { $mode = array_shift($fields); switch ($mode) { case 'username': $userObject = $this->mapper->findByUsername($identity); break; case 'email': $userObject = $this->mapper->findByEmail($identity); break; } } if (!$userObject) { $this->event ->setCode(AuthenticationResult::FAILURE_IDENTITY_NOT_FOUND) ->setMessages([]); // NB: ne pas préciser la cause $this->setSatisfied(false); return null; } return $userObject; } /** * @param \ZfcUser\Entity\UserInterface $userObject * @return bool */ protected function authenticateUserObject(UserInterface $userObject): bool { $credential = $this->event->getRequest()->getPost()->get('credential'); $credential = $this->preProcessCredential($credential); $bcrypt = new Bcrypt(); $bcrypt->setCost($this->moduleOptions->getPasswordCost()); $ok = $bcrypt->verify($credential, $userObject->getPassword()); if (!$ok) { $this->event ->setCode(AuthenticationResult::FAILURE_CREDENTIAL_INVALID) ->setMessages([]); // NB: ne pas préciser la cause $this->setSatisfied(false); return false; } // Update user's password hash if the cost parameter has changed $this->updateUserPasswordHash($userObject, $credential, $bcrypt); return true; } protected function updateUserPasswordHash(UserInterface $userObject, $password, Bcrypt $bcrypt): self { $hash = explode('$', $userObject->getPassword()); if ($hash[2] === $bcrypt->getCost()) { return $this; } $userObject->setPassword($bcrypt->create($password)); $this->mapper->update($userObject); return $this; } public function preProcessCredential($credential) { $processor = $this->getCredentialPreprocessor(); if (is_callable($processor)) { return $processor($credential); } return $credential; } /** * Get credentialPreprocessor. * * @return callable|null */ public function getCredentialPreprocessor(): ?callable { return $this->credentialPreprocessor; } /** * Set credentialPreprocessor. * * @param callable $credentialPreprocessor * @return self */ public function setCredentialPreprocessor(callable $credentialPreprocessor): self { $this->credentialPreprocessor = $credentialPreprocessor; return $this; } }