diff --git a/src/onepasswordconnectsdk/config.py b/src/onepasswordconnectsdk/config.py index 9de206b..09fc55d 100644 --- a/src/onepasswordconnectsdk/config.py +++ b/src/onepasswordconnectsdk/config.py @@ -81,8 +81,9 @@ def load_dict(client: "Client", config: dict): opitem (required): describes the name of the item to access from 1Password - offield (required): describes the name of the field to access within - the specified item + opfield (required): the section and field label, separated by the first + period. Additional periods are part of the field label. Use an empty + section for fields outside a section, for example .test.name@example.com. opvault: Only required if OP_VAULT is not set. Used to decribe the vault in which to fetch the item @@ -140,7 +141,8 @@ class Foo(): opitem (required): describes the name of the item to access from 1Password opfield (required): describes the name of the field to access - within the specified item + within the specified item. The first period separates the section from + the field label; additional periods are part of the field label. opvault: Only required if OP_VAULT is not set. Used to decribe the vault in which to fetch the item @@ -223,7 +225,7 @@ def _set_values_for_item( for {parsed_field.name}" ) - path_parts = parsed_field.tag.split(".") + path_parts = parsed_field.tag.split(".", 1) if len(path_parts) != 2: raise InvalidFieldPathException( f"Invalid field path format for \ diff --git a/src/tests/test_config.py b/src/tests/test_config.py index 04835d5..0fbd99e 100644 --- a/src/tests/test_config.py +++ b/src/tests/test_config.py @@ -1,4 +1,5 @@ from httpx import Response +import pytest import onepasswordconnectsdk from onepasswordconnectsdk import client @@ -25,6 +26,30 @@ class Config: CONFIG_CLASS = Config() +@pytest.mark.parametrize("section", ["", "section1"]) +@pytest.mark.parametrize("use_object", [False, True]) +def test_load_dotted_field_labels(respx_mock, section, use_object): + field = {"id": "email", "label": "test.name@example.com", "value": "secret"} + if section: + field["section"] = {"id": section} + payload = dict(item, fields=[field]) + respx_mock.get(f"v1/vaults/{VAULT_ID}/items/{ITEM_ID1}").mock( + return_value=Response(200, json=payload) + ) + field_path = f"{section}.test.name@example.com" + if use_object: + class DottedConfig: + password: f'opitem:{ITEM_ID1} opfield:{field_path} opvault:{VAULT_ID}' + + result = onepasswordconnectsdk.load(SS_CLIENT, DottedConfig()) + assert result.password == "secret" + else: + result = onepasswordconnectsdk.load_dict(SS_CLIENT, { + "password": {"opitem": ITEM_ID1, "opfield": field_path, "opvault": VAULT_ID} + }) + assert result == {"password": "secret"} + + def test_load(respx_mock): mock_items_list1 = respx_mock.get(f"v1/vaults/{VAULT_ID}/items?filter=title eq \"{ITEM_NAME1}\"").mock( return_value=Response(200, json=[item])