feat: identify accounts by a uuid in the oauth2 sub claim

This commit is contained in:
fromme committed 2026-09-23 15:17:09 +02:00
1 parent cc3d32fcbb
commit bad916cfb7
6 files changed
+153 -7

No files matched your search

+23
View File
@@ -6,6 +6,7 @@ use App\Repository\UserRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: UserRepository::class)]
class User implements UserInterface, PasswordAuthenticatedUserInterface
@@ -15,6 +16,22 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\Column(type: 'integer')]
private ?int $id = null;
/**
* The account's external identifier, exported as the OAuth2 `sub` claim.
*
* Separate from the primary key on purpose: `sub` is handed to other applications, which
* store it and match their own accounts on it, so it has to be stable, unique and free of
* anything the row's position in the table implies. The auto-increment id satisfied the
* first two and neither of the last: it disclosed how many accounts exist and made one
* account's identifier a guess away from the next.
*
* v4 rather than the framework's default v7 (see config/packages/uid.yaml): v7 embeds its
* creation timestamp and sorts, which is useful for a key and is exactly the leak this
* column exists to avoid. Matches Groups\AccommodationBooking::$uuid in shape and version.
*/
#[ORM\Column(type: 'string', length: 36, unique: true)]
private string $uuid;
#[ORM\Column(type: 'string', length: 180, unique: true)]
private ?string $email;
@@ -54,6 +71,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
public function __construct(string $email)
{
$this->email = $email;
$this->uuid = Uuid::v4()->toRfc4122();
}
public function getId(): ?int
@@ -61,6 +79,11 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this->id;
}
public function getUuid(): string
{
return $this->uuid;
}
public function getEmail(): ?string
{
return $this->email;