From b530a6e6350bfe485672bd65829c9fbf61a2705e Mon Sep 17 00:00:00 2001 From: "Jokob @NetAlertX" <96159884+jokob-sk@users.noreply.github.com> Date: Wed, 8 Apr 2026 21:57:58 +0000 Subject: [PATCH] Enhance API documentation and schemas: add new device field locking/unlocking endpoints and expand allowed column names for updates #1598 --- docs/API_DEVICE.md | 131 +++++++++++++++++++++++++++ server/api_server/openapi/schemas.py | 14 ++- 2 files changed, 143 insertions(+), 2 deletions(-) diff --git a/docs/API_DEVICE.md b/docs/API_DEVICE.md index 99692c3c..e07a470b 100755 --- a/docs/API_DEVICE.md +++ b/docs/API_DEVICE.md @@ -165,6 +165,8 @@ Manage a **single device** by its MAC address. Operations include retrieval, upd * **POST** `/device//update-column` Update one specific column for a device. +Allowed `columnName` values: `devName`, `devOwner`, `devType`, `devVendor`, `devGroup`, `devLocation`, `devComments`, `devIcon`, `devFavorite`, `devAlertEvents`, `devAlertDown`, `devCanSleep`, `devSkipRepeated`, `devReqNicsOnline`, `devForceStatus`, `devParentMAC`, `devParentPort`, `devParentRelType`, `devSSID`, `devSite`, `devVlan`, `devStaticIP`, `devIsNew`, `devIsArchived`, `devCustomProps`. + **Request Body**: ```json @@ -190,6 +192,108 @@ Manage a **single device** by its MAC address. Operations include retrieval, upd --- +## 8. Lock / Unlock a Device Field + +* **POST** `/device//field/lock` + Lock a field to prevent plugin overwrites, or unlock it to allow overwrites again. + +**Request Body**: + +```json +{ + "fieldName": "devName", + "lock": true +} +``` + +| Field | Type | Required | Description | +|---|---|---|---| +| `fieldName` | string | ✅ | Field to lock/unlock (e.g. `devName`, `devVendor`) | +| `lock` | boolean | ❌ | `true` to lock (default), `false` to unlock | + +**Response** (success): + +```json +{ + "success": true, + "fieldName": "devName", + "locked": true, + "message": "Field devName locked" +} +``` + +**Error Responses**: + +* Field does not support locking → HTTP 400 +* Unauthorized → HTTP 403 + +--- + +## 9. Unlock / Clear Device Fields (Bulk) + +* **POST** `/devices/fields/unlock` + Unlock fields (clear `LOCKED`/`USER` sources) for one device, a list of devices, or all devices. + +**Request Body**: + +```json +{ + "mac": "AA:BB:CC:DD:EE:FF", + "fields": ["devName", "devVendor"], + "clearAll": false +} +``` + +| Field | Type | Required | Description | +|---|---|---|---| +| `mac` | string or array | ❌ | Single MAC, list of MACs, or omit for all devices | +| `fields` | array of strings | ❌ | Fields to unlock. Omit to unlock all tracked fields | +| `clearAll` | boolean | ❌ | `true` clears all sources; `false` (default) clears only `LOCKED`/`USER` | + +**Response** (success): + +```json +{ + "success": true +} +``` + +**Error Responses**: + +* `fields` is not a list → HTTP 400 +* Unauthorized → HTTP 403 + +--- + +## 10. Set Device Alias + +* **POST** `/device//set-alias` + Convenience wrapper to update the device display name (`devName`). + +**Request Body**: + +```json +{ + "alias": "My Router" +} +``` + +**Response** (success): + +```json +{ + "success": true +} +``` + +**Error Responses**: + +* Missing `alias` → HTTP 400 +* Device not found → HTTP 404 +* Unauthorized → HTTP 403 + +--- + ## Example `curl` Requests **Get Device Details**: @@ -233,3 +337,30 @@ curl -X POST "http://:/device/AA:BB:CC:DD:EE:FF/update- --data '{"columnName":"devName","columnValue":"Updated Device"}' ``` +**Lock a Field**: + +```bash +curl -X POST "http://:/device/AA:BB:CC:DD:EE:FF/field/lock" \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + --data '{"fieldName":"devName","lock":true}' +``` + +**Unlock Fields (all devices)**: + +```bash +curl -X POST "http://:/devices/fields/unlock" \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + --data '{"fields":["devName","devVendor"]}' +``` + +**Set Device Alias**: + +```bash +curl -X POST "http://:/device/AA:BB:CC:DD:EE:FF/set-alias" \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + --data '{"alias":"My Router"}' +``` + diff --git a/server/api_server/openapi/schemas.py b/server/api_server/openapi/schemas.py index 7310f637..f3fbccbc 100644 --- a/server/api_server/openapi/schemas.py +++ b/server/api_server/openapi/schemas.py @@ -33,9 +33,19 @@ COLUMN_NAME_PATTERN = re.compile(r"^[a-zA-Z0-9_]+$") # Security whitelists & Literals for documentation ALLOWED_DEVICE_COLUMNS = Literal[ + # Main Info "devName", "devOwner", "devType", "devVendor", - "devGroup", "devLocation", "devComments", "devFavorite", - "devParentMAC", "devCanSleep" + "devGroup", "devLocation", "devComments", "devIcon", + # Alerts & Behavior + "devFavorite", "devAlertEvents", "devAlertDown", + "devCanSleep", "devSkipRepeated", "devReqNicsOnline", "devForceStatus", + # Network topology + "devParentMAC", "devParentPort", "devParentRelType", + "devSSID", "devSite", "devVlan", + # Display / Status + "devStaticIP", "devIsNew", "devIsArchived", + # Custom properties + "devCustomProps", ] ALLOWED_NMAP_MODES = Literal[