@voxgig/sdkgen 4.9.0 → 4.11.0
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/bin/voxgig-sdkgen +1 -1
- package/dist/helpers/manifest.d.ts +2 -1
- package/dist/helpers/manifest.js +75 -1
- package/dist/helpers/manifest.js.map +1 -1
- package/dist/helpers/modelNames.d.ts +7 -0
- package/dist/helpers/modelNames.js +232 -0
- package/dist/helpers/modelNames.js.map +1 -0
- package/dist/helpers/naming.d.ts +2 -1
- package/dist/helpers/naming.js +45 -1
- package/dist/helpers/naming.js.map +1 -1
- package/dist/sdkgen.d.ts +3 -2
- package/dist/sdkgen.js +12 -3
- package/dist/sdkgen.js.map +1 -1
- package/dist/testkit.d.ts +2 -0
- package/dist/testkit.js +80 -24
- package/dist/testkit.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utility.js +17 -7
- package/dist/utility.js.map +1 -1
- package/package.json +1 -1
- package/project/.sdk/model/feature/secrets.aon +1001 -0
- package/project/.sdk/model/target/c.aon +15 -2
- package/project/.sdk/model/target/clojure.aon +10 -0
- package/project/.sdk/model/target/cpp.aon +18 -0
- package/project/.sdk/model/target/csharp.aon +5 -0
- package/project/.sdk/model/target/elixir.aon +6 -0
- package/project/.sdk/model/target/java.aon +5 -0
- package/project/.sdk/model/target/js.aon +5 -0
- package/project/.sdk/model/target/kotlin.aon +7 -0
- package/project/.sdk/model/target/lua.aon +17 -0
- package/project/.sdk/model/target/ocaml.aon +48 -5
- package/project/.sdk/model/target/perl.aon +5 -0
- package/project/.sdk/model/target/php.aon +5 -0
- package/project/.sdk/model/target/rb.aon +5 -0
- package/project/.sdk/model/target/rust.aon +5 -0
- package/project/.sdk/model/target/scala.aon +38 -2
- package/project/.sdk/model/target/swift.aon +10 -0
- package/project/.sdk/model/target/zig.aon +30 -4
- package/project/.sdk/src/cmp/c/Config_c.ts +338 -1
- package/project/.sdk/src/cmp/c/Main_c.ts +57 -2
- package/project/.sdk/src/cmp/c/Package_c.ts +12 -2
- package/project/.sdk/src/cmp/clojure/Config_clojure.ts +51 -4
- package/project/.sdk/src/cmp/clojure/Main_clojure.ts +43 -1
- package/project/.sdk/src/cmp/clojure/Package_clojure.ts +17 -1
- package/project/.sdk/src/cmp/clojure/featureextra_clojure.ts +130 -0
- package/project/.sdk/src/cmp/cpp/Config_cpp.ts +324 -2
- package/project/.sdk/src/cmp/cpp/Gitignore_cpp.ts +2 -0
- package/project/.sdk/src/cmp/cpp/Main_cpp.ts +62 -4
- package/project/.sdk/src/cmp/cpp/Package_cpp.ts +10 -0
- package/project/.sdk/src/cmp/csharp/Config_csharp.ts +70 -0
- package/project/.sdk/src/cmp/csharp/Main_csharp.ts +9 -1
- package/project/.sdk/src/cmp/csharp/Package_csharp.ts +25 -1
- package/project/.sdk/src/cmp/elixir/Config_elixir.ts +68 -2
- package/project/.sdk/src/cmp/elixir/Main_elixir.ts +16 -0
- package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +14 -1
- package/project/.sdk/src/cmp/java/Config_java.ts +84 -2
- package/project/.sdk/src/cmp/java/Main_java.ts +10 -1
- package/project/.sdk/src/cmp/js/Config_js.ts +75 -8
- package/project/.sdk/src/cmp/js/Main_js.ts +66 -2
- package/project/.sdk/src/cmp/js/fragment/Config.data.fragment.js +18 -1
- package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +18 -1
- package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +7 -0
- package/project/.sdk/src/cmp/kotlin/Config_kotlin.ts +63 -1
- package/project/.sdk/src/cmp/kotlin/Main_kotlin.ts +32 -2
- package/project/.sdk/src/cmp/lua/Config_lua.ts +88 -0
- package/project/.sdk/src/cmp/lua/Gitignore_lua.ts +4 -0
- package/project/.sdk/src/cmp/lua/Main_lua.ts +93 -3
- package/project/.sdk/src/cmp/lua/Package_lua.ts +60 -0
- package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +10 -0
- package/project/.sdk/src/cmp/ocaml/Config_ocaml.ts +183 -5
- package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +160 -3
- package/project/.sdk/src/cmp/ocaml/Package_ocaml.ts +25 -1
- package/project/.sdk/src/cmp/perl/Config_perl.ts +129 -3
- package/project/.sdk/src/cmp/perl/Main_perl.ts +41 -1
- package/project/.sdk/src/cmp/perl/Package_perl.ts +13 -1
- package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +1 -0
- package/project/.sdk/src/cmp/php/Config_php.ts +105 -1
- package/project/.sdk/src/cmp/php/Gitignore_php.ts +4 -2
- package/project/.sdk/src/cmp/php/Main_php.ts +16 -1
- package/project/.sdk/src/cmp/rb/Config_rb.ts +92 -2
- package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +11 -1
- package/project/.sdk/src/cmp/rb/Main_rb.ts +7 -1
- package/project/.sdk/src/cmp/rust/Main_rust.ts +99 -1
- package/project/.sdk/src/cmp/rust/Package_rust.ts +72 -6
- package/project/.sdk/src/cmp/scala/Config_scala.ts +44 -0
- package/project/.sdk/src/cmp/scala/Main_scala.ts +68 -1
- package/project/.sdk/src/cmp/swift/Config_swift.ts +62 -1
- package/project/.sdk/src/cmp/swift/Main_swift.ts +35 -1
- package/project/.sdk/src/cmp/swift/Package_swift.ts +81 -11
- package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +58 -44
- package/project/.sdk/src/cmp/swift/utility_swift.ts +22 -0
- package/project/.sdk/src/cmp/zig/Config_zig.ts +130 -9
- package/project/.sdk/src/cmp/zig/Main_zig.ts +208 -4
- package/project/.sdk/{tm/zig/build.zig → src/cmp/zig/fragment/Build.fragment.zig} +7 -0
- package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +25 -0
- package/project/.sdk/{tm/zig/root.zig → src/cmp/zig/fragment/Root.fragment.zig} +9 -0
- package/project/.sdk/tm/c/Makefile +58 -9
- package/project/.sdk/tm/c/core/sdk.h +10 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/capability.c +133 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/capability.h +39 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/catalog.c +83 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/catalog.h +48 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/config.c +413 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/config.h +24 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/depend.c +264 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/depend.h +29 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/env.c +220 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/env.h +19 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/export.c +97 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/export.h +19 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/graph.c +237 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/graph.h +17 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/host.c +1494 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/host.h +135 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/order.c +288 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/order.h +18 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/point.c +141 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/point.h +80 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/ref.c +170 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/ref.h +52 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/resolve.c +98 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/resolve.h +18 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/types.c +150 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/types.h +104 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/value.c +649 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/value.h +135 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/version.c +151 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/version.h +34 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/aws.c +281 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/azuresecrets.c +207 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/boru.c +164 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/clock.c +75 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/doppler.c +141 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/encode.c +144 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/gcpsecrets.c +177 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/hashicorp.c +239 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/httpjson.c +599 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/infisical.c +165 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/onepassword.c +194 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/proc.c +233 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/secretspec.c +125 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/sekretoplugins.h +125 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/sha256.c +270 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/sigv4.c +382 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/support.h +153 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/tls.c +420 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/internal.h +86 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/json.c +721 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/providers.c +813 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.c +944 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.h +490 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/util.c +442 -0
- package/project/.sdk/tm/c/feature/secrets.c +797 -0
- package/project/.sdk/tm/c/feature/secrets.h +46 -0
- package/project/.sdk/tm/c/tests/feature/secrets/secrets_test.c +802 -0
- package/project/.sdk/tm/c/tests/vendor/omni/json.c +2 -2
- package/project/.sdk/tm/c/tests/vendor/omni/omni.h +2 -2
- package/project/.sdk/tm/c/tests/vendor/omni/runner.c +2 -2
- package/project/.sdk/tm/c/tests/vendor/omni/util.c +2 -2
- package/project/.sdk/tm/clojure/Makefile +3 -0
- package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +530 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/capability.clj +84 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/catalog.clj +44 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/config.clj +240 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/depend.clj +199 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/env.clj +111 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/export.clj +46 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/graph.clj +122 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/host.clj +1018 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/json.clj +106 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/order.clj +157 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/point.clj +77 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/ref.clj +92 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/resolve.clj +46 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/types.clj +177 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/version.clj +90 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin.clj +40 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/addr.clj +111 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/chain.clj +297 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/core.clj +192 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/json.clj +261 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/aws.clj +165 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/azuresecrets.clj +111 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/boru.clj +107 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/doppler.clj +61 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/gcpsecrets.clj +88 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/hashicorp.clj +115 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/httpjson.clj +214 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/infisical.clj +80 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/onepassword.clj +93 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/proc.clj +63 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/secretspec.clj +99 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/sigv4.clj +142 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/provider.clj +25 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/providers.clj +196 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto.clj +113 -0
- package/project/.sdk/tm/clojure/src/sdk/core.clj +9 -0
- package/project/.sdk/tm/clojure/src/sdk/features.clj +13 -1
- package/project/.sdk/tm/clojure/test/sdk/test/feature/secrets.clj +581 -0
- package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +103 -14
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/json.clj +2 -2
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/runner.clj +2 -2
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/util.clj +2 -2
- package/project/.sdk/tm/cpp/Makefile +48 -4
- package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.cpp +121 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.hpp +41 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.cpp +60 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.hpp +66 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/config.cpp +376 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/config.hpp +29 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.cpp +230 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.hpp +31 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/env.cpp +205 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/env.hpp +25 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/export.cpp +84 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/export.hpp +24 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.cpp +222 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.hpp +21 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/host.cpp +1200 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/host.hpp +250 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/order.cpp +250 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/order.hpp +22 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/point.cpp +110 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/point.hpp +79 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.cpp +136 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.hpp +60 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.cpp +82 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.hpp +25 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/types.cpp +90 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/types.hpp +65 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/value.cpp +491 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/value.hpp +120 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/version.cpp +143 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/version.hpp +36 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.cpp +248 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.hpp +30 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.cpp +149 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.cpp +117 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.hpp +27 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.cpp +180 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.hpp +52 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.cpp +87 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.cpp +121 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.cpp +153 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.cpp +666 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.hpp +160 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.cpp +123 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.cpp +125 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.cpp +223 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.hpp +47 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.cpp +104 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.hpp +27 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.cpp +242 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.hpp +58 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.cpp +260 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.hpp +47 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.cpp +476 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.hpp +89 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.cpp +312 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.hpp +263 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.cpp +354 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.hpp +111 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.cpp +613 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.hpp +227 -0
- package/project/.sdk/tm/cpp/feature/secrets.hpp +745 -0
- package/project/.sdk/tm/cpp/test/feature/secrets/secrets_test.cpp +808 -0
- package/project/.sdk/tm/cpp/test/vendor/omni/json.hpp +2 -2
- package/project/.sdk/tm/cpp/test/vendor/omni/omni.hpp +2 -2
- package/project/.sdk/tm/cpp/test/vendor/omni/util.hpp +2 -2
- package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +915 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Capability.cs +196 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Catalog.cs +70 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Config.cs +505 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Definition.cs +52 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Depend.cs +285 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Entry.cs +55 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Env.cs +228 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Export.cs +102 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Graph.cs +256 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Host.cs +1379 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Inst.cs +177 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Json.cs +326 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Order.cs +295 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Plugin.cs +113 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Point.cs +177 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Refs.cs +198 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Resolve.cs +95 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Types.cs +351 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Version.cs +196 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Aws.cs +325 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/AzureSecrets.cs +195 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Boru.cs +192 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Child.cs +75 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Doppler.cs +112 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/GcpSecrets.cs +167 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Hashicorp.cs +221 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/HttpJson.cs +213 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Infisical.cs +155 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/OnePassword.cs +169 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/SecretSpec.cs +172 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Sigv4.cs +240 -0
- package/project/.sdk/tm/csharp/feature/secrets/sekreto/Json.cs +192 -0
- package/project/.sdk/tm/csharp/feature/secrets/sekreto/Providers.cs +503 -0
- package/project/.sdk/tm/csharp/feature/secrets/sekreto/Sekreto.cs +775 -0
- package/project/.sdk/tm/csharp/test/feature/secrets/SecretsFeatureTest.cs +1787 -0
- package/project/.sdk/tm/csharp/test/vendor/omni/Runner.cs +2 -2
- package/project/.sdk/tm/csharp/test/vendor/omni/Util.cs +2 -2
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +10 -0
- package/project/.sdk/tm/csharp/utility/struct/Struct.cs +1 -1
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/capability.ex +118 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/catalog.ex +56 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/config.ex +320 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/depend.ex +205 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/env.ex +166 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/error.ex +13 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/export.ex +73 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/graph.ex +185 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/host.ex +1182 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/inst.ex +139 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/json.ex +132 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/order.ex +179 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/point.ex +99 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/ref.ex +129 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/resolve.ex +59 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/types.ex +190 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/version.ex +136 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/voxgig_plugin.ex +42 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/json.ex +368 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/aws.ex +257 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/azuresecrets.ex +160 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/boru.ex +127 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/doppler.ex +96 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/gcpsecrets.ex +124 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/hashicorp.ex +162 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/http.ex +627 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/httpjson.ex +134 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/infisical.ex +125 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/onepassword.ex +152 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/proc.ex +80 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/secretspec.ex +101 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/sigv4.ex +176 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/provider.ex +67 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/providers.ex +536 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/sekreto.ex +662 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +839 -0
- package/project/.sdk/tm/elixir/test/feature/secrets/secrets_test.exs +1113 -0
- package/project/.sdk/tm/elixir/test/vendor/omni/json.ex +2 -2
- package/project/.sdk/tm/elixir/test/vendor/omni/runner.ex +2 -2
- package/project/.sdk/tm/elixir/test/vendor/omni/util.ex +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugin/capability.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/catalog.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/config.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/depend.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/env.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/export.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/graph.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/host.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/order.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/point.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/ref.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/resolve.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/types.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/util.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/version.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugins/aws/aws.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/aws/sigv4.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/azuresecrets/azuresecrets.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/boru/boru.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/doppler/doppler.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/gcpsecrets/gcpsecrets.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/hashicorp/hashicorp.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/httpjson/httpjson.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/infisical/infisical.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/onepassword/onepassword.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/secretspec/secretspec.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/sekreto/addr.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/sekreto/providers.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/sekreto/sekreto.go +2 -2
- package/project/.sdk/tm/go/feature/secrets_feature.go +48 -10
- package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +239 -0
- package/project/.sdk/tm/go/test/omni/omni.go +2 -2
- package/project/.sdk/tm/go/test/omni/util.go +2 -2
- package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +1 -1
- package/project/.sdk/tm/java/feature/SecretsFeature.java +791 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Capability.java +181 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Catalog.java +64 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Config.java +433 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Definition.java +54 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Depend.java +292 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Entry.java +49 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Env.java +204 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Export.java +93 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Graph.java +244 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Host.java +1196 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Inst.java +173 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Json.java +339 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Order.java +274 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Plugin.java +94 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/PluginException.java +37 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Point.java +172 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Refs.java +171 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Resolve.java +89 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Types.java +232 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Version.java +198 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Addr.java +142 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Builtins.java +229 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Json.java +302 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Provider.java +21 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Sekreto.java +698 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Support.java +100 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Aws.java +294 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Azuresecrets.java +164 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Boru.java +161 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Doppler.java +103 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Gcpsecrets.java +143 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Hashicorp.java +186 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Httpjson.java +192 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Infisical.java +139 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Onepassword.java +143 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Proc.java +80 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Secretspec.java +138 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Sigv4.java +243 -0
- package/project/.sdk/tm/java/test/feature/secrets/SecretsFeatureTest.java +1050 -0
- package/project/.sdk/tm/java/test/vendor/omni/Json.java +2 -2
- package/project/.sdk/tm/java/test/vendor/omni/Runner.java +2 -2
- package/project/.sdk/tm/java/test/vendor/omni/Util.java +2 -2
- package/project/.sdk/tm/java/utility/MakeOptions.java +7 -0
- package/project/.sdk/tm/java/utility/struct/Struct.java +1 -1
- package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +454 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/capability.js +119 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/catalog.js +42 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/config.js +323 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/depend.js +196 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/env.js +120 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/export.js +48 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/graph.js +150 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/host.js +949 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/index.js +35 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/order.js +165 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/point.js +94 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/ref.js +106 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/resolve.js +59 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/types.js +79 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/version.js +100 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/Sekreto.js +574 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/index.js +56 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/aws.js +188 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/azuresecrets.js +135 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/boru.js +128 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/doppler.js +67 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/gcpsecrets.js +115 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/hashicorp.js +139 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/httpjson.js +93 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/infisical.js +99 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/onepassword.js +111 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/secretspec.js +105 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/sigv4.js +157 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/addr.js +119 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/builtin.js +39 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/dotenv.js +40 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/env.js +21 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/file.js +42 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/memory.js +18 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/support.js +151 -0
- package/project/.sdk/tm/js/src/utility/StructUtility.js +1 -1
- package/project/.sdk/tm/js/test/feature/secrets/Secrets.test.js +1019 -0
- package/project/.sdk/tm/js/test/vendor/omni/index.js +1 -1
- package/project/.sdk/tm/js/test/vendor/omni/runner.js +1 -1
- package/project/.sdk/tm/js/test/vendor/omni/util.js +1 -1
- package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +684 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Capability.kt +117 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Catalog.kt +40 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Config.kt +322 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Depend.kt +227 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Env.kt +163 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Export.kt +57 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Graph.kt +179 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Host.kt +1131 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Json.kt +241 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Order.kt +180 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Plugin.kt +64 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Point.kt +124 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Refs.kt +125 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Resolve.kt +66 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Types.kt +171 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Version.kt +132 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Json.kt +359 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Provider.kt +21 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Providers.kt +308 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Sekreto.kt +525 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Spec.kt +126 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Support.kt +205 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Aws.kt +251 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Azuresecrets.kt +145 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Boru.kt +130 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Doppler.kt +77 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Gcpsecrets.kt +119 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Hashicorp.kt +156 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Httpjson.kt +219 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Infisical.kt +114 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Onepassword.kt +114 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Secretspec.kt +118 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Sigv4.kt +220 -0
- package/project/.sdk/tm/kotlin/test/feature/secrets/SecretsTest.kt +1217 -0
- package/project/.sdk/tm/kotlin/test/vendor/omni/Json.kt +2 -2
- package/project/.sdk/tm/kotlin/test/vendor/omni/Runner.kt +2 -2
- package/project/.sdk/tm/kotlin/test/vendor/omni/Util.kt +2 -2
- package/project/.sdk/tm/kotlin/utility/struct/Struct.kt +1 -1
- package/project/.sdk/tm/lua/Makefile +15 -4
- package/project/.sdk/tm/lua/feature/secrets/native/sekretonet.c +806 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/capability.lua +135 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/catalog.lua +63 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/config.lua +361 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/depend.lua +232 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/env.lua +168 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/export.lua +66 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/graph.lua +194 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/host.lua +1190 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/json.lua +169 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/order.lua +207 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/point.lua +106 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/ref.lua +115 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/resolve.lua +78 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/types.lua +275 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/version.lua +131 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin.lua +76 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/addr.lua +124 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/err.lua +47 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/name.lua +315 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/aws.lua +228 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/azuresecrets.lua +137 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/boru.lua +124 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/crypto.lua +212 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/doppler.lua +89 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/gcpsecrets.lua +129 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/hashicorp.lua +154 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/httpjson.lua +248 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/infisical.lua +113 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/json.lua +449 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/net.lua +198 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/onepassword.lua +126 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/secretspec.lua +93 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/sigv4.lua +269 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/support.lua +146 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/providers.lua +346 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto.lua +479 -0
- package/project/.sdk/tm/lua/feature/secrets_feature.lua +690 -0
- package/project/.sdk/tm/lua/test/extend_test.lua +105 -0
- package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +862 -0
- package/project/.sdk/tm/lua/test/vendor/omni/json.lua +2 -2
- package/project/.sdk/tm/lua/test/vendor/omni/regex.lua +2 -2
- package/project/.sdk/tm/lua/test/vendor/omni/runner.lua +2 -2
- package/project/.sdk/tm/lua/test/vendor/omni/util.lua +2 -2
- package/project/.sdk/tm/lua/utility/struct/regex.lua +1 -1
- package/project/.sdk/tm/lua/utility/struct/struct.lua +1 -1
- package/project/.sdk/tm/ocaml/Makefile +52 -8
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/capability.ml +106 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/catalog.ml +43 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/config.ml +349 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/defs.ml +143 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/depend.ml +217 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/env.ml +197 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/export.ml +89 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/graph.ml +227 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/host.ml +1112 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/order.ml +202 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/point.ml +138 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/ref.ml +126 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/resolve.ml +62 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/types.ml +97 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/value.ml +387 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/version.ml +139 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/aws.ml +171 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/azuresecrets.ml +116 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/boru.ml +95 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/crypto.ml +149 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/doppler.ml +61 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/gcpsecrets.ml +93 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/hashicorp.ml +120 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/http.ml +421 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/httpjson.ml +66 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/infisical.ml +85 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/onepassword.ml +112 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/runcmd.ml +97 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/secretspec.ml +68 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/sigv4.ml +259 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls.ml +44 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls_stubs.c +358 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/json.ml +376 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/provider.ml +647 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/secret.ml +299 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/sekreto.ml +347 -0
- package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +453 -0
- package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +670 -0
- package/project/.sdk/tm/ocaml/test/vendor/omni/omni.ml +2 -2
- package/project/.sdk/tm/perl/Makefile +6 -1
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Capability.pm +141 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Catalog.pm +65 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Config.pm +346 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Depend.pm +216 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Env.pm +176 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Export.pm +59 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Graph.pm +157 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Host.pm +1139 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Order.pm +187 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Point.pm +100 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Ref.pm +119 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Resolve.pm +71 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Types.pm +251 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Version.pm +122 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin.pm +70 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Aws.pm +263 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Azuresecrets.pm +159 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Boru.pm +180 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Doppler.pm +92 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Gcpsecrets.pm +138 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Hashicorp.pm +213 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Httpjson.pm +173 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Infisical.pm +132 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Onepassword.pm +132 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Proc.pm +102 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Secretspec.pm +132 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Sigv4.pm +190 -0
- package/project/.sdk/tm/perl/feature/secrets/sekreto/Voxgig/Sekreto/Addr.pm +124 -0
- package/project/.sdk/tm/perl/feature/secrets/sekreto/Voxgig/Sekreto/Providers.pm +301 -0
- package/project/.sdk/tm/perl/feature/secrets/sekreto/Voxgig/Sekreto.pm +605 -0
- package/project/.sdk/tm/perl/feature/secrets_feature.pm +696 -0
- package/project/.sdk/tm/perl/lib/Voxgig/Struct.pm +1 -1
- package/project/.sdk/tm/perl/t/feature/secrets/secrets.t +1004 -0
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Runner.pm +1 -1
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Util.pm +1 -1
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni.pm +1 -1
- package/project/.sdk/tm/php/feature/SecretsFeature.php +694 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Capability.php +226 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Catalog.php +75 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Config.php +444 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Depend.php +262 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Env.php +202 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Export.php +74 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Graph.php +195 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Host.php +1514 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Order.php +260 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Point.php +129 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Ref.php +169 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Resolve.php +79 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Types.php +348 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Version.php +163 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/plugin.php +40 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/aws.php +274 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/azuresecrets.php +170 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/boru.php +163 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/doppler.php +106 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/gcpsecrets.php +144 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/hashicorp.php +194 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/httpjson.php +113 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/infisical.php +131 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/onepassword.php +150 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/runcmd.php +101 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/secretspec.php +146 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/sigv4.php +161 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/src/Addr.php +129 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/src/Providers.php +322 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/src/Sekreto.php +724 -0
- package/project/.sdk/tm/php/test/feature/secrets/SecretsTest.php +1165 -0
- package/project/.sdk/tm/php/test/vendor/omni/Runner.php +2 -2
- package/project/.sdk/tm/php/test/vendor/omni/Util.php +2 -2
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/__init__.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/capability.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/catalog.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/config.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/depend.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/env.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/export.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/graph.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/host.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/order.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/point.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/ref.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/resolve.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/types.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/version.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/__init__.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/addr.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/aws.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/azuresecrets.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/boru.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/doppler.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/hashicorp.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/httpjson.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/infisical.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/onepassword.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/secretspec.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/sigv4.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/providers.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/sekreto.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +28 -6
- package/project/.sdk/tm/py/pkg/utility/voxgig_struct/voxgig_struct.py +1 -1
- package/project/.sdk/tm/py/test/feature/secrets/test_secrets.py +114 -0
- package/project/.sdk/tm/py/test/voxgig_omni/__init__.py +1 -1
- package/project/.sdk/tm/py/test/voxgig_omni/runner.py +1 -1
- package/project/.sdk/tm/py/test/voxgig_omni/util.py +1 -1
- package/project/.sdk/tm/rb/Makefile +7 -1
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/capability.rb +118 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/catalog.rb +55 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/config.rb +315 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/depend.rb +197 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/env.rb +143 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/export.rb +52 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/graph.rb +147 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/host.rb +1079 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/order.rb +169 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/point.rb +93 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/ref.rb +112 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/resolve.rb +56 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/types.rb +99 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/version.rb +106 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin.rb +24 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/addr.rb +111 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/aws.rb +200 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/azuresecrets.rb +130 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/boru.rb +121 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/doppler.rb +66 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.rb +107 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/hashicorp.rb +137 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/httpjson.rb +136 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/infisical.rb +97 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/onepassword.rb +104 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/secretspec.rb +113 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/sigv4.rb +127 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/providers.rb +210 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/sekreto.rb +465 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto.rb +30 -0
- package/project/.sdk/tm/rb/feature/secrets_feature.rb +583 -0
- package/project/.sdk/tm/rb/test/feature/secrets/secrets_feature_test.rb +935 -0
- package/project/.sdk/tm/rb/test/vendor/omni/runner.rb +2 -2
- package/project/.sdk/tm/rb/test/vendor/omni/util.rb +2 -2
- package/project/.sdk/tm/rb/test/vendor/omni/voxgig_omni.rb +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/capability.rs +130 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/catalog.rs +114 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/config.rs +416 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/depend.rs +245 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/env.rs +200 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/export.rs +90 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/graph.rs +231 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/host.rs +1565 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/mod.rs +18 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/order.rs +226 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/point.rs +137 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/refs.rs +148 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/resolve.rs +83 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/types.rs +132 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/value.rs +433 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/version.rs +174 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/aws/crypto.rs +146 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/aws/sigv4.rs +230 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/aws.rs +328 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/azuresecrets.rs +184 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/boru.rs +172 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/doppler.rs +102 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/gcpsecrets.rs +153 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/hashicorp.rs +228 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/httpjson/http.rs +537 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/httpjson/json.rs +300 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/httpjson.rs +137 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/infisical.rs +148 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/onepassword.rs +165 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/secretspec.rs +150 -0
- package/project/.sdk/tm/rust/feature/secrets/sekreto/addr.rs +144 -0
- package/project/.sdk/tm/rust/feature/secrets/sekreto/mod.rs +51 -0
- package/project/.sdk/tm/rust/feature/secrets/sekreto/providers.rs +637 -0
- package/project/.sdk/tm/rust/feature/secrets/sekreto/sekreto.rs +677 -0
- package/project/.sdk/tm/rust/feature/secrets.rs +984 -0
- package/project/.sdk/tm/rust/tests/feature/secrets/main.rs +1605 -0
- package/project/.sdk/tm/rust/tests/vendor/omni/json.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/mod.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/regex.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/runner.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/util.rs +2 -2
- package/project/.sdk/tm/scala/Makefile +8 -3
- package/project/.sdk/tm/scala/feature/SecretsFeature.scala +578 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Capability.scala +96 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Config.scala +270 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Depend.scala +216 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Env.scala +144 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Export.scala +59 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Graph.scala +149 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Host.scala +1089 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Json.scala +156 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Order.scala +169 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Plugin.scala +47 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Point.scala +107 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Refs.scala +131 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Resolve.scala +53 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Types.scala +110 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Value.scala +157 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Version.scala +136 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Json.scala +302 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Provider.scala +20 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Providers.scala +281 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Sekreto.scala +473 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Spec.scala +123 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Support.scala +216 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Aws.scala +225 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Azuresecrets.scala +124 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Boru.scala +104 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Doppler.scala +68 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Gcpsecrets.scala +97 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Hashicorp.scala +131 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Httpjson.scala +209 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Infisical.scala +98 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Onepassword.scala +90 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Secretspec.scala +95 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Sigv4.scala +214 -0
- package/project/.sdk/tm/scala/sdktest/feature/secrets/SecretsTestMain.scala +1042 -0
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Json.scala +2 -2
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Runner.scala +2 -2
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Util.scala +2 -2
- package/project/.sdk/tm/scala/utility/Make.scala +7 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/SecretsFeature.swift +669 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Capability.swift +98 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Catalog.swift +87 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Config.swift +298 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Depend.swift +209 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Env.swift +191 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Export.swift +63 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Graph.swift +158 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Host.swift +1141 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Json.swift +192 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Order.swift +183 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Point.swift +130 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Refs.swift +141 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Resolve.swift +59 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Types.swift +125 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Value.swift +198 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Version.swift +139 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Aws.swift +271 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Azuresecrets.swift +173 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Boru.swift +139 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Crypto.swift +198 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Doppler.swift +86 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Gcpsecrets.swift +129 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Hashicorp.swift +175 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Httpjson.swift +310 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Infisical.swift +140 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Onepassword.swift +118 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Proc.swift +105 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Secretspec.swift +111 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Sigv4.swift +297 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Addr.swift +120 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Json.swift +452 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Provider.swift +25 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Providers.swift +689 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Sekreto.swift +755 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +9 -0
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +30 -0
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/feature/secrets/SecretsFeatureTest.swift +1030 -0
- package/project/.sdk/tm/swift/Tests/vendor/omni/Json.swift +2 -2
- package/project/.sdk/tm/swift/Tests/vendor/omni/Runner.swift +2 -2
- package/project/.sdk/tm/swift/Tests/vendor/omni/Util.swift +2 -2
- package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +35 -12
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Capability.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Catalog.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Config.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Depend.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Env.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Export.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/FeatureHost.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Graph.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Host.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Order.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Point.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Ref.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Resolve.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Types.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Version.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/index.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/aws.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/azuresecrets.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/boru.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/doppler.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/gcpsecrets.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/hashicorp.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/httpjson.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/infisical.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/onepassword.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/secretspec.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/sigv4.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/builtin.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +1 -1
- package/project/.sdk/tm/ts/src/utility/StructUtility.ts +1 -1
- package/project/.sdk/tm/ts/test/feature/secrets/Secrets.test.ts +73 -0
- package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +1 -1
- package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +1 -1
- package/project/.sdk/tm/ts/test/vendor/omni/index.ts +1 -1
- package/project/.sdk/tm/zig/feature/secrets/plugin/capability.zig +137 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/catalog.zig +90 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/config.zig +346 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/depend.zig +244 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/env.zig +201 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/export.zig +83 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/graph.zig +212 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/host.zig +1224 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/inst.zig +126 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/order.zig +228 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/plugin.zig +34 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/point.zig +166 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/ref.zig +147 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/resolve.zig +74 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/types.zig +140 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/value.zig +662 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/version.zig +139 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/aws.zig +294 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/azuresecrets.zig +222 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/boru.zig +188 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/doppler.zig +135 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/gcpsecrets.zig +170 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/hashicorp.zig +242 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/httpjson.zig +535 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/infisical.zig +167 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/onepassword.zig +202 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/secretspec.zig +160 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/sigv4.zig +336 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/addr.zig +148 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/builtins.zig +259 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/provider.zig +440 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/sekreto.zig +944 -0
- package/project/.sdk/tm/zig/feature/secrets.zig +854 -0
- package/project/.sdk/tm/zig/test/feature/secrets/secrets_test.zig +891 -0
- package/project/.sdk/tm/zig/test/vendor/omni/omni.zig +2 -2
- package/project/.sdk/tm/zig/test/vendor/omni/regex.zig +2 -2
- package/project/.sdk/tm/zig/utility/voxgigstruct/regex.zig +2 -2
- package/project/.sdk/tm/zig/utility/voxgigstruct/struct.zig +2 -2
- package/project/sdkgen-package.json +1 -4
- package/src/helpers/manifest.ts +81 -1
- package/src/helpers/modelNames.ts +284 -0
- package/src/helpers/naming.ts +45 -1
- package/src/sdkgen.ts +11 -1
- package/src/testkit.ts +115 -26
- package/src/utility.ts +17 -7
- package/project/.sdk/model/target/dart.aon +0 -58
- package/project/.sdk/model/target/lean.aon +0 -91
- package/project/.sdk/model/target/seneca-provider.aon +0 -120
- package/project/.sdk/src/cmp/dart/Config_dart.ts +0 -176
- package/project/.sdk/src/cmp/dart/EntityBase_dart.ts +0 -34
- package/project/.sdk/src/cmp/dart/EntityOperation_dart.ts +0 -43
- package/project/.sdk/src/cmp/dart/EntityTypes_dart.ts +0 -207
- package/project/.sdk/src/cmp/dart/Entity_dart.ts +0 -87
- package/project/.sdk/src/cmp/dart/Gitignore_dart.ts +0 -34
- package/project/.sdk/src/cmp/dart/MainEntity_dart.ts +0 -33
- package/project/.sdk/src/cmp/dart/Main_dart.ts +0 -106
- package/project/.sdk/src/cmp/dart/Package_dart.ts +0 -82
- package/project/.sdk/src/cmp/dart/ReadmeEntity_dart.ts +0 -177
- package/project/.sdk/src/cmp/dart/ReadmeExamplesTest_dart.ts +0 -238
- package/project/.sdk/src/cmp/dart/ReadmeExplanation_dart.ts +0 -53
- package/project/.sdk/src/cmp/dart/ReadmeHowto_dart.ts +0 -152
- package/project/.sdk/src/cmp/dart/ReadmeInstall_dart.ts +0 -59
- package/project/.sdk/src/cmp/dart/ReadmeIntro_dart.ts +0 -65
- package/project/.sdk/src/cmp/dart/ReadmeModel_dart.ts +0 -151
- package/project/.sdk/src/cmp/dart/ReadmeOptions_dart.ts +0 -63
- package/project/.sdk/src/cmp/dart/ReadmeQuick_dart.ts +0 -225
- package/project/.sdk/src/cmp/dart/ReadmeRef_dart.ts +0 -397
- package/project/.sdk/src/cmp/dart/ReadmeTopHowto_dart.ts +0 -24
- package/project/.sdk/src/cmp/dart/ReadmeTopQuick_dart.ts +0 -106
- package/project/.sdk/src/cmp/dart/ReadmeTopTest_dart.ts +0 -78
- package/project/.sdk/src/cmp/dart/SdkError_dart.ts +0 -42
- package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +0 -516
- package/project/.sdk/src/cmp/dart/TestEntity_dart.ts +0 -628
- package/project/.sdk/src/cmp/dart/Test_dart.ts +0 -116
- package/project/.sdk/src/cmp/dart/fragment/Config.data.fragment.dart +0 -79
- package/project/.sdk/src/cmp/dart/fragment/Config.fragment.dart +0 -51
- package/project/.sdk/src/cmp/dart/fragment/Direct.test.fragment.dart +0 -25
- package/project/.sdk/src/cmp/dart/fragment/Entity.fragment.dart +0 -29
- package/project/.sdk/src/cmp/dart/fragment/Entity.test.fragment.dart +0 -28
- package/project/.sdk/src/cmp/dart/fragment/EntityBase.fragment.dart +0 -302
- package/project/.sdk/src/cmp/dart/fragment/EntityCreateOp.fragment.dart +0 -98
- package/project/.sdk/src/cmp/dart/fragment/EntityListOp.fragment.dart +0 -90
- package/project/.sdk/src/cmp/dart/fragment/EntityLoadOp.fragment.dart +0 -102
- package/project/.sdk/src/cmp/dart/fragment/EntityRemoveOp.fragment.dart +0 -108
- package/project/.sdk/src/cmp/dart/fragment/EntityUpdateOp.fragment.dart +0 -102
- package/project/.sdk/src/cmp/dart/fragment/Main.fragment.dart +0 -338
- package/project/.sdk/src/cmp/dart/fragment/SdkError.fragment.dart +0 -26
- package/project/.sdk/src/cmp/dart/tsconfig.json +0 -15
- package/project/.sdk/src/cmp/dart/utility_dart.ts +0 -155
- package/project/.sdk/src/cmp/lean/Config_lean.ts +0 -93
- package/project/.sdk/src/cmp/lean/Entity_lean.ts +0 -9
- package/project/.sdk/src/cmp/lean/Gitignore_lean.ts +0 -18
- package/project/.sdk/src/cmp/lean/Main_lean.ts +0 -120
- package/project/.sdk/src/cmp/lean/Package_lean.ts +0 -93
- package/project/.sdk/src/cmp/lean/ReadmeEntity_lean.ts +0 -29
- package/project/.sdk/src/cmp/lean/ReadmeExplanation_lean.ts +0 -19
- package/project/.sdk/src/cmp/lean/ReadmeHowto_lean.ts +0 -25
- package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +0 -39
- package/project/.sdk/src/cmp/lean/ReadmeIntro_lean.ts +0 -25
- package/project/.sdk/src/cmp/lean/ReadmeModel_lean.ts +0 -24
- package/project/.sdk/src/cmp/lean/ReadmeOptions_lean.ts +0 -22
- package/project/.sdk/src/cmp/lean/ReadmeQuick_lean.ts +0 -50
- package/project/.sdk/src/cmp/lean/ReadmeRef_lean.ts +0 -40
- package/project/.sdk/src/cmp/lean/ReadmeTopHowto_lean.ts +0 -16
- package/project/.sdk/src/cmp/lean/ReadmeTopQuick_lean.ts +0 -23
- package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +0 -19
- package/project/.sdk/src/cmp/lean/Test_lean.ts +0 -261
- package/project/.sdk/src/cmp/lean/utility_lean.ts +0 -129
- package/project/.sdk/src/cmp/seneca-provider/Extras_seneca-provider.ts +0 -4080
- package/project/.sdk/src/cmp/seneca-provider/Gitignore_seneca-provider.ts +0 -161
- package/project/.sdk/src/cmp/seneca-provider/Main_seneca-provider.ts +0 -1011
- package/project/.sdk/tm/dart/LICENSE +0 -22
- package/project/.sdk/tm/dart/Makefile +0 -50
- package/project/.sdk/tm/dart/lib/Context.dart +0 -150
- package/project/.sdk/tm/dart/lib/Control.dart +0 -15
- package/project/.sdk/tm/dart/lib/Operation.dart +0 -31
- package/project/.sdk/tm/dart/lib/Point.dart +0 -51
- package/project/.sdk/tm/dart/lib/Response.dart +0 -32
- package/project/.sdk/tm/dart/lib/Result.dart +0 -39
- package/project/.sdk/tm/dart/lib/Spec.dart +0 -49
- package/project/.sdk/tm/dart/lib/feature/audit/AuditFeature.dart +0 -103
- package/project/.sdk/tm/dart/lib/feature/base/BaseFeature.dart +0 -76
- package/project/.sdk/tm/dart/lib/feature/cache/CacheFeature.dart +0 -152
- package/project/.sdk/tm/dart/lib/feature/clienttrack/ClienttrackFeature.dart +0 -104
- package/project/.sdk/tm/dart/lib/feature/cost/CostFeature.dart +0 -446
- package/project/.sdk/tm/dart/lib/feature/debug/DebugFeature.dart +0 -153
- package/project/.sdk/tm/dart/lib/feature/idempotency/IdempotencyFeature.dart +0 -92
- package/project/.sdk/tm/dart/lib/feature/log/LogFeature.dart +0 -85
- package/project/.sdk/tm/dart/lib/feature/metrics/MetricsFeature.dart +0 -103
- package/project/.sdk/tm/dart/lib/feature/netsim/NetsimFeature.dart +0 -186
- package/project/.sdk/tm/dart/lib/feature/paging/PagingFeature.dart +0 -240
- package/project/.sdk/tm/dart/lib/feature/proxy/ProxyFeature.dart +0 -118
- package/project/.sdk/tm/dart/lib/feature/ratelimit/RatelimitFeature.dart +0 -103
- package/project/.sdk/tm/dart/lib/feature/rbac/RbacFeature.dart +0 -121
- package/project/.sdk/tm/dart/lib/feature/retry/RetryFeature.dart +0 -155
- package/project/.sdk/tm/dart/lib/feature/streaming/StreamingFeature.dart +0 -97
- package/project/.sdk/tm/dart/lib/feature/telemetry/TelemetryFeature.dart +0 -136
- package/project/.sdk/tm/dart/lib/feature/test/TestFeature.dart +0 -328
- package/project/.sdk/tm/dart/lib/feature/timeout/TimeoutFeature.dart +0 -104
- package/project/.sdk/tm/dart/lib/utility/CleanUtility.dart +0 -12
- package/project/.sdk/tm/dart/lib/utility/DoneUtility.dart +0 -18
- package/project/.sdk/tm/dart/lib/utility/ErrUtility.dart +0 -46
- package/project/.sdk/tm/dart/lib/utility/FeatureAddUtility.dart +0 -35
- package/project/.sdk/tm/dart/lib/utility/FeatureHookUtility.dart +0 -20
- package/project/.sdk/tm/dart/lib/utility/FeatureInitUtility.dart +0 -9
- package/project/.sdk/tm/dart/lib/utility/FetcherUtility.dart +0 -104
- package/project/.sdk/tm/dart/lib/utility/GraphqlUtility.dart +0 -162
- package/project/.sdk/tm/dart/lib/utility/MakeContextUtility.dart +0 -6
- package/project/.sdk/tm/dart/lib/utility/MakeErrorUtility.dart +0 -71
- package/project/.sdk/tm/dart/lib/utility/MakeFetchDefUtility.dart +0 -42
- package/project/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +0 -233
- package/project/.sdk/tm/dart/lib/utility/MakePointUtility.dart +0 -130
- package/project/.sdk/tm/dart/lib/utility/MakeRequestUtility.dart +0 -66
- package/project/.sdk/tm/dart/lib/utility/MakeResponseUtility.dart +0 -59
- package/project/.sdk/tm/dart/lib/utility/MakeResultUtility.dart +0 -49
- package/project/.sdk/tm/dart/lib/utility/MakeSpecUtility.dart +0 -77
- package/project/.sdk/tm/dart/lib/utility/MakeUrlUtility.dart +0 -51
- package/project/.sdk/tm/dart/lib/utility/ParamUtility.dart +0 -56
- package/project/.sdk/tm/dart/lib/utility/PrepareAuthUtility.dart +0 -46
- package/project/.sdk/tm/dart/lib/utility/PrepareBodyUtility.dart +0 -19
- package/project/.sdk/tm/dart/lib/utility/PrepareHeadersUtility.dart +0 -11
- package/project/.sdk/tm/dart/lib/utility/PrepareMethodUtility.dart +0 -30
- package/project/.sdk/tm/dart/lib/utility/PrepareParamsUtility.dart +0 -23
- package/project/.sdk/tm/dart/lib/utility/PreparePathUtility.dart +0 -9
- package/project/.sdk/tm/dart/lib/utility/PrepareQueryUtility.dart +0 -18
- package/project/.sdk/tm/dart/lib/utility/ResultBasicUtility.dart +0 -29
- package/project/.sdk/tm/dart/lib/utility/ResultBodyUtility.dart +0 -15
- package/project/.sdk/tm/dart/lib/utility/ResultHeadersUtility.dart +0 -18
- package/project/.sdk/tm/dart/lib/utility/StructUtility.dart +0 -127
- package/project/.sdk/tm/dart/lib/utility/TransformRequestUtility.dart +0 -28
- package/project/.sdk/tm/dart/lib/utility/TransformResponseUtility.dart +0 -44
- package/project/.sdk/tm/dart/lib/utility/Utility.dart +0 -239
- package/project/.sdk/tm/dart/lib/utility/voxgig_struct.dart +0 -2462
- package/project/.sdk/tm/dart/src/feature/README.md +0 -3
- package/project/.sdk/tm/dart/src/feature/telemetry/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/test/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/timeout/.gitkeep +0 -0
- package/project/.sdk/tm/dart/test/custom_test.dart +0 -65
- package/project/.sdk/tm/dart/test/exists_test.dart +0 -12
- package/project/.sdk/tm/dart/test/feature/harness.dart +0 -329
- package/project/.sdk/tm/dart/test/feature_test.dart +0 -1193
- package/project/.sdk/tm/dart/test/harness.dart +0 -153
- package/project/.sdk/tm/dart/test/netsim_test.dart +0 -48
- package/project/.sdk/tm/dart/test/omni.dart +0 -520
- package/project/.sdk/tm/dart/test/omni_smoke_test.dart +0 -143
- package/project/.sdk/tm/dart/test/pipeline_test.dart +0 -608
- package/project/.sdk/tm/dart/test/primary_test.dart +0 -476
- package/project/.sdk/tm/dart/test/sdk-test-control.json +0 -19
- package/project/.sdk/tm/dart/test/struct_test.dart +0 -468
- package/project/.sdk/tm/dart/test/utility.dart +0 -198
- package/project/.sdk/tm/dart/test/vendor/omni/omni.dart +0 -7
- package/project/.sdk/tm/dart/test/vendor/omni/runner.dart +0 -653
- package/project/.sdk/tm/dart/test/vendor/omni/util.dart +0 -232
- package/project/.sdk/tm/lean/LICENSE +0 -21
- package/project/.sdk/tm/lean/Makefile +0 -32
- package/project/.sdk/tm/lean/VERSION +0 -1
- package/project/.sdk/tm/lean/src/SdkFeature.lean +0 -171
- package/project/.sdk/tm/lean/src/SdkFeatures.lean +0 -787
- package/project/.sdk/tm/lean/src/SdkJson.lean +0 -134
- package/project/.sdk/tm/lean/src/SdkRuntime.lean +0 -374
- package/project/.sdk/tm/lean/src/SdkUtility.lean +0 -809
- package/project/.sdk/tm/lean/src/VoxgigStruct.lean +0 -2880
- package/project/.sdk/tm/lean/src/Vregex.lean +0 -412
- package/project/.sdk/tm/lean/src/feature/README.md +0 -5
- package/project/.sdk/tm/lean/src/feature/audit/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/base/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/cache/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/clienttrack/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/cost/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/debug/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/idempotency/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/log/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/metrics/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/netsim/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/paging/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/proxy/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/ratelimit/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/rbac/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/retry/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/streaming/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/telemetry/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/test/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/timeout/.gitkeep +0 -0
- package/project/.sdk/tm/lean/test/OmniResolver.lean +0 -358
- package/project/.sdk/tm/lean/test/OmniSmoke.lean +0 -174
- package/project/.sdk/tm/lean/test/StructCorpus.lean +0 -368
- package/project/.sdk/tm/lean/test/TFeature.lean +0 -281
- package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +0 -227
- package/project/.sdk/tm/lean/test/vendor/omni/Omni.lean +0 -997
- package/project/.sdk/tm/seneca-provider/CODE_OF_CONDUCT.md +0 -132
- package/project/.sdk/tm/seneca-provider/LICENSE +0 -21
- package/project/.sdk/tm/seneca-provider/Makefile +0 -15
- package/project/.sdk/tm/seneca-provider/src/tsconfig.json +0 -18
- package/project/.sdk/tm/seneca-provider/test/tsconfig.json +0 -16
- package/project/.sdk/tm/seneca-provider/tsfmt.json +0 -3
- /package/project/.sdk/tm/{dart/src/feature/audit → c/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/base → clojure/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/cache → cpp/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/clienttrack → csharp/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/cost → elixir/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/debug → java/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/idempotency → kotlin/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/log → lua/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/metrics → ocaml/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/netsim → perl/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/paging → php/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/proxy → rb/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/ratelimit → rust/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/rbac → scala/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/retry → swift/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/streaming → zig/src/feature/secrets}/.gitkeep +0 -0
|
@@ -0,0 +1,1787 @@
|
|
|
1
|
+
// Behavioural tests for the secrets feature (vendored @voxgig/sekreto) -
|
|
2
|
+
// the csharp port of tm/ts/test/feature/secrets/Secrets.test.ts and
|
|
3
|
+
// tm/go/test/feature/secrets/secrets_feature_test.go.
|
|
4
|
+
//
|
|
5
|
+
// The contract under test: the `apikey` OPTION keeps its exact old meaning
|
|
6
|
+
// and always wins, because SecretsFeature places it FIRST in the provider
|
|
7
|
+
// chain (a `memory` store named `options`) - explicit-beats-lookup falls
|
|
8
|
+
// out of sekreto's first-hit rule rather than from special-case logic.
|
|
9
|
+
// With the feature inactive nothing changes at all. With it active and the
|
|
10
|
+
// option unset, the chain (env, dotenv, a custom provider, a vault)
|
|
11
|
+
// supplies the credential instead.
|
|
12
|
+
//
|
|
13
|
+
// This file lives in the test `feature/` container on purpose: `target add`
|
|
14
|
+
// trims it, along with the feature source and the vendored library, for a
|
|
15
|
+
// project whose model does not select `secrets`.
|
|
16
|
+
//
|
|
17
|
+
// WHAT MAKES THESE TESTS ABLE TO FAIL, which is the whole point of the
|
|
18
|
+
// file. Every fail-closed case is driven through a LIVE client with a
|
|
19
|
+
// recording `system.fetch`, so the thing being counted IS the transport.
|
|
20
|
+
// A previous tranche shipped fail-closed tests built on the offline test
|
|
21
|
+
// harness, whose mock transport REPLACES the fetcher - so the counter they
|
|
22
|
+
// asserted on was never reached, and "no request went out" was true for a
|
|
23
|
+
// healthy SDK carrying no secrets feature at all. Here:
|
|
24
|
+
//
|
|
25
|
+
// * the assertion is on a recorder hung off `system.fetch`;
|
|
26
|
+
// * the failure is matched on the PROVIDER'S OWN message, so an
|
|
27
|
+
// unrelated failure (a blocked op, a missing route) cannot stand in
|
|
28
|
+
// for fail-closed;
|
|
29
|
+
// * and every fail-closed case carries a CONTROL leg - the same
|
|
30
|
+
// construction with a WORKING provider, which must reach that same
|
|
31
|
+
// transport exactly once, carrying the credential. Only then does a
|
|
32
|
+
// zero mean REFUSED rather than UNWIRED.
|
|
33
|
+
//
|
|
34
|
+
// The feature is CONSTRUCTED DIRECTLY and handed in through the `extend`
|
|
35
|
+
// option when the generated config did not already install it, so these
|
|
36
|
+
// tests hold in any generated tree - whether or not the project's model
|
|
37
|
+
// activated the feature.
|
|
38
|
+
|
|
39
|
+
using System.Net;
|
|
40
|
+
using System.Reflection;
|
|
41
|
+
using System.Text;
|
|
42
|
+
using System.Text.Json;
|
|
43
|
+
|
|
44
|
+
using Voxgig.Struct;
|
|
45
|
+
using Xunit;
|
|
46
|
+
|
|
47
|
+
using Voxgig.Sekreto;
|
|
48
|
+
|
|
49
|
+
using ProjectNameSdk;
|
|
50
|
+
using ProjectNameSdk.Feature;
|
|
51
|
+
|
|
52
|
+
namespace ProjectNameSdk.Test.Secrets;
|
|
53
|
+
|
|
54
|
+
// --- support ---------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
// A source of secrets built in code: sekreto's IProvider is two methods,
|
|
57
|
+
// and Sekreto's constructor takes a live instance directly.
|
|
58
|
+
internal class ProbeProvider : IProvider
|
|
59
|
+
{
|
|
60
|
+
public Func<string, string?> Fn = _ => null;
|
|
61
|
+
public List<string> Asked = new();
|
|
62
|
+
|
|
63
|
+
public string Lookup(string name)
|
|
64
|
+
{
|
|
65
|
+
lock (Asked)
|
|
66
|
+
{
|
|
67
|
+
Asked.Add(name);
|
|
68
|
+
}
|
|
69
|
+
return Fn(name)!;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public string Describe() => "probe:test";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// One recorded request, as the transport saw it.
|
|
76
|
+
internal class WireCall
|
|
77
|
+
{
|
|
78
|
+
public string Url = "";
|
|
79
|
+
public string Auth = "";
|
|
80
|
+
public bool HasAuth;
|
|
81
|
+
public string Body = "";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// The recording transport: `system.fetch` for a LIVE client. It scripts one
|
|
85
|
+
// status per API call (the last repeating) and answers the exchange's token
|
|
86
|
+
// endpoint separately, so a case can say "401 then 200" without counting
|
|
87
|
+
// calls itself.
|
|
88
|
+
internal class Wire
|
|
89
|
+
{
|
|
90
|
+
private readonly object _mu = new();
|
|
91
|
+
|
|
92
|
+
public List<WireCall> Calls = new();
|
|
93
|
+
public List<int> ApiStatus = new() { 200 };
|
|
94
|
+
public List<string> Tokens = new() { "ACCESS01", "ACCESS02", "ACCESS03" };
|
|
95
|
+
public string TokenPath = "auth/token";
|
|
96
|
+
public string RespField = "access_token";
|
|
97
|
+
|
|
98
|
+
private int _issued;
|
|
99
|
+
private int _apicalls;
|
|
100
|
+
|
|
101
|
+
public Dictionary<string, object?> Fetch(string url, Dictionary<string, object?> fetchdef)
|
|
102
|
+
{
|
|
103
|
+
lock (_mu)
|
|
104
|
+
{
|
|
105
|
+
var call = new WireCall { Url = url };
|
|
106
|
+
|
|
107
|
+
if (fetchdef.TryGetValue("headers", out var hraw) &&
|
|
108
|
+
hraw is Dictionary<string, object?> headers &&
|
|
109
|
+
headers.TryGetValue("authorization", out var auth))
|
|
110
|
+
{
|
|
111
|
+
call.HasAuth = true;
|
|
112
|
+
call.Auth = auth as string ?? "";
|
|
113
|
+
}
|
|
114
|
+
if (fetchdef.TryGetValue("body", out var braw) && braw is string body)
|
|
115
|
+
{
|
|
116
|
+
call.Body = body;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
Calls.Add(call);
|
|
120
|
+
|
|
121
|
+
if (url.EndsWith("/" + TokenPath))
|
|
122
|
+
{
|
|
123
|
+
var token = Tokens[Math.Min(_issued, Tokens.Count - 1)];
|
|
124
|
+
_issued++;
|
|
125
|
+
return Response(200, new Dictionary<string, object?> { [RespField] = token });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
var status = ApiStatus[Math.Min(_apicalls, ApiStatus.Count - 1)];
|
|
129
|
+
_apicalls++;
|
|
130
|
+
return Response(status,
|
|
131
|
+
new Dictionary<string, object?> { ["ok"] = status < 400 });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private static Dictionary<string, object?> Response(int status, object? payload)
|
|
136
|
+
{
|
|
137
|
+
return new Dictionary<string, object?>
|
|
138
|
+
{
|
|
139
|
+
["status"] = status,
|
|
140
|
+
["statusText"] = "X",
|
|
141
|
+
["headers"] = new Dictionary<string, object?>(),
|
|
142
|
+
["json"] = (Func<object?>)(() => payload),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// The calls that did NOT go to the token endpoint.
|
|
147
|
+
public List<WireCall> Api()
|
|
148
|
+
{
|
|
149
|
+
lock (_mu)
|
|
150
|
+
{
|
|
151
|
+
return Calls.FindAll(c => !c.Url.EndsWith("/" + TokenPath));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public List<WireCall> Token()
|
|
156
|
+
{
|
|
157
|
+
lock (_mu)
|
|
158
|
+
{
|
|
159
|
+
return Calls.FindAll(c => c.Url.EndsWith("/" + TokenPath));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// What went out, for a failure message that names the leak rather than
|
|
164
|
+
// just its count.
|
|
165
|
+
public string Report()
|
|
166
|
+
{
|
|
167
|
+
lock (_mu)
|
|
168
|
+
{
|
|
169
|
+
return string.Join(", ", Calls.ConvertAll(c => c.Url + " auth=" + c.Auth));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public class SecretsFeatureTest
|
|
175
|
+
{
|
|
176
|
+
private const string EnvPrefix = "PROJECTENV_TEST_SECRETS_";
|
|
177
|
+
private const string SecretsBase = "http://secrets.test/api";
|
|
178
|
+
|
|
179
|
+
// The Authorization header carries the SPEC's credential prefix, which a
|
|
180
|
+
// TEMPLATE cannot know: an OpenAPI `http`/`bearer` scheme gives
|
|
181
|
+
// `Bearer <token>`, an apiKey scheme the raw token. So assert on the
|
|
182
|
+
// CREDENTIAL and let the prefix be whatever this SDK's API declares -
|
|
183
|
+
// pinning the whole header value passes only for a prefix-less API, and
|
|
184
|
+
// this file ships to every project that selects the feature.
|
|
185
|
+
private static void CredentialIs(string header, string token)
|
|
186
|
+
{
|
|
187
|
+
var got = header ?? "";
|
|
188
|
+
Assert.True(got == token || got.EndsWith(" " + token),
|
|
189
|
+
"expected the authorization header to carry " + token + ", got: " + got);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Construct the client and ADOPT the feature via `extend` ONLY when the
|
|
193
|
+
// generated config did not already install it. When this SDK was
|
|
194
|
+
// generated with `secrets` model-active the ordinary factory path builds
|
|
195
|
+
// the instance, and adding a second via extend would DOUBLE the feature:
|
|
196
|
+
// two transport wraps, two resolutions, and a token purchase the
|
|
197
|
+
// assertions cannot account for.
|
|
198
|
+
private static ProjectNameSDK WithSecrets(Func<bool, ProjectNameSDK> build)
|
|
199
|
+
{
|
|
200
|
+
var client = build(false);
|
|
201
|
+
if (null == SecretsOf(client))
|
|
202
|
+
{
|
|
203
|
+
client = build(true);
|
|
204
|
+
}
|
|
205
|
+
return client;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private static SecretsFeature? SecretsOf(ProjectNameSDK client)
|
|
209
|
+
{
|
|
210
|
+
foreach (var f in client.Features)
|
|
211
|
+
{
|
|
212
|
+
if (f is SecretsFeature sf)
|
|
213
|
+
{
|
|
214
|
+
return sf;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// A LIVE client carrying the secrets feature, wired to the recording
|
|
221
|
+
// transport. `allow.op` is named explicitly: a project that narrows the
|
|
222
|
+
// default set would otherwise turn the raw-path cases into a false RED
|
|
223
|
+
// (the control leg refused before it reached the transport), and the
|
|
224
|
+
// rule under test lives at the transport, downstream of the allow gate
|
|
225
|
+
// either way.
|
|
226
|
+
private static ProjectNameSDK SecretsClient(Wire w, Dictionary<string, object?> extra)
|
|
227
|
+
{
|
|
228
|
+
return WithSecrets(extend =>
|
|
229
|
+
{
|
|
230
|
+
var opts = new Dictionary<string, object?>
|
|
231
|
+
{
|
|
232
|
+
["base"] = SecretsBase,
|
|
233
|
+
["allow"] = new Dictionary<string, object?>
|
|
234
|
+
{
|
|
235
|
+
["op"] = "create,update,load,list,remove,command,direct,graphql",
|
|
236
|
+
},
|
|
237
|
+
["system"] = new Dictionary<string, object?>
|
|
238
|
+
{
|
|
239
|
+
["fetch"] = (Func<string, Dictionary<string, object?>,
|
|
240
|
+
Dictionary<string, object?>>)w.Fetch,
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
foreach (var kv in extra)
|
|
244
|
+
{
|
|
245
|
+
opts[kv.Key] = kv.Value;
|
|
246
|
+
}
|
|
247
|
+
if (extend)
|
|
248
|
+
{
|
|
249
|
+
opts["extend"] = new List<object?> { new SecretsFeature() };
|
|
250
|
+
}
|
|
251
|
+
return new ProjectNameSDK(opts);
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// The env chain, the shape most of these tests use.
|
|
256
|
+
private static Dictionary<string, object?> SecretsOpts(Dictionary<string, object?>? extra)
|
|
257
|
+
{
|
|
258
|
+
var fopts = new Dictionary<string, object?>
|
|
259
|
+
{
|
|
260
|
+
["active"] = true,
|
|
261
|
+
["providers"] = new List<object?>
|
|
262
|
+
{
|
|
263
|
+
new Dictionary<string, object?>
|
|
264
|
+
{
|
|
265
|
+
["kind"] = "env",
|
|
266
|
+
["prefix"] = EnvPrefix,
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
foreach (var kv in extra ?? new Dictionary<string, object?>())
|
|
271
|
+
{
|
|
272
|
+
fopts[kv.Key] = kv.Value;
|
|
273
|
+
}
|
|
274
|
+
return new Dictionary<string, object?> { ["secrets"] = fopts };
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private static Dictionary<string, object?> ProviderOpts(object provider,
|
|
278
|
+
Dictionary<string, object?>? extra)
|
|
279
|
+
{
|
|
280
|
+
var fopts = new Dictionary<string, object?>
|
|
281
|
+
{
|
|
282
|
+
["active"] = true,
|
|
283
|
+
["providers"] = new List<object?> { provider },
|
|
284
|
+
};
|
|
285
|
+
foreach (var kv in extra ?? new Dictionary<string, object?>())
|
|
286
|
+
{
|
|
287
|
+
fopts[kv.Key] = kv.Value;
|
|
288
|
+
}
|
|
289
|
+
return new Dictionary<string, object?> { ["secrets"] = fopts };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Perform real entity operations - which is what runs the PreSpec hook
|
|
293
|
+
// and the ordinary request pipeline - until `stop` reports the
|
|
294
|
+
// observable state a test is waiting for. Each op's own outcome is
|
|
295
|
+
// irrelevant (no seeded data, a scripted response); an op the API does
|
|
296
|
+
// not define fails BEFORE the transport, which is why several may need
|
|
297
|
+
// driving. Entity names come from the SDK's own config, because this
|
|
298
|
+
// file is a TEMPLATE and no project's entity names are known here.
|
|
299
|
+
private static void DriveEntityOpUntil(ProjectNameSDK client, string what, Func<bool> stop)
|
|
300
|
+
{
|
|
301
|
+
var entities = StructUtils.GetProp(client.OptionsMap(), "entity")
|
|
302
|
+
as Dictionary<string, object?> ?? new Dictionary<string, object?>();
|
|
303
|
+
|
|
304
|
+
foreach (var name in entities.Keys)
|
|
305
|
+
{
|
|
306
|
+
if ("" == name)
|
|
307
|
+
{
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
var accessor = client.GetType().GetMethod(
|
|
312
|
+
char.ToUpperInvariant(name[0]) + name.Substring(1),
|
|
313
|
+
new[] { typeof(Dictionary<string, object?>) });
|
|
314
|
+
|
|
315
|
+
if (null == accessor)
|
|
316
|
+
{
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
object? ent;
|
|
321
|
+
try
|
|
322
|
+
{
|
|
323
|
+
ent = accessor.Invoke(client, new object?[] { null });
|
|
324
|
+
}
|
|
325
|
+
catch (TargetInvocationException)
|
|
326
|
+
{
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (null == ent)
|
|
331
|
+
{
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
foreach (var opname in new[] { "List", "Load" })
|
|
336
|
+
{
|
|
337
|
+
var op = ent.GetType().GetMethod(opname,
|
|
338
|
+
new[]
|
|
339
|
+
{
|
|
340
|
+
typeof(Dictionary<string, object?>),
|
|
341
|
+
typeof(Dictionary<string, object?>),
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
if (null == op)
|
|
345
|
+
{
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
try
|
|
350
|
+
{
|
|
351
|
+
op.Invoke(ent, new object?[] { null, null });
|
|
352
|
+
}
|
|
353
|
+
catch (Exception ex)
|
|
354
|
+
{
|
|
355
|
+
// The operation's own outcome is not what is under test,
|
|
356
|
+
// but the fail-closed cases assert on the PROVIDER'S OWN
|
|
357
|
+
// message, so the last failure is kept. Reflection wraps
|
|
358
|
+
// the SDK's throw in a TargetInvocationException; the
|
|
359
|
+
// SDK error is the inner one.
|
|
360
|
+
_lasterr = (ex as TargetInvocationException)?.InnerException ?? ex;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (stop())
|
|
364
|
+
{
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
Assert.Fail("no entity operation " + what + " - nothing to assert on");
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// The last error an entity op raised, for the fail-closed cases that
|
|
374
|
+
// assert on the PROVIDER'S OWN message. Per thread: xunit runs test
|
|
375
|
+
// classes in parallel.
|
|
376
|
+
[ThreadStatic]
|
|
377
|
+
private static Exception? _lasterr;
|
|
378
|
+
|
|
379
|
+
// Drive ops until one request reached the recorder.
|
|
380
|
+
private static void DriveEntityOp(ProjectNameSDK client, Wire w)
|
|
381
|
+
{
|
|
382
|
+
var before = w.Api().Count;
|
|
383
|
+
DriveEntityOpUntil(client, "reached the transport", () => before < w.Api().Count);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
// --- the feature-inactive baseline: bit-identical behaviour ------------
|
|
388
|
+
|
|
389
|
+
[Fact]
|
|
390
|
+
public void InactiveApikeyOptionBehavesExactlyAsBefore()
|
|
391
|
+
{
|
|
392
|
+
var client = ProjectNameSDK.TestSDK(null,
|
|
393
|
+
new Dictionary<string, object?> { ["apikey"] = "OPTKEY01" });
|
|
394
|
+
|
|
395
|
+
var fetchdef = client.Prepare(new Dictionary<string, object?> { ["path"] = "/" });
|
|
396
|
+
var headers = fetchdef["headers"] as Dictionary<string, object?>;
|
|
397
|
+
|
|
398
|
+
CredentialIs(headers!["authorization"] as string ?? "", "OPTKEY01");
|
|
399
|
+
|
|
400
|
+
Assert.True(null == SecretsOf(client),
|
|
401
|
+
"no model activation and no extend: the feature must not be installed");
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
[Fact]
|
|
405
|
+
public void InactiveNoApikeyMeansNoAuthorizationHeader()
|
|
406
|
+
{
|
|
407
|
+
var client = ProjectNameSDK.TestSDK(null, null);
|
|
408
|
+
|
|
409
|
+
var fetchdef = client.Prepare(new Dictionary<string, object?> { ["path"] = "/" });
|
|
410
|
+
var headers = fetchdef["headers"] as Dictionary<string, object?>;
|
|
411
|
+
|
|
412
|
+
Assert.False(headers!.ContainsKey("authorization"),
|
|
413
|
+
"an SDK with no apikey must send no authorization header");
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
// --- active: the provider chain, on the wire ---------------------------
|
|
418
|
+
|
|
419
|
+
[Fact]
|
|
420
|
+
public void ApikeyOptionStillWinsOverTheChain()
|
|
421
|
+
{
|
|
422
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "APIKEY", "ENVKEY01");
|
|
423
|
+
try
|
|
424
|
+
{
|
|
425
|
+
var w = new Wire();
|
|
426
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
427
|
+
{
|
|
428
|
+
["apikey"] = "OPTKEY01",
|
|
429
|
+
["feature"] = SecretsOpts(null),
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
DriveEntityOp(client, w);
|
|
433
|
+
CredentialIs(w.Api()[0].Auth, "OPTKEY01");
|
|
434
|
+
|
|
435
|
+
// The explicit option is a real store, not a special case: a
|
|
436
|
+
// directed read names it like any other.
|
|
437
|
+
var sf = SecretsOf(client);
|
|
438
|
+
Assert.True(null != sf, "the extend seam did not install the feature");
|
|
439
|
+
Assert.Equal("OPTKEY01", sf!.GetSekreto()!.GetFrom("options", "apikey"));
|
|
440
|
+
}
|
|
441
|
+
finally
|
|
442
|
+
{
|
|
443
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "APIKEY", null);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
[Fact]
|
|
448
|
+
public void AnOmittedApikeyDefersToTheChainAtTheTransportSeam()
|
|
449
|
+
{
|
|
450
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "APIKEY", "ENVKEY02");
|
|
451
|
+
try
|
|
452
|
+
{
|
|
453
|
+
var w = new Wire();
|
|
454
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
455
|
+
{
|
|
456
|
+
["feature"] = SecretsOpts(null),
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
// Before any op, nothing has been resolved.
|
|
460
|
+
Assert.Equal("", SecretsOf(client)!.Credential());
|
|
461
|
+
|
|
462
|
+
DriveEntityOp(client, w);
|
|
463
|
+
|
|
464
|
+
// Resolution happens AT THE TRANSPORT - the one seam every wire
|
|
465
|
+
// path crosses - so the credential is ON THE WIRE, not merely
|
|
466
|
+
// resolved.
|
|
467
|
+
CredentialIs(w.Api()[0].Auth, "ENVKEY02");
|
|
468
|
+
Assert.Equal("ENVKEY02", SecretsOf(client)!.Credential());
|
|
469
|
+
|
|
470
|
+
// csharp holds the credential in FEATURE STATE and injects it at
|
|
471
|
+
// the transport; the shared options map is never written, which
|
|
472
|
+
// is what keeps every concurrent operation's raw read safe.
|
|
473
|
+
Assert.Equal("", StructUtils.GetProp(client.OptionsMap(), "apikey") as string ?? "");
|
|
474
|
+
}
|
|
475
|
+
finally
|
|
476
|
+
{
|
|
477
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "APIKEY", null);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
[Fact]
|
|
482
|
+
public void CustomProviderObjectsAreAcceptedVerbatim()
|
|
483
|
+
{
|
|
484
|
+
var probe = new ProbeProvider { Fn = _ => "CUSTOM01" };
|
|
485
|
+
|
|
486
|
+
var w = new Wire();
|
|
487
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
488
|
+
{
|
|
489
|
+
["feature"] = ProviderOpts(probe, null),
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
DriveEntityOp(client, w);
|
|
493
|
+
|
|
494
|
+
CredentialIs(w.Api()[0].Auth, "CUSTOM01");
|
|
495
|
+
Assert.Equal("apikey", probe.Asked[0]);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
[Fact]
|
|
499
|
+
public void AMissEverywhereLeavesTheHeaderOff()
|
|
500
|
+
{
|
|
501
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "APIKEY", null);
|
|
502
|
+
|
|
503
|
+
var w = new Wire();
|
|
504
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
505
|
+
{
|
|
506
|
+
["feature"] = SecretsOpts(null),
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
DriveEntityOp(client, w);
|
|
510
|
+
|
|
511
|
+
Assert.False(w.Api()[0].HasAuth,
|
|
512
|
+
"a chain MISS must fall through to an unauthenticated request, got header " +
|
|
513
|
+
w.Api()[0].Auth);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// sekreto's miss-vs-error invariant: a MISS falls through to the next
|
|
517
|
+
// provider, an ERROR does not. A broken vault must never degrade into an
|
|
518
|
+
// unauthenticated request.
|
|
519
|
+
[Fact]
|
|
520
|
+
public void AProviderErrorFailsTheEntityOpAndNothingReachesTheWire()
|
|
521
|
+
{
|
|
522
|
+
var broken = new ProbeProvider
|
|
523
|
+
{
|
|
524
|
+
Fn = _ => throw new SekretoError("vault unreachable"),
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
var w = new Wire();
|
|
528
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
529
|
+
{
|
|
530
|
+
["feature"] = ProviderOpts(broken, null),
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
DriveEntityOpUntil(client, "consulted the chain", () => 0 < broken.Asked.Count);
|
|
534
|
+
|
|
535
|
+
Assert.True(0 == w.Api().Count,
|
|
536
|
+
"a broken vault must never yield a request, but the transport saw: " +
|
|
537
|
+
w.Report());
|
|
538
|
+
|
|
539
|
+
// CONTROL, which makes that zero mean REFUSED rather than UNWIRED:
|
|
540
|
+
// the same construction with a WORKING provider must reach the same
|
|
541
|
+
// transport, once, carrying the credential.
|
|
542
|
+
var control = new Wire();
|
|
543
|
+
var ok = SecretsClient(control, new Dictionary<string, object?>
|
|
544
|
+
{
|
|
545
|
+
["feature"] = ProviderOpts(
|
|
546
|
+
new ProbeProvider { Fn = _ => "CONTROL01" }, null),
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
DriveEntityOp(ok, control);
|
|
550
|
+
|
|
551
|
+
Assert.True(1 == control.Api().Count,
|
|
552
|
+
"the control request did not reach system.fetch exactly once, so this " +
|
|
553
|
+
"test cannot observe a request going out at all: " + control.Report());
|
|
554
|
+
CredentialIs(control.Api()[0].Auth, "CONTROL01");
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// A settled failure must not latch. Holding one meant a transient vault
|
|
558
|
+
// outage poisoned the client permanently: every later operation kept
|
|
559
|
+
// failing long after the vault recovered.
|
|
560
|
+
[Fact]
|
|
561
|
+
public void AProviderRecoversAfterATransientFailure()
|
|
562
|
+
{
|
|
563
|
+
var calls = 0;
|
|
564
|
+
var flaky = new ProbeProvider
|
|
565
|
+
{
|
|
566
|
+
Fn = _ =>
|
|
567
|
+
{
|
|
568
|
+
calls++;
|
|
569
|
+
if (1 == calls)
|
|
570
|
+
{
|
|
571
|
+
throw new SekretoError("vault unreachable");
|
|
572
|
+
}
|
|
573
|
+
return "RECOVERED01";
|
|
574
|
+
},
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
var w = new Wire();
|
|
578
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
579
|
+
{
|
|
580
|
+
["feature"] = ProviderOpts(flaky, null),
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
DriveEntityOpUntil(client, "consulted the chain", () => 0 < calls);
|
|
584
|
+
Assert.True(0 == w.Api().Count, "the first op must not reach the wire");
|
|
585
|
+
|
|
586
|
+
DriveEntityOp(client, w);
|
|
587
|
+
CredentialIs(w.Api()[0].Auth, "RECOVERED01");
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// `auth: null` is the documented way to disable auth outright, and
|
|
591
|
+
// PrepareAuth honours it before it ever reads the apikey. csharp needs a
|
|
592
|
+
// TWO-BRANCH check (key absent OR key present-and-null), because
|
|
593
|
+
// MakeOptions deliberately keeps a supplied null PRESENT - unlike go,
|
|
594
|
+
// where one nil test covers both. Getting this wrong re-transmits
|
|
595
|
+
// exactly the credential the caller suppressed.
|
|
596
|
+
[Fact]
|
|
597
|
+
public void AuthNullSuppressesTheCredentialChainOrNoChain()
|
|
598
|
+
{
|
|
599
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "APIKEY", "ENVKEY03");
|
|
600
|
+
try
|
|
601
|
+
{
|
|
602
|
+
var w = new Wire();
|
|
603
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
604
|
+
{
|
|
605
|
+
["auth"] = null,
|
|
606
|
+
["apikey"] = "OPTKEY01",
|
|
607
|
+
["feature"] = SecretsOpts(null),
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
DriveEntityOp(client, w);
|
|
611
|
+
|
|
612
|
+
Assert.False(w.Api()[0].HasAuth,
|
|
613
|
+
"auth null must suppress the credential, got header " + w.Api()[0].Auth);
|
|
614
|
+
|
|
615
|
+
// The suppression survives option validation rather than being
|
|
616
|
+
// replaced by the optspec's default auth map.
|
|
617
|
+
var opts = client.OptionsMap();
|
|
618
|
+
Assert.True(opts.TryGetValue("auth", out var authval) && null == authval,
|
|
619
|
+
"options.auth must stay a PRESENT null");
|
|
620
|
+
}
|
|
621
|
+
finally
|
|
622
|
+
{
|
|
623
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "APIKEY", null);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// With `cache: false`, a provider that answered once and then reports a
|
|
628
|
+
// MISS (a revoked secret) must RETRACT the credential: the next request
|
|
629
|
+
// must go out with no authorization header.
|
|
630
|
+
[Fact]
|
|
631
|
+
public void UncachedMissRetractsTheCredential()
|
|
632
|
+
{
|
|
633
|
+
var have = true;
|
|
634
|
+
var revocable = new ProbeProvider { Fn = _ => have ? "REVOCABLE01" : null };
|
|
635
|
+
|
|
636
|
+
var w = new Wire();
|
|
637
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
638
|
+
{
|
|
639
|
+
["feature"] = ProviderOpts(revocable,
|
|
640
|
+
new Dictionary<string, object?> { ["cache"] = false }),
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
DriveEntityOp(client, w);
|
|
644
|
+
CredentialIs(w.Api()[0].Auth, "REVOCABLE01");
|
|
645
|
+
|
|
646
|
+
have = false;
|
|
647
|
+
|
|
648
|
+
DriveEntityOp(client, w);
|
|
649
|
+
var last = w.Api()[w.Api().Count - 1];
|
|
650
|
+
Assert.True(!last.HasAuth || "" == last.Auth,
|
|
651
|
+
"after the chain reports a miss, the retracted credential must not go " +
|
|
652
|
+
"out; the wire saw " + last.Auth);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// A MISS IS NOT A CACHEABLE ANSWER - sekreto's own rule, which this
|
|
656
|
+
// feature used to override from the layer above.
|
|
657
|
+
//
|
|
658
|
+
// DEFAULT caching here, which is the whole point: `cache: true` is
|
|
659
|
+
// about holding a HIT, and keeping the settled resolution after a miss
|
|
660
|
+
// meant the chain was never asked again for the life of the client. A
|
|
661
|
+
// secret provisioned after startup (a mounted file, a vault policy
|
|
662
|
+
// granted a minute late) was invisible forever, and the only workaround
|
|
663
|
+
// was giving up hit caching entirely.
|
|
664
|
+
[Fact]
|
|
665
|
+
public void CachedMissIsReasked()
|
|
666
|
+
{
|
|
667
|
+
var present = false;
|
|
668
|
+
var calls = 0;
|
|
669
|
+
var late = new ProbeProvider
|
|
670
|
+
{
|
|
671
|
+
Fn = _ =>
|
|
672
|
+
{
|
|
673
|
+
calls++;
|
|
674
|
+
return present ? "LATEKEY01" : null;
|
|
675
|
+
},
|
|
676
|
+
};
|
|
677
|
+
|
|
678
|
+
var w = new Wire();
|
|
679
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
680
|
+
{
|
|
681
|
+
["feature"] = ProviderOpts(late, null),
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
DriveEntityOp(client, w);
|
|
685
|
+
var first = w.Api()[0];
|
|
686
|
+
Assert.True(!first.HasAuth || "" == first.Auth,
|
|
687
|
+
"the chain has nothing yet, so no credential should go out");
|
|
688
|
+
|
|
689
|
+
var asked = calls;
|
|
690
|
+
Assert.True(0 < asked);
|
|
691
|
+
|
|
692
|
+
// The secret is provisioned while the client is live.
|
|
693
|
+
present = true;
|
|
694
|
+
|
|
695
|
+
DriveEntityOp(client, w);
|
|
696
|
+
CredentialIs(w.Api()[w.Api().Count - 1].Auth, "LATEKEY01");
|
|
697
|
+
|
|
698
|
+
Assert.True(asked < calls,
|
|
699
|
+
"the MISS was cached: a secret that appears later can never be picked up");
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// The other half of the same rule: a HIT is still cached by default, so
|
|
703
|
+
// the fix above must not turn every request into a chain walk.
|
|
704
|
+
[Fact]
|
|
705
|
+
public void CachedHitIsKept()
|
|
706
|
+
{
|
|
707
|
+
var calls = 0;
|
|
708
|
+
var counting = new ProbeProvider
|
|
709
|
+
{
|
|
710
|
+
Fn = _ =>
|
|
711
|
+
{
|
|
712
|
+
calls++;
|
|
713
|
+
return "STABLEKEY01";
|
|
714
|
+
},
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
var w = new Wire();
|
|
718
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
719
|
+
{
|
|
720
|
+
["feature"] = ProviderOpts(counting, null),
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
DriveEntityOp(client, w);
|
|
724
|
+
DriveEntityOp(client, w);
|
|
725
|
+
|
|
726
|
+
Assert.True(1 == calls,
|
|
727
|
+
"a hit must be cached under the default cache: true, chain asked " +
|
|
728
|
+
calls + " times");
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
[Fact]
|
|
732
|
+
public void CacheFalseAsksTheChainOnEveryResolve()
|
|
733
|
+
{
|
|
734
|
+
var calls = 0;
|
|
735
|
+
var counting = new ProbeProvider
|
|
736
|
+
{
|
|
737
|
+
Fn = _ =>
|
|
738
|
+
{
|
|
739
|
+
calls++;
|
|
740
|
+
return "KEY" + calls;
|
|
741
|
+
},
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
var w = new Wire();
|
|
745
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
746
|
+
{
|
|
747
|
+
["feature"] = ProviderOpts(counting,
|
|
748
|
+
new Dictionary<string, object?> { ["cache"] = false }),
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
DriveEntityOp(client, w);
|
|
752
|
+
DriveEntityOp(client, w);
|
|
753
|
+
|
|
754
|
+
Assert.True(1 < calls,
|
|
755
|
+
"the chain was asked once and cached, despite cache: false");
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
[Fact]
|
|
759
|
+
public void SecretNameIsConfigurable()
|
|
760
|
+
{
|
|
761
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "API_TOKEN", "TOKKEY01");
|
|
762
|
+
try
|
|
763
|
+
{
|
|
764
|
+
var w = new Wire();
|
|
765
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
766
|
+
{
|
|
767
|
+
["feature"] = SecretsOpts(
|
|
768
|
+
new Dictionary<string, object?> { ["name"] = "api.token" }),
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
DriveEntityOp(client, w);
|
|
772
|
+
CredentialIs(w.Api()[0].Auth, "TOKKEY01");
|
|
773
|
+
}
|
|
774
|
+
finally
|
|
775
|
+
{
|
|
776
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "API_TOKEN", null);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// The Sekreto instance is LIVE, for callers who want arbitrary secrets
|
|
781
|
+
// or redaction. Never a clone: sekreto holds provider state that has to
|
|
782
|
+
// stay live to be worth anything.
|
|
783
|
+
[Fact]
|
|
784
|
+
public void SekretoIsLiveForArbitrarySecretsAndRedaction()
|
|
785
|
+
{
|
|
786
|
+
var w = new Wire();
|
|
787
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
788
|
+
{
|
|
789
|
+
["feature"] = new Dictionary<string, object?>
|
|
790
|
+
{
|
|
791
|
+
["secrets"] = new Dictionary<string, object?>
|
|
792
|
+
{
|
|
793
|
+
["active"] = true,
|
|
794
|
+
["providers"] = new List<object?>
|
|
795
|
+
{
|
|
796
|
+
new Dictionary<string, object?>
|
|
797
|
+
{
|
|
798
|
+
["kind"] = "memory",
|
|
799
|
+
["values"] = new Dictionary<string, object?>
|
|
800
|
+
{
|
|
801
|
+
["DB_PASSWORD"] = "dbpass01",
|
|
802
|
+
},
|
|
803
|
+
},
|
|
804
|
+
},
|
|
805
|
+
},
|
|
806
|
+
},
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
var secrets = SecretsOf(client)!.GetSekreto()!;
|
|
810
|
+
|
|
811
|
+
// The nested `values` map arrives in the SDK's loose object model
|
|
812
|
+
// and sekreto reads it as Dictionary<string, object>: a converter
|
|
813
|
+
// that dropped the nested block would leave the store EMPTY and this
|
|
814
|
+
// read would miss.
|
|
815
|
+
Assert.Equal("dbpass01", secrets.Get("db.password"));
|
|
816
|
+
Assert.Equal("the password is [redacted], keep it safe",
|
|
817
|
+
secrets.Redact("the password is dbpass01, keep it safe"));
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// THE PROVIDER VOCABULARY IS NON-EMPTY, and it matches what the SDK
|
|
821
|
+
// actually carries.
|
|
822
|
+
//
|
|
823
|
+
// A provider kind the model did NOT select is unknown to this Sekreto -
|
|
824
|
+
// upstream's contract since the registry was retired, and the reason
|
|
825
|
+
// Config emits the plugin definitions at all. The failure this exists to
|
|
826
|
+
// catch is the SILENT one: a Config that emits an EMPTY vocabulary while
|
|
827
|
+
// the SDK still ships every plugin file its model selected. Every
|
|
828
|
+
// builtin-only test above stays green through that, and the SDK then
|
|
829
|
+
// refuses each of those kinds at runtime as "unknown provider kind".
|
|
830
|
+
//
|
|
831
|
+
// So the expected set is read off the ASSEMBLY, not off the config: the
|
|
832
|
+
// vendored plugin classes compile into this SDK exactly when the model
|
|
833
|
+
// selected their group, so what they export is an independent witness of
|
|
834
|
+
// what the model asked for. Conditioning on the config instead would let
|
|
835
|
+
// an empty vocabulary make this test pass by returning early - which is
|
|
836
|
+
// the whole defect.
|
|
837
|
+
[Fact]
|
|
838
|
+
public void ASelectedPluginKindIsInTheSdkVocabulary()
|
|
839
|
+
{
|
|
840
|
+
// Every Definition the generated tree carries, discovered rather
|
|
841
|
+
// than listed: this file ships to projects with any subset of the
|
|
842
|
+
// plugin groups, and upstream is free to add a kind.
|
|
843
|
+
var carried = new List<string>();
|
|
844
|
+
foreach (var t in typeof(SecretsFeature).Assembly.GetTypes())
|
|
845
|
+
{
|
|
846
|
+
if ("Voxgig.Sekreto.Plugins" != t.Namespace)
|
|
847
|
+
{
|
|
848
|
+
continue;
|
|
849
|
+
}
|
|
850
|
+
foreach (var f in t.GetFields(BindingFlags.Public | BindingFlags.Static))
|
|
851
|
+
{
|
|
852
|
+
if (typeof(Voxgig.Plugin.Definition) == f.FieldType)
|
|
853
|
+
{
|
|
854
|
+
carried.Add(t.Name + "." + f.Name);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
if (0 == carried.Count)
|
|
860
|
+
{
|
|
861
|
+
// No plugin groups in this project's model: nothing to assert.
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
var vocabulary = SdkConfig.FeaturePlugins("secrets");
|
|
866
|
+
|
|
867
|
+
var kinds = new List<string>();
|
|
868
|
+
foreach (var d in vocabulary)
|
|
869
|
+
{
|
|
870
|
+
if (d is Voxgig.Plugin.Definition def)
|
|
871
|
+
{
|
|
872
|
+
kinds.Add(def.Name);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
Assert.True(carried.Count == kinds.Count,
|
|
877
|
+
"the SDK carries " + carried.Count + " plugin definitions (" +
|
|
878
|
+
string.Join(", ", carried) + ") but the config's vocabulary holds " +
|
|
879
|
+
kinds.Count + " (" + string.Join(", ", kinds) + ") - every kind the " +
|
|
880
|
+
"model selected must be passed to Sekreto, or the SDK refuses it at " +
|
|
881
|
+
"runtime as an unknown provider kind");
|
|
882
|
+
|
|
883
|
+
// Construction is where an unknown kind is refused, so the Sekreto
|
|
884
|
+
// being built at all IS the second half of the check. The memory
|
|
885
|
+
// store comes FIRST so sekreto's first-hit rule answers from it and
|
|
886
|
+
// the vault is never contacted - the kind has to be DECLARABLE, not
|
|
887
|
+
// reachable.
|
|
888
|
+
|
|
889
|
+
var w = new Wire();
|
|
890
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
891
|
+
{
|
|
892
|
+
["feature"] = new Dictionary<string, object?>
|
|
893
|
+
{
|
|
894
|
+
["secrets"] = new Dictionary<string, object?>
|
|
895
|
+
{
|
|
896
|
+
["active"] = true,
|
|
897
|
+
["providers"] = new List<object?>
|
|
898
|
+
{
|
|
899
|
+
new Dictionary<string, object?>
|
|
900
|
+
{
|
|
901
|
+
["kind"] = "memory",
|
|
902
|
+
["values"] = new Dictionary<string, object?>
|
|
903
|
+
{
|
|
904
|
+
["APIKEY"] = "VOCAB01",
|
|
905
|
+
},
|
|
906
|
+
},
|
|
907
|
+
new Dictionary<string, object?>
|
|
908
|
+
{
|
|
909
|
+
["kind"] = kinds[0],
|
|
910
|
+
["addr"] = "https://vault.test",
|
|
911
|
+
["token"] = "x",
|
|
912
|
+
["command"] = "true",
|
|
913
|
+
["project"] = "p",
|
|
914
|
+
["region"] = "eu-west-1",
|
|
915
|
+
["vault"] = "v",
|
|
916
|
+
["account"] = "a",
|
|
917
|
+
},
|
|
918
|
+
},
|
|
919
|
+
},
|
|
920
|
+
},
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
DriveEntityOp(client, w);
|
|
924
|
+
CredentialIs(w.Api()[0].Auth, "VOCAB01");
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
// --- THE RAW PATHS ----------------------------------------------------
|
|
929
|
+
//
|
|
930
|
+
// Direct and Graphql run NO feature hooks at all - the client fragment
|
|
931
|
+
// says so itself ("like Direct, this bypasses the feature pipeline") -
|
|
932
|
+
// so for them the transport seam is the ONLY place resolution can
|
|
933
|
+
// happen. These are the cases that would pass vacuously against a
|
|
934
|
+
// PreSpec-only implementation, and the ones that pin the seam choice.
|
|
935
|
+
|
|
936
|
+
[Fact]
|
|
937
|
+
public void DirectCarriesTheChainCredential()
|
|
938
|
+
{
|
|
939
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "APIKEY", "DIRECTKEY01");
|
|
940
|
+
try
|
|
941
|
+
{
|
|
942
|
+
var w = new Wire();
|
|
943
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
944
|
+
{
|
|
945
|
+
["feature"] = SecretsOpts(null),
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
var res = client.Direct(new Dictionary<string, object?> { ["path"] = "/probe" });
|
|
949
|
+
|
|
950
|
+
Assert.True(Equals(res["ok"], true), "direct refused: " + res.GetValueOrDefault("err"));
|
|
951
|
+
Assert.True(1 == w.Api().Count,
|
|
952
|
+
"expected one direct call on the wire, got " + w.Api().Count);
|
|
953
|
+
CredentialIs(w.Api()[0].Auth, "DIRECTKEY01");
|
|
954
|
+
}
|
|
955
|
+
finally
|
|
956
|
+
{
|
|
957
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "APIKEY", null);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
[Fact]
|
|
962
|
+
public void AProviderErrorFailsDirectRatherThanSending()
|
|
963
|
+
{
|
|
964
|
+
var w = new Wire();
|
|
965
|
+
var broken = SecretsClient(w, new Dictionary<string, object?>
|
|
966
|
+
{
|
|
967
|
+
["feature"] = ProviderOpts(
|
|
968
|
+
new ProbeProvider { Fn = _ => throw new SekretoError("vault unreachable") },
|
|
969
|
+
null),
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
var res = broken.Direct(new Dictionary<string, object?> { ["path"] = "/probe" });
|
|
973
|
+
|
|
974
|
+
Assert.True(0 == w.Calls.Count,
|
|
975
|
+
"a request must not go out unauthenticated because a provider broke, " +
|
|
976
|
+
"but one reached the transport: " + w.Report());
|
|
977
|
+
Assert.True(Equals(res["ok"], false), "a broken chain must refuse the raw path");
|
|
978
|
+
|
|
979
|
+
// The PROVIDER'S OWN message, so an unrelated failure cannot stand
|
|
980
|
+
// in for fail-closed.
|
|
981
|
+
var err = res.GetValueOrDefault("err") as Exception;
|
|
982
|
+
Assert.True(null != err, "expected the provider error in-band, got: " +
|
|
983
|
+
res.GetValueOrDefault("err"));
|
|
984
|
+
Assert.Contains("vault unreachable", err!.Message);
|
|
985
|
+
|
|
986
|
+
// CONTROL: the same construction with a WORKING provider must reach
|
|
987
|
+
// the same transport exactly once, carrying the credential.
|
|
988
|
+
var control = new Wire();
|
|
989
|
+
var ok = SecretsClient(control, new Dictionary<string, object?>
|
|
990
|
+
{
|
|
991
|
+
["feature"] = ProviderOpts(new ProbeProvider { Fn = _ => "RAWKEY01" }, null),
|
|
992
|
+
});
|
|
993
|
+
|
|
994
|
+
var good = ok.Direct(new Dictionary<string, object?> { ["path"] = "/probe" });
|
|
995
|
+
|
|
996
|
+
Assert.True(Equals(good["ok"], true),
|
|
997
|
+
"the control request failed: " + good.GetValueOrDefault("err"));
|
|
998
|
+
Assert.True(1 == control.Calls.Count,
|
|
999
|
+
"the control request never reached system.fetch, so this test cannot " +
|
|
1000
|
+
"observe a request going out at all");
|
|
1001
|
+
CredentialIs(control.Calls[0].Auth, "RAWKEY01");
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
[Fact]
|
|
1005
|
+
public void AProviderErrorFailsGraphqlRatherThanSending()
|
|
1006
|
+
{
|
|
1007
|
+
var w = new Wire();
|
|
1008
|
+
var broken = SecretsClient(w, new Dictionary<string, object?>
|
|
1009
|
+
{
|
|
1010
|
+
["feature"] = ProviderOpts(
|
|
1011
|
+
new ProbeProvider { Fn = _ => throw new SekretoError("vault unreachable") },
|
|
1012
|
+
null),
|
|
1013
|
+
});
|
|
1014
|
+
|
|
1015
|
+
var res = broken.Graphql("{ thing }", null);
|
|
1016
|
+
|
|
1017
|
+
Assert.True(0 == w.Calls.Count,
|
|
1018
|
+
"a graphql request must not go out unauthenticated, but one reached " +
|
|
1019
|
+
"the transport: " + w.Report());
|
|
1020
|
+
Assert.True(Equals(res["ok"], false), "a broken chain must refuse graphql");
|
|
1021
|
+
|
|
1022
|
+
var err = res.GetValueOrDefault("err") as Exception;
|
|
1023
|
+
Assert.True(null != err, "expected the provider error in-band, got: " +
|
|
1024
|
+
res.GetValueOrDefault("err"));
|
|
1025
|
+
Assert.Contains("vault unreachable", err!.Message);
|
|
1026
|
+
|
|
1027
|
+
var control = new Wire();
|
|
1028
|
+
var ok = SecretsClient(control, new Dictionary<string, object?>
|
|
1029
|
+
{
|
|
1030
|
+
["feature"] = ProviderOpts(new ProbeProvider { Fn = _ => "RAWKEY01" }, null),
|
|
1031
|
+
});
|
|
1032
|
+
|
|
1033
|
+
var good = ok.Graphql("{ thing }", null);
|
|
1034
|
+
|
|
1035
|
+
Assert.True(Equals(good["ok"], true),
|
|
1036
|
+
"the control request failed: " + good.GetValueOrDefault("err"));
|
|
1037
|
+
Assert.True(1 == control.Calls.Count,
|
|
1038
|
+
"the control graphql request never reached system.fetch, so this test " +
|
|
1039
|
+
"cannot observe a request going out at all");
|
|
1040
|
+
CredentialIs(control.Calls[0].Auth, "RAWKEY01");
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
// --- FAIL CLOSED ON A CONSTRUCTION FAILURE ----------------------------
|
|
1045
|
+
//
|
|
1046
|
+
// The chain a project configures can be wrong before a single lookup
|
|
1047
|
+
// happens: a provider kind that does not exist (or one whose plugin
|
|
1048
|
+
// group the model did not select), and sekreto's constructor refuses
|
|
1049
|
+
// it; or a secret name Names.EnvKey rejects. Init is void and cannot
|
|
1050
|
+
// fail the client construction the way ts's throwing init does, so it
|
|
1051
|
+
// HOLDS that error in `_initerr` and the transport gate refuses to send.
|
|
1052
|
+
//
|
|
1053
|
+
// That gate is worth exactly as much as the seam it lives behind, which
|
|
1054
|
+
// is why Init wraps FIRST and builds SECOND: an Init that returns early
|
|
1055
|
+
// on the construction failure before installing the wrapper leaves no
|
|
1056
|
+
// gate at all, and a misconfigured chain then sends ordinary
|
|
1057
|
+
// UNAUTHENTICATED requests - or, with an explicit apikey and a bad
|
|
1058
|
+
// secret name, the credential itself - while the held error is read by
|
|
1059
|
+
// nothing. Every other case in this file passes with the gate deleted
|
|
1060
|
+
// and with the wrap moved last; these four are the ones that go RED.
|
|
1061
|
+
// The three wire paths - the entity pipeline, Direct and Graphql - each
|
|
1062
|
+
// carry their own CONTROL leg, so a zero means REFUSED and not UNWIRED.
|
|
1063
|
+
|
|
1064
|
+
// A provider kind sekreto has never heard of: its constructor throws
|
|
1065
|
+
// before this feature has a Sekreto at all. Matched on sekreto's OWN
|
|
1066
|
+
// message, so an unrelated failure cannot stand in for fail-closed.
|
|
1067
|
+
private const string UnknownKind = "unknown provider kind: nosuchkind";
|
|
1068
|
+
|
|
1069
|
+
private static Dictionary<string, object?> MisconfiguredChain()
|
|
1070
|
+
{
|
|
1071
|
+
return ProviderOpts(new Dictionary<string, object?>
|
|
1072
|
+
{
|
|
1073
|
+
["kind"] = "nosuchkind",
|
|
1074
|
+
["name"] = "broken",
|
|
1075
|
+
}, null);
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
private static bool SaysUnknownKind(object? err)
|
|
1079
|
+
{
|
|
1080
|
+
var msg = err is Exception ex ? ex.Message : (err?.ToString() ?? "");
|
|
1081
|
+
return msg.Contains(UnknownKind);
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
private static string ErrMessage(Dictionary<string, object?> res)
|
|
1085
|
+
{
|
|
1086
|
+
var err = res.GetValueOrDefault("err");
|
|
1087
|
+
return err is Exception ex ? ex.Message : (err?.ToString() ?? "");
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
[Fact]
|
|
1091
|
+
public void AConstructionFailureFailsTheEntityOpAndNothingReachesTheWire()
|
|
1092
|
+
{
|
|
1093
|
+
// THE RULE.
|
|
1094
|
+
var w = new Wire();
|
|
1095
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1096
|
+
{
|
|
1097
|
+
["feature"] = MisconfiguredChain(),
|
|
1098
|
+
});
|
|
1099
|
+
|
|
1100
|
+
// The feature must still be INSTALLED: a construction failure that
|
|
1101
|
+
// silently uninstalls the feature is the same fail-open by another
|
|
1102
|
+
// route, and nothing downstream would be gating anything.
|
|
1103
|
+
Assert.True(null != SecretsOf(client),
|
|
1104
|
+
"a chain that failed to build must leave the feature installed and gating");
|
|
1105
|
+
|
|
1106
|
+
_lasterr = null;
|
|
1107
|
+
// Stop on EITHER outcome - the refusal we want, or a request going
|
|
1108
|
+
// out, which is the failure this test exists to catch. Stopping only
|
|
1109
|
+
// on the refusal would report "nothing to assert on" for the leak.
|
|
1110
|
+
DriveEntityOpUntil(client, "refused the operation or sent one",
|
|
1111
|
+
() => 0 < w.Api().Count || SaysUnknownKind(_lasterr));
|
|
1112
|
+
|
|
1113
|
+
Assert.True(0 == w.Api().Count,
|
|
1114
|
+
"a chain that failed to BUILD sent an UNAUTHENTICATED request: " + w.Report());
|
|
1115
|
+
|
|
1116
|
+
Assert.True(null != _lasterr, "the entity op must fail when the chain cannot be built");
|
|
1117
|
+
Assert.True(SaysUnknownKind(_lasterr),
|
|
1118
|
+
"the refusal must carry sekreto's own message (" + UnknownKind + "), got: " +
|
|
1119
|
+
_lasterr!.Message);
|
|
1120
|
+
|
|
1121
|
+
// CONTROL, which makes that zero mean REFUSED rather than UNWIRED:
|
|
1122
|
+
// the same construction with a WORKING provider must reach the same
|
|
1123
|
+
// transport, once, carrying the credential.
|
|
1124
|
+
var control = new Wire();
|
|
1125
|
+
var ok = SecretsClient(control, new Dictionary<string, object?>
|
|
1126
|
+
{
|
|
1127
|
+
["feature"] = ProviderOpts(new ProbeProvider { Fn = _ => "INITKEY01" }, null),
|
|
1128
|
+
});
|
|
1129
|
+
|
|
1130
|
+
DriveEntityOp(ok, control);
|
|
1131
|
+
|
|
1132
|
+
Assert.True(1 == control.Api().Count,
|
|
1133
|
+
"the control request did not reach system.fetch exactly once, so this " +
|
|
1134
|
+
"test cannot observe a request going out at all: " + control.Report());
|
|
1135
|
+
CredentialIs(control.Api()[0].Auth, "INITKEY01");
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
[Fact]
|
|
1139
|
+
public void AConstructionFailureFailsDirectRatherThanSending()
|
|
1140
|
+
{
|
|
1141
|
+
// THE RULE. Direct runs no feature hook at all, so the ONLY thing
|
|
1142
|
+
// that can refuse it is the transport wrapper - the one a
|
|
1143
|
+
// build-first Init never installs on a construction failure.
|
|
1144
|
+
var w = new Wire();
|
|
1145
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1146
|
+
{
|
|
1147
|
+
["feature"] = MisconfiguredChain(),
|
|
1148
|
+
});
|
|
1149
|
+
|
|
1150
|
+
var res = client.Direct(new Dictionary<string, object?> { ["path"] = "/probe" });
|
|
1151
|
+
|
|
1152
|
+
Assert.True(0 == w.Calls.Count,
|
|
1153
|
+
"a chain that failed to BUILD sent an UNAUTHENTICATED direct request: " +
|
|
1154
|
+
w.Report());
|
|
1155
|
+
Assert.True(Equals(res["ok"], false),
|
|
1156
|
+
"a chain that could not be built must refuse the raw path fail-closed");
|
|
1157
|
+
Assert.True(SaysUnknownKind(res.GetValueOrDefault("err")),
|
|
1158
|
+
"the refusal must carry sekreto's own message (" + UnknownKind + "), got: " +
|
|
1159
|
+
ErrMessage(res));
|
|
1160
|
+
|
|
1161
|
+
// CONTROL.
|
|
1162
|
+
var control = new Wire();
|
|
1163
|
+
var ok = SecretsClient(control, new Dictionary<string, object?>
|
|
1164
|
+
{
|
|
1165
|
+
["feature"] = ProviderOpts(new ProbeProvider { Fn = _ => "INITKEY01" }, null),
|
|
1166
|
+
});
|
|
1167
|
+
|
|
1168
|
+
var good = ok.Direct(new Dictionary<string, object?> { ["path"] = "/probe" });
|
|
1169
|
+
|
|
1170
|
+
Assert.True(Equals(good["ok"], true),
|
|
1171
|
+
"the control request failed: " + good.GetValueOrDefault("err"));
|
|
1172
|
+
Assert.True(1 == control.Calls.Count,
|
|
1173
|
+
"the control request never reached system.fetch, so this test cannot " +
|
|
1174
|
+
"observe a request going out at all");
|
|
1175
|
+
CredentialIs(control.Calls[0].Auth, "INITKEY01");
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
[Fact]
|
|
1179
|
+
public void AConstructionFailureFailsGraphqlRatherThanSending()
|
|
1180
|
+
{
|
|
1181
|
+
// THE RULE.
|
|
1182
|
+
var w = new Wire();
|
|
1183
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1184
|
+
{
|
|
1185
|
+
["feature"] = MisconfiguredChain(),
|
|
1186
|
+
});
|
|
1187
|
+
|
|
1188
|
+
var res = client.Graphql("{ thing }", null);
|
|
1189
|
+
|
|
1190
|
+
Assert.True(0 == w.Calls.Count,
|
|
1191
|
+
"a chain that failed to BUILD sent an UNAUTHENTICATED graphql request: " +
|
|
1192
|
+
w.Report());
|
|
1193
|
+
Assert.True(Equals(res["ok"], false),
|
|
1194
|
+
"a chain that could not be built must refuse graphql fail-closed");
|
|
1195
|
+
Assert.True(SaysUnknownKind(res.GetValueOrDefault("err")),
|
|
1196
|
+
"the refusal must carry sekreto's own message (" + UnknownKind + "), got: " +
|
|
1197
|
+
ErrMessage(res));
|
|
1198
|
+
|
|
1199
|
+
// CONTROL.
|
|
1200
|
+
var control = new Wire();
|
|
1201
|
+
var ok = SecretsClient(control, new Dictionary<string, object?>
|
|
1202
|
+
{
|
|
1203
|
+
["feature"] = ProviderOpts(new ProbeProvider { Fn = _ => "INITKEY01" }, null),
|
|
1204
|
+
});
|
|
1205
|
+
|
|
1206
|
+
var good = ok.Graphql("{ thing }", null);
|
|
1207
|
+
|
|
1208
|
+
Assert.True(Equals(good["ok"], true),
|
|
1209
|
+
"the control request failed: " + good.GetValueOrDefault("err"));
|
|
1210
|
+
Assert.True(1 == control.Calls.Count,
|
|
1211
|
+
"the control graphql request never reached system.fetch, so this test " +
|
|
1212
|
+
"cannot observe a request going out at all");
|
|
1213
|
+
CredentialIs(control.Calls[0].Auth, "INITKEY01");
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
// The OTHER construction failure, and the one that tells wrap-first
|
|
1217
|
+
// from wrap-last: an explicit apikey with a secret name Names.EnvKey
|
|
1218
|
+
// refuses. Init holds that error and returns before it ever builds a
|
|
1219
|
+
// Sekreto, so an Init that wraps at the END has installed nothing -
|
|
1220
|
+
// and the credential goes out on the wire through the ordinary
|
|
1221
|
+
// PrepareAuth path, EXPLICIT and unresolved, exactly as if the feature
|
|
1222
|
+
// had never been configured. The unknown-kind cases above cannot see
|
|
1223
|
+
// this: their failure lands in a catch that falls through to the wrap.
|
|
1224
|
+
private const string InvalidName = "sekreto: invalid name: Not Valid!";
|
|
1225
|
+
|
|
1226
|
+
[Fact]
|
|
1227
|
+
public void AnInvalidSecretNameFailsDirectRatherThanSending()
|
|
1228
|
+
{
|
|
1229
|
+
// THE RULE.
|
|
1230
|
+
var w = new Wire();
|
|
1231
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1232
|
+
{
|
|
1233
|
+
["apikey"] = "EXPLICIT01",
|
|
1234
|
+
["feature"] = new Dictionary<string, object?>
|
|
1235
|
+
{
|
|
1236
|
+
["secrets"] = new Dictionary<string, object?>
|
|
1237
|
+
{
|
|
1238
|
+
["active"] = true,
|
|
1239
|
+
["name"] = "Not Valid!",
|
|
1240
|
+
},
|
|
1241
|
+
},
|
|
1242
|
+
});
|
|
1243
|
+
|
|
1244
|
+
Assert.True(null != SecretsOf(client),
|
|
1245
|
+
"an invalid secret name must leave the feature installed and gating");
|
|
1246
|
+
|
|
1247
|
+
var res = client.Direct(new Dictionary<string, object?> { ["path"] = "/probe" });
|
|
1248
|
+
|
|
1249
|
+
Assert.True(0 == w.Calls.Count,
|
|
1250
|
+
"an invalid secret name still let a request out, carrying the explicit " +
|
|
1251
|
+
"credential: " + w.Report());
|
|
1252
|
+
Assert.True(Equals(res["ok"], false),
|
|
1253
|
+
"an invalid secret name must refuse the raw path fail-closed");
|
|
1254
|
+
Assert.Contains(InvalidName, ErrMessage(res));
|
|
1255
|
+
|
|
1256
|
+
// CONTROL: the same construction with a VALID name must reach the
|
|
1257
|
+
// transport once, carrying that same explicit credential.
|
|
1258
|
+
var control = new Wire();
|
|
1259
|
+
var ok = SecretsClient(control, new Dictionary<string, object?>
|
|
1260
|
+
{
|
|
1261
|
+
["apikey"] = "EXPLICIT01",
|
|
1262
|
+
["feature"] = new Dictionary<string, object?>
|
|
1263
|
+
{
|
|
1264
|
+
["secrets"] = new Dictionary<string, object?>
|
|
1265
|
+
{
|
|
1266
|
+
["active"] = true,
|
|
1267
|
+
["name"] = "apikey",
|
|
1268
|
+
},
|
|
1269
|
+
},
|
|
1270
|
+
});
|
|
1271
|
+
|
|
1272
|
+
var good = ok.Direct(new Dictionary<string, object?> { ["path"] = "/probe" });
|
|
1273
|
+
|
|
1274
|
+
Assert.True(Equals(good["ok"], true),
|
|
1275
|
+
"the control request failed: " + good.GetValueOrDefault("err"));
|
|
1276
|
+
Assert.True(1 == control.Calls.Count,
|
|
1277
|
+
"the control request never reached system.fetch, so this test cannot " +
|
|
1278
|
+
"observe a request going out at all");
|
|
1279
|
+
CredentialIs(control.Calls[0].Auth, "EXPLICIT01");
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
|
|
1283
|
+
// --- the access-token exchange ----------------------------------------
|
|
1284
|
+
|
|
1285
|
+
private static Dictionary<string, object?> ExchangeOpts(Dictionary<string, object?>? xextra)
|
|
1286
|
+
{
|
|
1287
|
+
var x = new Dictionary<string, object?> { ["active"] = true };
|
|
1288
|
+
foreach (var kv in xextra ?? new Dictionary<string, object?>())
|
|
1289
|
+
{
|
|
1290
|
+
x[kv.Key] = kv.Value;
|
|
1291
|
+
}
|
|
1292
|
+
return SecretsOpts(new Dictionary<string, object?>
|
|
1293
|
+
{
|
|
1294
|
+
["name"] = "refresh_token",
|
|
1295
|
+
["exchange"] = x,
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
[Fact]
|
|
1300
|
+
public void TheRefreshTokenBuysAnAccessTokenAndASpentOneIsReboughtOnce()
|
|
1301
|
+
{
|
|
1302
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", "REFRESH01");
|
|
1303
|
+
try
|
|
1304
|
+
{
|
|
1305
|
+
// First API call is refused, the retry succeeds.
|
|
1306
|
+
var w = new Wire { ApiStatus = new List<int> { 401, 200 } };
|
|
1307
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1308
|
+
{
|
|
1309
|
+
["feature"] = ExchangeOpts(null),
|
|
1310
|
+
});
|
|
1311
|
+
|
|
1312
|
+
var res = client.Direct(new Dictionary<string, object?> { ["path"] = "/thing" });
|
|
1313
|
+
|
|
1314
|
+
Assert.True(2 == w.Token().Count,
|
|
1315
|
+
"expected the initial purchase plus one rebuy, got " + w.Token().Count);
|
|
1316
|
+
Assert.Contains("REFRESH01", w.Token()[0].Body);
|
|
1317
|
+
|
|
1318
|
+
Assert.True(2 == w.Api().Count,
|
|
1319
|
+
"expected the request to be retried exactly once, got " + w.Api().Count);
|
|
1320
|
+
CredentialIs(w.Api()[0].Auth, "ACCESS01");
|
|
1321
|
+
// The retry must carry the NEW token, not the spent one.
|
|
1322
|
+
CredentialIs(w.Api()[1].Auth, "ACCESS02");
|
|
1323
|
+
|
|
1324
|
+
Assert.True(Equals(res["ok"], true), "the caller sees the successful retry");
|
|
1325
|
+
}
|
|
1326
|
+
finally
|
|
1327
|
+
{
|
|
1328
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", null);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
[Fact]
|
|
1333
|
+
public void AnExplicitExchangeRefreshWinsOverTheChain()
|
|
1334
|
+
{
|
|
1335
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", "FROMCHAIN");
|
|
1336
|
+
try
|
|
1337
|
+
{
|
|
1338
|
+
var w = new Wire();
|
|
1339
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1340
|
+
{
|
|
1341
|
+
["feature"] = ExchangeOpts(
|
|
1342
|
+
new Dictionary<string, object?> { ["refresh"] = "EXPLICIT01" }),
|
|
1343
|
+
});
|
|
1344
|
+
|
|
1345
|
+
client.Direct(new Dictionary<string, object?> { ["path"] = "/thing" });
|
|
1346
|
+
|
|
1347
|
+
Assert.Contains("EXPLICIT01", w.Token()[0].Body);
|
|
1348
|
+
Assert.DoesNotContain("FROMCHAIN", w.Token()[0].Body);
|
|
1349
|
+
}
|
|
1350
|
+
finally
|
|
1351
|
+
{
|
|
1352
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", null);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
[Fact]
|
|
1357
|
+
public void OnePurchaseServesManyRequests()
|
|
1358
|
+
{
|
|
1359
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", "REFRESH01");
|
|
1360
|
+
try
|
|
1361
|
+
{
|
|
1362
|
+
var w = new Wire();
|
|
1363
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1364
|
+
{
|
|
1365
|
+
["feature"] = ExchangeOpts(null),
|
|
1366
|
+
});
|
|
1367
|
+
|
|
1368
|
+
client.Direct(new Dictionary<string, object?> { ["path"] = "/one" });
|
|
1369
|
+
client.Direct(new Dictionary<string, object?> { ["path"] = "/two" });
|
|
1370
|
+
client.Direct(new Dictionary<string, object?> { ["path"] = "/three" });
|
|
1371
|
+
|
|
1372
|
+
Assert.True(1 == w.Token().Count,
|
|
1373
|
+
"a token still working must not be re-bought, saw " + w.Token().Count);
|
|
1374
|
+
Assert.True(3 == w.Api().Count);
|
|
1375
|
+
}
|
|
1376
|
+
finally
|
|
1377
|
+
{
|
|
1378
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", null);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
[Fact]
|
|
1383
|
+
public void ConcurrentFirstRequestsShareOnePurchase()
|
|
1384
|
+
{
|
|
1385
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", "REFRESH01");
|
|
1386
|
+
try
|
|
1387
|
+
{
|
|
1388
|
+
var w = new Wire();
|
|
1389
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1390
|
+
{
|
|
1391
|
+
["feature"] = ExchangeOpts(null),
|
|
1392
|
+
});
|
|
1393
|
+
|
|
1394
|
+
Parallel.For(0, 4, i =>
|
|
1395
|
+
client.Direct(new Dictionary<string, object?> { ["path"] = "/p" + i }));
|
|
1396
|
+
|
|
1397
|
+
Assert.True(1 == w.Token().Count,
|
|
1398
|
+
"four operations at once must not open four token requests, saw " +
|
|
1399
|
+
w.Token().Count);
|
|
1400
|
+
}
|
|
1401
|
+
finally
|
|
1402
|
+
{
|
|
1403
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", null);
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
[Fact]
|
|
1408
|
+
public void AStatusOutsideExchangeStatusesIsNotAnExpiry()
|
|
1409
|
+
{
|
|
1410
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", "REFRESH01");
|
|
1411
|
+
try
|
|
1412
|
+
{
|
|
1413
|
+
var w = new Wire { ApiStatus = new List<int> { 403 } };
|
|
1414
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1415
|
+
{
|
|
1416
|
+
["feature"] = ExchangeOpts(null),
|
|
1417
|
+
});
|
|
1418
|
+
|
|
1419
|
+
client.Direct(new Dictionary<string, object?> { ["path"] = "/thing" });
|
|
1420
|
+
|
|
1421
|
+
Assert.True(1 == w.Api().Count, "403 is not in the default statuses");
|
|
1422
|
+
Assert.True(1 == w.Token().Count);
|
|
1423
|
+
}
|
|
1424
|
+
finally
|
|
1425
|
+
{
|
|
1426
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", null);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
[Fact]
|
|
1431
|
+
public void ExchangeStatusesAndFieldNamesAreConfigurable()
|
|
1432
|
+
{
|
|
1433
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", "REFRESH01");
|
|
1434
|
+
try
|
|
1435
|
+
{
|
|
1436
|
+
var w = new Wire
|
|
1437
|
+
{
|
|
1438
|
+
ApiStatus = new List<int> { 403, 200 },
|
|
1439
|
+
TokenPath = "oauth/grant",
|
|
1440
|
+
RespField = "token",
|
|
1441
|
+
};
|
|
1442
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1443
|
+
{
|
|
1444
|
+
["feature"] = ExchangeOpts(new Dictionary<string, object?>
|
|
1445
|
+
{
|
|
1446
|
+
["path"] = "oauth/grant",
|
|
1447
|
+
["request"] = "grant",
|
|
1448
|
+
["response"] = "token",
|
|
1449
|
+
["statuses"] = new List<object?> { 403 },
|
|
1450
|
+
}),
|
|
1451
|
+
});
|
|
1452
|
+
|
|
1453
|
+
client.Direct(new Dictionary<string, object?> { ["path"] = "/thing" });
|
|
1454
|
+
|
|
1455
|
+
Assert.True(2 == w.Api().Count, "403 was declared an expiry");
|
|
1456
|
+
Assert.True(w.Token()[0].Url.EndsWith("/oauth/grant"),
|
|
1457
|
+
"the token endpoint is relative to base: " + w.Token()[0].Url);
|
|
1458
|
+
Assert.Contains("\"grant\"", w.Token()[0].Body);
|
|
1459
|
+
CredentialIs(w.Api()[1].Auth, "ACCESS02");
|
|
1460
|
+
}
|
|
1461
|
+
finally
|
|
1462
|
+
{
|
|
1463
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", null);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
[Fact]
|
|
1468
|
+
public void AnExplicitApikeyIsSpentBeforeAnythingIsBought()
|
|
1469
|
+
{
|
|
1470
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", "REFRESH01");
|
|
1471
|
+
try
|
|
1472
|
+
{
|
|
1473
|
+
var w = new Wire();
|
|
1474
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1475
|
+
{
|
|
1476
|
+
["apikey"] = "HELDTOKEN01",
|
|
1477
|
+
["feature"] = ExchangeOpts(null),
|
|
1478
|
+
});
|
|
1479
|
+
|
|
1480
|
+
client.Direct(new Dictionary<string, object?> { ["path"] = "/thing" });
|
|
1481
|
+
|
|
1482
|
+
Assert.True(0 == w.Token().Count, "nothing needed buying");
|
|
1483
|
+
CredentialIs(w.Api()[0].Auth, "HELDTOKEN01");
|
|
1484
|
+
}
|
|
1485
|
+
finally
|
|
1486
|
+
{
|
|
1487
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", null);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
[Fact]
|
|
1492
|
+
public void NoRefreshTokenAnywhereIsAnErrorNotAnUnauthenticatedCall()
|
|
1493
|
+
{
|
|
1494
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", null);
|
|
1495
|
+
|
|
1496
|
+
var w = new Wire();
|
|
1497
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1498
|
+
{
|
|
1499
|
+
["feature"] = ExchangeOpts(null),
|
|
1500
|
+
});
|
|
1501
|
+
|
|
1502
|
+
var res = client.Direct(new Dictionary<string, object?> { ["path"] = "/thing" });
|
|
1503
|
+
|
|
1504
|
+
Assert.True(Equals(res["ok"], false),
|
|
1505
|
+
"expected a failure, got: " + res.GetValueOrDefault("ok"));
|
|
1506
|
+
Assert.True(0 == w.Api().Count,
|
|
1507
|
+
"a request must not go out unauthenticated because the chain was empty: " +
|
|
1508
|
+
w.Report());
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
[Fact]
|
|
1512
|
+
public void ExchangeAuthNullSuppressesTheCredentialRefusalOrNot()
|
|
1513
|
+
{
|
|
1514
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", "REFRESH01");
|
|
1515
|
+
try
|
|
1516
|
+
{
|
|
1517
|
+
// `auth: null` is the documented way to send no credential at
|
|
1518
|
+
// all. A refusal of a deliberately unauthenticated request is
|
|
1519
|
+
// not an expired token: buying one and retrying would transmit
|
|
1520
|
+
// exactly the credential the caller suppressed.
|
|
1521
|
+
var w = new Wire { ApiStatus = new List<int> { 401 } };
|
|
1522
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1523
|
+
{
|
|
1524
|
+
["auth"] = null,
|
|
1525
|
+
["feature"] = ExchangeOpts(null),
|
|
1526
|
+
});
|
|
1527
|
+
|
|
1528
|
+
client.Direct(new Dictionary<string, object?> { ["path"] = "/thing" });
|
|
1529
|
+
|
|
1530
|
+
Assert.True(1 == w.Api().Count, "a suppressed request must not be retried");
|
|
1531
|
+
Assert.False(w.Api()[0].HasAuth,
|
|
1532
|
+
"no credential may be sent when auth is suppressed, got " +
|
|
1533
|
+
w.Api()[0].Auth);
|
|
1534
|
+
|
|
1535
|
+
// AND NO PURCHASE. Resolve() runs before WithRefresh's
|
|
1536
|
+
// suppression check, so the refresh token used to go to the
|
|
1537
|
+
// token endpoint in a request body even here. Stopping the
|
|
1538
|
+
// retry does not unsend it, and only the token endpoint can
|
|
1539
|
+
// see this.
|
|
1540
|
+
Assert.True(0 == w.Token().Count,
|
|
1541
|
+
"auth null suppressed the credential but the refresh token was " +
|
|
1542
|
+
"still POSTed to the exchange endpoint");
|
|
1543
|
+
}
|
|
1544
|
+
finally
|
|
1545
|
+
{
|
|
1546
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", null);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
// Test mode buys nothing and needs no token endpoint: the test feature
|
|
1551
|
+
// replaces the transport so no request leaves the process, and an
|
|
1552
|
+
// exchange would be the one HTTP call it could not stop.
|
|
1553
|
+
[Fact]
|
|
1554
|
+
public void TestModeBuysNothingAndNeedsNoTokenEndpoint()
|
|
1555
|
+
{
|
|
1556
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", "REFRESH01");
|
|
1557
|
+
try
|
|
1558
|
+
{
|
|
1559
|
+
var w = new Wire();
|
|
1560
|
+
var client = WithSecrets(extend =>
|
|
1561
|
+
{
|
|
1562
|
+
var opts = new Dictionary<string, object?>
|
|
1563
|
+
{
|
|
1564
|
+
["base"] = SecretsBase,
|
|
1565
|
+
["system"] = new Dictionary<string, object?>
|
|
1566
|
+
{
|
|
1567
|
+
["fetch"] = (Func<string, Dictionary<string, object?>,
|
|
1568
|
+
Dictionary<string, object?>>)w.Fetch,
|
|
1569
|
+
},
|
|
1570
|
+
["feature"] = ExchangeOpts(null),
|
|
1571
|
+
};
|
|
1572
|
+
if (extend)
|
|
1573
|
+
{
|
|
1574
|
+
opts["extend"] = new List<object?> { new SecretsFeature() };
|
|
1575
|
+
}
|
|
1576
|
+
return ProjectNameSDK.TestSDK(null, opts);
|
|
1577
|
+
});
|
|
1578
|
+
|
|
1579
|
+
DriveEntityOpUntil(client, "resolved the fake token",
|
|
1580
|
+
() => "" != SecretsOf(client)!.Credential());
|
|
1581
|
+
|
|
1582
|
+
Assert.True(0 == w.Calls.Count,
|
|
1583
|
+
"test mode must not do IO, saw " + w.Calls.Count + " calls");
|
|
1584
|
+
// A deterministic placeholder, so offline suites need no
|
|
1585
|
+
// configuration.
|
|
1586
|
+
Assert.Equal("test-access_token", SecretsOf(client)!.Credential());
|
|
1587
|
+
}
|
|
1588
|
+
finally
|
|
1589
|
+
{
|
|
1590
|
+
Environment.SetEnvironmentVariable(EnvPrefix + "REFRESH_TOKEN", null);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
// THE EXCHANGE WITH NO system.fetch, end to end over a real socket.
|
|
1595
|
+
//
|
|
1596
|
+
// The ordinary case: MakeOptions leaves system.fetch unset, so the API
|
|
1597
|
+
// call takes the SDK's default HttpClient transport and the token
|
|
1598
|
+
// purchase takes SdkUtility.DefaultHttpFetch. The refresh token is full
|
|
1599
|
+
// of JSON-hostile characters, which proves the body is SERIALISED and
|
|
1600
|
+
// not concatenated - a token carrying a quote, a backslash or a newline
|
|
1601
|
+
// must arrive as that literal value.
|
|
1602
|
+
[Fact]
|
|
1603
|
+
public void ExchangeOverARealSocketWithNoSystemFetch()
|
|
1604
|
+
{
|
|
1605
|
+
const string tricky = "re\"fresh\\to\nken";
|
|
1606
|
+
|
|
1607
|
+
var listener = new HttpListener();
|
|
1608
|
+
var port = FreePort();
|
|
1609
|
+
var prefix = "http://127.0.0.1:" + port + "/";
|
|
1610
|
+
listener.Prefixes.Add(prefix);
|
|
1611
|
+
listener.Start();
|
|
1612
|
+
|
|
1613
|
+
var gotrefresh = "";
|
|
1614
|
+
var gotauth = "";
|
|
1615
|
+
var served = new ManualResetEventSlim(false);
|
|
1616
|
+
|
|
1617
|
+
// A THREAD, not Task.Run: a test method that blocks on a Task is
|
|
1618
|
+
// xUnit1031, and the listener loop is not async work anyway.
|
|
1619
|
+
var serving = new Thread(() =>
|
|
1620
|
+
{
|
|
1621
|
+
try
|
|
1622
|
+
{
|
|
1623
|
+
while (listener.IsListening)
|
|
1624
|
+
{
|
|
1625
|
+
var ctx = listener.GetContext();
|
|
1626
|
+
var body = new StreamReader(ctx.Request.InputStream, Encoding.UTF8)
|
|
1627
|
+
.ReadToEnd();
|
|
1628
|
+
|
|
1629
|
+
string payload;
|
|
1630
|
+
if (ctx.Request.Url!.AbsolutePath.EndsWith("/auth/token"))
|
|
1631
|
+
{
|
|
1632
|
+
var parsed = JsonSerializer.Deserialize<Dictionary<string, string>>(body);
|
|
1633
|
+
gotrefresh = parsed != null && parsed.TryGetValue("refresh_token", out var r)
|
|
1634
|
+
? r : "";
|
|
1635
|
+
payload = "{\"access_token\": \"RAWTOK01\"}";
|
|
1636
|
+
}
|
|
1637
|
+
else
|
|
1638
|
+
{
|
|
1639
|
+
gotauth = ctx.Request.Headers["authorization"] ?? "";
|
|
1640
|
+
payload = "{}";
|
|
1641
|
+
served.Set();
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
var bytes = Encoding.UTF8.GetBytes(payload);
|
|
1645
|
+
ctx.Response.ContentType = "application/json";
|
|
1646
|
+
ctx.Response.ContentLength64 = bytes.Length;
|
|
1647
|
+
ctx.Response.OutputStream.Write(bytes, 0, bytes.Length);
|
|
1648
|
+
ctx.Response.OutputStream.Close();
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
catch (Exception)
|
|
1652
|
+
{
|
|
1653
|
+
// Teardown closes the listener out from under GetContext.
|
|
1654
|
+
}
|
|
1655
|
+
})
|
|
1656
|
+
{ IsBackground = true };
|
|
1657
|
+
serving.Start();
|
|
1658
|
+
|
|
1659
|
+
try
|
|
1660
|
+
{
|
|
1661
|
+
// No system.fetch ANYWHERE.
|
|
1662
|
+
var client = WithSecrets(extend =>
|
|
1663
|
+
{
|
|
1664
|
+
var opts = new Dictionary<string, object?>
|
|
1665
|
+
{
|
|
1666
|
+
["base"] = "http://127.0.0.1:" + port + "/api",
|
|
1667
|
+
["allow"] = new Dictionary<string, object?>
|
|
1668
|
+
{
|
|
1669
|
+
["op"] = "create,update,load,list,remove,command,direct,graphql",
|
|
1670
|
+
},
|
|
1671
|
+
["feature"] = new Dictionary<string, object?>
|
|
1672
|
+
{
|
|
1673
|
+
["secrets"] = new Dictionary<string, object?>
|
|
1674
|
+
{
|
|
1675
|
+
["active"] = true,
|
|
1676
|
+
["name"] = "refresh_token",
|
|
1677
|
+
["exchange"] = new Dictionary<string, object?>
|
|
1678
|
+
{
|
|
1679
|
+
["active"] = true,
|
|
1680
|
+
["refresh"] = tricky,
|
|
1681
|
+
},
|
|
1682
|
+
},
|
|
1683
|
+
},
|
|
1684
|
+
};
|
|
1685
|
+
if (extend)
|
|
1686
|
+
{
|
|
1687
|
+
opts["extend"] = new List<object?> { new SecretsFeature() };
|
|
1688
|
+
}
|
|
1689
|
+
return new ProjectNameSDK(opts);
|
|
1690
|
+
});
|
|
1691
|
+
|
|
1692
|
+
var res = client.Direct(new Dictionary<string, object?> { ["path"] = "/thing" });
|
|
1693
|
+
|
|
1694
|
+
Assert.True(Equals(res["ok"], true),
|
|
1695
|
+
"the raw exchange call failed: " + res.GetValueOrDefault("err"));
|
|
1696
|
+
Assert.True(served.Wait(TimeSpan.FromSeconds(5)),
|
|
1697
|
+
"the API request never reached the socket");
|
|
1698
|
+
|
|
1699
|
+
Assert.Equal(tricky, gotrefresh);
|
|
1700
|
+
CredentialIs(gotauth, "RAWTOK01");
|
|
1701
|
+
}
|
|
1702
|
+
finally
|
|
1703
|
+
{
|
|
1704
|
+
listener.Stop();
|
|
1705
|
+
listener.Close();
|
|
1706
|
+
serving.Join(TimeSpan.FromSeconds(5));
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
private static int FreePort()
|
|
1711
|
+
{
|
|
1712
|
+
var probe = new System.Net.Sockets.TcpListener(IPAddress.Loopback, 0);
|
|
1713
|
+
probe.Start();
|
|
1714
|
+
var port = ((IPEndPoint)probe.LocalEndpoint).Port;
|
|
1715
|
+
probe.Stop();
|
|
1716
|
+
return port;
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
|
|
1720
|
+
// --- concurrency -------------------------------------------------------
|
|
1721
|
+
|
|
1722
|
+
// A provider failure closes the transport gate; a later retry that
|
|
1723
|
+
// SUCCEEDS reopens it and every waiting operation goes out with the
|
|
1724
|
+
// FRESH credential - never the stale pre-failure header, and never
|
|
1725
|
+
// nothing. This is also the lane that would expose an unlocked Sekreto
|
|
1726
|
+
// cache (a concurrently-mutated List<T> corrupts silently) or a mutated
|
|
1727
|
+
// shared options map.
|
|
1728
|
+
[Fact]
|
|
1729
|
+
public void TheGateRecoversUnderConcurrency()
|
|
1730
|
+
{
|
|
1731
|
+
var mode = "fail";
|
|
1732
|
+
var release = new ManualResetEventSlim(false);
|
|
1733
|
+
|
|
1734
|
+
var flaky = new ProbeProvider
|
|
1735
|
+
{
|
|
1736
|
+
Fn = _ =>
|
|
1737
|
+
{
|
|
1738
|
+
var m = Volatile.Read(ref mode);
|
|
1739
|
+
if ("fail" == m)
|
|
1740
|
+
{
|
|
1741
|
+
throw new SekretoError("vault unreachable");
|
|
1742
|
+
}
|
|
1743
|
+
if ("slow" == m)
|
|
1744
|
+
{
|
|
1745
|
+
release.Wait(TimeSpan.FromSeconds(5));
|
|
1746
|
+
}
|
|
1747
|
+
return "FRESH01";
|
|
1748
|
+
},
|
|
1749
|
+
};
|
|
1750
|
+
|
|
1751
|
+
var w = new Wire();
|
|
1752
|
+
var client = SecretsClient(w, new Dictionary<string, object?>
|
|
1753
|
+
{
|
|
1754
|
+
["feature"] = ProviderOpts(flaky,
|
|
1755
|
+
new Dictionary<string, object?> { ["cache"] = false }),
|
|
1756
|
+
});
|
|
1757
|
+
|
|
1758
|
+
// 1. The failure closes the gate: nothing reaches the wire.
|
|
1759
|
+
var res = client.Direct(new Dictionary<string, object?> { ["path"] = "/gated" });
|
|
1760
|
+
Assert.True(Equals(res["ok"], false), "a failed resolution must refuse the request");
|
|
1761
|
+
Assert.True(0 == w.Calls.Count,
|
|
1762
|
+
"a failed resolution must keep the wire silent, saw " + w.Report());
|
|
1763
|
+
|
|
1764
|
+
// 2. Recovery under concurrency: eight operations race the slow
|
|
1765
|
+
// retry; all of them must come out carrying the fresh credential.
|
|
1766
|
+
Volatile.Write(ref mode, "slow");
|
|
1767
|
+
|
|
1768
|
+
var opening = new Thread(() =>
|
|
1769
|
+
{
|
|
1770
|
+
Thread.Sleep(20);
|
|
1771
|
+
release.Set();
|
|
1772
|
+
})
|
|
1773
|
+
{ IsBackground = true };
|
|
1774
|
+
opening.Start();
|
|
1775
|
+
|
|
1776
|
+
Parallel.For(0, 8, i =>
|
|
1777
|
+
client.Direct(new Dictionary<string, object?> { ["path"] = "/c" + i }));
|
|
1778
|
+
|
|
1779
|
+
opening.Join(TimeSpan.FromSeconds(5));
|
|
1780
|
+
|
|
1781
|
+
Assert.True(0 < w.Api().Count, "recovery must let the operations out");
|
|
1782
|
+
foreach (var call in w.Api())
|
|
1783
|
+
{
|
|
1784
|
+
CredentialIs(call.Auth, "FRESH01");
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
}
|