API keys: add read/read_write scopes + admin scope selector & pagination

Foundation for extending the Bearer API beyond create-only:
- api_keys gains a scope column (read | read_write); baseline schema updated
  and the column applied to the live DB. Existing keys default to
  read_write so the hwmon create key keeps working.
- ApiKeyModel: createKey() takes a validated scope; validateKey() always
  surfaces scope (defaults read_write); getAllKeys() is paginated
  ({keys,total,page,perPage}, key_hash stripped).
- ApiKeyAuth: expose getKeyContext() (scope/key_name/created_by/api_key_id)
  and requireScope() (403 on insufficient scope); existing return values
  unchanged.
- create_ticket_api.php: require read_write scope (a read key can't create).
- Admin /admin/api-keys: scope selector on the create form, a scope column,
  and pagination (revoked keys were stacking up).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 18:24:50 -04:00
co-authored by Claude Opus 4.8
parent d535557e5a
commit 5cf5aa9591
7 changed files with 211 additions and 20 deletions
+9 -1
View File
@@ -331,7 +331,15 @@ switch (true) {
requireAdmin($currentUser);
require_once 'models/ApiKeyModel.php';
$apiKeyModel = new ApiKeyModel($conn);
$apiKeys = $apiKeyModel->getAllKeys();
// Validate the requested page to a positive int (default 1)
$apiKeysPage = isset($_GET['page']) ? (int)$_GET['page'] : 1;
if ($apiKeysPage < 1) {
$apiKeysPage = 1;
}
$apiKeysPerPage = 20;
$apiKeys = $apiKeyModel->getAllKeys($apiKeysPage, $apiKeysPerPage);
include 'views/admin/ApiKeysView.php';
break;