Problem
Scan profiles can only be created and updated through the FAB HTML form endpoints (/scanprofilesview/add, /scanprofilesview/edit/<id>). These endpoints accept application/x-www-form-urlencoded bodies with one repeated field per port ID, which hits Flask-Werkzeug's MAX_CONTENT_LENGTH when a profile includes a large number of ports (e.g. all 65535 registered TCP ports). There is no JSON API alternative.
This makes it impossible to programmatically create a "scan all ports" profile without either raising MAX_CONTENT_LENGTH or monkey-patching the Flask config.
Proposed solution
Add a ScanProfilesApi class at /api/v1/scanprofiles/ following the same pattern as the existing NsesApi. All payloads are JSON, so the body size scales with the number of IDs rather than with URL-encoded repetition.
Endpoints
| Method |
URL |
Description |
GET |
/api/v1/scanprofiles/ |
List all scan profiles (sorted by name) |
POST |
/api/v1/scanprofiles/ |
Create a scan profile |
GET |
/api/v1/scanprofiles/<id> |
Get one scan profile by ID |
PUT |
/api/v1/scanprofiles/<id> |
Partial update (any subset of fields) |
DELETE |
/api/v1/scanprofiles/<id> |
Delete a scan profile |
POST / PUT body
{
"name": "All TCP Ports",
"port_ids": [1, 2, 3, ..., 65535],
"nse_ids": [1, 2, 3],
"scan_cycle_minutes": 720,
"priority": 0,
"apply_to_all": false
}
PUT accepts any subset of those fields (at least one required).
Response shape
{
"result": {
"id": 5,
"name": "All TCP Ports",
"scan_cycle_minutes": 720,
"priority": 0,
"apply_to_all": false,
"port_ids": [1, 2, 3],
"nse_ids": [1]
}
}
Validation
name — required on create, must be non-empty, must be unique (400 on collision)
scan_cycle_minutes — positive integer
priority — must be 0, 1, 2, 3, or 4 (matching the model validator)
port_ids — all IDs must reference existing Ports rows (400 on unknown IDs)
nse_ids — all IDs must reference existing Nses rows (400 on unknown IDs)
All endpoints are authenticated via @protect() / @safe (JWT Bearer).
Related
PR: https://github.com/D4-project/Plum-Island/pull/new/feat/scanprofiles-rest-api (from t0kubetsu fork)
Problem
Scan profiles can only be created and updated through the FAB HTML form endpoints (
/scanprofilesview/add,/scanprofilesview/edit/<id>). These endpoints acceptapplication/x-www-form-urlencodedbodies with one repeated field per port ID, which hits Flask-Werkzeug'sMAX_CONTENT_LENGTHwhen a profile includes a large number of ports (e.g. all 65535 registered TCP ports). There is no JSON API alternative.This makes it impossible to programmatically create a "scan all ports" profile without either raising
MAX_CONTENT_LENGTHor monkey-patching the Flask config.Proposed solution
Add a
ScanProfilesApiclass at/api/v1/scanprofiles/following the same pattern as the existingNsesApi. All payloads are JSON, so the body size scales with the number of IDs rather than with URL-encoded repetition.Endpoints
GET/api/v1/scanprofiles/POST/api/v1/scanprofiles/GET/api/v1/scanprofiles/<id>PUT/api/v1/scanprofiles/<id>DELETE/api/v1/scanprofiles/<id>POST / PUT body
{ "name": "All TCP Ports", "port_ids": [1, 2, 3, ..., 65535], "nse_ids": [1, 2, 3], "scan_cycle_minutes": 720, "priority": 0, "apply_to_all": false }PUTaccepts any subset of those fields (at least one required).Response shape
{ "result": { "id": 5, "name": "All TCP Ports", "scan_cycle_minutes": 720, "priority": 0, "apply_to_all": false, "port_ids": [1, 2, 3], "nse_ids": [1] } }Validation
name— required on create, must be non-empty, must be unique (400 on collision)scan_cycle_minutes— positive integerpriority— must be 0, 1, 2, 3, or 4 (matching the model validator)port_ids— all IDs must reference existingPortsrows (400 on unknown IDs)nse_ids— all IDs must reference existingNsesrows (400 on unknown IDs)All endpoints are authenticated via
@protect()/@safe(JWT Bearer).Related
PR: https://github.com/D4-project/Plum-Island/pull/new/feat/scanprofiles-rest-api (from t0kubetsu fork)