@synopackageland/cli 0.3.10 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +57 -9
- package/dist/bin.js +1 -2
- package/dist/build-spk/generator.d.ts +0 -3
- package/dist/build-spk/generator.js +138 -287
- package/dist/build-spk/native-lifecycle.js +0 -3
- package/dist/build-spk/native-payload.js +0 -1
- package/dist/build-spk/notices.d.ts +5 -0
- package/dist/build-spk/notices.js +60 -0
- package/dist/cli.js +178 -151
- package/dist/compose/analyze.d.ts +1 -2
- package/dist/compose/analyze.js +5 -48
- package/dist/contract/unsupported-types.d.ts +10 -0
- package/dist/contract/unsupported-types.js +49 -0
- package/dist/contract/validate.js +25 -2
- package/dist/contract/web-launch.js +0 -2
- package/dist/deploy/deploy.d.ts +1 -4
- package/dist/deploy/deploy.js +45 -156
- package/dist/deploy/homes-values.js +1 -1
- package/dist/deploy/plan.d.ts +18 -0
- package/dist/deploy/plan.js +54 -0
- package/dist/deploy/spk-version.d.ts +2 -14
- package/dist/deploy/spk-version.js +25 -111
- package/dist/dev.d.ts +1 -3
- package/dist/dev.js +14 -28
- package/dist/error-registry.js +830 -862
- package/dist/host/dsm-client.js +12 -272
- package/dist/host/dsm-port-profile.d.ts +0 -1
- package/dist/host/dsm-port-profile.js +0 -2
- package/dist/host/types.d.ts +1 -83
- package/dist/index.d.ts +0 -9
- package/dist/index.js +0 -6
- package/dist/info.d.ts +0 -1
- package/dist/info.js +3 -10
- package/dist/init.d.ts +15 -1
- package/dist/init.js +128 -12
- package/dist/log.js +2 -3
- package/dist/native/validate.js +0 -1
- package/dist/standalone/binary.d.ts +9 -0
- package/dist/standalone/binary.js +67 -0
- package/dist/standalone/build.d.ts +25 -0
- package/dist/standalone/build.js +110 -0
- package/dist/standalone/daemon.d.ts +23 -0
- package/dist/standalone/daemon.js +114 -0
- package/dist/standalone/dsm-window.d.ts +26 -0
- package/dist/standalone/dsm-window.js +291 -0
- package/dist/standalone/helper-inventory.d.ts +16 -0
- package/dist/standalone/helper-inventory.js +2 -0
- package/dist/standalone/helper.d.ts +21 -0
- package/dist/standalone/helper.js +105 -0
- package/dist/standalone/host-adapter.d.ts +5 -0
- package/dist/standalone/host-adapter.js +148 -0
- package/dist/standalone/host-platform.d.ts +13 -0
- package/dist/standalone/host-platform.js +42 -0
- package/dist/standalone/host-types.d.ts +49 -0
- package/dist/standalone/host-types.js +1 -0
- package/dist/standalone/i18n.d.ts +28 -0
- package/dist/standalone/i18n.js +161 -0
- package/dist/standalone/inspect-helper.d.ts +6 -0
- package/dist/standalone/inspect-helper.js +88 -0
- package/dist/standalone/inspect-spk.d.ts +23 -0
- package/dist/standalone/inspect-spk.js +209 -0
- package/dist/standalone/lifecycle-helper.d.ts +2 -0
- package/dist/standalone/lifecycle-helper.js +12 -0
- package/dist/standalone/lifecycle.d.ts +3 -0
- package/dist/standalone/lifecycle.js +53 -0
- package/dist/standalone/manifest.d.ts +73 -0
- package/dist/standalone/manifest.js +279 -0
- package/dist/standalone/reopen-events.d.ts +2 -0
- package/dist/standalone/reopen-events.js +28 -0
- package/dist/standalone/root-messages.d.ts +7 -0
- package/dist/standalone/root-messages.js +259 -0
- package/dist/standalone/root-ops.d.ts +42 -0
- package/dist/standalone/root-ops.js +101 -0
- package/dist/standalone/root-window.d.ts +36 -0
- package/dist/standalone/root-window.js +302 -0
- package/dist/standalone/spk.d.ts +23 -0
- package/dist/standalone/spk.js +192 -0
- package/dist/template-paths.d.ts +2 -0
- package/dist/template-paths.js +9 -0
- package/dist/templates/_daemon/fixture_linux_test.go +15 -0
- package/dist/templates/_daemon/fixture_other_test.go +7 -0
- package/dist/templates/_daemon/go.mod +3 -0
- package/dist/templates/_daemon/main.go +608 -0
- package/dist/templates/_daemon/main_test.go +242 -0
- package/dist/templates/_daemon/process_linux.go +55 -0
- package/dist/templates/_daemon/process_linux_test.go +161 -0
- package/dist/templates/_daemon/process_other.go +14 -0
- package/dist/templates/_daemon/testdata/child.go +41 -0
- package/dist/templates/_shared/GO-LICENSE +27 -0
- package/dist/templates/_shared/GO-PATENTS +22 -0
- package/dist/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
- package/dist/templates/_shared/notice-overrides/index.json +14 -0
- package/dist/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
- package/dist/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
- package/dist/templates/_shared/third-party-notices.mjs +51 -0
- package/dist/templates/binary/synology-app.yaml +7 -0
- package/dist/templates/hello-files/compose.yaml +0 -1
- package/dist/templates/hello-web/compose.yaml +13 -10
- package/dist/templates/hello-web/html/app.js +1 -23
- package/dist/templates/hello-web/html/index.html +1 -3
- package/dist/templates/hello-web-page/compose.yaml +13 -10
- package/dist/templates/hello-web-page/html/app.js +1 -23
- package/dist/templates/hello-web-page/html/index.html +1 -3
- package/dist/templates/native-go/README.md +324 -0
- package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
- package/dist/templates/native-go/backend/cmd/app/main.go +49 -0
- package/dist/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
- package/dist/templates/native-go/backend/cmd/helper/main.go +38 -0
- package/dist/templates/native-go/backend/go.mod +7 -0
- package/dist/templates/native-go/backend/go.sum +4 -0
- package/dist/templates/native-go/backend/internal/api/binary.go +154 -0
- package/dist/templates/native-go/backend/internal/api/binary_test.go +165 -0
- package/dist/templates/native-go/backend/internal/api/errors.go +33 -0
- package/dist/templates/native-go/backend/internal/api/registry.go +104 -0
- package/dist/templates/native-go/backend/internal/api/registry_test.go +329 -0
- package/dist/templates/native-go/backend/internal/api/server.go +159 -0
- package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
- package/dist/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
- package/dist/templates/native-go/backend/internal/app/root_none.go +9 -0
- package/dist/templates/native-go/backend/internal/app/routes.go +138 -0
- package/dist/templates/native-go/backend/internal/app/routes_test.go +172 -0
- package/dist/templates/native-go/backend/internal/dsm/auth.go +118 -0
- package/dist/templates/native-go/backend/internal/dsm/auth_test.go +139 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
- package/dist/templates/native-go/backend/internal/helper/cohort.go +393 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
- package/dist/templates/native-go/backend/internal/helper/control.go +424 -0
- package/dist/templates/native-go/backend/internal/helper/control_test.go +250 -0
- package/dist/templates/native-go/backend/internal/helper/data_contract.go +242 -0
- package/dist/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/data_decode.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
- package/dist/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
- package/dist/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
- package/dist/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
- package/dist/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
- package/dist/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
- package/dist/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
- package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
- package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
- package/dist/templates/native-go/backend/internal/helper/lease.go +112 -0
- package/dist/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
- package/dist/templates/native-go/backend/internal/helper/lease_other.go +8 -0
- package/dist/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
- package/dist/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
- package/dist/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
- package/dist/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
- package/dist/templates/native-go/backend/internal/helper/native_identity.go +89 -0
- package/dist/templates/native-go/backend/internal/helper/native_provider.go +159 -0
- package/dist/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
- package/dist/templates/native-go/backend/internal/helper/observation.go +204 -0
- package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
- package/dist/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
- package/dist/templates/native-go/backend/internal/helper/observation_test.go +196 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
- package/dist/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
- package/dist/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
- package/dist/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
- package/dist/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
- package/dist/templates/native-go/backend/internal/helper/peer_linux.go +44 -0
- package/dist/templates/native-go/backend/internal/helper/peer_other.go +7 -0
- package/dist/templates/native-go/backend/internal/helper/process_linux.go +177 -0
- package/dist/templates/native-go/backend/internal/helper/process_other.go +5 -0
- package/dist/templates/native-go/backend/internal/helper/publication_test.go +178 -0
- package/dist/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
- package/dist/templates/native-go/backend/internal/helper/readonly.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
- package/dist/templates/native-go/backend/internal/helper/repair.go +132 -0
- package/dist/templates/native-go/backend/internal/helper/repair_test.go +271 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
- package/dist/templates/native-go/backend/internal/helper/server_linux.go +124 -0
- package/dist/templates/native-go/backend/internal/helper/status.go +334 -0
- package/dist/templates/native-go/backend/internal/helper/status_test.go +288 -0
- package/dist/templates/native-go/backend/internal/helper/supervision.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/supervision_test.go +124 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +363 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_linux_test.go +913 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
- package/dist/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
- package/dist/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
- package/dist/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
- package/dist/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
- package/dist/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
- package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
- package/dist/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
- package/dist/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
- package/dist/templates/native-go/backend/internal/helper/write.go +77 -0
- package/dist/templates/native-go/backend/internal/helper/write_admission.go +260 -0
- package/dist/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
- package/dist/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
- package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
- package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
- package/dist/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
- package/dist/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
- package/dist/templates/native-go/backend/internal/helper/write_test.go +53 -0
- package/dist/templates/native-go/dsm-package.yaml +58 -0
- package/dist/templates/native-go/gitignore +1 -0
- package/dist/templates/native-go/i18n/glossary.json +662 -0
- package/dist/templates/native-go/i18n/messages/de.json +28 -0
- package/dist/templates/native-go/i18n/messages/en.json +28 -0
- package/dist/templates/native-go/i18n/messages/es.json +28 -0
- package/dist/templates/native-go/i18n/messages/fr.json +28 -0
- package/dist/templates/native-go/i18n/messages/it.json +28 -0
- package/dist/templates/native-go/i18n/messages/ja.json +28 -0
- package/dist/templates/native-go/i18n/messages/ko.json +28 -0
- package/dist/templates/native-go/i18n/messages/zh-CN.json +28 -0
- package/dist/templates/native-go/i18n/messages/zh-TW.json +28 -0
- package/dist/templates/native-go/ui/app.css +35 -0
- package/dist/templates/native-go/ui/app.js +101 -0
- package/dist/templates/native-go-better-auth/backend/internal/app/identity.go +208 -0
- package/dist/templates/native-go-better-auth/backend/internal/app/identity_test.go +113 -0
- package/dist/templates/native-go-better-auth/node/app.mjs +72 -0
- package/dist/templates/native-go-better-auth/node/build.mjs +4 -0
- package/dist/templates/native-go-better-auth/node/package-lock.json +862 -0
- package/dist/templates/native-go-better-auth/node/package.json +1 -0
- package/dist/templates/native-go-better-auth/node/test/auth.test.mjs +31 -0
- package/dist/templates/native-go-integration/backend/internal/app/identity_none.go +6 -0
- package/dist/templates/native-go-integration/backend/internal/app/personal.go +203 -0
- package/dist/templates/native-go-integration/backend/internal/app/personal_test.go +119 -0
- package/dist/templates/native-go-root/backend/internal/app/root.go +107 -0
- package/dist/templates/native-go-root/backend/internal/app/root_test.go +124 -0
- package/dist/templates/native-go-root/root/whoami.sh +6 -0
- package/dist/templates/native-go-vue/README.md +224 -0
- package/dist/templates/native-go-vue/frontend/DESIGN.md +78 -0
- package/dist/templates/native-go-vue/frontend/package-lock.json +2410 -0
- package/dist/templates/native-go-vue/frontend/package.json +6 -0
- package/dist/templates/native-go-vue/frontend/src/App.vue +159 -0
- package/dist/templates/native-go-vue/frontend/src/context.ts +56 -0
- package/dist/templates/native-go-vue/frontend/src/main.ts +29 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
- package/dist/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
- package/dist/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
- package/dist/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
- package/dist/templates/native-go-vue/frontend/src/style.css +31 -0
- package/dist/templates/native-go-vue/frontend/test/apps.test.ts +190 -0
- package/dist/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
- package/dist/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
- package/dist/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
- package/dist/templates/native-go-vue/frontend/tsconfig.json +1 -0
- package/dist/templates/native-go-vue/frontend/vite.config.ts +10 -0
- package/dist/templates/native-go-vue/gitignore +2 -0
- package/dist/types.d.ts +1 -1
- package/dist/validate.js +11 -7
- package/package.json +5 -8
- package/schema/synology-app.schema.json +36 -37
- package/skills/SKILL.md +4 -48
- package/skills/reference/create.md +11 -83
- package/skills/reference/deploy.md +7 -78
- package/skills/reference/diagnose.md +4 -101
- package/skills/reference/files.md +5 -41
- package/skills/reference/identity.md +3 -29
- package/skills/reference/wrap.md +0 -2
- package/templates/_daemon/fixture_linux_test.go +15 -0
- package/templates/_daemon/fixture_other_test.go +7 -0
- package/templates/_daemon/go.mod +3 -0
- package/templates/_daemon/main.go +608 -0
- package/templates/_daemon/main_test.go +242 -0
- package/templates/_daemon/process_linux.go +55 -0
- package/templates/_daemon/process_linux_test.go +161 -0
- package/templates/_daemon/process_other.go +14 -0
- package/templates/_daemon/testdata/child.go +41 -0
- package/templates/_shared/GO-LICENSE +27 -0
- package/templates/_shared/GO-PATENTS +22 -0
- package/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
- package/templates/_shared/notice-overrides/index.json +14 -0
- package/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
- package/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
- package/templates/_shared/third-party-notices.mjs +51 -0
- package/templates/binary/synology-app.yaml +7 -0
- package/templates/hello-files/compose.yaml +0 -1
- package/templates/hello-web/compose.yaml +13 -10
- package/templates/hello-web/html/app.js +1 -23
- package/templates/hello-web/html/index.html +1 -3
- package/templates/hello-web-page/compose.yaml +13 -10
- package/templates/hello-web-page/html/app.js +1 -23
- package/templates/hello-web-page/html/index.html +1 -3
- package/templates/native-go/README.md +324 -0
- package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
- package/templates/native-go/backend/cmd/app/main.go +49 -0
- package/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
- package/templates/native-go/backend/cmd/helper/main.go +38 -0
- package/templates/native-go/backend/go.mod +7 -0
- package/templates/native-go/backend/go.sum +4 -0
- package/templates/native-go/backend/internal/api/binary.go +154 -0
- package/templates/native-go/backend/internal/api/binary_test.go +165 -0
- package/templates/native-go/backend/internal/api/errors.go +33 -0
- package/templates/native-go/backend/internal/api/registry.go +104 -0
- package/templates/native-go/backend/internal/api/registry_test.go +329 -0
- package/templates/native-go/backend/internal/api/server.go +159 -0
- package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
- package/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
- package/templates/native-go/backend/internal/app/root_none.go +9 -0
- package/templates/native-go/backend/internal/app/routes.go +138 -0
- package/templates/native-go/backend/internal/app/routes_test.go +172 -0
- package/templates/native-go/backend/internal/dsm/auth.go +118 -0
- package/templates/native-go/backend/internal/dsm/auth_test.go +139 -0
- package/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
- package/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
- package/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
- package/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
- package/templates/native-go/backend/internal/helper/cohort.go +393 -0
- package/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
- package/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
- package/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
- package/templates/native-go/backend/internal/helper/control.go +424 -0
- package/templates/native-go/backend/internal/helper/control_test.go +250 -0
- package/templates/native-go/backend/internal/helper/data_contract.go +242 -0
- package/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
- package/templates/native-go/backend/internal/helper/data_decode.go +184 -0
- package/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
- package/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
- package/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
- package/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
- package/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
- package/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
- package/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
- package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
- package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
- package/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
- package/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
- package/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
- package/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
- package/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
- package/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
- package/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
- package/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
- package/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
- package/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
- package/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
- package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
- package/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
- package/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
- package/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
- package/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
- package/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
- package/templates/native-go/backend/internal/helper/lease.go +112 -0
- package/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
- package/templates/native-go/backend/internal/helper/lease_other.go +8 -0
- package/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
- package/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
- package/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
- package/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
- package/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
- package/templates/native-go/backend/internal/helper/native_identity.go +89 -0
- package/templates/native-go/backend/internal/helper/native_provider.go +159 -0
- package/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
- package/templates/native-go/backend/internal/helper/observation.go +204 -0
- package/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
- package/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
- package/templates/native-go/backend/internal/helper/observation_test.go +196 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
- package/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
- package/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
- package/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
- package/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
- package/templates/native-go/backend/internal/helper/peer_linux.go +44 -0
- package/templates/native-go/backend/internal/helper/peer_other.go +7 -0
- package/templates/native-go/backend/internal/helper/process_linux.go +177 -0
- package/templates/native-go/backend/internal/helper/process_other.go +5 -0
- package/templates/native-go/backend/internal/helper/publication_test.go +178 -0
- package/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
- package/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
- package/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
- package/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
- package/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
- package/templates/native-go/backend/internal/helper/readonly.go +105 -0
- package/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
- package/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
- package/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
- package/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
- package/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
- package/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
- package/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
- package/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
- package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
- package/templates/native-go/backend/internal/helper/repair.go +132 -0
- package/templates/native-go/backend/internal/helper/repair_test.go +271 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
- package/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
- package/templates/native-go/backend/internal/helper/server_linux.go +124 -0
- package/templates/native-go/backend/internal/helper/status.go +334 -0
- package/templates/native-go/backend/internal/helper/status_test.go +288 -0
- package/templates/native-go/backend/internal/helper/supervision.go +107 -0
- package/templates/native-go/backend/internal/helper/supervision_test.go +124 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
- package/templates/native-go/backend/internal/helper/supervisor_linux.go +363 -0
- package/templates/native-go/backend/internal/helper/supervisor_linux_test.go +913 -0
- package/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
- package/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
- package/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
- package/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
- package/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
- package/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
- package/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
- package/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
- package/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
- package/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
- package/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
- package/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
- package/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
- package/templates/native-go/backend/internal/helper/write.go +77 -0
- package/templates/native-go/backend/internal/helper/write_admission.go +260 -0
- package/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
- package/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
- package/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
- package/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
- package/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
- package/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
- package/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
- package/templates/native-go/backend/internal/helper/write_test.go +53 -0
- package/templates/native-go/dsm-package.yaml +58 -0
- package/templates/native-go/gitignore +1 -0
- package/templates/native-go/i18n/glossary.json +662 -0
- package/templates/native-go/i18n/messages/de.json +28 -0
- package/templates/native-go/i18n/messages/en.json +28 -0
- package/templates/native-go/i18n/messages/es.json +28 -0
- package/templates/native-go/i18n/messages/fr.json +28 -0
- package/templates/native-go/i18n/messages/it.json +28 -0
- package/templates/native-go/i18n/messages/ja.json +28 -0
- package/templates/native-go/i18n/messages/ko.json +28 -0
- package/templates/native-go/i18n/messages/zh-CN.json +28 -0
- package/templates/native-go/i18n/messages/zh-TW.json +28 -0
- package/templates/native-go/ui/app.css +35 -0
- package/templates/native-go/ui/app.js +101 -0
- package/templates/native-go-better-auth/backend/internal/app/identity.go +208 -0
- package/templates/native-go-better-auth/backend/internal/app/identity_test.go +113 -0
- package/templates/native-go-better-auth/node/app.mjs +72 -0
- package/templates/native-go-better-auth/node/build.mjs +4 -0
- package/templates/native-go-better-auth/node/package-lock.json +862 -0
- package/templates/native-go-better-auth/node/package.json +1 -0
- package/templates/native-go-better-auth/node/test/auth.test.mjs +31 -0
- package/templates/native-go-integration/backend/internal/app/identity_none.go +6 -0
- package/templates/native-go-integration/backend/internal/app/personal.go +203 -0
- package/templates/native-go-integration/backend/internal/app/personal_test.go +119 -0
- package/templates/native-go-root/backend/internal/app/root.go +107 -0
- package/templates/native-go-root/backend/internal/app/root_test.go +124 -0
- package/templates/native-go-root/root/whoami.sh +6 -0
- package/templates/native-go-vue/README.md +224 -0
- package/templates/native-go-vue/frontend/DESIGN.md +78 -0
- package/templates/native-go-vue/frontend/package-lock.json +2410 -0
- package/templates/native-go-vue/frontend/package.json +6 -0
- package/templates/native-go-vue/frontend/src/App.vue +159 -0
- package/templates/native-go-vue/frontend/src/context.ts +56 -0
- package/templates/native-go-vue/frontend/src/main.ts +29 -0
- package/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
- package/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
- package/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
- package/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
- package/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
- package/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
- package/templates/native-go-vue/frontend/src/style.css +31 -0
- package/templates/native-go-vue/frontend/test/apps.test.ts +190 -0
- package/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
- package/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
- package/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
- package/templates/native-go-vue/frontend/tsconfig.json +1 -0
- package/templates/native-go-vue/frontend/vite.config.ts +10 -0
- package/templates/native-go-vue/gitignore +2 -0
- package/dist/attestation/app-package.d.ts +0 -86
- package/dist/attestation/app-package.js +0 -206
- package/dist/attestation/install-on-host.d.ts +0 -14
- package/dist/attestation/install-on-host.js +0 -52
- package/dist/attestation/keyring.d.ts +0 -21
- package/dist/attestation/keyring.js +0 -168
- package/dist/attestation/platform-service.d.ts +0 -70
- package/dist/attestation/platform-service.js +0 -250
- package/dist/build-spk/broker-glue.d.ts +0 -16
- package/dist/build-spk/broker-glue.js +0 -40
- package/dist/deploy/catalog-publish.d.ts +0 -3
- package/dist/deploy/catalog-publish.js +0 -7
- package/dist/doctor.d.ts +0 -22
- package/dist/doctor.js +0 -822
- package/dist/error-collector.d.ts +0 -2
- package/dist/error-collector.js +0 -46
- package/dist/host/broker-paths.d.ts +0 -1
- package/dist/host/broker-paths.js +0 -1
- package/dist/host/broker-upgrade-preflight.d.ts +0 -61
- package/dist/host/broker-upgrade-preflight.js +0 -156
- package/dist/host/digests.d.ts +0 -5
- package/dist/host/digests.js +0 -63
- package/dist/host/fake-nas.d.ts +0 -49
- package/dist/host/fake-nas.js +0 -193
- package/dist/mock-broker/bootstrap.d.ts +0 -2
- package/dist/mock-broker/bootstrap.js +0 -8
- package/dist/mock-broker/files.d.ts +0 -60
- package/dist/mock-broker/files.js +0 -408
- package/dist/mock-broker/oidc.d.ts +0 -31
- package/dist/mock-broker/oidc.js +0 -161
- package/dist/mock-broker/path.d.ts +0 -9
- package/dist/mock-broker/path.js +0 -50
- package/dist/mock-broker/server.d.ts +0 -19
- package/dist/mock-broker/server.js +0 -350
- package/dist/publish/build-ledger.d.ts +0 -22
- package/dist/publish/build-ledger.js +0 -26
- package/dist/publish/community-path.d.ts +0 -6
- package/dist/publish/community-path.js +0 -41
- package/dist/publish/curated-release.d.ts +0 -78
- package/dist/publish/curated-release.js +0 -883
- package/dist/publish/file-build-ledger.d.ts +0 -18
- package/dist/publish/file-build-ledger.js +0 -268
- package/dist/publish/github-pr.d.ts +0 -25
- package/dist/publish/github-pr.js +0 -85
- package/dist/publish/github-repo.d.ts +0 -8
- package/dist/publish/github-repo.js +0 -21
- package/dist/publish/platform-service-release.d.ts +0 -60
- package/dist/publish/platform-service-release.js +0 -333
- package/dist/publish/preflight.d.ts +0 -24
- package/dist/publish/preflight.js +0 -138
- package/dist/publish/publish.d.ts +0 -27
- package/dist/publish/publish.js +0 -136
- package/dist/publish/sync-definition.d.ts +0 -4
- package/dist/publish/sync-definition.js +0 -48
- package/dist/release-bin.d.ts +0 -2
- package/dist/release-bin.js +0 -23
- package/dist/templates/hello-web/html/sdk.js +0 -68
- package/dist/templates/hello-web-page/html/sdk.js +0 -68
- package/dist/templates/native/synology-app.yaml +0 -7
- package/dist/test-host.d.ts +0 -15
- package/dist/test-host.js +0 -37
- package/templates/hello-web/html/sdk.js +0 -68
- package/templates/hello-web-page/html/sdk.js +0 -68
- package/templates/native/synology-app.yaml +0 -7
- /package/dist/templates/{native → binary}/native.yaml +0 -0
- /package/templates/{native → binary}/native.yaml +0 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// A standalone evidence-only static probe. No helper activation or mutation.
|
|
2
|
+
package main
|
|
3
|
+
|
|
4
|
+
import (
|
|
5
|
+
"context"
|
|
6
|
+
"dsmapp/internal/dsmprobe"
|
|
7
|
+
"encoding/json"
|
|
8
|
+
"golang.org/x/sys/unix"
|
|
9
|
+
"io"
|
|
10
|
+
"os"
|
|
11
|
+
"runtime"
|
|
12
|
+
"time"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
func main() {
|
|
16
|
+
if len(os.Args) != 2 || os.Args[1] != "--wire-v1" {
|
|
17
|
+
os.Exit(2)
|
|
18
|
+
}
|
|
19
|
+
// Watchdog owns this bounded observation; no children or services are created.
|
|
20
|
+
go func() { time.Sleep(8 * time.Second); os.Exit(124) }()
|
|
21
|
+
runtime.LockOSThread()
|
|
22
|
+
if unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != nil || unix.Prctl(unix.PR_SET_DUMPABLE, 0, 0, 0, 0) != nil {
|
|
23
|
+
os.Exit(3)
|
|
24
|
+
}
|
|
25
|
+
data, e := io.ReadAll(io.LimitReader(os.Stdin, dsmprobe.MaxRequestBytes+1))
|
|
26
|
+
if e != nil {
|
|
27
|
+
os.Exit(2)
|
|
28
|
+
}
|
|
29
|
+
request, e := dsmprobe.DecodeRequest(data)
|
|
30
|
+
if e != nil {
|
|
31
|
+
os.Exit(2)
|
|
32
|
+
}
|
|
33
|
+
ctx, cancel := context.WithTimeout(context.Background(), 7*time.Second)
|
|
34
|
+
defer cancel()
|
|
35
|
+
out, e := dsmprobe.Collect(ctx, request)
|
|
36
|
+
if e != nil {
|
|
37
|
+
out.Status = "unsupported"
|
|
38
|
+
}
|
|
39
|
+
data, e = json.Marshal(out)
|
|
40
|
+
if e != nil || len(data) > dsmprobe.MaxResponseBytes {
|
|
41
|
+
os.Exit(3)
|
|
42
|
+
}
|
|
43
|
+
if _, e = os.Stdout.Write(append(data, '\n')); e != nil {
|
|
44
|
+
os.Exit(3)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Built only when dsm-package.yaml explicitly opts into integration.
|
|
2
|
+
package main
|
|
3
|
+
|
|
4
|
+
import (
|
|
5
|
+
"context"
|
|
6
|
+
"dsmapp/internal/helper"
|
|
7
|
+
"encoding/json"
|
|
8
|
+
"fmt"
|
|
9
|
+
"os"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
var helperInventory string
|
|
13
|
+
|
|
14
|
+
func main() {
|
|
15
|
+
var i helper.Inventory
|
|
16
|
+
if len(os.Args) != 2 || json.Unmarshal([]byte(helperInventory), &i) != nil {
|
|
17
|
+
os.Exit(2)
|
|
18
|
+
}
|
|
19
|
+
if os.Args[1] == "check-stopped" || os.Args[1] == "diagnose" {
|
|
20
|
+
c, err := helper.LocalClient(i)
|
|
21
|
+
if err != nil {
|
|
22
|
+
os.Exit(1)
|
|
23
|
+
}
|
|
24
|
+
if os.Args[1] == "diagnose" {
|
|
25
|
+
json.NewEncoder(os.Stdout).Encode(c.Status(context.Background()))
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
if c.CheckStopped(context.Background()) != nil {
|
|
29
|
+
os.Exit(1)
|
|
30
|
+
}
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
if err := helper.RunLinux(i, os.Args[1]); err != nil {
|
|
34
|
+
fmt.Fprintln(os.Stderr, "helper lifecycle refused")
|
|
35
|
+
os.Exit(1)
|
|
36
|
+
}
|
|
37
|
+
fmt.Println(`{"success":true}`)
|
|
38
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ=
|
|
2
|
+
github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
|
|
3
|
+
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
|
4
|
+
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
package api
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"context"
|
|
6
|
+
"encoding/json"
|
|
7
|
+
"io"
|
|
8
|
+
"net/http"
|
|
9
|
+
"regexp"
|
|
10
|
+
"strconv"
|
|
11
|
+
"sync"
|
|
12
|
+
"time"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const MaxBinaryReadBytes = 1 << 20
|
|
16
|
+
const BinaryReadTimeout = 10 * time.Second
|
|
17
|
+
|
|
18
|
+
// Control IDs are not bearer authority. The trusted adapter must revalidate
|
|
19
|
+
// the original caller/session, epoch, grant revision and every chunk ticket.
|
|
20
|
+
// The fixed route accepts no path, offset, range, URL, filename or MIME type.
|
|
21
|
+
type BinaryReadRequest struct {
|
|
22
|
+
OperationID string `json:"operationId"`
|
|
23
|
+
Epoch string `json:"epoch"`
|
|
24
|
+
Token string `json:"token"`
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Body must implement Close concurrently with Read and unblock it on Close.
|
|
28
|
+
// Close releases/cancels the helper transfer; it is not itself a Q receipt.
|
|
29
|
+
type BinaryRead struct {
|
|
30
|
+
Body io.ReadCloser
|
|
31
|
+
Bytes uint64
|
|
32
|
+
OperationID string
|
|
33
|
+
}
|
|
34
|
+
type BinaryReadHandler func(context.Context, Caller, *http.Request, json.RawMessage) (BinaryRead, error)
|
|
35
|
+
|
|
36
|
+
func BoundedRead(h BinaryReadHandler) Route {
|
|
37
|
+
return Route{method: "nas.files.read.binary", policy: policyUser, binary: h}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var binaryReference = regexp.MustCompile(`^[a-f0-9]{64}$`)
|
|
41
|
+
|
|
42
|
+
func serveBoundedRead(w http.ResponseWriter, r *http.Request, c Caller, params json.RawMessage, h BinaryReadHandler) {
|
|
43
|
+
if r.Context().Err() != nil {
|
|
44
|
+
writeError(w, &Error{"canceled", "read canceled"})
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
if r.Header.Get("Range") != "" {
|
|
48
|
+
writeError(w, BadRequest("ranges are unsupported"))
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
in, ok := decodeBinaryReadControl(params)
|
|
52
|
+
if !ok {
|
|
53
|
+
writeError(w, BadRequest("invalid binary read control"))
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
ctx, cancel := context.WithTimeout(r.Context(), BinaryReadTimeout)
|
|
57
|
+
defer cancel()
|
|
58
|
+
result, err := h(ctx, c, r, params)
|
|
59
|
+
if err != nil {
|
|
60
|
+
if result.Body != nil {
|
|
61
|
+
result.Body.Close()
|
|
62
|
+
}
|
|
63
|
+
writeError(w, asError(err))
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
if result.Body == nil {
|
|
67
|
+
writeError(w, internalError)
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
var once sync.Once
|
|
71
|
+
var closeErr error
|
|
72
|
+
closeBody := func() { once.Do(func() { closeErr = result.Body.Close() }) }
|
|
73
|
+
defer closeBody()
|
|
74
|
+
if result.Bytes > MaxBinaryReadBytes || result.OperationID != in.OperationID {
|
|
75
|
+
writeError(w, BadRequest("invalid bounded read result"))
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
stop := make(chan struct{})
|
|
79
|
+
done := make(chan struct{})
|
|
80
|
+
go func() {
|
|
81
|
+
defer close(done)
|
|
82
|
+
select {
|
|
83
|
+
case <-ctx.Done():
|
|
84
|
+
closeBody()
|
|
85
|
+
case <-stop:
|
|
86
|
+
}
|
|
87
|
+
}()
|
|
88
|
+
// Materialize only the bounded response so short/error/overlong transfers
|
|
89
|
+
// cannot become successful binary responses. Helper relay still leases at
|
|
90
|
+
// most one 64KiB chunk. Long CGI streaming remains disabled pending DSM proof.
|
|
91
|
+
body, readErr := io.ReadAll(io.LimitReader(result.Body, int64(result.Bytes)+1))
|
|
92
|
+
closeBody()
|
|
93
|
+
close(stop)
|
|
94
|
+
<-done
|
|
95
|
+
if ctx.Err() != nil {
|
|
96
|
+
writeError(w, &Error{"canceled", "read expired or canceled"})
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
if readErr != nil || closeErr != nil || uint64(len(body)) != result.Bytes {
|
|
100
|
+
writeError(w, &Error{"read_failed", "binary read failed"})
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
headers := w.Header()
|
|
104
|
+
headers.Set("Content-Type", "application/octet-stream")
|
|
105
|
+
headers.Set("Content-Length", strconv.FormatUint(result.Bytes, 10))
|
|
106
|
+
headers.Set("Cache-Control", "no-store")
|
|
107
|
+
headers.Set("X-Content-Type-Options", "nosniff")
|
|
108
|
+
w.WriteHeader(http.StatusOK)
|
|
109
|
+
// Go CGI may buffer or block stdout. All helper resources have already been
|
|
110
|
+
// released; there is no long-stream readiness claim from this bounded write.
|
|
111
|
+
_, _ = w.Write(body)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Fixed shape with duplicate-key rejection, so two parsers cannot bind a token
|
|
115
|
+
// to different operations. Controls never grow the existing ctx.call envelope.
|
|
116
|
+
func decodeBinaryReadControl(raw json.RawMessage) (BinaryReadRequest, bool) {
|
|
117
|
+
var in BinaryReadRequest
|
|
118
|
+
if len(raw) > 16*1024 {
|
|
119
|
+
return in, false
|
|
120
|
+
}
|
|
121
|
+
d := json.NewDecoder(bytes.NewReader(raw))
|
|
122
|
+
first, e := d.Token()
|
|
123
|
+
if e != nil || first != json.Delim('{') {
|
|
124
|
+
return in, false
|
|
125
|
+
}
|
|
126
|
+
seen := map[string]bool{}
|
|
127
|
+
for d.More() {
|
|
128
|
+
token, e := d.Token()
|
|
129
|
+
key, ok := token.(string)
|
|
130
|
+
if e != nil || !ok || seen[key] {
|
|
131
|
+
return in, false
|
|
132
|
+
}
|
|
133
|
+
seen[key] = true
|
|
134
|
+
var value string
|
|
135
|
+
if d.Decode(&value) != nil {
|
|
136
|
+
return in, false
|
|
137
|
+
}
|
|
138
|
+
switch key {
|
|
139
|
+
case "operationId":
|
|
140
|
+
in.OperationID = value
|
|
141
|
+
case "epoch":
|
|
142
|
+
in.Epoch = value
|
|
143
|
+
case "token":
|
|
144
|
+
in.Token = value
|
|
145
|
+
default:
|
|
146
|
+
return in, false
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
end, e := d.Token()
|
|
150
|
+
if e != nil || end != json.Delim('}') || d.Decode(new(any)) != io.EOF {
|
|
151
|
+
return in, false
|
|
152
|
+
}
|
|
153
|
+
return in, binaryReference.MatchString(in.OperationID) && binaryReference.MatchString(in.Epoch) && binaryReference.MatchString(in.Token)
|
|
154
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
package api
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"context"
|
|
6
|
+
"encoding/json"
|
|
7
|
+
"io"
|
|
8
|
+
"net/http"
|
|
9
|
+
"net/http/cgi"
|
|
10
|
+
"net/http/httptest"
|
|
11
|
+
"os"
|
|
12
|
+
"strings"
|
|
13
|
+
"sync"
|
|
14
|
+
"testing"
|
|
15
|
+
"time"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
type binarySource struct {
|
|
19
|
+
io.Reader
|
|
20
|
+
closed bool
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func (s *binarySource) Close() error { s.closed = true; return nil }
|
|
24
|
+
func TestBoundedReadBinaryGuardAndBody(t *testing.T) {
|
|
25
|
+
for _, kind := range []string{"valid", "anonymous", "cross-origin", "oversize", "short", "nil", "cancel"} {
|
|
26
|
+
t.Run(kind, func(t *testing.T) {
|
|
27
|
+
auth := &fakeAuth{user: "normal1"}
|
|
28
|
+
if kind == "anonymous" {
|
|
29
|
+
auth.err = ErrNoSession
|
|
30
|
+
}
|
|
31
|
+
src := &binarySource{Reader: bytes.NewReader([]byte{0, 1, 255, 10})}
|
|
32
|
+
called := false
|
|
33
|
+
srv, e := NewServer(auth, BoundedRead(func(ctx context.Context, c Caller, r *http.Request, params json.RawMessage) (BinaryRead, error) {
|
|
34
|
+
called = true
|
|
35
|
+
if !c.Authenticated() || c.User() != "normal1" {
|
|
36
|
+
t.Fatal(c)
|
|
37
|
+
}
|
|
38
|
+
n := uint64(4)
|
|
39
|
+
if kind == "oversize" {
|
|
40
|
+
n = MaxBinaryReadBytes + 1
|
|
41
|
+
}
|
|
42
|
+
if kind == "short" {
|
|
43
|
+
n = 5
|
|
44
|
+
}
|
|
45
|
+
if kind == "nil" {
|
|
46
|
+
return BinaryRead{}, nil
|
|
47
|
+
}
|
|
48
|
+
return BinaryRead{Body: src, Bytes: n, OperationID: strings.Repeat("a", 64)}, nil
|
|
49
|
+
}))
|
|
50
|
+
if e != nil {
|
|
51
|
+
t.Fatal(e)
|
|
52
|
+
}
|
|
53
|
+
r := httptest.NewRequest("POST", "http://nas.local/cgi/api.cgi", strings.NewReader(`{"method":"nas.files.read.binary","params":{"operationId":"`+strings.Repeat("a", 64)+`","epoch":"`+strings.Repeat("b", 64)+`","token":"`+strings.Repeat("c", 64)+`"}}`))
|
|
54
|
+
r.Header.Set("Content-Type", "application/json")
|
|
55
|
+
if kind == "cross-origin" {
|
|
56
|
+
r.Header.Set("Origin", "http://evil.local")
|
|
57
|
+
}
|
|
58
|
+
if kind == "cancel" {
|
|
59
|
+
ctx, cancel := context.WithCancel(r.Context())
|
|
60
|
+
cancel()
|
|
61
|
+
r = r.WithContext(ctx)
|
|
62
|
+
}
|
|
63
|
+
w := httptest.NewRecorder()
|
|
64
|
+
srv.ServeHTTP(w, r)
|
|
65
|
+
if kind == "valid" {
|
|
66
|
+
if w.Header().Get("Content-Type") != "application/octet-stream" || !bytes.Equal(w.Body.Bytes(), []byte{0, 1, 255, 10}) || w.Header().Get("Content-Length") != "4" || !src.closed {
|
|
67
|
+
t.Fatal(w.Body.String(), w.Header())
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
if w.Header().Get("Content-Type") != "application/json" {
|
|
71
|
+
t.Fatal("invalid binary escaped")
|
|
72
|
+
}
|
|
73
|
+
if (kind == "anonymous" || kind == "cross-origin" || kind == "cancel") && called {
|
|
74
|
+
t.Fatal("handler called before guards")
|
|
75
|
+
}
|
|
76
|
+
if called && kind != "nil" && !src.closed {
|
|
77
|
+
t.Fatal("source not closed")
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
type blockedBinarySource struct {
|
|
85
|
+
done chan struct{}
|
|
86
|
+
once sync.Once
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
func (s *blockedBinarySource) Read([]byte) (int, error) { <-s.done; return 0, io.ErrClosedPipe }
|
|
90
|
+
func (s *blockedBinarySource) Close() error { s.once.Do(func() { close(s.done) }); return nil }
|
|
91
|
+
func TestBoundedBinaryDisconnectCancelsSource(t *testing.T) {
|
|
92
|
+
src := &blockedBinarySource{done: make(chan struct{})}
|
|
93
|
+
started := make(chan struct{})
|
|
94
|
+
srv, e := NewServer(&fakeAuth{user: "normal1"}, BoundedRead(func(context.Context, Caller, *http.Request, json.RawMessage) (BinaryRead, error) {
|
|
95
|
+
close(started)
|
|
96
|
+
return BinaryRead{Body: src, Bytes: 1, OperationID: strings.Repeat("a", 64)}, nil
|
|
97
|
+
}))
|
|
98
|
+
if e != nil {
|
|
99
|
+
t.Fatal(e)
|
|
100
|
+
}
|
|
101
|
+
ctx, cancel := context.WithCancel(context.Background())
|
|
102
|
+
r := httptest.NewRequest("POST", "http://nas.local/cgi/api.cgi", strings.NewReader(`{"method":"nas.files.read.binary","params":{"operationId":"`+strings.Repeat("a", 64)+`","epoch":"`+strings.Repeat("b", 64)+`","token":"`+strings.Repeat("c", 64)+`"}}`)).WithContext(ctx)
|
|
103
|
+
r.Header.Set("Content-Type", "application/json")
|
|
104
|
+
done := make(chan struct{})
|
|
105
|
+
go func() { defer close(done); srv.ServeHTTP(httptest.NewRecorder(), r) }()
|
|
106
|
+
<-started
|
|
107
|
+
cancel()
|
|
108
|
+
select {
|
|
109
|
+
case <-done:
|
|
110
|
+
case <-time.After(time.Second):
|
|
111
|
+
t.Fatal("disconnect did not release bounded source")
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
func TestBoundedBinaryRejectsCallerPathsAndTransferSubstitution(t *testing.T) {
|
|
115
|
+
calls := 0
|
|
116
|
+
srv, e := NewServer(&fakeAuth{user: "normal1"}, BoundedRead(func(context.Context, Caller, *http.Request, json.RawMessage) (BinaryRead, error) {
|
|
117
|
+
calls++
|
|
118
|
+
return BinaryRead{}, nil
|
|
119
|
+
}))
|
|
120
|
+
if e != nil {
|
|
121
|
+
t.Fatal(e)
|
|
122
|
+
}
|
|
123
|
+
for _, params := range []string{`{}`, `{"operationId":"x"}`, `{"operationId":"` + strings.Repeat("a", 64) + `","epoch":"` + strings.Repeat("b", 64) + `","token":"` + strings.Repeat("c", 64) + `","path":"/secret"}`} {
|
|
124
|
+
_, env := post(t, srv, `{"method":"nas.files.read.binary","params":`+params+`}`)
|
|
125
|
+
if env.Success || env.Error == nil || env.Error.Code != "bad_request" {
|
|
126
|
+
t.Fatal(env)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if calls != 0 {
|
|
130
|
+
t.Fatal("invalid control reached adapter")
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
func TestBoundedBinaryRealCGIWire(t *testing.T) {
|
|
135
|
+
requestBody := `{"method":"nas.files.read.binary","params":{"operationId":"` + strings.Repeat("a", 64) + `","epoch":"` + strings.Repeat("b", 64) + `","token":"` + strings.Repeat("c", 64) + `"}}`
|
|
136
|
+
h := &cgi.Handler{Path: os.Args[0], Args: []string{"-test.run=TestBoundedBinaryCGIProcessFixture"}, Env: []string{"S6_CGI_FIXTURE=1"}}
|
|
137
|
+
r := httptest.NewRequest("POST", "http://nas.local/cgi/api.cgi", strings.NewReader(requestBody))
|
|
138
|
+
r.Header.Set("Content-Type", "application/json")
|
|
139
|
+
w := httptest.NewRecorder()
|
|
140
|
+
h.ServeHTTP(w, r)
|
|
141
|
+
if w.Code != http.StatusOK || w.Header().Get("Content-Type") != "application/octet-stream" || w.Header().Get("Content-Length") != "1048576" || !bytes.Equal(w.Body.Bytes(), bytes.Repeat([]byte{0, 255, 10, 13}, MaxBinaryReadBytes/4)) {
|
|
142
|
+
t.Fatal(w.Code, w.Header(), w.Body.Len())
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
func TestBoundedBinaryCGIProcessFixture(t *testing.T) {
|
|
146
|
+
if os.Getenv("S6_CGI_FIXTURE") != "1" {
|
|
147
|
+
t.Skip("spawned CGI-only process")
|
|
148
|
+
}
|
|
149
|
+
srv, e := NewServer(&fakeAuth{user: "normal1"}, BoundedRead(func(context.Context, Caller, *http.Request, json.RawMessage) (BinaryRead, error) {
|
|
150
|
+
return BinaryRead{Body: io.NopCloser(bytes.NewReader(bytes.Repeat([]byte{0, 255, 10, 13}, MaxBinaryReadBytes/4))), Bytes: MaxBinaryReadBytes, OperationID: strings.Repeat("a", 64)}, nil
|
|
151
|
+
}))
|
|
152
|
+
if e != nil {
|
|
153
|
+
os.Exit(1)
|
|
154
|
+
}
|
|
155
|
+
if cgi.Serve(srv) != nil {
|
|
156
|
+
os.Exit(1)
|
|
157
|
+
}
|
|
158
|
+
os.Exit(0)
|
|
159
|
+
}
|
|
160
|
+
func TestBinaryControlRejectsDuplicates(t *testing.T) {
|
|
161
|
+
raw := `{"operationId":"` + strings.Repeat("a", 64) + `","epoch":"` + strings.Repeat("b", 64) + `","token":"` + strings.Repeat("c", 64) + `","token":"` + strings.Repeat("d", 64) + `"}`
|
|
162
|
+
if _, ok := decodeBinaryReadControl(json.RawMessage(raw)); ok {
|
|
163
|
+
t.Fatal("duplicate transfer token")
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package api
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"errors"
|
|
5
|
+
"log"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
// Error is an API error the browser may see. Any other error a handler
|
|
9
|
+
// returns is logged and reported only as "internal". Errors travel in the
|
|
10
|
+
// JSON envelope with HTTP 200, as DSM's own WebAPI does: DSM's web server
|
|
11
|
+
// replaces the body of a CGI's 403, 404 and 5xx replies with its own page.
|
|
12
|
+
type Error struct {
|
|
13
|
+
Code string
|
|
14
|
+
Message string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
func (e *Error) Error() string { return e.Code + ": " + e.Message }
|
|
18
|
+
|
|
19
|
+
// BadRequest reports invalid params.
|
|
20
|
+
func BadRequest(message string) *Error {
|
|
21
|
+
return &Error{"bad_request", message}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var internalError = &Error{"internal", "internal error"}
|
|
25
|
+
|
|
26
|
+
func asError(err error) *Error {
|
|
27
|
+
var apiErr *Error
|
|
28
|
+
if errors.As(err, &apiErr) {
|
|
29
|
+
return apiErr
|
|
30
|
+
}
|
|
31
|
+
log.Printf("handler error: %v", err)
|
|
32
|
+
return internalError
|
|
33
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Package api is the package's one HTTP entry point. Every request passes the
|
|
2
|
+
// same transport guards and, unless its route was explicitly declared Public,
|
|
3
|
+
// one DSM authentication before any handler runs. The policy is part of the
|
|
4
|
+
// route itself: a Route can only be made through User, Admin or Public, so a
|
|
5
|
+
// handler cannot be registered without saying who may call it.
|
|
6
|
+
package api
|
|
7
|
+
|
|
8
|
+
import (
|
|
9
|
+
"context"
|
|
10
|
+
"encoding/json"
|
|
11
|
+
"errors"
|
|
12
|
+
"fmt"
|
|
13
|
+
"regexp"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
type policy int
|
|
17
|
+
|
|
18
|
+
const (
|
|
19
|
+
policyUnset policy = iota
|
|
20
|
+
policyUser
|
|
21
|
+
policyAdmin
|
|
22
|
+
policyPublic
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
// Handler runs one business operation. It receives the caller the server
|
|
26
|
+
// verified and the raw `params` object; it decodes params itself.
|
|
27
|
+
type Handler func(ctx context.Context, caller Caller, params json.RawMessage) (any, error)
|
|
28
|
+
|
|
29
|
+
// Route binds a method name to its handler and access policy. Its fields are
|
|
30
|
+
// private: build routes with User, Admin or Public.
|
|
31
|
+
type Route struct {
|
|
32
|
+
method string
|
|
33
|
+
policy policy
|
|
34
|
+
handler Handler
|
|
35
|
+
binary BinaryReadHandler
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// User declares an operation any signed-in DSM user may call.
|
|
39
|
+
func User(method string, h Handler) Route {
|
|
40
|
+
return Route{method: method, policy: policyUser, handler: h}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Admin declares an operation only members of DSM's administrators group may call.
|
|
44
|
+
func Admin(method string, h Handler) Route {
|
|
45
|
+
return Route{method: method, policy: policyAdmin, handler: h}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Public declares an operation that runs WITHOUT a DSM session. Use it only for
|
|
49
|
+
// data that is safe to show anyone who can reach the NAS's DSM port.
|
|
50
|
+
func Public(method string, h Handler) Route {
|
|
51
|
+
return Route{method: method, policy: policyPublic, handler: h}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Identity is what an Authenticator established about the requester.
|
|
55
|
+
type Identity struct {
|
|
56
|
+
User string
|
|
57
|
+
Admin bool
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Caller is the verified requester handed to handlers. Only the server sets
|
|
61
|
+
// its fields, so a handler cannot fabricate an authenticated caller; the zero
|
|
62
|
+
// value carries no authority.
|
|
63
|
+
type Caller struct {
|
|
64
|
+
identity Identity
|
|
65
|
+
authenticated bool
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
func (c Caller) Authenticated() bool { return c.authenticated }
|
|
69
|
+
func (c Caller) User() string { return c.identity.User }
|
|
70
|
+
func (c Caller) Admin() bool { return c.authenticated && c.identity.Admin }
|
|
71
|
+
|
|
72
|
+
var methodName = regexp.MustCompile(`^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$`)
|
|
73
|
+
|
|
74
|
+
func buildRegistry(routes []Route) (map[string]Route, error) {
|
|
75
|
+
registry := make(map[string]Route, len(routes))
|
|
76
|
+
for _, r := range routes {
|
|
77
|
+
if r.policy == policyUnset {
|
|
78
|
+
return nil, errors.New("route without access policy: build it with api.User, api.Admin or api.Public")
|
|
79
|
+
}
|
|
80
|
+
if !methodName.MatchString(r.method) {
|
|
81
|
+
return nil, fmt.Errorf("route %q: method must look like \"area.action\" (lowercase)", r.method)
|
|
82
|
+
}
|
|
83
|
+
if r.binary != nil && (r.method != "nas.files.read.binary" || r.policy != policyUser || r.handler != nil) {
|
|
84
|
+
return nil, errors.New("binary read must use the fixed authenticated route")
|
|
85
|
+
}
|
|
86
|
+
if r.handler == nil && r.binary == nil {
|
|
87
|
+
return nil, fmt.Errorf("route %q has no handler", r.method)
|
|
88
|
+
}
|
|
89
|
+
if _, dup := registry[r.method]; dup {
|
|
90
|
+
return nil, fmt.Errorf("route %q is registered twice", r.method)
|
|
91
|
+
}
|
|
92
|
+
registry[r.method] = r
|
|
93
|
+
}
|
|
94
|
+
return registry, nil
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Method is the route's method name, e.g. "greeting.set".
|
|
98
|
+
func (r Route) Method() string { return r.method }
|
|
99
|
+
|
|
100
|
+
// Public reports whether the route was declared with Public.
|
|
101
|
+
func (r Route) Public() bool { return r.policy == policyPublic }
|
|
102
|
+
|
|
103
|
+
// AdminOnly reports whether the route was declared with Admin.
|
|
104
|
+
func (r Route) AdminOnly() bool { return r.policy == policyAdmin }
|