Skip to content

feat/onesig api integration#195

Merged
xiami762 merged 4 commits intomainfrom
feature/onesig-api-integration
Apr 27, 2026
Merged

feat/onesig api integration#195
xiami762 merged 4 commits intomainfrom
feature/onesig-api-integration

Conversation

@duguwanglong
Copy link
Copy Markdown
Contributor

feat(onesig): persist cookie session, default-off SSL verify, blank api_prefix

Three interlocking changes that make OneSIG v2.5.x easier to bring online
out of the box and align SSL / cookie behaviour with the other built-in
providers (onesec / ngtip / qingteng).

  • Persistent login session: after a successful login the aiohttp
    CookieJar is serialised into ~/.flocks/config/.secret.json under a
    key shaped like onesig_session_cookie__<sha1[:12]>. On process
    restart, if at least one cookie is still alive the jar is rehydrated
    in-place and the captcha -> pubkey -> /v3/login -> /v3/account chain
    is skipped entirely; the very first business request that returns
    401 / responseCode 1019..1022 still triggers exactly one auto re-login
    to preserve previous behaviour. logout() wipes the on-disk entry,
    close() does not. The persist_cookies toggle defaults to True and
    honours camelCase / custom_settings / ONESIG_PERSIST_COOKIES
    fallbacks.
  • SSL verification defaults to OFF, matching onesec / ngtip / qingteng.
    Five sources are recognised in priority order: verify_ssl,
    ssl_verify, verifySsl, custom_settings.verify_ssl, and the
    ONESIG_VERIFY_SSL env var, falling back to False. The
    verify_ssl field is removed from provider.credential_fields so
    the global "SSL verify" switch on ServiceDetailPanel becomes the
    single source of truth.
  • api_prefix default changes from "/api" to "", matching the
    common v2.5.x deployments where nginx already routes /v3/... to
    the backend. Reverse-proxy deployments can set it back to "/api".
    _provider.yaml notes are updated with the 404 -> flip-prefix
    troubleshooting tip.

tests/tool/test_onesig_api_tool.py covers: the three verify_ssl
aliases ending up as the right ssl= argument on
aiohttp.session.request, cookie snapshot purity (round-trip and
expired-cookie filtering), __init__ load / login() save /
logout() delete, and the persisted-cookie path bypassing the full
captcha -> pubkey -> login -> account chain.

Mirror the existing onesec plugin pattern under
`.flocks/plugins/tools/api/onesig/`, exposing the full OneSIG Web API
(~340 endpoints, 39 doc modules) as 6 grouped tools:
onesig_login / onesig_monitoring / onesig_strategy / onesig_assets /
onesig_device / onesig_helper.

Authentication & session
  - Cookie-based session via aiohttp ClientSession + CookieJar
  - Login flow: GET /v3/captcha -> GET /v3/pubkey ->
    RSA-OAEP(password) -> POST /v3/login -> optional POST /v3/login/totp
  - JSEncrypt-compatible RSA-OAEP (default sha1, switchable to sha256
    via api_services.onesig_api.oaep_hash)
  - Auto re-login on HTTP 401/403 and responseCode 1019..1022
  - Inline TOTP (`enableTotp=true` from /v3/captcha) and QR-scan TOTP
    (responseCode 1012) both surface clear errors when missing
  - 1010 / 1011 (default / expired password) routed to a hint that
    points at onesig_login(action='change_password', ...)

Sensitive write operations (RSA-OAEP encrypted body fields)
ActionSpec.encrypt_fields auto-fetches a fresh /v3/pubkey and replaces
plaintext fields before sending. Applies to:
  - DELETE /v3/aclog              -> aclog_delete            (password)
  - DELETE /v3/user               -> user_delete             (password)
  - PUT    /v3/user/secret/reset  -> user_secret_reset       (password)
  - POST   /v3/user               -> user_create             (password,
                                                              dupPassword)
  - PUT    /v3/interface          -> interface_update        (password)
  - POST   /v3/device/upgrade     -> device_upgrade          (password)
  - POST   /v3/device/upgrade     -> device_upgrade_upload   (password,
                                                              multipart)
  - PUT    /v3/user/password      -> change_password (each of
    oldPassword / newPassword / dupPassword encrypted independently)

Multipart uploads
ActionSpec.multipart streams a local file via aiohttp.FormData under the
documented field name (default `file`, certificates use `certFile`).
Callers pass `file_path: <local absolute path>`. Wired up to:
  - asset_import              (assets/.csv)
  - tls_cert_create / tls_cert_update  (certFile field)
  - basic_information_import  (offline intel package)
  - basic_license_upload      (license file)
  - system_upgrade            (system upgrade package)
  - device_upgrade_upload     (firmware + RSA password combined)
  - backup_import             (config backup archive)

Binary downloads
31 export / template / pcap / coredump endpoints flagged binary=True;
the dispatcher saves the response stream to outputs/<date>/ and surfaces
saved_path / size / content_type in both output and metadata.

Observability
ToolResult.metadata now includes source / api / method / path /
http_status / response_code / verbose_msg (and saved_path for binary
endpoints) so callers can debug "HTTP 200 but responseCode != 0" and
locate downloaded files without parsing output.

Cross-validation: 340 ActionSpecs across 6 groups vs YAML enums all
align (assets=15 / device=148 / helper=6 / login=10 / monitoring=75 /
strategy=89). Reuses transitively-installed cryptography (46.x); no new
dependency required.

Made-with: Cursor
Introduce a unified entry skill for all `onesig_*` tools, mirroring the
style of `onesec-use` / `qingteng-use`. Any task that mentions OneSIG /
SIG / Secure Internet Gateway must load this skill first instead of
calling the tools directly.

- SKILL.md: API-vs-browser decision flow and write-action confirmation
  protocol; declares the skill as the single decision entry-point.
- references/api-reference.md: action routing table for the six grouped
  tools (`onesig_login` / `assets` / `device` / `helper` / `monitoring`
  / `strategy`), business primary keys (uniqueId / uid / pid / groupId /
  ruleId / srcIp / server+port, etc.), high-frequency call examples,
  binary/file endpoints (`document_preview`, multipart uploads), the
  RSA-OAEP auto-encrypted fields (`password`, `dupPassword`), the
  mandatory `type=physical` flag for API Key endpoints, and the fact
  that `ips_rule_create` is actually a query.
- references/browser-workflow.md: console navigation map and
  `agent-browser` operating rules for the fallback path when the API is
  unavailable.

The reference has been cross-checked against the vendor SIGWEBAPI docs
and `onesig.handler.py`, fixing legacy drifts such as
assetType -> type, name -> username, fileName -> id,
port_protect_group_port_list -> port_protect_port_list, and the
top-level placement of `condition` / `comments` in `whitelist_add`.

Made-with: Cursor
…pi_prefix

Three interlocking changes that make OneSIG v2.5.x easier to bring online
out of the box and align SSL / cookie behaviour with the other built-in
providers (onesec / ngtip / qingteng).

- Persistent login session: after a successful login the aiohttp
  CookieJar is serialised into `~/.flocks/config/.secret.json` under a
  key shaped like `onesig_session_cookie__<sha1[:12]>`. On process
  restart, if at least one cookie is still alive the jar is rehydrated
  in-place and the captcha -> pubkey -> /v3/login -> /v3/account chain
  is skipped entirely; the very first business request that returns
  401 / responseCode 1019..1022 still triggers exactly one auto re-login
  to preserve previous behaviour. `logout()` wipes the on-disk entry,
  `close()` does not. The `persist_cookies` toggle defaults to True and
  honours camelCase / `custom_settings` / `ONESIG_PERSIST_COOKIES`
  fallbacks.
- SSL verification defaults to OFF, matching onesec / ngtip / qingteng.
  Five sources are recognised in priority order: `verify_ssl`,
  `ssl_verify`, `verifySsl`, `custom_settings.verify_ssl`, and the
  `ONESIG_VERIFY_SSL` env var, falling back to False. The
  `verify_ssl` field is removed from `provider.credential_fields` so
  the global "SSL verify" switch on `ServiceDetailPanel` becomes the
  single source of truth.
- `api_prefix` default changes from `"/api"` to `""`, matching the
  common v2.5.x deployments where nginx already routes `/v3/...` to
  the backend. Reverse-proxy deployments can set it back to `"/api"`.
  `_provider.yaml` notes are updated with the 404 -> flip-prefix
  troubleshooting tip.

`tests/tool/test_onesig_api_tool.py` covers: the three `verify_ssl`
aliases ending up as the right `ssl=` argument on
`aiohttp.session.request`, cookie snapshot purity (round-trip and
expired-cookie filtering), `__init__` load / `login()` save /
`logout()` delete, and the persisted-cookie path bypassing the full
captcha -> pubkey -> login -> account chain.

Made-with: Cursor
Some providers (onesig in particular) reuse the persisted `base_url`
as `default_value` on the metadata endpoint. The previous reload logic
in `ServiceDetailPanel` treated `value === effectiveDefault` as a
"placeholder" case and cleared the input, so reopening a configured
service showed an empty API URL and saving immediately overwrote the
backend record with an empty string.

The form now renders whatever the backend returns under `fields`
(falling back to legacy keys only) and never compares against
`default_value`. `ServiceDetailPanelApi.test.tsx` adds a regression
test where metadata returns the same value in both `default_value` and
`fields`, asserting the form still shows the persisted URL.

Made-with: Cursor
@duguwanglong duguwanglong requested a review from xiami762 April 27, 2026 07:16
@xiami762 xiami762 merged commit 0091fd8 into main Apr 27, 2026
2 checks passed
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.

2 participants