Check editor accounts.

A new editor needs a username and a password of at least 12 characters. A persistent login needs an unexpired key and an existing account. Removing an account revokes its persistent logins, and its sessions end.
This commit is contained in:
tim
2026-09-26 15:27:51 +02:00
parent 5d657d7e45
commit 3df88e0b4c
10 changed files with 217 additions and 16 deletions
+10 -1
View File
@@ -124,8 +124,17 @@ abstract class PageTestCase extends \PHPUnit\Framework\TestCase {
return $id;
}
// An editor's session, with a CSRF token; returns the token
/*
* An editor's session, with a CSRF token; returns the token. The pages
* log out an editor without an account, so this adds the account to the
* editors table if it is missing.
*/
protected function loginAs(string $username = 'ed', array $data = array()): string {
$saved = unserialize(file_get_contents(self::$state . '/tables.ser'));
if (!in_array($username, array_column($saved['tables']['editors'], 'username'), TRUE)) {
$saved['tables']['editors'][] = array('username' => $username, 'password' => '', 'email' => '');
file_put_contents(self::$state . '/tables.ser', serialize($saved));
}
$token = str_repeat('c0ffee', 10) . 'c0de';
$this->startSession($data + array('editor' => $username, 'csrf_token' => $token));
return $token;
+16
View File
@@ -75,6 +75,22 @@ class SiteData {
return $row['username'] === $params[0] && $row['session'] === $params[1];
})), 0, 1);
});
FakeDb::on('/^SELECT p\.username, p\.session FROM persistent_sessions p JOIN editors e ON e\.username = p\.username\s+WHERE p\.username = \? AND p\.session = \? AND p\.created > DATE_SUB\(now\(\), INTERVAL 1 YEAR\)/', function ($sql, $params) {
$editors = array_column(self::$tables['editors'], 'username');
$limit = gmdate('Y-m-d H:i:s', strtotime('-1 year'));
return array_slice(array_values(array_map(function ($row) {
return array('username' => $row['username'], 'session' => $row['session']);
}, array_filter(self::$tables['persistent_sessions'], function ($row) use ($params, $editors, $limit) {
return $row['username'] === $params[0] && $row['session'] === $params[1]
&& in_array($row['username'], $editors, TRUE) && ($row['created'] ?? $limit) > $limit;
}))), 0, 1);
});
FakeDb::on('/^DELETE FROM persistent_sessions WHERE username = \?$/', function ($sql, $params) {
self::$tables['persistent_sessions'] = array_values(array_filter(self::$tables['persistent_sessions'], function ($row) use ($params) {
return $row['username'] !== $params[0];
}));
return TRUE;
});
FakeDb::on('/^INSERT INTO persistent_sessions \(username, session\) VALUES \(\?, \?\)/', function ($sql, $params) {
self::$tables['persistent_sessions'][] = array('username' => $params[0], 'session' => $params[1], 'created' => gmdate('Y-m-d H:i:s'));
return TRUE;