Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Operations:
- [x] [Delete items](https://developer.1password.com/docs/sdks/manage-items#delete-an-item)
- [x] [Archive items](https://developer.1password.com/docs/sdks/manage-items/#archive-an-item)
- [x] [List items](https://developer.1password.com/docs/sdks/list-vaults-items/)
- [x] [Share items](https://developer.1password.com/docs/sdks/share-items) (items with files cannot be shared)
- [x] [Share items](https://developer.1password.com/docs/sdks/share-items)
- [x] [Generate PIN, random and memorable passwords](https://developer.1password.com/docs/sdks/manage-items#generate-a-password)

Field types:
Expand All @@ -98,7 +98,7 @@ Field types:
- [x] Concealed fields
- [x] Text fields
- [x] Notes
- [x] SSH private keys, public keys, fingerprint and key type
- [x] SSH private keys, public keys, fingerprint and key type
- [x] One-time passwords
- [x] URLs
- [x] Websites (used to suggest and autofill logins)
Expand All @@ -107,8 +107,8 @@ Field types:
- [x] Credit card numbers
- [x] Emails
- [x] References to other items
- [ ] Address
- [ ] Date
- [x] Address
- [x] Date
- [x] MM/YY
- [x] Files attachments and Document items
- [x] Menu
Expand Down
86 changes: 84 additions & 2 deletions example/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ async def main():
)
print(code)
# [developer-docs.sdk.python.resolve-totp-code]-end

await resolve_all_secrets(
client, created_item.vault_id, created_item.id, "username", "password"
)
# [developer-docs.sdk.python.get-totp-item-crud]-start
# Fetch a totp code from the item
for f in created_item.fields:
Expand Down Expand Up @@ -229,6 +231,7 @@ async def share_item(client: Client, vault_id: str, item_id: str):


async def create_ssh_key_item(client: Client):
# [developer-docs.sdk.python.create-sshkey-item]-start
# Generate a 2048-bit RSA private key
private_key = rsa.generate_private_key(
public_exponent=65537,
Expand All @@ -242,7 +245,6 @@ async def create_ssh_key_item(client: Client):
encryption_algorithm=serialization.NoEncryption(),
)

# [developer-docs.sdk.python.create-sshkey-item]-start
# Create an Item containing SSH Key and add it to your vault.
to_create = ItemCreateParams(
title="SSH Key Item Created With Python SDK",
Expand Down Expand Up @@ -382,5 +384,85 @@ async def create_attach_and_delete_file_field_item(client: Client):
await client.items.delete(deleted_file_item.vault_id, deleted_file_item.id)


async def resolve_all_secrets(
client: Client, vault_id: str, item_id: str, field_id: str, field_id2: str
):
# [developer-docs.sdk.python.resolve-bulk-secret]-start
# Retrieves multiple secret from 1Password.
secrets = await client.secrets.resolve_all(
[
f"op://{vault_id}//{item_id}/{field_id}",
f"op://{vault_id}/{item_id}/{field_id2}",
]
)
for secret in secrets.individual_responses.values():
if secret.error is not None:
print(str(secret.error))
else:
print(secret.content.secret)
# [developer-docs.sdk.python.resolve-bulk-secret]-end


def generate_special_item_fields():
fields = (
[
# [developer-docs.sdk.python.address-field-type]-start
ItemField(
id="address",
title="Address",
sectionId="",
field_type=ItemFieldType.ADDRESS,
value="",
details=ItemFieldDetailsAddress(
content=AddressFieldDetails(
street="1234 Main St",
city="San Francisco",
state="CA",
zip="94111",
country="USA",
),
),
),
# [developer-docs.sdk.python.address-field-type]-end
# [developer-docs.sdk.python.date-field-type]-start
ItemField(
id="date",
title="Date",
section_id="",
field_type=ItemFieldType.DATE,
value="1998-03-15",
),
# [developer-docs.sdk.python.date-field-type]-end
# [developer-docs.sdk.python.month-year-field-type]-start
ItemField(
id="month_year",
title="Month Year",
section_id="",
field_type=ItemFieldType.MONTHYEAR,
value="03/1998",
),
# [developer-docs.sdk.python.month-year-field-type]-end
# [developer-docs.sdk.python.reference-field-type]-start
ItemField(
id="Reference",
title="Reference",
sectionId="",
field_type=ItemFieldType.REFERENCE,
value="f43hnkatjllm5fsfsmgaqdhv7a",
),
# [developer-docs.sdk.python.reference-field-type]-end
# [developer-docs.sdk.python.totp-field-type]-start
ItemField(
id="onetimepassword",
title="one-time-password",
section_id="",
field_type=ItemFieldType.TOTP,
value="otpauth://totp/my-example-otp?secret=jncrjgbdjnrncbjsr&issuer=1Password",
),
# [developer-docs.sdk.python.totp-field-type]-end
],
)


if __name__ == "__main__":
asyncio.run(main())
2 changes: 1 addition & 1 deletion src/onepassword/build_number.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
SDK_BUILD_NUMBER = "0020001"
SDK_BUILD_NUMBER = "0020101"
8 changes: 5 additions & 3 deletions src/onepassword/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from onepassword.errors import raise_typed_exception

# In empirical tests, we determined that maximum message size that can cross the FFI boundary
# In empirical tests, we determined that maximum message size that can cross the FFI boundary
# is ~128MB. Past this limit, FFI will throw an error and the program will crash.
# We set the limit to 50MB to be safe and consistent with the other SDKs (where this limit is 64MB), to be reconsidered upon further testing
MESSAGE_LIMIT = 50 * 1024 * 1024
Expand Down Expand Up @@ -33,7 +33,8 @@ async def _invoke(invoke_config):
serialized_config = json.dumps(invoke_config)
if len(serialized_config.encode()) > MESSAGE_LIMIT:
raise ValueError(
f"message size exceeds the limit of {MESSAGE_LIMIT} bytes, please contact 1Password at [email protected] or https://developer.1password.com/joinslack if you need help.")
f"message size exceeds the limit of {MESSAGE_LIMIT} bytes, please contact 1Password at [email protected] or https://developer.1password.com/joinslack if you need help."
)
try:
return await core.invoke(serialized_config)
except Exception as e:
Expand All @@ -45,7 +46,8 @@ def _invoke_sync(invoke_config):
serialized_config = json.dumps(invoke_config)
if len(serialized_config.encode()) > MESSAGE_LIMIT:
raise ValueError(
f"message size exceeds the limit of {MESSAGE_LIMIT} bytes, please contact 1Password at [email protected] or https://developer.1password.com/joinslack if you need help.")
f"message size exceeds the limit of {MESSAGE_LIMIT} bytes, please contact 1Password at [email protected] or https://developer.1password.com/joinslack if you need help."
)
try:
return core.invoke_sync(serialized_config)
except Exception as e:
Expand Down
Binary file modified src/onepassword/lib/aarch64/libop_uniffi_core.dylib
Binary file not shown.
Binary file modified src/onepassword/lib/aarch64/libop_uniffi_core.so
Binary file not shown.
Binary file modified src/onepassword/lib/x86_64/libop_uniffi_core.dylib
Binary file not shown.
Binary file modified src/onepassword/lib/x86_64/libop_uniffi_core.so
Binary file not shown.
Binary file modified src/onepassword/lib/x86_64/op_uniffi_core.dll
Binary file not shown.
21 changes: 20 additions & 1 deletion src/onepassword/secrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .iterator import SDKIterator
from typing import Optional, List
from pydantic import TypeAdapter
from .types import GeneratePasswordResponse, PasswordRecipe
from .types import GeneratePasswordResponse, PasswordRecipe, ResolveAllResponse


class Secrets:
Expand Down Expand Up @@ -35,6 +35,25 @@ async def resolve(self, secret_reference: str) -> str:
response = TypeAdapter(str).validate_json(response)
return response

async def resolve_all(self, secret_references: List[str]) -> ResolveAllResponse:
"""
Resolve takes in a list of secret references and returns the secrets they point to or errors if any.
"""
response = await _invoke(
{
"invocation": {
"clientId": self.client_id,
"parameters": {
"name": "SecretsResolveAll",
"parameters": {"secret_references": secret_references},
},
}
}
)

response = TypeAdapter(ResolveAllResponse).validate_json(response)
return response

@staticmethod
def validate_secret_reference(secret_reference: str) -> None:
"""
Expand Down
Loading
Loading