52 lines
1.9 KiB
PHP
52 lines
1.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace DoctrineMigrations;
|
|
|
|
use Doctrine\DBAL\Schema\Schema;
|
|
use Doctrine\Migrations\AbstractMigration;
|
|
use Symfony\Component\Uid\Uuid;
|
|
|
|
/**
|
|
* Gives every account a uuid, which replaces the primary key as the OAuth2 `sub` claim.
|
|
*
|
|
* The UUIDs are generated here in PHP rather than with MariaDB's UUID(): that function
|
|
* returns v1, which encodes a timestamp and the server's node id, so a whole backfill
|
|
* would come out time-ordered and share a suffix. Guessing one account's identifier from
|
|
* another's is the property this column exists to remove, so the backfill has to be as
|
|
* random as the ones App\Entity\User generates from now on.
|
|
*
|
|
* One statement per row, which is why it is emitted rather than written out: the values
|
|
* cannot exist before the migration runs. Added nullable and tightened afterwards, since
|
|
* there is no single default that could satisfy a unique column.
|
|
*/
|
|
final class Version20260923150000 extends AbstractMigration
|
|
{
|
|
public function getDescription(): string
|
|
{
|
|
return 'Adds user.uuid and backfills it; the OAuth2 sub claim moves off the primary key.';
|
|
}
|
|
|
|
public function up(Schema $schema): void
|
|
{
|
|
$this->addSql('ALTER TABLE user ADD uuid VARCHAR(36) DEFAULT NULL');
|
|
|
|
foreach ($this->connection->fetchFirstColumn('SELECT id FROM user') as $id) {
|
|
$this->addSql('UPDATE user SET uuid = :uuid WHERE id = :id', [
|
|
'uuid' => Uuid::v4()->toRfc4122(),
|
|
'id' => $id,
|
|
]);
|
|
}
|
|
|
|
$this->addSql('ALTER TABLE user MODIFY uuid VARCHAR(36) NOT NULL');
|
|
$this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D649D17F50A6 ON user (uuid)');
|
|
}
|
|
|
|
public function down(Schema $schema): void
|
|
{
|
|
$this->addSql('DROP INDEX UNIQ_8D93D649D17F50A6 ON user');
|
|
$this->addSql('ALTER TABLE user DROP uuid');
|
|
}
|
|
}
|