Skip to content

Commit 7c3302f

Browse files
committed
fix: let user API key migration run on populated databases
Version20260702123347 added user.api_key as NOT NULL and then put a unique index on it, so every existing user got the same empty string and the index collided on the second row. Any database holding more than one user failed to migrate. Generate a key for each existing user before creating the index, matching App\Entity\User::__construct, which gives every user created since #88 a key of its own. The keys come from PHP rather than SQL because they are credentials and SQL's RAND() and UUID() are not cryptographically secure.
1 parent ca17d7e commit 7c3302f

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
- [#90](https://github.com/itk-dev/devops_itksites/pull/90)
11+
- Fixed user API key migration failing on databases with more than one user
12+
- Generated an API key for existing users, as users created since already get
13+
- Added users to the fixtures and a CI job running migrations on a populated
14+
database
1015
- [#89](https://github.com/itk-dev/devops_itksites/pull/89)
1116
Added `--rm` to `docker compose run` in prod deployment
1217
- [#88](https://github.com/itk-dev/devops_itksites/pull/88)

migrations/Version20260702123347.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,20 @@ public function getDescription(): string
1919

2020
public function up(Schema $schema): void
2121
{
22-
// this up() migration is auto-generated, please modify it to your needs
22+
// Adding the column gives every existing user the same empty string,
23+
// which collides on the unique index below as soon as a second user
24+
// exists, so give each of them a key of their own first. Users created
25+
// from here on get one from App\Entity\User::__construct.
26+
//
27+
// The keys are generated in PHP because they are credentials and have
28+
// to come from a cryptographically secure source. SQL's RAND() and
29+
// UUID() are not one.
2330
$this->addSql('ALTER TABLE user ADD api_key VARCHAR(255) NOT NULL');
31+
32+
foreach ($this->connection->fetchFirstColumn('SELECT email FROM user') as $email) {
33+
$this->addSql('UPDATE user SET api_key = ? WHERE email = ?', [sha1(\random_bytes(40)), $email]);
34+
}
35+
2436
$this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D649C912ED9D ON user (api_key)');
2537
}
2638

0 commit comments

Comments
 (0)