* * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */ namespace CodeIgniter\Honeypot; use CodeIgniter\Honeypot\Exceptions\HoneypotException; use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use Config\Honeypot as HoneypotConfig; /** * class Honeypot * * @see \CodeIgniter\Honeypot\HoneypotTest */ class Honeypot { /** * Our configuration. * * @var HoneypotConfig */ protected $config; /** * Constructor. * * @throws HoneypotException */ public function __construct(HoneypotConfig $config) { $this->config = $config; if (! $this->config->hidden) { throw HoneypotException::forNoHiddenValue(); } if ($this->config->container === '' || strpos($this->config->container, '{template}') === false) { $this->config->container = '
{template}
'; } $this->config->containerId ??= 'hpc'; if ($this->config->template === '') { throw HoneypotException::forNoTemplate(); } if ($this->config->name === '') { throw HoneypotException::forNoNameField(); } } /** * Checks the request if honeypot field has data. * * @return bool */ public function hasContent(RequestInterface $request) { assert($request instanceof IncomingRequest); return ! empty($request->getPost($this->config->name)); } /** * Attaches Honeypot template to response. * * @return void */ public function attachHoneypot(ResponseInterface $response) { if ($response->getBody() === null) { return; } if ($response->getCSP()->enabled()) { // Add id attribute to the container tag. $this->config->container = str_ireplace( '>{template}', ' id="' . $this->config->containerId . '">{template}', $this->config->container ); } $prepField = $this->prepareTemplate($this->config->template); $bodyBefore = $response->getBody(); $bodyAfter = str_ireplace('', $prepField . '', $bodyBefore); if ($response->getCSP()->enabled() && ($bodyBefore !== $bodyAfter)) { // Add style tag for the container tag in the head tag. $style = ''; $bodyAfter = str_ireplace('', $style . '', $bodyAfter); } $response->setBody($bodyAfter); } /** * Prepares the template by adding label * content and field name. */ protected function prepareTemplate(string $template): string { $template = str_ireplace('{label}', $this->config->label, $template); $template = str_ireplace('{name}', $this->config->name, $template); if ($this->config->hidden) { $template = str_ireplace('{template}', $template, $this->config->container); } return $template; } }