Skip to content

Commit

Permalink
Merge branch 'release/0.4.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
matthieu2607 committed May 31, 2024
2 parents 59a5abc + 9e9a5c6 commit f52ffbb
Show file tree
Hide file tree
Showing 19 changed files with 335 additions and 103 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php
with:
Expand All @@ -31,9 +31,12 @@ jobs:

- name: Check for vulnerabilities
uses: symfonycorp/security-checker-action@v4

- name: Run Easy Coding Standard
run: vendor/bin/ecs check src
run: vendor/bin/ecs check

- name: Run phpstan
run: vendor/bin/phpstan analyse
run: vendor/bin/phpstan analyse -c phpstan.neon src

- name: Run tests
run: vendor/bin/phpunit --configuration=./tests/phpunit.xml.dist
5 changes: 5 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 0.4.0 (31/05/2024)

+ Decouple HTTP client and validator so we can verify responses outside Forms #7 (thank you ikvasnica)
- Fix TreeBuilder name #8 (thank you IndraGunawan)

## 0.3.0 (08/12/2023)

+ Allow Symfony 7 (thank you HeahDude)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A simple package to help integrate Cloudflare Turnstile on Symfony Form.
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.4-green)](https://php.net/)
[![Minimum Symfony Version](https://img.shields.io/badge/symfony-%3E%3D%205.4-green)](https://symfony.com)
[![GitHub release](https://img.shields.io/github/v/release/Pixel-Open/cloudflare-turnstile-bundle)](https://github.com/Pixel-Open/cloudflare-turnstile-bundle/releases)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/ddb39773b71a4ad2ac4bd08fbb7b09e3)](https://www.codacy.com/gh/Pixel-Open/cloudflare-turnstile-bundle/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Pixel-Open/cloudflare-turnstile-bundle&utm_campaign=Badge_Grade)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Pixel-Open_cloudflare-turnstile-bundle&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Pixel-Open_cloudflare-turnstile-bundle)

This packages provides helper for setting up and validating Cloudflare Turnstile CAPTCHA responses.

Expand Down Expand Up @@ -100,7 +100,7 @@ Use the following sitekeys and secret keys for testing purposes:

## Todo

+ Add phpunit to test field and validator
+ Add phpunit to test field ~~and validator~~

## License

Expand Down
8 changes: 7 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,16 @@
"PixelOpen\\CloudflareTurnstileBundle\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"PixelOpen\\CloudflareTurnstileBundle\\": "tests/"
}
},
"require-dev": {
"phpstan/phpstan": "^1.8",
"phpstan/phpstan-symfony": "^1.2",
"symplify/easy-coding-standard": "^11.1",
"rector/rector": "^0.14.5"
"rector/rector": "^0.14.5",
"phpunit/phpunit": "^9.6"
}
}
14 changes: 9 additions & 5 deletions ecs.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
use Symplify\EasyCodingStandard\ValueObject\Set\SetList;

return static function (ECSConfig $ecsConfig): void {
$ecsConfig->paths([__DIR__ . '/src']);
$ecsConfig->paths([
__DIR__ . '/src',
__DIR__ . '/tests',
]);
$ecsConfig->sets([SetList::PSR_12]);

$ecsConfig->ruleWithConfiguration(ArraySyntaxFixer::class, [
Expand All @@ -16,9 +19,10 @@

$ecsConfig->sets([
// run and fix, one by one
SetList::SPACES,
SetList::ARRAY,
SetList::DOCBLOCK,
SetList::PSR_12,
SetList::SPACES,
SetList::ARRAY,
SetList::DOCBLOCK,
SetList::PSR_12,
SetList::SYMPLIFY,
]);
};
8 changes: 1 addition & 7 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@ includes:
- vendor/phpstan/phpstan-symfony/extension.neon

parameters:
paths:
- src
level: 7
excludes_analyse:
- %currentWorkingDirectory%/src/DependencyInjection/Configuration.php
- %currentWorkingDirectory%/vendor/*
- %currentWorkingDirectory%/Tests/*
ignoreErrors:
- '#^Access to an undefined property Symfony\\Component\\Validator\\Constraint\:\:\$message\.$#'
- '#^Access to an undefined property Symfony\\Component\\Validator\\Constraint\:\:\$message\.$#'
77 changes: 0 additions & 77 deletions src/Constraints/CloudflareTurnstileValidator.php

This file was deleted.

3 changes: 2 additions & 1 deletion src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

declare(strict_types=1);

namespace PixelOpen\CloudflareTurnstileBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
Expand All @@ -15,7 +16,7 @@ class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder('pixelopen_cloudflare_turnstile');
$treeBuilder = new TreeBuilder('pixel_open_cloudflare_turnstile');
$rootNode = $treeBuilder->getRootNode();

$rootNode
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

declare(strict_types=1);

namespace PixelOpen\CloudflareTurnstileBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
Expand Down
58 changes: 58 additions & 0 deletions src/Http/CloudflareTurnstileHttpClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace PixelOpen\CloudflareTurnstileBundle\Http;

use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

final class CloudflareTurnstileHttpClient
{
private const SITEVERIFY_ENDPOINT = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';

private HttpClientInterface $httpClient;

private string $secret;

private LoggerInterface $logger;

public function __construct(string $secret, HttpClientInterface $httpClient, LoggerInterface $logger)
{
$this->secret = $secret;
$this->httpClient = $httpClient;
$this->logger = $logger;
}

public function verifyResponse(string $turnstileResponse): bool
{
$response = $this->httpClient->request(
Request::METHOD_POST,
self::SITEVERIFY_ENDPOINT,
[
'body' => [
'response' => $turnstileResponse,
'secret' => $this->secret,
],
]
);

try {
$content = $response->toArray();
} catch (ExceptionInterface $e) {
$this->logger->error(
\sprintf(
'Cloudflare Turnstile HTTP exception (%s) with a message: %s',
\get_class($e),
$e->getMessage(),
),
);

return false;
}

return \array_key_exists('success', $content) && $content['success'] === true;
}
}
1 change: 1 addition & 0 deletions src/PixelOpenCloudflareTurnstileBundle.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

declare(strict_types=1);

namespace PixelOpen\CloudflareTurnstileBundle;

use PixelOpen\CloudflareTurnstileBundle\PixelOpenCloudflareTurnstileCompilerPass;
Expand Down
1 change: 1 addition & 0 deletions src/PixelOpenCloudflareTurnstileCompilerPass.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

declare(strict_types=1);

namespace PixelOpen\CloudflareTurnstileBundle;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
Expand Down
11 changes: 8 additions & 3 deletions src/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ services:
$key: '%pixelopen_cloudflare_turnstile.key%'
$enable: '%pixelopen_cloudflare_turnstile.enable%'
turnstile.validator:
class: PixelOpen\CloudflareTurnstileBundle\Constraints\CloudflareTurnstileValidator
class: PixelOpen\CloudflareTurnstileBundle\Validator\CloudflareTurnstileValidator
tags: ['validator.constraint_validator']
arguments:
$secret: '%pixelopen_cloudflare_turnstile.secret%'
$enable: '%pixelopen_cloudflare_turnstile.enable%'
autowire: true
$turnstileHttpClient: '@turnstile.http_client'
autowire: true
turnstile.http_client:
class: PixelOpen\CloudflareTurnstileBundle\Http\CloudflareTurnstileHttpClient
arguments:
$secret: '%pixelopen_cloudflare_turnstile.secret%'
autowire: true
3 changes: 2 additions & 1 deletion src/Type/TurnstileType.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<?php

declare(strict_types=1);

namespace PixelOpen\CloudflareTurnstileBundle\Type;

use PixelOpen\CloudflareTurnstileBundle\Constraints\CloudflareTurnstile;
use PixelOpen\CloudflareTurnstileBundle\Validator\CloudflareTurnstile;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormInterface;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<?php

declare(strict_types=1);
namespace PixelOpen\CloudflareTurnstileBundle\Constraints;

namespace PixelOpen\CloudflareTurnstileBundle\Validator;

use Symfony\Component\Validator\Constraint;

class CloudflareTurnstile extends Constraint
final class CloudflareTurnstile extends Constraint
{
/**
* @var string
Expand Down
58 changes: 58 additions & 0 deletions src/Validator/CloudflareTurnstileValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace PixelOpen\CloudflareTurnstileBundle\Validator;

use PixelOpen\CloudflareTurnstileBundle\Http\CloudflareTurnstileHttpClient;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

final class CloudflareTurnstileValidator extends ConstraintValidator
{
private bool $enable;

private RequestStack $requestStack;

private CloudflareTurnstileHttpClient $turnstileHttpClient;

public function __construct(
bool $enable,
RequestStack $requestStack,
CloudflareTurnstileHttpClient $turnstileHttpClient
) {
$this->enable = $enable;
$this->requestStack = $requestStack;
$this->turnstileHttpClient = $turnstileHttpClient;
}

/**
* Checks if the passed value is valid.
*
* @param mixed $value The value that should be validated
* @param Constraint $constraint The constraint for the validation
*/
public function validate($value, Constraint $constraint): void
{
if ($this->enable === false) {
return;
}

$request = $this->requestStack->getCurrentRequest();
\assert($request !== null);
$turnstileResponse = (string) $request->request->get('cf-turnstile-response');

if ($turnstileResponse === '') {
$this->context->buildViolation($constraint->message)
->addviolation();

return;
}

if ($this->turnstileHttpClient->verifyResponse($turnstileResponse) === false) {
$this->context->buildViolation($constraint->message)
->addviolation();
}
}
}
Loading

0 comments on commit f52ffbb

Please sign in to comment.