From 1614ea44adf38b0c0c3701f3973c10d621e3e3a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20R=C3=BCdiger?= Date: Wed, 13 Apr 2022 15:59:57 +0200 Subject: [PATCH 1/3] improve vault and item parsing By replacing string.Split in ParseVaultAndItemFromPath with a regexp, you can use vault and item names containing slashes --- pkg/onepassword/items.go | 10 +++--- pkg/onepassword/items_test.go | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 pkg/onepassword/items_test.go diff --git a/pkg/onepassword/items.go b/pkg/onepassword/items.go index c022f5d5..108932b2 100644 --- a/pkg/onepassword/items.go +++ b/pkg/onepassword/items.go @@ -2,7 +2,7 @@ package onepassword import ( "fmt" - "strings" + "regexp" "github.com/1Password/connect-sdk-go/connect" "github.com/1Password/connect-sdk-go/onepassword" @@ -42,9 +42,11 @@ func GetOnePasswordItemByPath(opConnectClient connect.Client, path string) (*one } func ParseVaultAndItemFromPath(path string) (string, string, error) { - splitPath := strings.Split(path, "/") - if len(splitPath) == 4 && splitPath[0] == "vaults" && splitPath[2] == "items" { - return splitPath[1], splitPath[3], nil + r := regexp.MustCompile("vaults/(.*)/items/(.*)") + splitPath := r.FindAllStringSubmatch(path, -1) + + if len(splitPath) == 1 && len(splitPath[0]) == 3 { + return splitPath[0][1], splitPath[0][2], nil } return "", "", fmt.Errorf("%q is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`", path) } diff --git a/pkg/onepassword/items_test.go b/pkg/onepassword/items_test.go new file mode 100644 index 00000000..f97bac58 --- /dev/null +++ b/pkg/onepassword/items_test.go @@ -0,0 +1,57 @@ +package onepassword + +import ( + "fmt" + "testing" +) + +func TestParseVaultAndItemFromPath(t *testing.T) { + cases := []struct { + Path string + Vault string + Item string + Error error + }{ + { + "vaults/foo/items/bar", + "foo", + "bar", + nil, + }, + { + "vaults/foo/items/bar/baz", + "foo", + "bar/baz", + nil, + }, + { + "vaults/foo/bar/items/baz", + "foo/bar", + "baz", + nil, + }, + { + "foo/bar", + "", + "", + fmt.Errorf("\"foo/bar\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), + }, + } + + for _, c := range cases { + vault, item, err := ParseVaultAndItemFromPath(c.Path) + + if err != c.Error && err.Error() != c.Error.Error() { + t.Errorf("unexpected error %v: %v", err, c.Error) + } + + if vault != c.Vault { + t.Errorf("couldn't extract vault out of path %s: %s", c.Path, vault) + } + + if item != c.Item { + t.Errorf("couldn't extract item out of path %s: %s != %s", c.Path, item, c.Item) + } + + } +} From 896d3fbdf2aaabf1c3a1cfaad508378603734660 Mon Sep 17 00:00:00 2001 From: Jill Regan Date: Wed, 11 Feb 2026 14:44:39 -0500 Subject: [PATCH 2/3] Use FindStringSubmatch --- pkg/onepassword/items.go | 7 ++-- pkg/onepassword/items_test.go | 78 +++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/pkg/onepassword/items.go b/pkg/onepassword/items.go index 108932b2..c98791ec 100644 --- a/pkg/onepassword/items.go +++ b/pkg/onepassword/items.go @@ -43,11 +43,12 @@ func GetOnePasswordItemByPath(opConnectClient connect.Client, path string) (*one func ParseVaultAndItemFromPath(path string) (string, string, error) { r := regexp.MustCompile("vaults/(.*)/items/(.*)") - splitPath := r.FindAllStringSubmatch(path, -1) + splitPath := r.FindStringSubmatch(path) - if len(splitPath) == 1 && len(splitPath[0]) == 3 { - return splitPath[0][1], splitPath[0][2], nil + if len(splitPath) == 3 { + return splitPath[1], splitPath[2], nil } + return "", "", fmt.Errorf("%q is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`", path) } diff --git a/pkg/onepassword/items_test.go b/pkg/onepassword/items_test.go index f97bac58..015f5e6e 100644 --- a/pkg/onepassword/items_test.go +++ b/pkg/onepassword/items_test.go @@ -36,6 +36,84 @@ func TestParseVaultAndItemFromPath(t *testing.T) { "", fmt.Errorf("\"foo/bar\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), }, + { + "vaults/foo1/items/bar1/vaults/foo2/items/bar2", + "foo1/items/bar1/vaults/foo2", + "bar2", + nil, + }, + { + "items/bar/vaults/foo", + "", + "", + fmt.Errorf("\"items/bar/vaults/foo\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), + }, + { + "vaults/foo", + "", + "", + fmt.Errorf("\"vaults/foo\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), + }, + { + "vaults/foo/items/bar/", + "foo", + "bar/", + nil, + }, + { + "vaults/abc123-def456/items/xyz789-uvw012", + "abc123-def456", + "xyz789-uvw012", + nil, + }, + { + "vaults/a/items/b", + "a", + "b", + nil, + }, + { + "", + "", + "", + fmt.Errorf("\"\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), + }, + { + "vaults//foo/items/bar", + "/foo", + "bar", + nil, + }, + { + "vaults/foo/items/", + "foo", + "", + nil, + }, + { + "vaults/items", + "", + "", + fmt.Errorf("\"vaults/items\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), + }, + { + "vaults/foo bar/items/baz", + "foo bar", + "baz", + nil, + }, + { + "vaults/日本/items/条目", + "日本", + "条目", + nil, + }, + { + "prefix/vaults/foo/items/bar", + "foo", + "bar", + nil, + }, } for _, c := range cases { From 09fdc45aaaf11fad6e664b075d326cf09550a9e8 Mon Sep 17 00:00:00 2001 From: Jill Regan Date: Wed, 11 Feb 2026 14:50:52 -0500 Subject: [PATCH 3/3] Fix linting error --- pkg/onepassword/items_test.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pkg/onepassword/items_test.go b/pkg/onepassword/items_test.go index 015f5e6e..732924fa 100644 --- a/pkg/onepassword/items_test.go +++ b/pkg/onepassword/items_test.go @@ -5,6 +5,9 @@ import ( "testing" ) +const badPathErrFmt = "%q is not an acceptable path for One Password item. " + + "Must be of the format: `vaults/{vault_id}/items/{item_id}`" + func TestParseVaultAndItemFromPath(t *testing.T) { cases := []struct { Path string @@ -34,7 +37,7 @@ func TestParseVaultAndItemFromPath(t *testing.T) { "foo/bar", "", "", - fmt.Errorf("\"foo/bar\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), + fmt.Errorf(badPathErrFmt, "foo/bar"), }, { "vaults/foo1/items/bar1/vaults/foo2/items/bar2", @@ -46,13 +49,13 @@ func TestParseVaultAndItemFromPath(t *testing.T) { "items/bar/vaults/foo", "", "", - fmt.Errorf("\"items/bar/vaults/foo\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), + fmt.Errorf(badPathErrFmt, "items/bar/vaults/foo"), }, { "vaults/foo", "", "", - fmt.Errorf("\"vaults/foo\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), + fmt.Errorf(badPathErrFmt, "vaults/foo"), }, { "vaults/foo/items/bar/", @@ -76,7 +79,7 @@ func TestParseVaultAndItemFromPath(t *testing.T) { "", "", "", - fmt.Errorf("\"\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), + fmt.Errorf(badPathErrFmt, ""), }, { "vaults//foo/items/bar", @@ -94,7 +97,7 @@ func TestParseVaultAndItemFromPath(t *testing.T) { "vaults/items", "", "", - fmt.Errorf("\"vaults/items\" is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`"), + fmt.Errorf(badPathErrFmt, "vaults/items"), }, { "vaults/foo bar/items/baz",