@voxgig/sdkgen 4.9.0 → 4.10.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/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 +671 -0
- package/project/.sdk/model/target/clojure.aon +10 -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/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/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/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/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/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 +503 -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 +547 -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/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 +889 -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 +1702 -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 +824 -0
- package/project/.sdk/tm/elixir/test/feature/secrets/secrets_test.exs +1072 -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 +16 -0
- package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +123 -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 +766 -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 +986 -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 +431 -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 +946 -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 +659 -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 +1148 -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/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/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 +675 -0
- package/project/.sdk/tm/perl/lib/Voxgig/Struct.pm +1 -1
- package/project/.sdk/tm/perl/t/feature/secrets/secrets.t +957 -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 +670 -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 +1067 -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/utility/voxgig_struct/voxgig_struct.py +1 -1
- 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 +561 -0
- package/project/.sdk/tm/rb/test/feature/secrets/secrets_feature_test.rb +842 -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 +961 -0
- package/project/.sdk/tm/rust/tests/feature/secrets/main.rs +1509 -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 +556 -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 +971 -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/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/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/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/proxy/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/ratelimit/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/rbac/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/retry/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/streaming/.gitkeep +0 -0
- 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 → clojure/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/base → csharp/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/cache → elixir/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/clienttrack → java/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/cost → kotlin/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/debug → perl/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/idempotency → php/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/log → rb/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/metrics → rust/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/netsim → scala/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/paging → swift/src/feature/secrets}/.gitkeep +0 -0
|
@@ -0,0 +1,1509 @@
|
|
|
1
|
+
// Behavioural tests for the secrets feature (vendored @voxgig/sekreto).
|
|
2
|
+
//
|
|
3
|
+
// The contract under test: the `apikey` OPTION keeps its exact old meaning
|
|
4
|
+
// and always wins, because the feature places it FIRST in the provider
|
|
5
|
+
// chain (a `memory` store named `options`) - explicit-beats-lookup falls
|
|
6
|
+
// out of sekreto's first-hit rule rather than from special-case logic. With
|
|
7
|
+
// the feature inactive nothing changes at all. With it active and the
|
|
8
|
+
// option unset, the chain supplies the credential instead.
|
|
9
|
+
//
|
|
10
|
+
// EVERY CLIENT HERE IS LIVE, and the thing counted is `system.fetch` - the
|
|
11
|
+
// real transport the whole fetcher chain ends at. That is deliberate, and
|
|
12
|
+
// it is the mistake this file exists to avoid: under `test_sdk` the test
|
|
13
|
+
// feature REPLACES the transport with its own in-memory mock, so a counter
|
|
14
|
+
// hung off `system.fetch` is never reached, and "no request was sent" would
|
|
15
|
+
// hold for a healthy SDK carrying no secrets feature at all. An assertion
|
|
16
|
+
// that cannot fail pins no rule. So each fail-closed case proves its own
|
|
17
|
+
// counter FIRST, with the same construction and a WORKING provider: one
|
|
18
|
+
// request must reach `system.fetch` carrying the resolved credential. Only
|
|
19
|
+
// then does a zero from the broken provider mean REFUSED rather than
|
|
20
|
+
// UNWIRED. And the refusal is matched on the PROVIDER'S OWN message, so an
|
|
21
|
+
// unrelated failure cannot stand in for fail-closed.
|
|
22
|
+
//
|
|
23
|
+
// This file lives in the `feature/` container on purpose: `target add`
|
|
24
|
+
// trims it, along with the feature source and the vendored library, for a
|
|
25
|
+
// project whose model does not select `secrets`.
|
|
26
|
+
|
|
27
|
+
use std::cell::RefCell;
|
|
28
|
+
use std::rc::Rc;
|
|
29
|
+
|
|
30
|
+
use RUSTCRATE::core::context::CtxSpec;
|
|
31
|
+
use RUSTCRATE::core::helpers::{
|
|
32
|
+
call_vfn, get_str, getp, getpath, ja, jo, json_thunk, to_int, vfn,
|
|
33
|
+
};
|
|
34
|
+
use RUSTCRATE::core::spec::Spec;
|
|
35
|
+
use RUSTCRATE::{ProjectNameSDK, Value};
|
|
36
|
+
|
|
37
|
+
const BASE: &str = "http://secrets.test/api";
|
|
38
|
+
|
|
39
|
+
// ---- the counted transport ---------------------------------------------
|
|
40
|
+
|
|
41
|
+
/// One recorded request, SNAPSHOT at the moment it was handed to the
|
|
42
|
+
/// transport.
|
|
43
|
+
///
|
|
44
|
+
/// A snapshot, not the fetchdef itself, and that is load-bearing: the
|
|
45
|
+
/// fetchdef's `headers` map is an Rc the retry path rewrites IN PLACE, so
|
|
46
|
+
/// a recorder that kept the live map would report every earlier call as
|
|
47
|
+
/// carrying the LAST token - and "the retry carried a new credential"
|
|
48
|
+
/// would pass whether or not it did.
|
|
49
|
+
#[derive(Clone)]
|
|
50
|
+
struct Call {
|
|
51
|
+
url: String,
|
|
52
|
+
auth: Option<String>,
|
|
53
|
+
body: Option<String>,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/// A `system.fetch` that records every call it is handed, so "sent" is a
|
|
57
|
+
/// fact about the wire rather than about a mock somewhere up the chain.
|
|
58
|
+
#[derive(Clone)]
|
|
59
|
+
struct Wire {
|
|
60
|
+
calls: Rc<RefCell<Vec<Call>>>,
|
|
61
|
+
/// One status per API call, the last repeating - so a case can say
|
|
62
|
+
/// "401 then 200" without counting calls itself.
|
|
63
|
+
apistatus: Rc<Vec<i64>>,
|
|
64
|
+
/// The access tokens the token endpoint issues, in order.
|
|
65
|
+
tokens: Rc<Vec<String>>,
|
|
66
|
+
/// The token endpoint path, relative to base.
|
|
67
|
+
tokenpath: String,
|
|
68
|
+
/// The JSON field the token endpoint answers in.
|
|
69
|
+
tokenfield: String,
|
|
70
|
+
/// Statuses for the token endpoint itself (the last repeating).
|
|
71
|
+
tokenstatus: Rc<Vec<i64>>,
|
|
72
|
+
issued: Rc<RefCell<usize>>,
|
|
73
|
+
apicalls: Rc<RefCell<usize>>,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
impl Wire {
|
|
77
|
+
fn new() -> Wire {
|
|
78
|
+
Wire {
|
|
79
|
+
calls: Rc::new(RefCell::new(Vec::new())),
|
|
80
|
+
apistatus: Rc::new(vec![200]),
|
|
81
|
+
tokens: Rc::new(vec![
|
|
82
|
+
"ACCESS01".to_string(),
|
|
83
|
+
"ACCESS02".to_string(),
|
|
84
|
+
"ACCESS03".to_string(),
|
|
85
|
+
]),
|
|
86
|
+
tokenpath: "auth/token".to_string(),
|
|
87
|
+
tokenfield: "access_token".to_string(),
|
|
88
|
+
tokenstatus: Rc::new(vec![200]),
|
|
89
|
+
issued: Rc::new(RefCell::new(0)),
|
|
90
|
+
apicalls: Rc::new(RefCell::new(0)),
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
fn apistatus(mut self, statuses: &[i64]) -> Wire {
|
|
95
|
+
self.apistatus = Rc::new(statuses.to_vec());
|
|
96
|
+
self
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
fn tokenstatus(mut self, statuses: &[i64]) -> Wire {
|
|
100
|
+
self.tokenstatus = Rc::new(statuses.to_vec());
|
|
101
|
+
self
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
fn tokenpath(mut self, path: &str, field: &str) -> Wire {
|
|
105
|
+
self.tokenpath = path.to_string();
|
|
106
|
+
self.tokenfield = field.to_string();
|
|
107
|
+
self
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
fn istoken(&self, url: &str) -> bool {
|
|
111
|
+
url.ends_with(&format!("/{}", self.tokenpath))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/// The Value::Func that goes into `system.fetch`.
|
|
115
|
+
fn fetch(&self) -> Value {
|
|
116
|
+
let w = self.clone();
|
|
117
|
+
vfn(move |arg| {
|
|
118
|
+
let url = match getp(arg, "0") {
|
|
119
|
+
Value::Str(s) => s,
|
|
120
|
+
_ => String::new(),
|
|
121
|
+
};
|
|
122
|
+
let fetchdef = getp(arg, "1");
|
|
123
|
+
w.calls.borrow_mut().push(Call {
|
|
124
|
+
url: url.clone(),
|
|
125
|
+
auth: authof(&fetchdef),
|
|
126
|
+
body: get_str(&fetchdef, "body"),
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
if w.istoken(&url) {
|
|
130
|
+
let n = *w.issued.borrow();
|
|
131
|
+
*w.issued.borrow_mut() = n + 1;
|
|
132
|
+
let status = pick(&w.tokenstatus, n);
|
|
133
|
+
let body = if (200..300).contains(&status) {
|
|
134
|
+
jo(vec![(
|
|
135
|
+
w.tokenfield.as_str(),
|
|
136
|
+
Value::str(pickstr(&w.tokens, n)),
|
|
137
|
+
)])
|
|
138
|
+
} else {
|
|
139
|
+
jo(vec![("error", Value::str("nope"))])
|
|
140
|
+
};
|
|
141
|
+
return response(status, body);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
let n = *w.apicalls.borrow();
|
|
145
|
+
*w.apicalls.borrow_mut() = n + 1;
|
|
146
|
+
let status = pick(&w.apistatus, n);
|
|
147
|
+
response(status, jo(vec![("ok", Value::Bool(status < 400))]))
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
fn api(&self) -> Vec<Call> {
|
|
152
|
+
self.calls
|
|
153
|
+
.borrow()
|
|
154
|
+
.iter()
|
|
155
|
+
.filter(|c| !self.istoken(&c.url))
|
|
156
|
+
.cloned()
|
|
157
|
+
.collect()
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
fn token(&self) -> Vec<Call> {
|
|
161
|
+
self.calls
|
|
162
|
+
.borrow()
|
|
163
|
+
.iter()
|
|
164
|
+
.filter(|c| self.istoken(&c.url))
|
|
165
|
+
.cloned()
|
|
166
|
+
.collect()
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
fn sent(&self) -> usize {
|
|
170
|
+
self.calls.borrow().len()
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/// What went out, for a failure message that names the leak rather
|
|
174
|
+
/// than just its count.
|
|
175
|
+
fn trace(&self) -> String {
|
|
176
|
+
self.calls
|
|
177
|
+
.borrow()
|
|
178
|
+
.iter()
|
|
179
|
+
.map(|c| format!("{} auth={:?}", c.url, c.auth))
|
|
180
|
+
.collect::<Vec<String>>()
|
|
181
|
+
.join(", ")
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
fn pick(list: &Rc<Vec<i64>>, n: usize) -> i64 {
|
|
186
|
+
list[n.min(list.len() - 1)]
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
fn pickstr(list: &Rc<Vec<String>>, n: usize) -> String {
|
|
190
|
+
list[n.min(list.len() - 1)].clone()
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
fn response(status: i64, body: Value) -> Value {
|
|
194
|
+
jo(vec![
|
|
195
|
+
("status", Value::Num(status as f64)),
|
|
196
|
+
("headers", Value::empty_map()),
|
|
197
|
+
("json", json_thunk(body)),
|
|
198
|
+
])
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
fn authof(fetchdef: &Value) -> Option<String> {
|
|
202
|
+
match getpath(&["headers", "authorization"], fetchdef) {
|
|
203
|
+
Value::Str(s) => Some(s),
|
|
204
|
+
_ => None,
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// The Authorization header carries the SPEC's credential prefix, which a
|
|
209
|
+
// TEMPLATE cannot know: an OpenAPI `http`/`bearer` scheme gives
|
|
210
|
+
// `Bearer <token>`, an apiKey scheme the raw token. So assert on the
|
|
211
|
+
// CREDENTIAL and let the prefix be whatever this SDK's API declares -
|
|
212
|
+
// pinning the whole header value passes only for a prefix-less API, and
|
|
213
|
+
// this file ships to every project that selects the feature.
|
|
214
|
+
fn credential_is(header: Option<String>, token: &str) {
|
|
215
|
+
let got = header.unwrap_or_default();
|
|
216
|
+
assert!(
|
|
217
|
+
got == token || got.ends_with(&format!(" {}", token)),
|
|
218
|
+
"expected the Authorization header to carry {}, got: {:?}",
|
|
219
|
+
token,
|
|
220
|
+
got
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
fn call_auth(calls: &[Call], i: usize) -> Option<String> {
|
|
225
|
+
calls.get(i).and_then(|c| c.auth.clone())
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// ---- clients ------------------------------------------------------------
|
|
229
|
+
|
|
230
|
+
// `allow.op` is named explicitly: a project that narrows the default set
|
|
231
|
+
// would otherwise turn the raw-path cases into a false RED (the control leg
|
|
232
|
+
// refused before it reached the transport), and the rule under test lives
|
|
233
|
+
// at the transport, downstream of the allow gate either way.
|
|
234
|
+
//
|
|
235
|
+
// `base` is named explicitly too: a LIVE client whose model has a templated
|
|
236
|
+
// base URL panics on a missing server variable at construction, and this
|
|
237
|
+
// file ships to every project.
|
|
238
|
+
fn sdk(wire: &Wire, secrets: Vec<(&str, Value)>) -> Rc<ProjectNameSDK> {
|
|
239
|
+
let fopts = jo(vec![("active", Value::Bool(true))]);
|
|
240
|
+
for (k, v) in secrets {
|
|
241
|
+
RUSTCRATE::core::helpers::setp(&fopts, k, v);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
ProjectNameSDK::new(jo(vec![
|
|
245
|
+
("base", Value::str(BASE)),
|
|
246
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
247
|
+
("system", jo(vec![("fetch", wire.fetch())])),
|
|
248
|
+
("feature", jo(vec![("secrets", fopts)])),
|
|
249
|
+
]))
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
fn providers(list: Vec<Value>) -> (&'static str, Value) {
|
|
253
|
+
("providers", Value::list(list))
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/// A `memory` provider spec: the chain, with no process-wide state, so
|
|
257
|
+
/// tests running in parallel cannot see each other's credentials.
|
|
258
|
+
fn memory(key: &str, value: &str) -> Value {
|
|
259
|
+
jo(vec![
|
|
260
|
+
("kind", Value::str("memory")),
|
|
261
|
+
("values", jo(vec![(key, Value::str(value))])),
|
|
262
|
+
])
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/// A provider written as a plain callable - the Value-shaped half of the
|
|
266
|
+
/// custom-provider seam.
|
|
267
|
+
fn callable<F>(f: F) -> Value
|
|
268
|
+
where
|
|
269
|
+
F: Fn(&str) -> Value + 'static,
|
|
270
|
+
{
|
|
271
|
+
vfn(move |arg| match arg {
|
|
272
|
+
Value::Str(name) => f(name),
|
|
273
|
+
_ => Value::Noval,
|
|
274
|
+
})
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
fn working() -> Value {
|
|
278
|
+
callable(|name| {
|
|
279
|
+
if "apikey" == name {
|
|
280
|
+
Value::str("RAWKEY01")
|
|
281
|
+
} else {
|
|
282
|
+
Value::Noval
|
|
283
|
+
}
|
|
284
|
+
})
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const BROKEN_MSG: &str = "vault unreachable";
|
|
288
|
+
|
|
289
|
+
fn broken() -> Value {
|
|
290
|
+
callable(|_name| jo(vec![("__err__", Value::str(BROKEN_MSG))]))
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/// The feature's public accessor, published on the client's shared map.
|
|
294
|
+
fn secrets_call(client: &Rc<ProjectNameSDK>, args: Vec<Value>) -> Value {
|
|
295
|
+
let shared = client.get_root_ctx().shared.borrow().clone();
|
|
296
|
+
let f = getp(&shared, "secrets");
|
|
297
|
+
assert!(
|
|
298
|
+
matches!(f, Value::Func(_)),
|
|
299
|
+
"the secrets accessor is not published: the feature never initialised"
|
|
300
|
+
);
|
|
301
|
+
call_vfn(&f, &Value::list(args))
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// ---- the ENTITY path ----------------------------------------------------
|
|
305
|
+
|
|
306
|
+
/// One request through the REAL entity-request utility, on the client's own
|
|
307
|
+
/// utility - the one the feature wrapped.
|
|
308
|
+
///
|
|
309
|
+
/// `direct()` and `graphql()` are the raw paths and are exercised as
|
|
310
|
+
/// themselves below; this is the OTHER half, and it cannot be reached by
|
|
311
|
+
/// naming an entity because this file is a TEMPLATE and no project's entity
|
|
312
|
+
/// names are known here. `make_request` is the utility every generated
|
|
313
|
+
/// entity op ends at, so driving it directly exercises the same seam with
|
|
314
|
+
/// the same wiring.
|
|
315
|
+
fn entity_request(client: &Rc<ProjectNameSDK>, path: &str) -> Option<String> {
|
|
316
|
+
let rootctx = client.get_root_ctx();
|
|
317
|
+
let utility = rootctx.util();
|
|
318
|
+
|
|
319
|
+
let ctx = utility.make_context(
|
|
320
|
+
CtxSpec {
|
|
321
|
+
opname: Some("list".to_string()),
|
|
322
|
+
..Default::default()
|
|
323
|
+
},
|
|
324
|
+
Some(&rootctx),
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
let spec = Rc::new(RefCell::new(Spec::new(&jo(vec![
|
|
328
|
+
("base", Value::str(BASE)),
|
|
329
|
+
("path", Value::str(path)),
|
|
330
|
+
("method", Value::str("GET")),
|
|
331
|
+
("headers", Value::empty_map()),
|
|
332
|
+
("step", Value::str("start")),
|
|
333
|
+
]))));
|
|
334
|
+
*ctx.spec.borrow_mut() = Some(spec);
|
|
335
|
+
|
|
336
|
+
utility.feature_hook(&ctx, "PreSpec");
|
|
337
|
+
utility.prepare_auth(&ctx).expect("prepare_auth");
|
|
338
|
+
|
|
339
|
+
match utility.make_request(&ctx) {
|
|
340
|
+
Ok(response) => response.borrow().err.as_ref().map(|e| e.msg.clone()),
|
|
341
|
+
Err(err) => Some(err.msg),
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// ---- the chain ----------------------------------------------------------
|
|
346
|
+
|
|
347
|
+
#[test]
|
|
348
|
+
fn inactive_leaves_the_apikey_option_exactly_as_it_was() {
|
|
349
|
+
let wire = Wire::new();
|
|
350
|
+
|
|
351
|
+
// Not `sdk()`: the point is a client with the feature OFF.
|
|
352
|
+
let client = ProjectNameSDK::new(jo(vec![
|
|
353
|
+
("base", Value::str(BASE)),
|
|
354
|
+
("apikey", Value::str("OPTKEY01")),
|
|
355
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
356
|
+
("system", jo(vec![("fetch", wire.fetch())])),
|
|
357
|
+
(
|
|
358
|
+
"feature",
|
|
359
|
+
jo(vec![(
|
|
360
|
+
"secrets",
|
|
361
|
+
jo(vec![
|
|
362
|
+
("active", Value::Bool(false)),
|
|
363
|
+
providers(vec![memory("APIKEY", "CHAINKEY01")]),
|
|
364
|
+
]),
|
|
365
|
+
)]),
|
|
366
|
+
),
|
|
367
|
+
]));
|
|
368
|
+
|
|
369
|
+
client
|
|
370
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
371
|
+
.expect("direct");
|
|
372
|
+
|
|
373
|
+
assert_eq!(wire.sent(), 1);
|
|
374
|
+
credential_is(call_auth(&wire.api(), 0), "OPTKEY01");
|
|
375
|
+
|
|
376
|
+
// No feature, no accessor.
|
|
377
|
+
let shared = client.get_root_ctx().shared.borrow().clone();
|
|
378
|
+
assert!(
|
|
379
|
+
!matches!(getp(&shared, "secrets"), Value::Func(_)),
|
|
380
|
+
"an inactive feature must publish nothing"
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
#[test]
|
|
385
|
+
fn apikey_option_still_wins_over_the_chain() {
|
|
386
|
+
let wire = Wire::new();
|
|
387
|
+
|
|
388
|
+
// The explicit credential is a CLIENT option, not a feature option -
|
|
389
|
+
// that is the whole point: `apikey` keeps its old meaning and the
|
|
390
|
+
// feature seats it first in the chain.
|
|
391
|
+
let client = ProjectNameSDK::new(jo(vec![
|
|
392
|
+
("base", Value::str(BASE)),
|
|
393
|
+
("apikey", Value::str("OPTKEY01")),
|
|
394
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
395
|
+
("system", jo(vec![("fetch", wire.fetch())])),
|
|
396
|
+
(
|
|
397
|
+
"feature",
|
|
398
|
+
jo(vec![(
|
|
399
|
+
"secrets",
|
|
400
|
+
jo(vec![
|
|
401
|
+
("active", Value::Bool(true)),
|
|
402
|
+
providers(vec![memory("APIKEY", "CHAINKEY01")]),
|
|
403
|
+
]),
|
|
404
|
+
)]),
|
|
405
|
+
),
|
|
406
|
+
]));
|
|
407
|
+
|
|
408
|
+
client
|
|
409
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
410
|
+
.expect("direct");
|
|
411
|
+
|
|
412
|
+
credential_is(call_auth(&wire.api(), 0), "OPTKEY01");
|
|
413
|
+
|
|
414
|
+
// The explicit option is a real store, not a special case: a directed
|
|
415
|
+
// read names it like any other.
|
|
416
|
+
let got = secrets_call(
|
|
417
|
+
&client,
|
|
418
|
+
vec![
|
|
419
|
+
Value::str("getfrom"),
|
|
420
|
+
Value::str("options"),
|
|
421
|
+
Value::str("apikey"),
|
|
422
|
+
],
|
|
423
|
+
);
|
|
424
|
+
assert_eq!(
|
|
425
|
+
got,
|
|
426
|
+
Value::str("OPTKEY01"),
|
|
427
|
+
"the explicit apikey is not seated as the `options` memory store"
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
#[test]
|
|
432
|
+
fn an_omitted_apikey_defers_to_the_chain() {
|
|
433
|
+
let wire = Wire::new();
|
|
434
|
+
let client = sdk(&wire, vec![providers(vec![memory("APIKEY", "CHAINKEY01")])]);
|
|
435
|
+
|
|
436
|
+
client
|
|
437
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
438
|
+
.expect("direct");
|
|
439
|
+
|
|
440
|
+
credential_is(call_auth(&wire.api(), 0), "CHAINKEY01");
|
|
441
|
+
|
|
442
|
+
// The options map is FROZEN: the credential lives in feature state, and
|
|
443
|
+
// a feature that wrote the shared options would be visible everywhere.
|
|
444
|
+
assert_eq!(
|
|
445
|
+
getp(&client.options_map(), "apikey"),
|
|
446
|
+
Value::str(""),
|
|
447
|
+
"the feature must not write the shared options map"
|
|
448
|
+
);
|
|
449
|
+
assert_eq!(
|
|
450
|
+
secrets_call(&client, vec![Value::str("credential")]),
|
|
451
|
+
Value::str("CHAINKEY01")
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
#[test]
|
|
456
|
+
fn an_explicitly_empty_apikey_also_defers_to_the_chain() {
|
|
457
|
+
let wire = Wire::new();
|
|
458
|
+
let client = ProjectNameSDK::new(jo(vec![
|
|
459
|
+
("base", Value::str(BASE)),
|
|
460
|
+
("apikey", Value::str("")),
|
|
461
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
462
|
+
("system", jo(vec![("fetch", wire.fetch())])),
|
|
463
|
+
(
|
|
464
|
+
"feature",
|
|
465
|
+
jo(vec![(
|
|
466
|
+
"secrets",
|
|
467
|
+
jo(vec![
|
|
468
|
+
("active", Value::Bool(true)),
|
|
469
|
+
providers(vec![memory("APIKEY", "CHAINKEY01")]),
|
|
470
|
+
]),
|
|
471
|
+
)]),
|
|
472
|
+
),
|
|
473
|
+
]));
|
|
474
|
+
|
|
475
|
+
client
|
|
476
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
477
|
+
.expect("direct");
|
|
478
|
+
|
|
479
|
+
credential_is(call_auth(&wire.api(), 0), "CHAINKEY01");
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// `auth: null` - the documented way to disable auth outright, which
|
|
483
|
+
// prepare_auth honours before it ever reads the apikey, and which the
|
|
484
|
+
// transport injection must honour too.
|
|
485
|
+
#[test]
|
|
486
|
+
fn auth_null_suppresses_the_credential_chain_or_no_chain() {
|
|
487
|
+
let wire = Wire::new();
|
|
488
|
+
let client = ProjectNameSDK::new(jo(vec![
|
|
489
|
+
("base", Value::str(BASE)),
|
|
490
|
+
("auth", Value::Null),
|
|
491
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
492
|
+
("system", jo(vec![("fetch", wire.fetch())])),
|
|
493
|
+
(
|
|
494
|
+
"feature",
|
|
495
|
+
jo(vec![(
|
|
496
|
+
"secrets",
|
|
497
|
+
jo(vec![
|
|
498
|
+
("active", Value::Bool(true)),
|
|
499
|
+
providers(vec![memory("APIKEY", "CHAINKEY01")]),
|
|
500
|
+
]),
|
|
501
|
+
)]),
|
|
502
|
+
),
|
|
503
|
+
]));
|
|
504
|
+
|
|
505
|
+
client
|
|
506
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
507
|
+
.expect("direct");
|
|
508
|
+
|
|
509
|
+
assert_eq!(wire.sent(), 1, "the request must still go out");
|
|
510
|
+
assert_eq!(
|
|
511
|
+
call_auth(&wire.api(), 0),
|
|
512
|
+
None,
|
|
513
|
+
"nothing may be sent when auth is suppressed, but the wire carried: {}",
|
|
514
|
+
wire.trace()
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
// The suppression survives option validation rather than being replaced
|
|
518
|
+
// by the optspec's default auth map.
|
|
519
|
+
//
|
|
520
|
+
// Read from the RAW map: `getp` applies the Group A rule and answers
|
|
521
|
+
// the alt for a stored null, so it cannot tell an absent auth from a
|
|
522
|
+
// suppressed one - and only the latter is a suppression.
|
|
523
|
+
let opts = client.options_map();
|
|
524
|
+
let suppressed = match &opts {
|
|
525
|
+
Value::Map(m) => matches!(m.borrow().get("auth"), Some(Value::Null)),
|
|
526
|
+
_ => false,
|
|
527
|
+
};
|
|
528
|
+
assert!(suppressed, "auth: null did not survive make_options");
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
#[test]
|
|
532
|
+
fn auth_null_suppresses_an_explicit_apikey_too() {
|
|
533
|
+
let wire = Wire::new();
|
|
534
|
+
let client = ProjectNameSDK::new(jo(vec![
|
|
535
|
+
("base", Value::str(BASE)),
|
|
536
|
+
("apikey", Value::str("OPTKEY01")),
|
|
537
|
+
("auth", Value::Null),
|
|
538
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
539
|
+
("system", jo(vec![("fetch", wire.fetch())])),
|
|
540
|
+
(
|
|
541
|
+
"feature",
|
|
542
|
+
jo(vec![(
|
|
543
|
+
"secrets",
|
|
544
|
+
jo(vec![
|
|
545
|
+
("active", Value::Bool(true)),
|
|
546
|
+
providers(vec![memory("APIKEY", "CHAINKEY01")]),
|
|
547
|
+
]),
|
|
548
|
+
)]),
|
|
549
|
+
),
|
|
550
|
+
]));
|
|
551
|
+
|
|
552
|
+
client
|
|
553
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
554
|
+
.expect("direct");
|
|
555
|
+
|
|
556
|
+
assert_eq!(call_auth(&wire.api(), 0), None, "wire: {}", wire.trace());
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
#[test]
|
|
560
|
+
fn a_miss_everywhere_leaves_the_header_off() {
|
|
561
|
+
let wire = Wire::new();
|
|
562
|
+
let client = sdk(
|
|
563
|
+
&wire,
|
|
564
|
+
vec![providers(vec![callable(|_name| Value::Noval)])],
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
client
|
|
568
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
569
|
+
.expect("direct");
|
|
570
|
+
|
|
571
|
+
// A MISS falls through: the request still goes out, unauthenticated.
|
|
572
|
+
assert_eq!(wire.sent(), 1, "a miss must not refuse the request");
|
|
573
|
+
assert_eq!(call_auth(&wire.api(), 0), None);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// A MISS is not an ERROR: the chain CONTINUES past a provider that simply
|
|
577
|
+
// does not have the secret. The other half of sekreto's invariant, and the
|
|
578
|
+
// half that must not be "fixed" by making every miss fail.
|
|
579
|
+
#[test]
|
|
580
|
+
fn a_miss_falls_through_to_the_next_provider() {
|
|
581
|
+
let wire = Wire::new();
|
|
582
|
+
let asked: Rc<RefCell<i64>> = Rc::new(RefCell::new(0));
|
|
583
|
+
let n = asked.clone();
|
|
584
|
+
|
|
585
|
+
let client = sdk(
|
|
586
|
+
&wire,
|
|
587
|
+
vec![providers(vec![
|
|
588
|
+
callable(move |_name| {
|
|
589
|
+
*n.borrow_mut() += 1;
|
|
590
|
+
Value::Noval
|
|
591
|
+
}),
|
|
592
|
+
memory("APIKEY", "SECOND01"),
|
|
593
|
+
])],
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
client
|
|
597
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
598
|
+
.expect("direct");
|
|
599
|
+
|
|
600
|
+
assert_eq!(*asked.borrow(), 1, "the first provider was never asked");
|
|
601
|
+
credential_is(call_auth(&wire.api(), 0), "SECOND01");
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
#[test]
|
|
606
|
+
fn a_callable_provider_is_accepted_verbatim() {
|
|
607
|
+
let wire = Wire::new();
|
|
608
|
+
let asked: Rc<RefCell<Vec<String>>> = Rc::new(RefCell::new(Vec::new()));
|
|
609
|
+
let seen = asked.clone();
|
|
610
|
+
|
|
611
|
+
let client = sdk(
|
|
612
|
+
&wire,
|
|
613
|
+
vec![providers(vec![callable(move |name| {
|
|
614
|
+
seen.borrow_mut().push(name.to_string());
|
|
615
|
+
Value::str("CUSTOM01")
|
|
616
|
+
})])],
|
|
617
|
+
);
|
|
618
|
+
|
|
619
|
+
client
|
|
620
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
621
|
+
.expect("direct");
|
|
622
|
+
|
|
623
|
+
credential_is(call_auth(&wire.api(), 0), "CUSTOM01");
|
|
624
|
+
assert_eq!(asked.borrow().clone(), vec!["apikey".to_string()]);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// ---- FAIL-CLOSED: a provider ERROR is not a miss -------------------------
|
|
628
|
+
//
|
|
629
|
+
// sekreto's miss-vs-error invariant: a MISS falls through to the next
|
|
630
|
+
// provider, an ERROR does not. A broken vault must never degrade into an
|
|
631
|
+
// unauthenticated request.
|
|
632
|
+
|
|
633
|
+
#[test]
|
|
634
|
+
fn a_provider_error_fails_direct_rather_than_sending() {
|
|
635
|
+
// THE RULE, asserted first so a regression reports the leak itself.
|
|
636
|
+
let wire = Wire::new();
|
|
637
|
+
let res = sdk(&wire, vec![providers(vec![broken()])])
|
|
638
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
639
|
+
.expect("direct itself should not error");
|
|
640
|
+
|
|
641
|
+
assert_eq!(
|
|
642
|
+
wire.sent(),
|
|
643
|
+
0,
|
|
644
|
+
"a request must not go out unauthenticated because a provider broke, \
|
|
645
|
+
but one reached system.fetch: {}",
|
|
646
|
+
wire.trace()
|
|
647
|
+
);
|
|
648
|
+
assert_eq!(getp(&res, "ok"), Value::Bool(false));
|
|
649
|
+
let err = get_str(&res, "err").unwrap_or_default();
|
|
650
|
+
assert!(
|
|
651
|
+
err.contains(BROKEN_MSG),
|
|
652
|
+
"expected the provider's own message, got: {}",
|
|
653
|
+
err
|
|
654
|
+
);
|
|
655
|
+
|
|
656
|
+
// CONTROL, which makes that zero mean REFUSED rather than UNWIRED: the
|
|
657
|
+
// same construction with a WORKING provider must reach the same
|
|
658
|
+
// transport, once, carrying the credential.
|
|
659
|
+
let control = Wire::new();
|
|
660
|
+
let ok = sdk(&control, vec![providers(vec![working()])])
|
|
661
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
662
|
+
.expect("direct");
|
|
663
|
+
|
|
664
|
+
assert_eq!(
|
|
665
|
+
getp(&ok, "ok"),
|
|
666
|
+
Value::Bool(true),
|
|
667
|
+
"the control request failed: {:?}",
|
|
668
|
+
get_str(&ok, "err")
|
|
669
|
+
);
|
|
670
|
+
assert_eq!(
|
|
671
|
+
control.sent(),
|
|
672
|
+
1,
|
|
673
|
+
"the control request never reached system.fetch, so this test cannot \
|
|
674
|
+
observe a request going out at all"
|
|
675
|
+
);
|
|
676
|
+
credential_is(call_auth(&control.api(), 0), "RAWKEY01");
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
#[test]
|
|
680
|
+
fn a_provider_error_fails_graphql_rather_than_sending() {
|
|
681
|
+
let wire = Wire::new();
|
|
682
|
+
let res = sdk(&wire, vec![providers(vec![broken()])])
|
|
683
|
+
.graphql("{ thing }", Value::empty_map(), Value::empty_map())
|
|
684
|
+
.expect("graphql itself should not error");
|
|
685
|
+
|
|
686
|
+
assert_eq!(
|
|
687
|
+
wire.sent(),
|
|
688
|
+
0,
|
|
689
|
+
"a graphql request must not go out unauthenticated, but one reached \
|
|
690
|
+
system.fetch: {}",
|
|
691
|
+
wire.trace()
|
|
692
|
+
);
|
|
693
|
+
assert_eq!(getp(&res, "ok"), Value::Bool(false));
|
|
694
|
+
let err = get_str(&res, "err").unwrap_or_default();
|
|
695
|
+
assert!(
|
|
696
|
+
err.contains(BROKEN_MSG),
|
|
697
|
+
"expected the provider's own message, got: {}",
|
|
698
|
+
err
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
let control = Wire::new();
|
|
702
|
+
let ok = sdk(&control, vec![providers(vec![working()])])
|
|
703
|
+
.graphql("{ thing }", Value::empty_map(), Value::empty_map())
|
|
704
|
+
.expect("graphql");
|
|
705
|
+
|
|
706
|
+
assert_eq!(
|
|
707
|
+
getp(&ok, "ok"),
|
|
708
|
+
Value::Bool(true),
|
|
709
|
+
"the control request failed: {:?}",
|
|
710
|
+
get_str(&ok, "err")
|
|
711
|
+
);
|
|
712
|
+
assert_eq!(
|
|
713
|
+
control.sent(),
|
|
714
|
+
1,
|
|
715
|
+
"the control request never reached system.fetch, so this test cannot \
|
|
716
|
+
observe a request going out at all"
|
|
717
|
+
);
|
|
718
|
+
credential_is(call_auth(&control.api(), 0), "RAWKEY01");
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
#[test]
|
|
722
|
+
fn a_provider_error_fails_the_entity_path_rather_than_sending() {
|
|
723
|
+
let wire = Wire::new();
|
|
724
|
+
let err = entity_request(&sdk(&wire, vec![providers(vec![broken()])]), "/thing");
|
|
725
|
+
|
|
726
|
+
assert_eq!(
|
|
727
|
+
wire.sent(),
|
|
728
|
+
0,
|
|
729
|
+
"an entity request must not go out unauthenticated, but one reached \
|
|
730
|
+
system.fetch: {}",
|
|
731
|
+
wire.trace()
|
|
732
|
+
);
|
|
733
|
+
let err = err.unwrap_or_default();
|
|
734
|
+
assert!(
|
|
735
|
+
err.contains(BROKEN_MSG),
|
|
736
|
+
"expected the provider's own message, got: {}",
|
|
737
|
+
err
|
|
738
|
+
);
|
|
739
|
+
|
|
740
|
+
let control = Wire::new();
|
|
741
|
+
let ok = entity_request(&sdk(&control, vec![providers(vec![working()])]), "/thing");
|
|
742
|
+
|
|
743
|
+
assert_eq!(ok, None, "the control request failed: {:?}", ok);
|
|
744
|
+
assert_eq!(
|
|
745
|
+
control.sent(),
|
|
746
|
+
1,
|
|
747
|
+
"the control request never reached system.fetch, so this test cannot \
|
|
748
|
+
observe a request going out at all"
|
|
749
|
+
);
|
|
750
|
+
credential_is(call_auth(&control.api(), 0), "RAWKEY01");
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// A CHAIN that cannot be BUILT is the same rule one step earlier: an
|
|
754
|
+
// unknown provider kind (a typo in a project's model) must refuse the
|
|
755
|
+
// request rather than send it without a credential.
|
|
756
|
+
#[test]
|
|
757
|
+
fn an_unknown_provider_kind_refuses_rather_than_sending() {
|
|
758
|
+
let wire = Wire::new();
|
|
759
|
+
let res = sdk(
|
|
760
|
+
&wire,
|
|
761
|
+
vec![providers(vec![jo(vec![(
|
|
762
|
+
"kind",
|
|
763
|
+
Value::str("nosuchkind"),
|
|
764
|
+
)])])],
|
|
765
|
+
)
|
|
766
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
767
|
+
.expect("direct");
|
|
768
|
+
|
|
769
|
+
assert_eq!(
|
|
770
|
+
wire.sent(),
|
|
771
|
+
0,
|
|
772
|
+
"a chain that could not be built must not send: {}",
|
|
773
|
+
wire.trace()
|
|
774
|
+
);
|
|
775
|
+
assert_eq!(getp(&res, "ok"), Value::Bool(false));
|
|
776
|
+
let err = get_str(&res, "err").unwrap_or_default();
|
|
777
|
+
assert!(
|
|
778
|
+
err.contains("unknown provider kind"),
|
|
779
|
+
"expected sekreto's own refusal, got: {}",
|
|
780
|
+
err
|
|
781
|
+
);
|
|
782
|
+
|
|
783
|
+
let control = Wire::new();
|
|
784
|
+
sdk(&control, vec![providers(vec![working()])])
|
|
785
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
786
|
+
.expect("direct");
|
|
787
|
+
assert_eq!(control.sent(), 1, "the control request never reached the wire");
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// A MALFORMED entry is the same rule again, and the one a typed port can
|
|
791
|
+
// get wrong silently: `providers` is a Value list, so an entry that is
|
|
792
|
+
// neither a callable nor a spec map (a bare "hashicorp" where a spec was
|
|
793
|
+
// meant) matches no arm. Dropping it leaves the chain quietly SHORTER than
|
|
794
|
+
// the options say - a fail-OPEN that sends the request without the
|
|
795
|
+
// credential the project configured. It must refuse instead, carrying
|
|
796
|
+
// sekreto's own wording, on every wire path.
|
|
797
|
+
const MALFORMED_MSG: &str = "sekreto: not a provider or a provider spec";
|
|
798
|
+
|
|
799
|
+
#[test]
|
|
800
|
+
fn a_malformed_provider_entry_refuses_rather_than_being_dropped() {
|
|
801
|
+
// CONTROL first: the same construction with a WORKING provider reaches
|
|
802
|
+
// the transport exactly once, carrying its credential. Without this a
|
|
803
|
+
// zero below could mean UNWIRED rather than REFUSED.
|
|
804
|
+
let control = Wire::new();
|
|
805
|
+
let ok = sdk(&control, vec![providers(vec![working()])])
|
|
806
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
807
|
+
.expect("direct");
|
|
808
|
+
assert_eq!(
|
|
809
|
+
getp(&ok, "ok"),
|
|
810
|
+
Value::Bool(true),
|
|
811
|
+
"the control request failed: {:?}",
|
|
812
|
+
get_str(&ok, "err")
|
|
813
|
+
);
|
|
814
|
+
assert_eq!(
|
|
815
|
+
control.sent(),
|
|
816
|
+
1,
|
|
817
|
+
"the control request never reached system.fetch, so this test cannot \
|
|
818
|
+
observe a request going out at all"
|
|
819
|
+
);
|
|
820
|
+
credential_is(call_auth(&control.api(), 0), "RAWKEY01");
|
|
821
|
+
|
|
822
|
+
let malformed = || providers(vec![Value::str("hashicorp")]);
|
|
823
|
+
let refused = |what: &str, err: String, wire: &Wire| {
|
|
824
|
+
assert_eq!(
|
|
825
|
+
wire.sent(),
|
|
826
|
+
0,
|
|
827
|
+
"{}: a malformed provider entry must refuse, not be dropped, but a \
|
|
828
|
+
request reached system.fetch: {}",
|
|
829
|
+
what,
|
|
830
|
+
wire.trace()
|
|
831
|
+
);
|
|
832
|
+
assert!(
|
|
833
|
+
err.contains(MALFORMED_MSG) && err.contains("hashicorp"),
|
|
834
|
+
"{}: expected sekreto's own refusal naming the entry, got: {}",
|
|
835
|
+
what,
|
|
836
|
+
err
|
|
837
|
+
);
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
// The raw paths. This port runs no feature hooks on direct()/graphql()
|
|
841
|
+
// (Main.fragment.rs raw_request calls utility.fetch directly), so the
|
|
842
|
+
// refusal is the TRANSPORT gate's, the same seam the tests above use.
|
|
843
|
+
let wire = Wire::new();
|
|
844
|
+
let res = sdk(&wire, vec![malformed()])
|
|
845
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
846
|
+
.expect("direct itself should not error");
|
|
847
|
+
refused("direct", get_str(&res, "err").unwrap_or_default(), &wire);
|
|
848
|
+
assert_eq!(getp(&res, "ok"), Value::Bool(false));
|
|
849
|
+
|
|
850
|
+
let wire = Wire::new();
|
|
851
|
+
let res = sdk(&wire, vec![malformed()])
|
|
852
|
+
.graphql("{ thing }", Value::empty_map(), Value::empty_map())
|
|
853
|
+
.expect("graphql itself should not error");
|
|
854
|
+
refused("graphql", get_str(&res, "err").unwrap_or_default(), &wire);
|
|
855
|
+
assert_eq!(getp(&res, "ok"), Value::Bool(false));
|
|
856
|
+
|
|
857
|
+
// The entity path.
|
|
858
|
+
let wire = Wire::new();
|
|
859
|
+
let err = entity_request(&sdk(&wire, vec![malformed()]), "/thing");
|
|
860
|
+
refused("entity", err.unwrap_or_default(), &wire);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
// The provider VOCABULARY. The generated plugins.rs index IS the set of
|
|
864
|
+
// kinds this SDK can build (upstream sekreto's contract since its registry
|
|
865
|
+
// was retired), so every definition it declares must carry a usable name -
|
|
866
|
+
// an empty or duplicated one is a kind nothing can name.
|
|
867
|
+
#[test]
|
|
868
|
+
fn the_selected_plugin_kinds_have_distinct_names() {
|
|
869
|
+
let defs = RUSTCRATE::feature::secrets::plugins::definitions();
|
|
870
|
+
let mut names: Vec<String> = defs.iter().map(|d| d.name.clone()).collect();
|
|
871
|
+
let count = names.len();
|
|
872
|
+
names.sort();
|
|
873
|
+
names.dedup();
|
|
874
|
+
|
|
875
|
+
assert_eq!(names.len(), count, "duplicate plugin kind: {:?}", names);
|
|
876
|
+
assert!(
|
|
877
|
+
names.iter().all(|n| !n.is_empty()),
|
|
878
|
+
"a plugin definition with no name is a kind nothing can select"
|
|
879
|
+
);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
// A SELECTED plugin kind is really in the vocabulary.
|
|
883
|
+
//
|
|
884
|
+
// Construction is where an unknown kind is refused, so a chain that names
|
|
885
|
+
// the kind and still reaches the wire IS the check. The memory store comes
|
|
886
|
+
// FIRST so sekreto's first-hit rule answers from it and the vault is never
|
|
887
|
+
// contacted - the kind has to be declarable, not reachable.
|
|
888
|
+
//
|
|
889
|
+
// Conditional on the kind being selected, because this file ships to
|
|
890
|
+
// projects that take the feature without the `vault` plugin group.
|
|
891
|
+
#[test]
|
|
892
|
+
fn a_selected_plugin_kind_is_in_the_sdk_vocabulary() {
|
|
893
|
+
let defs = RUSTCRATE::feature::secrets::plugins::definitions();
|
|
894
|
+
if !defs.iter().any(|d| "hashicorp" == d.name) {
|
|
895
|
+
// No vault group in this project's model: nothing to assert.
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
let wire = Wire::new();
|
|
900
|
+
let client = sdk(
|
|
901
|
+
&wire,
|
|
902
|
+
vec![providers(vec![
|
|
903
|
+
memory("APIKEY", "VOCAB01"),
|
|
904
|
+
jo(vec![
|
|
905
|
+
("kind", Value::str("hashicorp")),
|
|
906
|
+
("addr", Value::str("https://vault.test")),
|
|
907
|
+
("token", Value::str("x")),
|
|
908
|
+
]),
|
|
909
|
+
])],
|
|
910
|
+
);
|
|
911
|
+
|
|
912
|
+
client
|
|
913
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
914
|
+
.expect("direct");
|
|
915
|
+
|
|
916
|
+
assert_eq!(wire.api().len(), 1, "the chain was refused: {}", wire.trace());
|
|
917
|
+
credential_is(call_auth(&wire.api(), 0), "VOCAB01");
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
// A settled failure must not be held forever: a transient vault outage
|
|
922
|
+
// would otherwise poison the client permanently, every later operation
|
|
923
|
+
// failing with the original error long after the vault recovered.
|
|
924
|
+
#[test]
|
|
925
|
+
fn a_provider_recovers_after_a_transient_failure() {
|
|
926
|
+
let wire = Wire::new();
|
|
927
|
+
let calls = Rc::new(RefCell::new(0i64));
|
|
928
|
+
let n = calls.clone();
|
|
929
|
+
|
|
930
|
+
let client = sdk(
|
|
931
|
+
&wire,
|
|
932
|
+
vec![providers(vec![callable(move |_name| {
|
|
933
|
+
*n.borrow_mut() += 1;
|
|
934
|
+
if 1 == *n.borrow() {
|
|
935
|
+
jo(vec![("__err__", Value::str(BROKEN_MSG))])
|
|
936
|
+
} else {
|
|
937
|
+
Value::str("RECOVERED01")
|
|
938
|
+
}
|
|
939
|
+
})])],
|
|
940
|
+
);
|
|
941
|
+
|
|
942
|
+
let first = client
|
|
943
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
944
|
+
.expect("direct");
|
|
945
|
+
assert_eq!(getp(&first, "ok"), Value::Bool(false));
|
|
946
|
+
assert_eq!(wire.sent(), 0);
|
|
947
|
+
|
|
948
|
+
let second = client
|
|
949
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
950
|
+
.expect("direct");
|
|
951
|
+
assert_eq!(
|
|
952
|
+
getp(&second, "ok"),
|
|
953
|
+
Value::Bool(true),
|
|
954
|
+
"the second attempt should recover: {:?}",
|
|
955
|
+
get_str(&second, "err")
|
|
956
|
+
);
|
|
957
|
+
credential_is(call_auth(&wire.api(), 0), "RECOVERED01");
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
// `cache: false` is documented as "every resolve asks the chain again".
|
|
961
|
+
#[test]
|
|
962
|
+
fn cache_false_asks_the_chain_on_every_request() {
|
|
963
|
+
let wire = Wire::new();
|
|
964
|
+
let calls = Rc::new(RefCell::new(0i64));
|
|
965
|
+
let n = calls.clone();
|
|
966
|
+
|
|
967
|
+
let client = sdk(
|
|
968
|
+
&wire,
|
|
969
|
+
vec![
|
|
970
|
+
("cache", Value::Bool(false)),
|
|
971
|
+
providers(vec![callable(move |_name| {
|
|
972
|
+
*n.borrow_mut() += 1;
|
|
973
|
+
Value::str(format!("KEY{}", n.borrow()))
|
|
974
|
+
})]),
|
|
975
|
+
],
|
|
976
|
+
);
|
|
977
|
+
|
|
978
|
+
for _ in 0..2 {
|
|
979
|
+
client
|
|
980
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
981
|
+
.expect("direct");
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
assert!(
|
|
985
|
+
1 < *calls.borrow(),
|
|
986
|
+
"the chain was asked once and cached, despite cache: false"
|
|
987
|
+
);
|
|
988
|
+
credential_is(call_auth(&wire.api(), 0), "KEY1");
|
|
989
|
+
credential_is(call_auth(&wire.api(), 1), "KEY2");
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
// An UNCACHED miss after a hit is a revocation: the resolved value must
|
|
993
|
+
// stop going out.
|
|
994
|
+
#[test]
|
|
995
|
+
fn an_uncached_miss_retracts_the_credential() {
|
|
996
|
+
let wire = Wire::new();
|
|
997
|
+
let calls = Rc::new(RefCell::new(0i64));
|
|
998
|
+
let n = calls.clone();
|
|
999
|
+
|
|
1000
|
+
let client = sdk(
|
|
1001
|
+
&wire,
|
|
1002
|
+
vec![
|
|
1003
|
+
("cache", Value::Bool(false)),
|
|
1004
|
+
providers(vec![callable(move |_name| {
|
|
1005
|
+
*n.borrow_mut() += 1;
|
|
1006
|
+
if 1 == *n.borrow() {
|
|
1007
|
+
Value::str("ONCE01")
|
|
1008
|
+
} else {
|
|
1009
|
+
Value::Noval
|
|
1010
|
+
}
|
|
1011
|
+
})]),
|
|
1012
|
+
],
|
|
1013
|
+
);
|
|
1014
|
+
|
|
1015
|
+
for _ in 0..2 {
|
|
1016
|
+
client
|
|
1017
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1018
|
+
.expect("direct");
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
credential_is(call_auth(&wire.api(), 0), "ONCE01");
|
|
1022
|
+
assert_eq!(
|
|
1023
|
+
call_auth(&wire.api(), 1),
|
|
1024
|
+
None,
|
|
1025
|
+
"a revoked credential kept going out: {}",
|
|
1026
|
+
wire.trace()
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
#[test]
|
|
1031
|
+
fn the_secret_name_is_configurable() {
|
|
1032
|
+
let wire = Wire::new();
|
|
1033
|
+
let client = sdk(
|
|
1034
|
+
&wire,
|
|
1035
|
+
vec![
|
|
1036
|
+
("name", Value::str("api.token")),
|
|
1037
|
+
providers(vec![memory("API_TOKEN", "TOKKEY01")]),
|
|
1038
|
+
],
|
|
1039
|
+
);
|
|
1040
|
+
|
|
1041
|
+
client
|
|
1042
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1043
|
+
.expect("direct");
|
|
1044
|
+
|
|
1045
|
+
credential_is(call_auth(&wire.api(), 0), "TOKKEY01");
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
#[test]
|
|
1049
|
+
fn sekreto_is_live_for_arbitrary_secrets_and_redaction() {
|
|
1050
|
+
let wire = Wire::new();
|
|
1051
|
+
let client = sdk(
|
|
1052
|
+
&wire,
|
|
1053
|
+
vec![providers(vec![memory("DB_PASSWORD", "dbpass01")])],
|
|
1054
|
+
);
|
|
1055
|
+
|
|
1056
|
+
assert_eq!(
|
|
1057
|
+
secrets_call(&client, vec![Value::str("get"), Value::str("db.password")]),
|
|
1058
|
+
Value::str("dbpass01")
|
|
1059
|
+
);
|
|
1060
|
+
assert_eq!(
|
|
1061
|
+
secrets_call(
|
|
1062
|
+
&client,
|
|
1063
|
+
vec![
|
|
1064
|
+
Value::str("redact"),
|
|
1065
|
+
Value::str("the password is dbpass01, keep it safe")
|
|
1066
|
+
]
|
|
1067
|
+
),
|
|
1068
|
+
Value::str("the password is [redacted], keep it safe")
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// ---- ACCESS-TOKEN EXCHANGE ----------------------------------------------
|
|
1073
|
+
//
|
|
1074
|
+
// What the chain resolves is a REFRESH token, which is POSTed to a token
|
|
1075
|
+
// endpoint for a short-lived ACCESS token; the access token is what the
|
|
1076
|
+
// Authorization header carries; and when the API answers 401 the client
|
|
1077
|
+
// buys another and tries the same request again, once.
|
|
1078
|
+
|
|
1079
|
+
const REFRESH: &str = "REFRESH01";
|
|
1080
|
+
|
|
1081
|
+
fn exchange(extra: Vec<(&str, Value)>) -> (&'static str, Value) {
|
|
1082
|
+
let x = jo(vec![("active", Value::Bool(true))]);
|
|
1083
|
+
for (k, v) in extra {
|
|
1084
|
+
RUSTCRATE::core::helpers::setp(&x, k, v);
|
|
1085
|
+
}
|
|
1086
|
+
("exchange", x)
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
fn exchange_sdk(wire: &Wire, extra: Vec<(&str, Value)>) -> Rc<ProjectNameSDK> {
|
|
1090
|
+
let mut opts: Vec<(&str, Value)> = vec![
|
|
1091
|
+
("name", Value::str("refresh_token")),
|
|
1092
|
+
providers(vec![memory("REFRESH_TOKEN", REFRESH)]),
|
|
1093
|
+
];
|
|
1094
|
+
opts.extend(extra);
|
|
1095
|
+
sdk(wire, opts)
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
fn bodyof(call: &Call) -> Value {
|
|
1099
|
+
let raw = call.body.clone().unwrap_or_default();
|
|
1100
|
+
RUSTCRATE::json_parse(&raw).unwrap_or(Value::Noval)
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
#[test]
|
|
1104
|
+
fn the_refresh_token_buys_an_access_token_and_the_request_carries_it() {
|
|
1105
|
+
let wire = Wire::new();
|
|
1106
|
+
let client = exchange_sdk(&wire, vec![exchange(vec![])]);
|
|
1107
|
+
|
|
1108
|
+
client
|
|
1109
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1110
|
+
.expect("direct");
|
|
1111
|
+
|
|
1112
|
+
assert_eq!(wire.token().len(), 1, "expected exactly one token purchase");
|
|
1113
|
+
assert_eq!(
|
|
1114
|
+
getp(&bodyof(&wire.token()[0]), "refresh_token"),
|
|
1115
|
+
Value::str(REFRESH),
|
|
1116
|
+
"the refresh token is sent in the request field"
|
|
1117
|
+
);
|
|
1118
|
+
assert_eq!(wire.api().len(), 1);
|
|
1119
|
+
credential_is(call_auth(&wire.api(), 0), "ACCESS01");
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
#[test]
|
|
1123
|
+
fn an_explicit_exchange_refresh_wins_over_the_chain() {
|
|
1124
|
+
let wire = Wire::new();
|
|
1125
|
+
let client = exchange_sdk(
|
|
1126
|
+
&wire,
|
|
1127
|
+
vec![exchange(vec![("refresh", Value::str("EXPLICIT01"))])],
|
|
1128
|
+
);
|
|
1129
|
+
|
|
1130
|
+
client
|
|
1131
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1132
|
+
.expect("direct");
|
|
1133
|
+
|
|
1134
|
+
assert_eq!(
|
|
1135
|
+
getp(&bodyof(&wire.token()[0]), "refresh_token"),
|
|
1136
|
+
Value::str("EXPLICIT01")
|
|
1137
|
+
);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
#[test]
|
|
1141
|
+
fn one_purchase_serves_many_requests() {
|
|
1142
|
+
let wire = Wire::new();
|
|
1143
|
+
let client = exchange_sdk(&wire, vec![exchange(vec![])]);
|
|
1144
|
+
|
|
1145
|
+
for path in ["/one", "/two", "/three"] {
|
|
1146
|
+
client
|
|
1147
|
+
.direct(jo(vec![("path", Value::str(path))]))
|
|
1148
|
+
.expect("direct");
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
assert_eq!(
|
|
1152
|
+
wire.token().len(),
|
|
1153
|
+
1,
|
|
1154
|
+
"a token still working must not be re-bought"
|
|
1155
|
+
);
|
|
1156
|
+
assert_eq!(wire.api().len(), 3);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
#[test]
|
|
1160
|
+
fn an_expiry_buys_another_token_and_retries_the_same_request() {
|
|
1161
|
+
let wire = Wire::new().apistatus(&[401, 200]);
|
|
1162
|
+
let client = exchange_sdk(&wire, vec![exchange(vec![])]);
|
|
1163
|
+
|
|
1164
|
+
let res = client
|
|
1165
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1166
|
+
.expect("direct");
|
|
1167
|
+
|
|
1168
|
+
assert_eq!(wire.token().len(), 2, "expected a second token purchase");
|
|
1169
|
+
assert_eq!(wire.api().len(), 2, "expected the request to be retried");
|
|
1170
|
+
credential_is(call_auth(&wire.api(), 0), "ACCESS01");
|
|
1171
|
+
// The retry must carry the NEW token, not the spent one.
|
|
1172
|
+
credential_is(call_auth(&wire.api(), 1), "ACCESS02");
|
|
1173
|
+
assert_eq!(
|
|
1174
|
+
getp(&res, "ok"),
|
|
1175
|
+
Value::Bool(true),
|
|
1176
|
+
"the caller sees the successful retry"
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
#[test]
|
|
1181
|
+
fn the_retry_happens_once_not_in_a_loop() {
|
|
1182
|
+
// Every API call is refused: a second refusal on a token bought moments
|
|
1183
|
+
// ago is a real failure, and spinning on it would hang instead.
|
|
1184
|
+
let wire = Wire::new().apistatus(&[401]);
|
|
1185
|
+
let client = exchange_sdk(&wire, vec![exchange(vec![])]);
|
|
1186
|
+
|
|
1187
|
+
client
|
|
1188
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1189
|
+
.expect("direct");
|
|
1190
|
+
|
|
1191
|
+
assert_eq!(wire.api().len(), 2, "exactly one retry");
|
|
1192
|
+
assert_eq!(wire.token().len(), 2);
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
#[test]
|
|
1196
|
+
fn a_status_outside_exchange_statuses_is_not_an_expiry() {
|
|
1197
|
+
let wire = Wire::new().apistatus(&[403]);
|
|
1198
|
+
let client = exchange_sdk(&wire, vec![exchange(vec![])]);
|
|
1199
|
+
|
|
1200
|
+
client
|
|
1201
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1202
|
+
.expect("direct");
|
|
1203
|
+
|
|
1204
|
+
assert_eq!(wire.api().len(), 1, "403 is not in the default statuses");
|
|
1205
|
+
assert_eq!(wire.token().len(), 1);
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
#[test]
|
|
1209
|
+
fn exchange_statuses_are_configurable() {
|
|
1210
|
+
let wire = Wire::new().apistatus(&[403, 200]);
|
|
1211
|
+
let client = exchange_sdk(
|
|
1212
|
+
&wire,
|
|
1213
|
+
vec![exchange(vec![(
|
|
1214
|
+
"statuses",
|
|
1215
|
+
Value::list(vec![Value::Num(403.0)]),
|
|
1216
|
+
)])],
|
|
1217
|
+
);
|
|
1218
|
+
|
|
1219
|
+
client
|
|
1220
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1221
|
+
.expect("direct");
|
|
1222
|
+
|
|
1223
|
+
assert_eq!(wire.api().len(), 2, "403 was declared an expiry");
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
#[test]
|
|
1227
|
+
fn the_endpoint_and_field_names_are_configurable_and_the_body_is_serialised() {
|
|
1228
|
+
// A JSON-HOSTILE refresh token: it must arrive as this literal value,
|
|
1229
|
+
// which only holds if the body is serialised rather than concatenated.
|
|
1230
|
+
const NASTY: &str = "re\"fresh\\01\nline";
|
|
1231
|
+
|
|
1232
|
+
let wire = Wire::new().tokenpath("oauth/grant", "token");
|
|
1233
|
+
let client = sdk(
|
|
1234
|
+
&wire,
|
|
1235
|
+
vec![
|
|
1236
|
+
("name", Value::str("refresh_token")),
|
|
1237
|
+
providers(vec![memory("REFRESH_TOKEN", NASTY)]),
|
|
1238
|
+
exchange(vec![
|
|
1239
|
+
("path", Value::str("oauth/grant")),
|
|
1240
|
+
("request", Value::str("grant")),
|
|
1241
|
+
("response", Value::str("token")),
|
|
1242
|
+
]),
|
|
1243
|
+
],
|
|
1244
|
+
);
|
|
1245
|
+
|
|
1246
|
+
client
|
|
1247
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1248
|
+
.expect("direct");
|
|
1249
|
+
|
|
1250
|
+
assert_eq!(wire.token().len(), 1);
|
|
1251
|
+
assert!(
|
|
1252
|
+
wire.token()[0].url.ends_with("/oauth/grant"),
|
|
1253
|
+
"the token endpoint is relative to base: {}",
|
|
1254
|
+
wire.token()[0].url
|
|
1255
|
+
);
|
|
1256
|
+
assert_eq!(
|
|
1257
|
+
getp(&bodyof(&wire.token()[0]), "grant"),
|
|
1258
|
+
Value::str(NASTY),
|
|
1259
|
+
"the refresh token must survive serialisation intact"
|
|
1260
|
+
);
|
|
1261
|
+
credential_is(call_auth(&wire.api(), 0), "ACCESS01");
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
#[test]
|
|
1265
|
+
fn an_explicit_apikey_is_spent_before_anything_is_bought() {
|
|
1266
|
+
let wire = Wire::new();
|
|
1267
|
+
let client = ProjectNameSDK::new(jo(vec![
|
|
1268
|
+
("base", Value::str(BASE)),
|
|
1269
|
+
("apikey", Value::str("HELDTOKEN01")),
|
|
1270
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
1271
|
+
("system", jo(vec![("fetch", wire.fetch())])),
|
|
1272
|
+
(
|
|
1273
|
+
"feature",
|
|
1274
|
+
jo(vec![(
|
|
1275
|
+
"secrets",
|
|
1276
|
+
jo(vec![
|
|
1277
|
+
("active", Value::Bool(true)),
|
|
1278
|
+
("name", Value::str("refresh_token")),
|
|
1279
|
+
providers(vec![memory("REFRESH_TOKEN", REFRESH)]),
|
|
1280
|
+
exchange(vec![]),
|
|
1281
|
+
]),
|
|
1282
|
+
)]),
|
|
1283
|
+
),
|
|
1284
|
+
]));
|
|
1285
|
+
|
|
1286
|
+
client
|
|
1287
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1288
|
+
.expect("direct");
|
|
1289
|
+
|
|
1290
|
+
assert_eq!(wire.token().len(), 0, "nothing needed buying");
|
|
1291
|
+
credential_is(call_auth(&wire.api(), 0), "HELDTOKEN01");
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
#[test]
|
|
1295
|
+
fn a_held_apikey_that_has_expired_falls_through_to_the_exchange() {
|
|
1296
|
+
let wire = Wire::new().apistatus(&[401, 200]);
|
|
1297
|
+
let client = ProjectNameSDK::new(jo(vec![
|
|
1298
|
+
("base", Value::str(BASE)),
|
|
1299
|
+
("apikey", Value::str("STALETOKEN01")),
|
|
1300
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
1301
|
+
("system", jo(vec![("fetch", wire.fetch())])),
|
|
1302
|
+
(
|
|
1303
|
+
"feature",
|
|
1304
|
+
jo(vec![(
|
|
1305
|
+
"secrets",
|
|
1306
|
+
jo(vec![
|
|
1307
|
+
("active", Value::Bool(true)),
|
|
1308
|
+
("name", Value::str("refresh_token")),
|
|
1309
|
+
providers(vec![memory("REFRESH_TOKEN", REFRESH)]),
|
|
1310
|
+
exchange(vec![]),
|
|
1311
|
+
]),
|
|
1312
|
+
)]),
|
|
1313
|
+
),
|
|
1314
|
+
]));
|
|
1315
|
+
|
|
1316
|
+
client
|
|
1317
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1318
|
+
.expect("direct");
|
|
1319
|
+
|
|
1320
|
+
credential_is(call_auth(&wire.api(), 0), "STALETOKEN01");
|
|
1321
|
+
credential_is(call_auth(&wire.api(), 1), "ACCESS01");
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
#[test]
|
|
1325
|
+
fn no_refresh_token_anywhere_is_an_error_not_an_unauthenticated_call() {
|
|
1326
|
+
let wire = Wire::new();
|
|
1327
|
+
let client = sdk(
|
|
1328
|
+
&wire,
|
|
1329
|
+
vec![
|
|
1330
|
+
("name", Value::str("refresh_token")),
|
|
1331
|
+
providers(vec![]),
|
|
1332
|
+
exchange(vec![]),
|
|
1333
|
+
],
|
|
1334
|
+
);
|
|
1335
|
+
|
|
1336
|
+
let res = client
|
|
1337
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1338
|
+
.expect("direct");
|
|
1339
|
+
|
|
1340
|
+
assert_eq!(getp(&res, "ok"), Value::Bool(false));
|
|
1341
|
+
assert_eq!(
|
|
1342
|
+
wire.api().len(),
|
|
1343
|
+
0,
|
|
1344
|
+
"a request must not go out unauthenticated because the chain was empty: {}",
|
|
1345
|
+
wire.trace()
|
|
1346
|
+
);
|
|
1347
|
+
let err = get_str(&res, "err").unwrap_or_default();
|
|
1348
|
+
assert!(
|
|
1349
|
+
err.contains("no refresh token"),
|
|
1350
|
+
"expected the exchange's own message, got: {}",
|
|
1351
|
+
err
|
|
1352
|
+
);
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
#[test]
|
|
1356
|
+
fn a_failing_token_endpoint_surfaces_the_api_refusal_not_a_spin() {
|
|
1357
|
+
// The first purchase succeeds; the second (after the 401) does not.
|
|
1358
|
+
let wire = Wire::new().apistatus(&[401]).tokenstatus(&[200, 500]);
|
|
1359
|
+
let client = exchange_sdk(&wire, vec![exchange(vec![])]);
|
|
1360
|
+
|
|
1361
|
+
let res = client
|
|
1362
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1363
|
+
.expect("the caller got an answer rather than a hang");
|
|
1364
|
+
|
|
1365
|
+
assert_eq!(getp(&res, "status"), Value::Num(401.0));
|
|
1366
|
+
assert_eq!(wire.api().len(), 1, "no retry after a failed purchase");
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
#[test]
|
|
1370
|
+
fn exchange_auth_null_suppresses_and_is_never_retried() {
|
|
1371
|
+
let wire = Wire::new().apistatus(&[401]);
|
|
1372
|
+
let client = ProjectNameSDK::new(jo(vec![
|
|
1373
|
+
("base", Value::str(BASE)),
|
|
1374
|
+
("auth", Value::Null),
|
|
1375
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
1376
|
+
("system", jo(vec![("fetch", wire.fetch())])),
|
|
1377
|
+
(
|
|
1378
|
+
"feature",
|
|
1379
|
+
jo(vec![(
|
|
1380
|
+
"secrets",
|
|
1381
|
+
jo(vec![
|
|
1382
|
+
("active", Value::Bool(true)),
|
|
1383
|
+
("name", Value::str("refresh_token")),
|
|
1384
|
+
providers(vec![memory("REFRESH_TOKEN", REFRESH)]),
|
|
1385
|
+
exchange(vec![]),
|
|
1386
|
+
]),
|
|
1387
|
+
)]),
|
|
1388
|
+
),
|
|
1389
|
+
]));
|
|
1390
|
+
|
|
1391
|
+
client
|
|
1392
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1393
|
+
.expect("direct");
|
|
1394
|
+
|
|
1395
|
+
assert_eq!(
|
|
1396
|
+
wire.api().len(),
|
|
1397
|
+
1,
|
|
1398
|
+
"a suppressed request must not be retried"
|
|
1399
|
+
);
|
|
1400
|
+
assert_eq!(
|
|
1401
|
+
call_auth(&wire.api(), 0),
|
|
1402
|
+
None,
|
|
1403
|
+
"no credential may be sent when auth is suppressed: {}",
|
|
1404
|
+
wire.trace()
|
|
1405
|
+
);
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
// The exchange with NO system.fetch: the ordinary case, where make_options
|
|
1409
|
+
// leaves the seam unset and the purchase takes its own raw HTTP path. There
|
|
1410
|
+
// is no token endpoint to talk to here, so what this pins is that the
|
|
1411
|
+
// fallback EXISTS and reports - before this, `buy` with no custom transport
|
|
1412
|
+
// simply had nothing to call - and that a failed purchase refuses the
|
|
1413
|
+
// operation rather than sending it unauthenticated.
|
|
1414
|
+
#[test]
|
|
1415
|
+
fn the_exchange_has_a_raw_transport_when_no_system_fetch_is_given() {
|
|
1416
|
+
// Port 1 is reserved and never listening, so the connection is refused
|
|
1417
|
+
// immediately rather than hanging on a timeout.
|
|
1418
|
+
let client = ProjectNameSDK::new(jo(vec![
|
|
1419
|
+
("base", Value::str("http://127.0.0.1:1/api")),
|
|
1420
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
1421
|
+
(
|
|
1422
|
+
"feature",
|
|
1423
|
+
jo(vec![(
|
|
1424
|
+
"secrets",
|
|
1425
|
+
jo(vec![
|
|
1426
|
+
("active", Value::Bool(true)),
|
|
1427
|
+
("name", Value::str("refresh_token")),
|
|
1428
|
+
providers(vec![memory("REFRESH_TOKEN", REFRESH)]),
|
|
1429
|
+
exchange(vec![]),
|
|
1430
|
+
]),
|
|
1431
|
+
)]),
|
|
1432
|
+
),
|
|
1433
|
+
]));
|
|
1434
|
+
|
|
1435
|
+
let res = client
|
|
1436
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1437
|
+
.expect("direct");
|
|
1438
|
+
|
|
1439
|
+
assert_eq!(getp(&res, "ok"), Value::Bool(false));
|
|
1440
|
+
let err = get_str(&res, "err").unwrap_or_default();
|
|
1441
|
+
assert!(
|
|
1442
|
+
err.contains("token exchange"),
|
|
1443
|
+
"expected the exchange's own refusal from the raw transport, got: {}",
|
|
1444
|
+
err
|
|
1445
|
+
);
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
// TEST MODE BUYS NOTHING: the test feature replaces the transport so no
|
|
1450
|
+
// request leaves the process, and an exchange would be the one call it
|
|
1451
|
+
// could not stop.
|
|
1452
|
+
#[test]
|
|
1453
|
+
fn test_mode_buys_nothing_and_needs_no_token_endpoint() {
|
|
1454
|
+
let wire = Wire::new();
|
|
1455
|
+
let client = RUSTCRATE::test_sdk(
|
|
1456
|
+
Value::Noval,
|
|
1457
|
+
jo(vec![
|
|
1458
|
+
("base", Value::str(BASE)),
|
|
1459
|
+
("allow", jo(vec![("op", Value::str("direct,graphql"))])),
|
|
1460
|
+
("system", jo(vec![("fetch", wire.fetch())])),
|
|
1461
|
+
(
|
|
1462
|
+
"feature",
|
|
1463
|
+
jo(vec![(
|
|
1464
|
+
"secrets",
|
|
1465
|
+
jo(vec![
|
|
1466
|
+
("active", Value::Bool(true)),
|
|
1467
|
+
("name", Value::str("refresh_token")),
|
|
1468
|
+
providers(vec![memory("REFRESH_TOKEN", REFRESH)]),
|
|
1469
|
+
exchange(vec![]),
|
|
1470
|
+
]),
|
|
1471
|
+
)]),
|
|
1472
|
+
),
|
|
1473
|
+
]),
|
|
1474
|
+
);
|
|
1475
|
+
|
|
1476
|
+
client
|
|
1477
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1478
|
+
.expect("direct");
|
|
1479
|
+
|
|
1480
|
+
assert_eq!(wire.sent(), 0, "test mode must not do IO");
|
|
1481
|
+
// A deterministic placeholder, so offline suites need no configuration.
|
|
1482
|
+
assert_eq!(
|
|
1483
|
+
secrets_call(&client, vec![Value::str("credential")]),
|
|
1484
|
+
Value::str("test-access_token")
|
|
1485
|
+
);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
// The exchange OFF leaves the feature exactly as it was.
|
|
1489
|
+
#[test]
|
|
1490
|
+
fn exchange_off_leaves_the_feature_exactly_as_it_was() {
|
|
1491
|
+
let wire = Wire::new();
|
|
1492
|
+
let client = sdk(&wire, vec![providers(vec![memory("APIKEY", "PLAINKEY01")])]);
|
|
1493
|
+
|
|
1494
|
+
client
|
|
1495
|
+
.direct(jo(vec![("path", Value::str("/thing"))]))
|
|
1496
|
+
.expect("direct");
|
|
1497
|
+
|
|
1498
|
+
assert_eq!(wire.token().len(), 0, "nothing may be bought");
|
|
1499
|
+
credential_is(call_auth(&wire.api(), 0), "PLAINKEY01");
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
// Keep `to_int`/`ja` referenced: they belong to the seam this file
|
|
1503
|
+
// documents (transport-shaped responses, the system.fetch argument list),
|
|
1504
|
+
// and an unused import would be a warning in a template that ships.
|
|
1505
|
+
#[test]
|
|
1506
|
+
fn helpers_are_the_ones_the_seam_uses() {
|
|
1507
|
+
assert_eq!(to_int(&Value::Num(401.0)), 401);
|
|
1508
|
+
assert!(matches!(ja(vec![Value::Noval]), Value::List(_)));
|
|
1509
|
+
}
|