Skip to content

Commit

Permalink
Merge pull request #27 from 1Password/feature/enhance-get-item
Browse files Browse the repository at this point in the history
Improve `get_item` and `get_item_by_title` functions
  • Loading branch information
edif2008 authored Nov 9, 2021
2 parents 2b4596e + a156c67 commit 678d607
Show file tree
Hide file tree
Showing 5 changed files with 378 additions and 132 deletions.
101 changes: 89 additions & 12 deletions src/onepasswordconnectsdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from onepasswordconnectsdk.models.constants import CONNECT_HOST_ENV_VARIABLE

ENV_SERVICE_ACCOUNT_JWT_VARIABLE = "OP_CONNECT_TOKEN"
UUIDLength = 26


class Client:
Expand Down Expand Up @@ -42,10 +43,9 @@ def create_session(self):

def build_headers(self):
"""Builds the headers needed to make a request to the server
Parameters:
Returns:
dict: The 1Password Connect API request headers
dict: The 1Password Connect API request headers
"""

headers = {}
Expand Down Expand Up @@ -101,14 +101,43 @@ def download_file(self, file_id: str, item_id: str, vault_id: str, path: str):
file.write(content)
file.close()

def get_item(self, item_id: str, vault_id: str):
def get_item(self, item: str, vault: str):
"""Get a specific item
Args:
item (str): the id or title of the item to be fetched
vault (str): the id or name of the vault in which to get the item from
Raises:
FailedToRetrieveItemException: Thrown when a HTTP error is returned
from the 1Password Connect API
Returns:
Item object: The found item
"""

vault_id = vault
if not self._is_valid_UUID(vault):
vault_id = self.get_vault_by_title(vault).id

if self._is_valid_UUID(item):
return self.get_item_by_id(item, vault_id)
else:
return self.get_item_by_title(item, vault_id)

def get_item_by_id(self, item_id: str, vault_id: str):
"""Get a specific item by uuid
Parameters:
item_id (str): The id of the item to be fetched
vault_id (str): The id of the vault in which to get the item from
Args:
item_id (str): The id of the item to be fetched
vault_id (str): The id of the vault in which to get the item from
Raises:
FailedToRetrieveItemException: Thrown when a HTTP error is returned
from the 1Password Connect API
Returns:
Item object: The found item
Item object: The found item
"""
url = f"/v1/vaults/{vault_id}/items/{item_id}"

Expand All @@ -124,12 +153,17 @@ def get_item(self, item_id: str, vault_id: str):

def get_item_by_title(self, title: str, vault_id: str):
"""Get a specific item by title
Parameters:
title (str): The title of the item to be fetched
vault_id (str): The id of the vault in which to get the item from
Args:
title (str): The title of the item to be fetched
vault_id (str): The id of the vault in which to get the item from
Raises:
FailedToRetrieveItemException: Thrown when a HTTP error is returned
from the 1Password Connect API
Returns:
Item object: A summary of the found item
Item object: The found item
"""
filter_query = f'title eq "{title}"'
url = f"/v1/vaults/{vault_id}/items?filter={filter_query}"
Expand All @@ -149,7 +183,8 @@ def get_item_by_title(self, title: str, vault_id: str):
title {title}"
)

return self.deserialize(response.content, "list[SummaryItem]")[0]
item_summary = self.deserialize(response.content, "list[SummaryItem]")[0]
return self.get_item_by_id(item_summary.id, vault_id)

def get_items(self, vault_id: str):
"""Returns a list of item summaries for the specified vault
Expand Down Expand Up @@ -281,6 +316,39 @@ def get_vault(self, vault_id: str):

return self.deserialize(response.content, "Vault")

def get_vault_by_title(self, name: str):
"""Returns the vault with the given name
Args:
name (str): The name of the vault in which to fetch
Raises:
FailedToRetrieveVaultException: Thrown when a HTTP error is
returned from the 1Password Connect API
Returns:
Vault: The specified vault
"""
filter_query = f'name eq "{name}"'
url = f"/v1/vaults?filter={filter_query}"

response = self.build_request("GET", url)
try:
response.raise_for_status()
except HTTPError:
raise FailedToRetrieveVaultException(
f"Unable to retrieve vaults. Received {response.status_code} \
for {url} with message {response.json().get('message')}"
)

if len(response.json()) != 1:
raise FailedToRetrieveItemException(
f"Found {len(response.json())} vaults with \
name {name}"
)

return self.deserialize(response.content, "list[Vault]")[0]

def get_vaults(self):
"""Returns all vaults for service account set in client
Expand Down Expand Up @@ -515,6 +583,15 @@ def __deserialize_model(self, data, klass):
instance = self.__deserialize(data, klass_name)
return instance

def _is_valid_UUID(self, uuid):
if len(uuid) is not UUIDLength:
return False
for c in uuid:
valid = (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9')
if valid is False:
return False
return True


def new_client(url: str, token: str):
"""Builds a new client for interacting with 1Password Connect
Expand Down
6 changes: 1 addition & 5 deletions src/onepasswordconnectsdk/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,8 @@ def _set_values_for_item(
config_dict={},
config_object: object = None,
):
# Retrieves a summary item
summary_item: Item = client.get_item_by_title(
parsed_item.item_title, parsed_item.vault_uuid
)
# Fetching the full item
item: Item = client.get_item(summary_item.id, parsed_item.vault_uuid)
item: Item = client.get_item(parsed_item.item_title, parsed_item.vault_uuid)

sections = _convert_sections_to_dict(item.sections)

Expand Down
Loading

0 comments on commit 678d607

Please sign in to comment.