1Password / connect-sdk-python

Python SDK for 1Password Connect
https://developer.1password.com/docs/connect
MIT License
200 stars 31 forks source link

Retrieved SummaryItem lacks "fields" attribute under released library versions (1.1 and 1.0) #38

Closed irons closed 2 years ago

irons commented 2 years ago

Your environment

SDK Version: 1.0, 1.1, and tip of main (c809bfa0f)

Connect Server Version: 1.5.0

OS: macOS 11.6.4

Python Version: 3.9.10, 3.9.11, 3.10.2, 3.10.3

What happened?

Upon upgrading from Python 3.9.10 to last week's 3.9.11, some pretty basic 1Password item retrieval code broke. On later examination, 3.9.10 only continued to work because I had previously built the library locally to troubleshoot #36 — the problem was in the released library versions.

Here's the complete json skeleton from a synthesized item I'm trying to retrieve:

{
  "createdAt": "2022-03-22T03:09:41.000Z",
  "details": {
    "notesPlain": "for something super important",
    "password": "K_.xqKvqrEAPAt63yfwGJU3z9bwBaR",
    "sections": [
      {
        "name": "linked items",
        "title": "Related Items"
      },
      {
        "fields": [
          {
            "k": "string",
            "n": "06836A624EC14D51A2BB4D5791213010",
            "t": "Key ID",
            "v": "2E1B839B-3EE2-42FA-ADE5-7BDC4E3ECA91"
          }
        ],
        "name": "Section_4144107279A848498B832C61BABC5E00",
        "title": ""
      }
    ]
  },
  "overview": {
    "ainfo": "Mar 21, 2022 at 8:09:41 PM",
    "pbe": 177.81768798828125,
    "pgrng": true,
    "ps": 100,
    "tags": [
      "team:Foo"
    ],
    "title": "Sanitized Item"
  },
  "templateUuid": "005",
  "trashed": "N",
  "updatedAt": "2022-03-22T03:10:40.000Z",
  "uuid": "yiapgssbg5hfxfbu2kczeprnuy"
}

Here's some code to retrieve it:

#!/usr/bin/env python

import os
import onepasswordconnectsdk
from pprint import pprint
from onepasswordconnectsdk.client import new_client
from onepasswordconnectsdk.models import (
    ItemVault, 
    Field, 
    Section, 
    FieldSection
)

item_name = "Sanitized item"
vault_id = "kmbbwba32eyx2qz5flk3z2frra"

client = new_client("http://localhost:8080", os.environ['OP_CONNECT_TOKEN'])

try:
    item = client.get_item_by_title(item_name, vault_id)
except onepasswordconnectsdk.client.FailedToRetrieveItemException as e:
    raise e 

pprint(item)

item_password = [item.value for item in item.fields if item.purpose == "PASSWORD"][0]
print(item_password)

Versions 1.0 and 1.1 of onepasswordconnectsdk get back a SummaryItem object which doesn't contain any fields attribute, which is where all my stuff is. pprint(item) on the failing versions returns this:

{'category': 'PASSWORD',
 'created_at': datetime.datetime(2022, 3, 22, 3, 9, 41, tzinfo=tzutc()),
 'favorite': False,
 'id': 'yiapgssbg5hfxfbu2kczeprnuy',
 'last_edited_by': 'FRAQH4JNUJG6XPMLJO2GVA72T4',
 'tags': ['team:Foo'],
 'title': 'Sanitized Item',
 'trashed': False,
 'updated_at': datetime.datetime(2022, 3, 22, 3, 10, 40, tzinfo=tzutc()),
 'urls': None,
 'vault': {'id': 'kmbbwba32eyx2qz5flk3z2frra'},
 'version': 2}

What did you expect to happen?

When I build c809bfa0f locally and install it, the pprint output looks like this:

{'category': 'PASSWORD',
 'created_at': datetime.datetime(2022, 3, 22, 3, 9, 41, tzinfo=tzutc()),
 'favorite': False,
 'fields': [{'entropy': 177.81768798828125,
             'generate': False,
             'id': 'password',
             'label': 'password',
             'purpose': 'PASSWORD',
             'section': None,
             'type': 'CONCEALED',
             'value': 'K_.xqKvqrEAPAt63yfwGJU3z9bwBaR'},
            {'entropy': None,
             'generate': False,
             'id': 'notesPlain',
             'label': 'notesPlain',
             'purpose': 'NOTES',
             'section': None,
             'type': 'STRING',
             'value': 'for something super important'},
            {'entropy': None,
             'generate': False,
             'id': '06836A624EC14D51A2BB4D5791213010',
             'label': 'Key ID',
             'purpose': None,
             'section': {'id': 'Section_4144107279A848498B832C61BABC5E00'},
             'type': 'STRING',
             'value': '2E1B839B-3EE2-42FA-ADE5-7BDC4E3ECA91'}],
 'id': 'yiapgssbg5hfxfbu2kczeprnuy',
 'last_edited_by': 'FRAQH4JNUJG6XPMLJO2GVA72T4',
 'sections': [{'id': 'Section_4144107279A848498B832C61BABC5E00', 'label': None},
              {'id': 'linked items', 'label': 'Related Items'}],
 'tags': ['team:Foo'],
 'title': 'Sanitized Item',
 'trashed': False,
 'updated_at': datetime.datetime(2022, 3, 22, 3, 10, 40, tzinfo=tzutc()),
 'urls': None,
 'vault': {'id': 'kmbbwba32eyx2qz5flk3z2frra'},
 'version': 2}

In the library version built from c809bfa0f, the list comprehension in the second-to-last line successfully squeezes a password out of this item. In the released versions, the list comprehension results in: "AttributeError: 'SummaryItem' object has no attribute 'fields'".

jillianwilson commented 2 years ago

Hi there!

I've just released version v1.2.0 that contains the code you tested on c809bfa0f. In the previously released versions the item returned was only a summary item so not all data was included. The get_item_by_title method should be updated now to include field data. Please let me know if you run into any issues!

irons commented 2 years ago

Thanks, that's very helpful.