From 147f750c905f317fe4199773824c767ae85d014e Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Tue, 20 Oct 2026 07:43:47 +0200 Subject: [PATCH] broker: rugnux live settings and model need no bearer token GET/PUT /config/rugnux and PUT/DELETE /config/rugnux/model prepare the next collection and expose nothing of the current one, so they are open like the rest of the configuration. Protecting them meant the next user needed the previous dataset's token to set up their own run. /rugnux/status, which reports the current collection, stays protected. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 --- broker/JFJochBrokerHttp.cpp | 5 ++--- broker/jfjoch_api.yaml | 32 -------------------------------- docs/JFJOCH_BROKER.md | 6 +++--- frontend/src/client/sdk.gen.ts | 4 ---- tests/BrokerHttpAuthTest.cpp | 13 ++++++------- 5 files changed, 11 insertions(+), 49 deletions(-) diff --git a/broker/JFJochBrokerHttp.cpp b/broker/JFJochBrokerHttp.cpp index 722301af0..4853b4b0a 100644 --- a/broker/JFJochBrokerHttp.cpp +++ b/broker/JFJochBrokerHttp.cpp @@ -143,7 +143,8 @@ JFJochBrokerHttp::HttpError JFJochBrokerHttp::handleOperationException(const std // The read endpoints that expose the current dataset (its name and unit cell, and its images). // While the dataset was started with tokens, they answer 401 to a request without one; the same // set carries the bearerAuth security scheme in jfjoch_api.yaml. Everything else - the control -// plane, instrument configuration, broker status - stays open. +// plane, instrument configuration (rugnux live settings and model included: they are set up for the +// next collection, not read from this one), broker status - stays open. static const std::set PROTECTED_PATHS{ "/statistics/data_collection", "/result/scan", @@ -154,8 +155,6 @@ static const std::set PROTECTED_PATHS{ "/preview/plot", "/preview/plot.bin", "/live/events", - "/config/rugnux", - "/config/rugnux/model", "/rugnux/status" }; diff --git a/broker/jfjoch_api.yaml b/broker/jfjoch_api.yaml index 58da1644d..c492e795b 100644 --- a/broker/jfjoch_api.yaml +++ b/broker/jfjoch_api.yaml @@ -3514,20 +3514,12 @@ paths: summary: Change rugnux live mode settings description: | This can only be done when detector is `Idle`, `Error` or `Inactive` states. - security: - - bearerAuth: [] requestBody: content: application/json: schema: $ref: '#/components/schemas/rugnux_settings' responses: - "401": - description: The current dataset is protected and no valid bearer token was presented. - content: - text/plain: - schema: - type: string "200": description: Everything OK "400": @@ -3546,15 +3538,7 @@ paths: get: summary: Get rugnux live mode settings and model status description: Can be done anytime - security: - - bearerAuth: [] responses: - "401": - description: The current dataset is protected and no valid bearer token was presented. - content: - text/plain: - schema: - type: string "200": description: Everything OK content: @@ -3569,8 +3553,6 @@ paths: The model (PDB or mmCIF, optionally gzipped; at most 64 MiB) is used for molecular replacement and validation of every following rugnux live collection, until it is removed with `DELETE /config/rugnux/model` or replaced by another upload. - security: - - bearerAuth: [] requestBody: content: application/octet-stream: @@ -3578,12 +3560,6 @@ paths: type: string format: binary responses: - "401": - description: The current dataset is protected and no valid bearer token was presented. - content: - text/plain: - schema: - type: string "200": description: All good "400": @@ -3600,15 +3576,7 @@ paths: summary: Remove the model used by rugnux live mode description: | This can only be done when detector is `Idle`, `Error` or `Inactive` states. - security: - - bearerAuth: [] responses: - "401": - description: The current dataset is protected and no valid bearer token was presented. - content: - text/plain: - schema: - type: string "200": description: All good "500": diff --git a/docs/JFJOCH_BROKER.md b/docs/JFJOCH_BROKER.md index 4d6258b91..b4350bba0 100644 --- a/docs/JFJOCH_BROKER.md +++ b/docs/JFJOCH_BROKER.md @@ -195,8 +195,8 @@ gets `413`, an empty one or one that cannot be read as a model `400`). The broke and keeps it in memory - nothing is written to disk - for every following collection until `DELETE /config/rugnux/model` removes it or another upload replaces it; a broker restart drops it. `GET /config/rugnux` reports whether a model is loaded and its size, never its contents. Changes are -refused during a collection, and while the current dataset was started with tokens, all of these -routes need its bearer token. +refused during a collection. Like the rest of the configuration these routes need no bearer token: +they prepare the next collection and expose nothing of the current one. The end message, and with it the end of the collection, waits for the analysis. `deadline_s` (default 60 s; 0 for no cutoff) bounds that wait: this long after the last image the analysis is cut. `POST /cancel` is @@ -212,7 +212,7 @@ state, the images received, the step it is on and how far into it, the steps so found, and once it is over the verdict, the summary, warnings and the time from the last image to every result written. The web frontend shows it on the dashboard and in its "Rugnux live" tab, which also changes the settings and uploads the model. It needs the dataset's bearer token -like the routes above. `GET /result/scan` carries the rotation lattice, unit cell and Bravais symbol +like the dataset routes (`/statistics/data_collection`, `/image_buffer/*`, `/preview/plot*`). `GET /result/scan` carries the rotation lattice, unit cell and Bravais symbol rugnux found. A collection in which rugnux finds no lattice still gets the spot count, resolution estimate and background of every image in `GET /result/scan` and the master file, marked as not indexed. diff --git a/frontend/src/client/sdk.gen.ts b/frontend/src/client/sdk.gen.ts index ae9c88485..9c5ed66ca 100644 --- a/frontend/src/client/sdk.gen.ts +++ b/frontend/src/client/sdk.gen.ts @@ -383,7 +383,6 @@ export const putConfigSelectDetector = (op * Can be done anytime */ export const getConfigRugnux = (options?: Options): RequestResult => (options?.client ?? client).get({ - security: [{ scheme: 'bearer', type: 'http' }], url: '/config/rugnux', ...options }); @@ -395,7 +394,6 @@ export const getConfigRugnux = (options?: * */ export const putConfigRugnux = (options?: Options): RequestResult => (options?.client ?? client).put({ - security: [{ scheme: 'bearer', type: 'http' }], url: '/config/rugnux', ...options, headers: { @@ -411,7 +409,6 @@ export const putConfigRugnux = (options?: * */ export const deleteConfigRugnuxModel = (options?: Options): RequestResult => (options?.client ?? client).delete({ - security: [{ scheme: 'bearer', type: 'http' }], url: '/config/rugnux/model', ...options }); @@ -427,7 +424,6 @@ export const deleteConfigRugnuxModel = (op */ export const putConfigRugnuxModel = (options?: Options): RequestResult => (options?.client ?? client).put({ bodySerializer: null, - security: [{ scheme: 'bearer', type: 'http' }], url: '/config/rugnux/model', ...options, headers: { diff --git a/tests/BrokerHttpAuthTest.cpp b/tests/BrokerHttpAuthTest.cpp index f6e39de3d..3af02f883 100644 --- a/tests/BrokerHttpAuthTest.cpp +++ b/tests/BrokerHttpAuthTest.cpp @@ -70,7 +70,7 @@ TEST_CASE("JFJochBrokerHttp_BearerTokens", "[broker]") { "/image_buffer/image.cbor?id=0", "/image_buffer/image.tiff?id=0", "/image_buffer/image.jpeg?id=0", "/preview/plot?type=bkg_estimate", "/preview/plot.bin?type=bkg_estimate", "/live/events", - "/config/rugnux", "/rugnux/status"}) { + "/rugnux/status"}) { INFO(path); auto res = client.Get(path); REQUIRE(res); @@ -79,11 +79,11 @@ TEST_CASE("JFJochBrokerHttp_BearerTokens", "[broker]") { REQUIRE(res->body.find("protected_run") == std::string::npos); REQUIRE(client.Get(path, wrong)->status == 401); } - // Live rugnux settings and its model are the dataset's too: changed only with a token. - REQUIRE(client.Put("/config/rugnux", R"({"enable":false})", "application/json")->status == 401); - REQUIRE(client.Put("/config/rugnux/model", "", "application/octet-stream")->status == 401); - REQUIRE(client.Delete("/config/rugnux/model")->status == 401); - REQUIRE(client.Delete("/config/rugnux/model", wrong)->status == 401); + // Live rugnux settings and its model prepare the next collection: open like the rest of the configuration. + REQUIRE(client.Get("/config/rugnux")->status == 200); + REQUIRE(client.Put("/config/rugnux", R"({"enable":false})", "application/json")->status == 200); + REQUIRE(client.Put("/config/rugnux/model", "", "application/octet-stream")->status == 400); + REQUIRE(client.Delete("/config/rugnux/model")->status == 200); } SECTION("either token opens them") { @@ -93,7 +93,6 @@ TEST_CASE("JFJochBrokerHttp_BearerTokens", "[broker]") { REQUIRE(client.Get("/statistics/data_collection", other)->status == 200); REQUIRE(client.Get("/preview/plot?type=bkg_estimate", good)->status == 200); REQUIRE(client.Get("/rugnux/status", good)->status == 200); - REQUIRE(client.Get("/config/rugnux", other)->status == 200); } SECTION("the aggregate statistics drop the measurement block instead of refusing") {