Repository navigation
Add REST API v1 for external PAT clients - #1556
Closed
maxijabase wants to merge 20 commits into
Closed
maxijabase wants to merge 20 commits into
maxijabase wants to merge 20 commits into
Conversation
The assistant workflow and CLA.md are unused here. Contributor docs and the PR template no longer tell people to sign.
chore: remove the CLA signing gate
fix(admin-mods): modernize mods list and forms
feat(admin-groups): polish Groups list and edit chrome
* progress towards activating/deactivating admins * feat(admins): soft-retire, durable issuer names, and bulk actions (sbpp#1509) Close deactivate/reactivate polish plus admins.bulk with list checkboxes, keeping ban/comm Admin cells on snapshot names after hard delete. * fix seeder to insert coherent data in admins * fix(admins): match reactivate row action to icon-only chrome Use the same ghost icon button pattern as deactivate/delete so inactive rows do not show a bordered labeled control. * feat(frontend): theme single-selects to match multi-select chrome Replace OS caret inconsistency with a progressive .ssel enhancer sharing Lucide chevron chrome with .msel, and keep narrow grid tracks from overflowing. * feat(admins): add password visibility toggle on add-admin form One eye control reveals password and confirm together; generate still resets to masked. * fix(frontend): flip themed select panels when they would overflow Open upward when there is more room above the trigger, and shrink max-height to the available viewport space. * switch add-admin server access to multiselects * fix missing mb-3 spacing on admins list * rehash admins after deactivate/reactivate * document windows powershell docker compose * theme bulk admin group selects * let dialog selects escape palette clip * keep filter select widths on themed wrap * mirror flex sizing onto themed select wrap * unify admins bulk action button chrome * fix mobile admins bulk select chrome * replace native confirm with panel dialogs * use multiselects on edit admin servers * fix ci * revert format version bump to 1
Publish the production image to ghcr.io/srcdslab/sourcebans-pp, including a rolling :main tag on pushes to main. Stop dispatching docs deploys into sbpp/sbpp.github.io. Point panel and operator-facing links at this repo.
External bots and website-next need PAT-authenticated REST instead of the panel RPC. Slice 0 covers admins, groups, and rehash.
Contributor
Author
|
Opened against the wrong remote; this change is going to srcdslab/sourcebans-pp main. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This ships a versioned HTTP API at
/api/v1for external clients: bots, website backends, and scripts. It is a separate product fromPOST /api.php. Panel JavaScript stays on the JSON RPC (cookie JWT + CSRF). REST never reads the panel cookie.How operators use it
sbpp_pat_plus 64 hex characters and is shown once. The panel stores only a SHA-256 hash.Authorization: Bearer sbpp_pat_…on each request./api/v1/…(Apache rewrite in the prod image and the rebuilt dev image). PATH_INFO fallback always works:/api/v1.php/….Tokens inherit that admin's web flags. There are no extra scopes. A read-only bot is an admin with list flags, not a trimmed token. Soft-retired admins (
enabled = 0) cannot use a token. Password lockout does not apply. Revoke is the kill switch.The intended staff-hub flow (website-next): mint an Owner (or Add/Edit/Delete Admins) PAT in the backend,
PUT /admins/{steam64}to grant in-game admin,POST /admins/{steam64}/deactivateto demote. Discord stays in the bot. SourceBans does not know about Discord.Request shape
{ "data": …, "meta": … }with real HTTP status (200, 201, 400, 401, 403, 404, 409, 429, 500).{ "error": { "code", "message", "field"? } }.{id}on/admins/{id}is a numeric aid or a 17-digit Steam64 starting with 7. Steam2/Steam3 in the path is 400./bansand/commslengthis minutes (0 = permanent). GETlengthis seconds (what is stored).Api::invoke()where those already exist (ban, unban, comms, comments, servers add/remove/rcon, notes, mods, protests, submissions, admin deactivate/reactivate/remove, rehash). List/get, Steam64 upsert, PATCH/servers, and GET/PATCH/settingsare dedicated REST queries.sm_rehashserver-side whenconfig.enableadminrehashingis on and puts the result inmeta.rehash. If the caller lacks rehash permission, the mutate still succeeds andmeta.rehash.attemptedisfalse(the write is not rolled back with a 403).Retry-After.SB_REST_CORS_ORIGINSinconfig.phpfor a browser origin. Backend-to-panel calls do not need it.Auth and isolation (baked into the design)
Authorization: Bearer sbpp_pat_…. Cookie JWT must not authenticate REST (that would be a CSRF trap in browsers, and would leak IPs on public GET).api/v1.phpdefinesSBPP_RESTbeforeinit.php;CSRF::init()no-ops. PanelPOST /api.phpstill requires CSRF.Log::initis rebound to the PAT (or anonymous) userbank so audit rows are attributed to the token admin, not a leftover cookie session.password/validate/attempts/lockout_until/srv_password,servers.rcon,settings.smtp.pass,settings.telemetry.instance_id.EDIT_ADMINSalone cannot change an Owner.cid, not a later audit-log insert id./serversmatches?p=servers: enabled hosts only, nogroup_ids, ignoresenabled=, 404 on a disabled{sid}. A PAT may filterenabled=and seesgroup_ids.rconis never returned./commsis 404 whenconfig.enablecommsis off. A PAT still reads./bansand/commsapply the samebanlist.hideplayerips/banlist.hideadminnamegates as the panel lists.config.enablepubliccommentsis off (admins still see them). DELETE/comments/{id}is Owner.Schema, rewrite, docs
:prefix_api_tokens(fresh install instruc.sql, upgrade via updater812.php). Hash + prefix only.account.tokens_create/list/revoke(panel UI, not REST)./api/v1in prod + dev conf. Docs nginx snippet +HTTP_AUTHORIZATIONnote.docs/src/content/docs/configuring/rest-api.mdx. OpenAPI:web/api/openapi-v1.yaml, also served atGET /api/v1/openapi.yaml.Sbpp\Rest\Routes::all(). Adding a write route requires a row inRestPermissionMatrixTest.Endpoints
Base:
/api/v1or/api/v1.php. All authenticated routes need a PAT unless marked public.Meta
/openapi.yamlCaller
/meAdmins and groups
{id}is aid or Steam64./adminspage,per_page, cap 100)/admins/{id}/admins/{id}/admins/{id}/admins/{id}/deactivateenabled=0). Ban history keeps the name/admins/{id}/reactivate/admins/{id}reason/groupsgidmapping). No group write in this version/system/rehash{ "sids": [1,2] }. Admin mutate already rehashes when the setting is onBans
/bans/bans/{bid}/banslengthminutes. Optionalkick: truefans RCON (meta.kick)/bans/{bid}/unbanureasonComm blocks
/commskindis mute or gag. Silence is two rows. *404 for anonymous when Comm blocks are off/comms/{cid}/commskind: mute, gag, or silence/comms/{cid}/unblockureason/comms/{cid}Servers
/serversquery, neverrcon. Anonymous omitsgroup_idsand ignoresenabled=. PAT may filter/servers/{sid}/serversip/address,port,mod.enableddefaults true/servers/{sid}rconto keep the stored password/servers/{sid}/servers/{sid}/rconNotes, mods, queues
/notes?steam=/notessteam+body/notes/{nid}/mods,/mods/{mid}/modsname+folder/mods/{mid}ureason/protests,/protests/{pid}archived=truefor the archive/protests/{pid}archiv=0)/submissions,/submissions/{sid}archived=truefor archive/submissions/{sid}Comments and settings
/bans/{bid}/comments,/comms/{cid}/comments/bans/{bid}/comments,/comms/{cid}/commentsbody. Responseidis the comment cid/comments/{cid}body/comments/{cid}/settingssmtp.passortelemetry.instance_id/settingsMotivation and Context
External clients (website-next staff hub, Discord bots, scripts) need a real HTTP API with Bearer tokens, real status codes, and a stable resource model.
POST /api.phpis the panel RPC: cookie + CSRF, chrome envelopes, no PAT. Mixing those clients onto RPC would either leak session auth into browsers or force bots through CSRF. This API is the supported path for that work.Not in this version (by design): generated password on PUT create, a designed-from-scratch rate limiter beyond the file limiter, comment PATCH author check, OpenAPI completeness polish,
kick: truevsenablekickit, blockit fan-out on POST/comms. Group create/edit stays in the panel.How Has This Been Tested?
RestAuth,RestAdmins,RestBans,RestComms,RestServers,RestNotes,RestMods,RestProtests,RestSubmissions,RestComments,RestSettings,RestSession,RestPermissionMatrix) plus account token RPC snapshots.web/tests/e2e/specs/flows/rest-api.spec.ts(mint PAT on Your account, call/meand a write).Screenshots (if appropriate):
N/A (API + Your account token card). Operator docs at Configuring → REST API.
Types of changes
Checklist: