Merged in feature_invite_validator (pull request #9)

Feature invite validator
This commit is contained in:
Alexey Eschenko 2018-06-30 00:05:55 +00:00
commit 390e21f44b
6 changed files with 77 additions and 26 deletions

View file

@ -5,12 +5,11 @@ namespace App\Controller;
use App\Form\{CreateUserRequestType}; use App\Form\{CreateUserRequestType};
use App\FormRequest\CreateUserRequest; use App\FormRequest\CreateUserRequest;
use App\Repository\InviteRepository; use App\Repository\InviteRepository;
use App\User\Exception\InvalidInviteException;
use App\User\{InviteManager, UserManager}; use App\User\{InviteManager, UserManager};
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\{FormError, FormInterface}; use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\{Request, Response}; use Symfony\Component\HttpFoundation\{Request, Response};
class UserController extends Controller class UserController extends Controller
@ -26,30 +25,19 @@ class UserController extends Controller
$createUserRequest = new CreateUserRequest($inviteCode); $createUserRequest = new CreateUserRequest($inviteCode);
$form = $this->createRegisterForm($createUserRequest, $inviteCode); $form = $this->createRegisterForm($createUserRequest, $inviteCode);
$inviteInvalid = false; $invite = $inviteRepo->findOneBy(['code' => $inviteCode, 'usedBy' => null]);
if (null === $invite = $inviteRepo->findOneBy(['code' => $inviteCode, 'usedBy' => null])) {
$inviteInvalid = true;
}
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
try { $user = $userManager->createUserByInvite(
$user = $userManager->createUserByInvite( $createUserRequest->username,
$createUserRequest->username, $createUserRequest->password,
$createUserRequest->password, $createUserRequest->email,
$createUserRequest->email, $invite
$invite );
);
$inviteManager->createInvitesForUser($user); $inviteManager->createInvitesForUser($user);
} catch (InvalidInviteException $ex) {
// @FIXME refactor InvalidInviteException to proper validator
$form->get('inviteCode')->addError(new FormError('Invalid invite code'));
return $this->render('User/register.html.twig', ['form' => $form->createView()]);
}
$em->flush(); $em->flush();
@ -58,7 +46,7 @@ class UserController extends Controller
return $this->render('User/register.html.twig', [ return $this->render('User/register.html.twig', [
'form' => $form->createView(), 'form' => $form->createView(),
'inviteInvalid' => $inviteInvalid, 'inviteValid' => $invite ? true : null,
]); ]);
} }

View file

@ -3,6 +3,7 @@
namespace App\FormRequest; namespace App\FormRequest;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
use App\Validator\Constraints as AppAssert;
/** /**
* @todo implement UniqueEntity constraint for DTO and use it here * @todo implement UniqueEntity constraint for DTO and use it here
@ -37,6 +38,7 @@ class CreateUserRequest
* *
* @Assert\NotBlank() * @Assert\NotBlank()
* @Assert\Length(min="32", max="32") * @Assert\Length(min="32", max="32")
* @AppAssert\ValidInvite()
*/ */
public $inviteCode; public $inviteCode;

View file

@ -2,7 +2,7 @@
namespace App\User\Exception; namespace App\User\Exception;
class InvalidInviteException extends \Exception class InvalidInviteException extends \InvalidArgumentException
{ {
protected $message = 'Invalid invite'; protected $message = 'Invalid invite';
} }

View file

@ -0,0 +1,19 @@
<?php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class ValidInvite extends Constraint
{
public $notFoundMessage = 'Invite {{ code }} not found.';
public $usedMessage = 'Invite {{ code }} is used.';
public function validatedBy(): string
{
return get_class($this).'Validator';
}
}

View file

@ -0,0 +1,42 @@
<?php
namespace App\Validator\Constraints;
use App\Entity\Invite;
use App\Repository\InviteRepository;
use Symfony\Component\Validator\{Constraint, ConstraintValidator};
class ValidInviteValidator extends ConstraintValidator
{
/** @var InviteRepository */
private $inviteRepo;
public function __construct(InviteRepository $inviteRepo)
{
$this->inviteRepo = $inviteRepo;
}
/**
* @param mixed $value
* @param ValidInvite $constraint
*/
public function validate($value, Constraint $constraint)
{
/** @var Invite $invite */
if (null === $invite = $this->inviteRepo->findOneBy(['code' => $value])) {
$this->context->buildViolation($constraint->notFoundMessage)
->setParameter('{{ code }}', $value)
->addViolation()
;
return;
}
if (null !== $invite->getUsedBy()) {
$this->context->buildViolation($constraint->usedMessage)
->setParameter('{{ code }}', $value)
->addViolation()
;
}
}
}

View file

@ -1,11 +1,11 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% block content %} {% block content %}
{% if inviteInvalid %} {% if inviteValid %}
<h1>Invalid invite</h1>
{% else %}
<div id="form-register"> <div id="form-register">
{{ form(form) }} {{ form(form) }}
</div> </div>
{% else %}
<h1>Invalid invite</h1>
{% endif %} {% endif %}
{% endblock %} {% endblock %}