-
Notifications
You must be signed in to change notification settings - Fork 486
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Internal: Add token validation system initial implementation - refs #…
- Loading branch information
1 parent
db594c2
commit 0018aea
Showing
8 changed files
with
369 additions
and
2 deletions.
There are no files selected for viewing
119 changes: 119 additions & 0 deletions
119
src/CoreBundle/Controller/ValidationTokenController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
namespace Chamilo\CoreBundle\Controller; | ||
|
||
use Chamilo\CoreBundle\Entity\ValidationToken; | ||
use Chamilo\CoreBundle\Repository\TrackEDefaultRepository; | ||
use Chamilo\CoreBundle\Repository\ValidationTokenRepository; | ||
use Chamilo\CoreBundle\ServiceHelper\ValidationTokenHelper; | ||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\Routing\Annotation\Route; | ||
use Symfony\Component\Security\Core\Security; | ||
|
||
#[Route('/validate')] | ||
class ValidationTokenController extends AbstractController | ||
{ | ||
public function __construct( | ||
private readonly ValidationTokenHelper $validationTokenHelper, | ||
private readonly ValidationTokenRepository $tokenRepository, | ||
private readonly TrackEDefaultRepository $trackEDefaultRepository, | ||
private readonly Security $security | ||
) {} | ||
|
||
#[Route('/{type}/{hash}', name: 'validate_token')] | ||
public function validate(string $type, string $hash): Response | ||
{ | ||
$token = $this->tokenRepository->findOneBy([ | ||
'type' => $this->validationTokenHelper->getTypeId($type), | ||
'hash' => $hash | ||
]); | ||
|
||
if (!$token) { | ||
throw $this->createNotFoundException('Invalid token.'); | ||
} | ||
|
||
// Process the action related to the token type | ||
$this->processAction($token); | ||
|
||
// Remove the used token | ||
$this->tokenRepository->remove($token, true); | ||
|
||
// Register the token usage event | ||
$this->registerTokenUsedEvent($token); | ||
|
||
return $this->render('@ChamiloCore/Validation/success.html.twig', [ | ||
'type' => $type, | ||
]); | ||
} | ||
|
||
#[Route('/test/generate-token/{type}/{resourceId}', name: 'test_generate_token')] | ||
public function testGenerateToken(string $type, int $resourceId): Response | ||
{ | ||
$typeId = $this->validationTokenHelper->getTypeId($type); | ||
$token = new ValidationToken($typeId, $resourceId); | ||
$this->tokenRepository->save($token, true); | ||
|
||
$validationLink = $this->generateUrl('validate_token', [ | ||
'type' => $type, | ||
'hash' => $token->getHash(), | ||
], \Symfony\Component\Routing\Generator\UrlGeneratorInterface::ABSOLUTE_URL); | ||
|
||
return new Response("Generated token: {$token->getHash()}<br>Validation link: <a href='{$validationLink}'>{$validationLink}</a>"); | ||
} | ||
|
||
private function processAction(ValidationToken $token): void | ||
{ | ||
switch ($token->getType()) { | ||
case 1: // Assuming 1 is for 'ticket' | ||
$this->processTicketValidation($token); | ||
break; | ||
case 2: // Assuming 2 is for 'user' | ||
// Implement user validation logic here | ||
break; | ||
default: | ||
throw new \InvalidArgumentException('Unrecognized token type'); | ||
} | ||
} | ||
|
||
private function processTicketValidation(ValidationToken $token): void | ||
{ | ||
$ticketId = $token->getResourceId(); | ||
|
||
// Simulate ticket validation logic | ||
// Here you would typically check if the ticket exists and is valid | ||
// For now, we'll just print a message to simulate this | ||
// Replace this with your actual ticket validation logic | ||
$ticketValid = $this->validateTicket($ticketId); | ||
|
||
if (!$ticketValid) { | ||
throw new \RuntimeException('Invalid ticket.'); | ||
} | ||
|
||
// If the ticket is valid, you can mark it as used or perform other actions | ||
// For example, update the ticket status in the database | ||
// $this->ticketRepository->markAsUsed($ticketId); | ||
} | ||
|
||
private function validateTicket(int $ticketId): bool | ||
{ | ||
// Here you would implement the logic to check if the ticket is valid. | ||
// This is a placeholder function to simulate validation. | ||
|
||
// For testing purposes, let's assume all tickets are valid. | ||
// In a real implementation, you would query your database or service. | ||
|
||
return true; // Assume the ticket is valid for now | ||
} | ||
|
||
private function registerTokenUsedEvent(ValidationToken $token): void | ||
{ | ||
$user = $this->security->getUser(); | ||
$userId = $user?->getId(); | ||
$this->trackEDefaultRepository->registerTokenUsedEvent($token, $userId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
namespace Chamilo\CoreBundle\Entity; | ||
|
||
use Chamilo\CoreBundle\Repository\ValidationTokenRepository; | ||
use Doctrine\ORM\Mapping as ORM; | ||
|
||
/** | ||
* ValidationToken entity. | ||
*/ | ||
#[ORM\Table(name: 'validation_token')] | ||
#[ORM\Index(columns: ['type', 'hash'], name: 'idx_type_hash')] | ||
#[ORM\Entity(repositoryClass: ValidationTokenRepository::class)] | ||
class ValidationToken | ||
{ | ||
#[ORM\Id] | ||
#[ORM\GeneratedValue(strategy: 'IDENTITY')] | ||
#[ORM\Column(type: 'integer')] | ||
protected ?int $id = null; | ||
|
||
#[ORM\Column(type: 'integer')] | ||
protected int $type; | ||
|
||
#[ORM\Column(type: 'bigint')] | ||
protected int $resourceId; | ||
|
||
#[ORM\Column(type: 'string', length: 64)] | ||
protected string $hash; | ||
|
||
#[ORM\Column(type: 'datetime')] | ||
protected \DateTime $createdAt; | ||
|
||
public function __construct(int $type, int $resourceId) | ||
{ | ||
$this->type = $type; | ||
$this->resourceId = $resourceId; | ||
$this->hash = hash('sha256', uniqid((string) rand(), true)); | ||
$this->createdAt = new \DateTime(); | ||
} | ||
|
||
public function getId(): ?int | ||
{ | ||
return $this->id; | ||
} | ||
|
||
public function getType(): int | ||
{ | ||
return $this->type; | ||
} | ||
|
||
public function setType(int $type): self | ||
{ | ||
$this->type = $type; | ||
return $this; | ||
} | ||
|
||
public function getResourceId(): int | ||
{ | ||
return $this->resourceId; | ||
} | ||
|
||
public function setResourceId(int $resourceId): self | ||
{ | ||
$this->resourceId = $resourceId; | ||
return $this; | ||
} | ||
|
||
public function getHash(): string | ||
{ | ||
return $this->hash; | ||
} | ||
|
||
public function getCreatedAt(): \DateTime | ||
{ | ||
return $this->createdAt; | ||
} | ||
|
||
public function setCreatedAt(\DateTime $createdAt): self | ||
{ | ||
$this->createdAt = $createdAt; | ||
return $this; | ||
} | ||
|
||
/** | ||
* Genera un enlace de validación. | ||
*/ | ||
public static function generateLink(int $type, int $resourceId): string | ||
{ | ||
$token = new self($type, $resourceId); | ||
return '/validate/' . $type . '/' . $token->getHash(); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/CoreBundle/Migrations/Schema/V200/Version20241211183300.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
namespace Chamilo\CoreBundle\Migrations\Schema\V200; | ||
|
||
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo; | ||
use Doctrine\DBAL\Schema\Schema; | ||
|
||
final class Version20241211183300 extends AbstractMigrationChamilo | ||
{ | ||
public function getDescription(): string | ||
{ | ||
return 'Migration for creating the validation_token table'; | ||
} | ||
|
||
public function up(Schema $schema): void | ||
{ | ||
if (!$schema->hasTable('validation_token')) { | ||
$this->addSql(" | ||
CREATE TABLE validation_token ( | ||
id INT AUTO_INCREMENT NOT NULL, | ||
type INT NOT NULL, | ||
resource_id BIGINT NOT NULL, | ||
hash CHAR(64) NOT NULL, | ||
created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime)', | ||
INDEX idx_type_hash (type, hash), | ||
PRIMARY KEY(id) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB ROW_FORMAT = DYNAMIC | ||
"); | ||
} | ||
} | ||
|
||
public function down(Schema $schema): void | ||
{ | ||
if ($schema->hasTable('validation_token')) { | ||
$this->addSql('DROP TABLE validation_token'); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
namespace Chamilo\CoreBundle\Repository; | ||
|
||
use Chamilo\CoreBundle\Entity\ValidationToken; | ||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; | ||
use Doctrine\Persistence\ManagerRegistry; | ||
|
||
class ValidationTokenRepository extends ServiceEntityRepository | ||
{ | ||
public function __construct(ManagerRegistry $registry) | ||
{ | ||
parent::__construct($registry, ValidationToken::class); | ||
} | ||
|
||
public function save(ValidationToken $entity, bool $flush = false): void | ||
{ | ||
$this->getEntityManager()->persist($entity); | ||
|
||
if ($flush) { | ||
$this->getEntityManager()->flush(); | ||
} | ||
} | ||
|
||
public function remove(ValidationToken $entity, bool $flush = false): void | ||
{ | ||
$this->getEntityManager()->remove($entity); | ||
|
||
if ($flush) { | ||
$this->getEntityManager()->flush(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{% extends "@ChamiloCore/Layout/layout_one_col.html.twig" %} | ||
|
||
{% block content %} | ||
<h1>Validation Successful</h1> | ||
<p>The token for {{ type }} has been successfully validated.</p> | ||
{% endblock %} |
Oops, something went wrong.