Skip to content

feat(api): add ScanProfilesApi for full CRUD management of scan profiles - #177

Open
t0kubetsu wants to merge 2 commits into
D4-project:mainfrom
t0kubetsu:feat/scanprofiles-rest-api
Open

feat(api): add ScanProfilesApi for full CRUD management of scan profiles#177
t0kubetsu wants to merge 2 commits into
D4-project:mainfrom
t0kubetsu:feat/scanprofiles-rest-api

Conversation

@t0kubetsu

Copy link
Copy Markdown
Contributor

Summary

Closes #176.

Adds a ScanProfilesApi REST class at /api/v1/scanprofiles/ so scan profiles can be managed programmatically via JSON rather than through the FAB HTML form at /scanprofilesview/add. The FAB form encodes port IDs as repeated &ports=N fields, which hits Flask-Werkzeug's MAX_CONTENT_LENGTH when a profile includes thousands of ports (e.g. all 65535 registered TCP ports). The JSON REST API compresses the same payload to ~460 KB and bypasses this limit entirely.

New endpoints

Method Path 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
PUT /api/v1/scanprofiles/<id> Partial update (any subset of fields)
DELETE /api/v1/scanprofiles/<id> Delete a scan profile

All endpoints require JWT Bearer authentication (@protect() / @safe), matching the pattern of the existing NsesApi.

Changes

  • webapp/app/apis.py: add ScanProfilesApi class + appbuilder.add_api(ScanProfilesApi) registration; import Ports and ScanProfiles models.

Validation

  • name — required on create, unique, non-empty
  • scan_cycle_minutes — positive integer
  • priority — one of {0, 1, 2, 3, 4}
  • port_ids / nse_ids — all IDs must reference existing rows (400 on unknown IDs)
  • PUT requires at least one field to be present (400 on empty body)

t0kubetsu and others added 2 commits June 9, 2026 15:22
Adds a JSON REST API at /api/v1/scanprofiles/ with list, create, read,
update, and delete endpoints.  The previous workflow required POSTing
thousands of repeated form fields to /scanprofilesview/add, which hits
Flask-Werkzeug's MAX_CONTENT_LENGTH when a profile includes all 65535
TCP ports.  The JSON body used by the new endpoints avoids this limit.

Endpoints:
  GET    /api/v1/scanprofiles/       — list all profiles
  POST   /api/v1/scanprofiles/       — create (name, port_ids, nse_ids,
                                       scan_cycle_minutes, priority,
                                       apply_to_all)
  GET    /api/v1/scanprofiles/<id>   — get one profile
  PUT    /api/v1/scanprofiles/<id>   — partial update (any subset of fields)
  DELETE /api/v1/scanprofiles/<id>   — delete

All endpoints are @Protect()/@safe (JWT Bearer auth).  port_ids and
nse_ids are validated against existing Ports/Nses records; unknown IDs
return 400.  Priority is validated to 0–4 (matching the model validator).
@Th4nat0s

Copy link
Copy Markdown
Collaborator

Fixed in d4a7995.\n\nMerged current main to resolve the PR conflict, then updated ScanProfilesApi with populated OpenAPI/Swagger docstrings for GET/POST/GET-by-id/PUT/DELETE. Also hardened JSON parsing and validation, made boolean/int/list handling strict, required at least one port ID, added IntegrityError rollback handling, marked profile updates for priority retag, added regression tests, and updated release_note.md.\n\nValidation run:\n- black on webapp/app/apis.py and test/test_api_marshmallow_validators.py\n- py_compile on changed Python files\n- test/test_api_marshmallow_validators.py: 20 tests OK\n- test/run_all.py: 31 tests OK\n- authenticated /api/v1/_openapi check confirms /api/v1/scanprofiles/ has GET+POST and /api/v1/scanprofiles/{pk} has GET+PUT+DELETE with requestBody for POST/PUT\n- pylint only reports existing legacy warnings outside this patch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add REST API for scan profile CRUD (GET/POST/PUT/DELETE /api/v1/scanprofiles/)

2 participants