diff --git a/lib/vault/client.rb b/lib/vault/client.rb index cc82f40..cf03415 100644 --- a/lib/vault/client.rb +++ b/lib/vault/client.rb @@ -305,6 +305,15 @@ def request(verb, path, data = {}, headers = {}) end end + # Removes double slashes from a path. + # + # @param [String] + # + # @return [String] + def remove_double_slash(path) + path.b.gsub(%r{//+}, '/') + end + # Construct a URL from the given verb and path. If the request is a GET or # DELETE request, the params are assumed to be query params are are # converted as such using {Client#to_query_string}. @@ -333,6 +342,8 @@ def build_uri(verb, path, params = {}) # Don't merge absolute URLs uri = URI.parse(File.join(address, path)) unless uri.absolute? + uri.path = remove_double_slash(uri.path) + # Return the URI object uri end diff --git a/spec/integration/api/logical_spec.rb b/spec/integration/api/logical_spec.rb index 1d40592..914314e 100644 --- a/spec/integration/api/logical_spec.rb +++ b/spec/integration/api/logical_spec.rb @@ -58,6 +58,20 @@ module Vault expect(secret).to be expect(secret.data).to eq(foo: "bar") end + + it "allows double slash" do + subject.write("secret/test-read", foo: "bar") + secret = subject.read("secret///test-read") + expect(secret).to be + expect(secret.data).to eq(foo: "bar") + end + + it "allows double slash and special characters" do + subject.write("secret/b:@c%n-read-slash", foo: "bar") + secret = subject.read("secret///b:@c%n-read-slash") + expect(secret).to be + expect(secret.data).to eq(foo: "bar") + end end describe "#write" do @@ -84,6 +98,21 @@ module Vault expect(secret.data).to eq(bacon: true) end + it "allows double slash" do + subject.write("secret///test-write", zip: "zap") + result = subject.read("secret/test-write") + expect(result).to be + expect(result.data).to eq(zip: "zap") + end + + it "allows double slash and special characters" do + subject.write("secret///b:@c%n-write", foo: "bar") + subject.write("secret///b:@c%n-write", bacon: true) + secret = subject.read("secret/b:@c%n-write") + expect(secret).to be + expect(secret.data).to eq(bacon: true) + end + it "respects spaces properly" do key = 'secret/sub/"Test Group"' subject.write(key, foo: "bar") @@ -107,6 +136,18 @@ module Vault expect(subject.read("secret/b:@c%n-delete")).to be(nil) end + it "allows double slash" do + subject.write("secret/delete", foo: "bar") + expect(subject.delete("secret///delete")).to be(true) + expect(subject.read("secret/delete")).to be(nil) + end + + it "allows double slash and special characters" do + subject.write("secret/b:@c%n-delete-slash", foo: "bar") + expect(subject.delete("secret///b:@c%n-delete-slash")).to be(true) + expect(subject.read("secret/b:@c%n-delete-slash")).to be(nil) + end + it "does not error if the secret does not exist" do expect { subject.delete("secret/delete")