Merge pull request 'Promote beta: local-only dev setup and notes' (#2) from beta into main
This commit was merged in pull request #2.
This commit is contained in:
commit
4c847267ea
1 file changed
+81
@@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* DEV ONLY -- idempotent upsert of the two standing test logins:
|
||||||
|
* sysadmin@mail.pt (role sysadmin) admin@mail.pt (role admin) password: 123
|
||||||
|
*
|
||||||
|
* CLI only. Fails closed: refuses unless APP_ENV is a development value AND the
|
||||||
|
* DB host is the dev server (192.168.1.3:3181) or localhost. Never run in prod.
|
||||||
|
* php scripts/dev_accounts.php
|
||||||
|
*/
|
||||||
|
if (PHP_SAPI !== 'cli') { http_response_code(404); exit; }
|
||||||
|
|
||||||
|
// ---- per-project schema (edit only this block) -----------------------------
|
||||||
|
$T = [
|
||||||
|
'table' => 'users', 'id' => 'id', 'email' => 'email', 'name' => 'name',
|
||||||
|
'password' => 'password_hash', 'role' => 'role',
|
||||||
|
'flags' => ['is_active' => 1], // column => value that lets login work (insert AND update)
|
||||||
|
'extra' => [], // column => value for new rows only; '{email}' is substituted
|
||||||
|
'roles' => ['sysadmin@mail.pt' => 'sysadmin', 'admin@mail.pt' => 'admin'],
|
||||||
|
];
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const DEV_PASSWORD = '123';
|
||||||
|
function dev_fail(string $m): never { fwrite(STDERR, "REFUSED: $m\n"); exit(1); }
|
||||||
|
|
||||||
|
$root = dirname(__DIR__);
|
||||||
|
$envFile = $root . '/.env';
|
||||||
|
if (!is_file($envFile)) dev_fail('.env not found');
|
||||||
|
$env = [];
|
||||||
|
foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $l) {
|
||||||
|
$l = trim($l);
|
||||||
|
if ($l === '' || $l[0] === '#' || !str_contains($l, '=')) continue;
|
||||||
|
[$k, $v] = explode('=', $l, 2);
|
||||||
|
$v = trim($v);
|
||||||
|
if ($v !== '' && $v[0] !== '"' && $v[0] !== "'" && ($h = strpos($v, ' #')) !== false) $v = rtrim(substr($v, 0, $h));
|
||||||
|
$env[trim($k)] = trim($v, " \"'");
|
||||||
|
}
|
||||||
|
foreach (array_keys($env) as $k) { if (($r = getenv($k)) !== false) $env[$k] = $r; } // real env wins, like the app
|
||||||
|
|
||||||
|
$appEnv = strtolower($env['APP_ENV'] ?? '');
|
||||||
|
if (!in_array($appEnv, ['dev', 'development', 'local'], true)) dev_fail('APP_ENV is not dev');
|
||||||
|
$host = strtolower($env['DB_HOST'] ?? ''); $port = (int) ($env['DB_PORT'] ?? 3306);
|
||||||
|
$ok = in_array($host, ['localhost', '127.0.0.1', '::1'], true) || ($host === '192.168.1.3' && $port === 3181);
|
||||||
|
if (!$ok) dev_fail('DB host is not the dev server');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new PDO("mysql:host=$host;port=$port;dbname={$env['DB_NAME']};charset=utf8mb4", $env['DB_USER'] ?? '', $env['DB_PASS'] ?? '',
|
||||||
|
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
|
||||||
|
} catch (Throwable $e) { dev_fail('DB connect failed'); }
|
||||||
|
|
||||||
|
$q = fn(string $c) => '`' . str_replace('`', '', $c) . '`';
|
||||||
|
$cols = $pdo->prepare('SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?');
|
||||||
|
$cols->execute([$T['table']]);
|
||||||
|
$have = $cols->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
$need = array_merge([$T['email'], $T['password'], $T['role']], array_keys($T['flags']), array_keys($T['extra']));
|
||||||
|
if ($T['name']) $need[] = $T['name'];
|
||||||
|
$missing = array_diff($need, $have);
|
||||||
|
if (!$have) dev_fail("table {$T['table']} missing (schema behind)");
|
||||||
|
if ($missing) dev_fail('schema behind, missing columns: ' . implode(', ', $missing));
|
||||||
|
|
||||||
|
$hash = password_hash(DEV_PASSWORD, PASSWORD_DEFAULT);
|
||||||
|
foreach ($T['roles'] as $email => $role) {
|
||||||
|
$set = [$T['password'] => $hash, $T['role'] => $role] + $T['flags'];
|
||||||
|
$s = $pdo->prepare("SELECT {$q($T['id'])} FROM {$q($T['table'])} WHERE {$q($T['email'])} = ? LIMIT 1");
|
||||||
|
$s->execute([$email]);
|
||||||
|
$id = $s->fetchColumn();
|
||||||
|
if ($id !== false) {
|
||||||
|
$sql = "UPDATE {$q($T['table'])} SET " . implode(', ', array_map(fn($c) => $q($c) . ' = ?', array_keys($set)))
|
||||||
|
. " WHERE {$q($T['id'])} = ?";
|
||||||
|
$pdo->prepare($sql)->execute([...array_values($set), $id]);
|
||||||
|
echo "updated $email ($role)\n";
|
||||||
|
} else {
|
||||||
|
$set[$T['email']] = $email;
|
||||||
|
if ($T['name']) $set[$T['name']] = ucfirst($role) . ' (dev)';
|
||||||
|
foreach ($T['extra'] as $c => $v) $set[$c] = is_string($v) ? str_replace('{email}', $email, $v) : $v;
|
||||||
|
$sql = "INSERT INTO {$q($T['table'])} (" . implode(', ', array_map($q, array_keys($set))) . ') VALUES ('
|
||||||
|
. implode(', ', array_fill(0, count($set), '?')) . ')';
|
||||||
|
$pdo->prepare($sql)->execute(array_values($set));
|
||||||
|
echo "created $email ($role)\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user