diff --git a/src/onepassword/__init__.py b/src/onepassword/__init__.py index 040ae01..bd9be8d 100644 --- a/src/onepassword/__init__.py +++ b/src/onepassword/__init__.py @@ -1,12 +1,13 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY -from .client import Client +from .client import Client, DesktopAuth from .defaults import DEFAULT_INTEGRATION_NAME, DEFAULT_INTEGRATION_VERSION from .types import * # noqa F403 from .errors import * # noqa F403 from .secrets import Secrets from .items import Items from .vaults import Vaults +from .groups import Groups import sys @@ -18,6 +19,8 @@ "Secrets", "Items", "Vaults", + "Groups", + "DesktopAuth", "DEFAULT_INTEGRATION_NAME", "DEFAULT_INTEGRATION_VERSION", ] diff --git a/src/onepassword/client.py b/src/onepassword/client.py index ae5377f..f5d191c 100644 --- a/src/onepassword/client.py +++ b/src/onepassword/client.py @@ -2,37 +2,48 @@ from __future__ import annotations import weakref -from .core import _init_client, _release_client -from .defaults import new_default_config +from .core import UniffiCore, InnerClient +from .desktop_core import DesktopCore +from .defaults import new_default_config, DesktopAuth from .secrets import Secrets from .items import Items from .vaults import Vaults +from .groups import Groups class Client: secrets: Secrets items: Items vaults: Vaults + groups: Groups @classmethod async def authenticate( - cls, auth: str, integration_name: str, integration_version: str + cls, auth: str | DesktopAuth, integration_name: str, integration_version: str ) -> Client: config = new_default_config( - auth=auth or "", + auth=auth, integration_name=integration_name, integration_version=integration_version, ) - client_id = int(await _init_client(config)) + if isinstance(auth, DesktopAuth): + core = DesktopCore(auth.account_name) + else: + core = UniffiCore() + + client_id = int(await core.init_client(config)) + + inner_client = InnerClient(client_id, core, config) authenticated_client = cls() - authenticated_client.secrets = Secrets(client_id) - authenticated_client.items = Items(client_id) - authenticated_client.vaults = Vaults(client_id) + authenticated_client.secrets = Secrets(inner_client) + authenticated_client.items = Items(inner_client) + authenticated_client.vaults = Vaults(inner_client) + authenticated_client.groups = Groups(inner_client) authenticated_client._finalizer = weakref.finalize( - cls, _release_client, client_id + cls, core.release_client, client_id ) return authenticated_client diff --git a/src/onepassword/errors.py b/src/onepassword/errors.py index df80c3a..811aebb 100644 --- a/src/onepassword/errors.py +++ b/src/onepassword/errors.py @@ -3,6 +3,12 @@ import json +class DesktopSessionExpiredException(Exception): + def __init__(self, message): + self.message = message + super().__init__(self.message) + + class RateLimitExceededException(Exception): def __init__(self, message): self.message = message @@ -18,7 +24,9 @@ def raise_typed_exception(e: Exception): error_name = typed_error.get("name") message = typed_error.get("message") - if error_name == "RateLimitExceeded": + if error_name == "DesktopSessionExpired": + raise DesktopSessionExpiredException(message) + elif error_name == "RateLimitExceeded": raise RateLimitExceededException(message) elif message is not None: raise Exception(message) diff --git a/src/onepassword/groups.py b/src/onepassword/groups.py new file mode 100644 index 0000000..5e2c74d --- /dev/null +++ b/src/onepassword/groups.py @@ -0,0 +1,36 @@ +# Code generated by op-codegen - DO NO EDIT MANUALLY + +from .core import InnerClient +from pydantic import TypeAdapter +from .types import Group, GroupGetParams + + +class Groups: + """ + The Groups API holds all the operations the SDK client can perform on 1Password groups. + """ + + def __init__(self, inner_client: InnerClient): + self.inner_client = inner_client + + async def get(self, group_id: str, group_params: GroupGetParams) -> Group: + """ + Get a group by its ID and parameters. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "GroupsGet", + "parameters": { + "group_id": group_id, + "group_params": group_params.model_dump(by_alias=True), + }, + }, + } + } + ) + + response = TypeAdapter(Group).validate_json(response) + return response diff --git a/src/onepassword/items.py b/src/onepassword/items.py index 0093e00..7f27678 100644 --- a/src/onepassword/items.py +++ b/src/onepassword/items.py @@ -1,11 +1,19 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY -from .core import _invoke, _invoke_sync -from typing import Optional, List +from .core import InnerClient +from typing import List from pydantic import TypeAdapter from .items_shares import ItemsShares from .items_files import ItemsFiles -from .types import Item, ItemCreateParams, ItemListFilter, ItemOverview +from .types import ( + Item, + ItemCreateParams, + ItemListFilter, + ItemOverview, + ItemsDeleteAllResponse, + ItemsGetAllResponse, + ItemsUpdateAllResponse, +) class Items: @@ -13,20 +21,19 @@ class Items: The Items API holds all operations the SDK client can perform on 1Password items. """ - def __init__(self, client_id): - self.client_id = client_id - self.shares = ItemsShares(client_id) - - self.files = ItemsFiles(client_id) + def __init__(self, inner_client: InnerClient): + self.inner_client = inner_client + self.shares = ItemsShares(inner_client) + self.files = ItemsFiles(inner_client) async def create(self, params: ItemCreateParams) -> Item: """ Create a new item. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsCreate", "parameters": {"params": params.model_dump(by_alias=True)}, @@ -38,14 +45,38 @@ async def create(self, params: ItemCreateParams) -> Item: response = TypeAdapter(Item).validate_json(response) return response + async def create_all( + self, vault_id: str, params: List[ItemCreateParams] + ) -> ItemsUpdateAllResponse: + """ + Create items in batch, within a single vault. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "ItemsCreateAll", + "parameters": { + "vault_id": vault_id, + "params": [o.model_dump(by_alias=True) for o in params], + }, + }, + } + } + ) + + response = TypeAdapter(ItemsUpdateAllResponse).validate_json(response) + return response + async def get(self, vault_id: str, item_id: str) -> Item: """ - Get an item by vault and item ID + Get an item by vault and item ID. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsGet", "parameters": {"vault_id": vault_id, "item_id": item_id}, @@ -57,14 +88,33 @@ async def get(self, vault_id: str, item_id: str) -> Item: response = TypeAdapter(Item).validate_json(response) return response + async def get_all(self, vault_id: str, item_ids: List[str]) -> ItemsGetAllResponse: + """ + Get items by vault and their item IDs. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "ItemsGetAll", + "parameters": {"vault_id": vault_id, "item_ids": item_ids}, + }, + } + } + ) + + response = TypeAdapter(ItemsGetAllResponse).validate_json(response) + return response + async def put(self, item: Item) -> Item: """ Update an existing item. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsPut", "parameters": {"item": item.model_dump(by_alias=True)}, @@ -80,10 +130,10 @@ async def delete(self, vault_id: str, item_id: str) -> None: """ Delete an item. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsDelete", "parameters": {"vault_id": vault_id, "item_id": item_id}, @@ -94,14 +144,35 @@ async def delete(self, vault_id: str, item_id: str) -> None: return None + async def delete_all( + self, vault_id: str, item_ids: List[str] + ) -> ItemsDeleteAllResponse: + """ + Delete items in batch, within a single vault. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "ItemsDeleteAll", + "parameters": {"vault_id": vault_id, "item_ids": item_ids}, + }, + } + } + ) + + response = TypeAdapter(ItemsDeleteAllResponse).validate_json(response) + return response + async def archive(self, vault_id: str, item_id: str) -> None: """ Archive an item. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsArchive", "parameters": {"vault_id": vault_id, "item_id": item_id}, @@ -116,10 +187,10 @@ async def list(self, vault_id: str, *filters: ItemListFilter) -> List[ItemOvervi """ List items based on filters. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsList", "parameters": { diff --git a/src/onepassword/items_files.py b/src/onepassword/items_files.py index 28213c9..6e3d83f 100644 --- a/src/onepassword/items_files.py +++ b/src/onepassword/items_files.py @@ -1,23 +1,23 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY -from .core import _invoke, _invoke_sync -from typing import Optional, List +from .core import InnerClient +from typing import List from pydantic import TypeAdapter from .types import DocumentCreateParams, FileAttributes, FileCreateParams, Item class ItemsFiles: - def __init__(self, client_id): - self.client_id = client_id + def __init__(self, inner_client: InnerClient): + self.inner_client = inner_client async def attach(self, item: Item, file_params: FileCreateParams) -> Item: """ - Attach files to Items + Attach files to Items. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsFilesAttach", "parameters": { @@ -34,12 +34,12 @@ async def attach(self, item: Item, file_params: FileCreateParams) -> Item: async def read(self, vault_id: str, item_id: str, attr: FileAttributes) -> bytes: """ - Read file content from the Item + Read file content from the Item. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsFilesRead", "parameters": { @@ -57,12 +57,12 @@ async def read(self, vault_id: str, item_id: str, attr: FileAttributes) -> bytes async def delete(self, item: Item, section_id: str, field_id: str) -> Item: """ - Delete a field file from Item using the section and field IDs + Delete a field file from Item using the section and field IDs. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsFilesDelete", "parameters": { @@ -82,12 +82,12 @@ async def replace_document( self, item: Item, doc_params: DocumentCreateParams ) -> Item: """ - Replace the document file within a document item + Replace the document file within a document item. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsFilesReplaceDocument", "parameters": { diff --git a/src/onepassword/items_shares.py b/src/onepassword/items_shares.py index 473292d..704ad1d 100644 --- a/src/onepassword/items_shares.py +++ b/src/onepassword/items_shares.py @@ -1,14 +1,14 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY -from .core import _invoke, _invoke_sync -from typing import Optional, List +from .core import InnerClient +from typing import List from pydantic import TypeAdapter from .types import Item, ItemShareAccountPolicy, ItemShareParams, ValidRecipient class ItemsShares: - def __init__(self, client_id): - self.client_id = client_id + def __init__(self, inner_client: InnerClient): + self.inner_client = inner_client async def get_account_policy( self, vault_id: str, item_id: str @@ -16,10 +16,10 @@ async def get_account_policy( """ Get the item sharing policy of your account. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsSharesGetAccountPolicy", "parameters": {"vault_id": vault_id, "item_id": item_id}, @@ -37,10 +37,10 @@ async def validate_recipients( """ Validate the recipients of an item sharing link. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsSharesValidateRecipients", "parameters": { @@ -61,10 +61,10 @@ async def create( """ Create a new item sharing link. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "ItemsSharesCreate", "parameters": { diff --git a/src/onepassword/lib/aarch64/libop_uniffi_core.dylib b/src/onepassword/lib/aarch64/libop_uniffi_core.dylib index 12f9ff7..1bd9aeb 100755 Binary files a/src/onepassword/lib/aarch64/libop_uniffi_core.dylib and b/src/onepassword/lib/aarch64/libop_uniffi_core.dylib differ diff --git a/src/onepassword/lib/aarch64/libop_uniffi_core.so b/src/onepassword/lib/aarch64/libop_uniffi_core.so deleted file mode 100755 index 364acb4..0000000 Binary files a/src/onepassword/lib/aarch64/libop_uniffi_core.so and /dev/null differ diff --git a/src/onepassword/lib/x86_64/libop_uniffi_core.dylib b/src/onepassword/lib/x86_64/libop_uniffi_core.dylib index 7246f08..dcd27d1 100755 Binary files a/src/onepassword/lib/x86_64/libop_uniffi_core.dylib and b/src/onepassword/lib/x86_64/libop_uniffi_core.dylib differ diff --git a/src/onepassword/lib/x86_64/libop_uniffi_core.so b/src/onepassword/lib/x86_64/libop_uniffi_core.so deleted file mode 100755 index 6c6f900..0000000 Binary files a/src/onepassword/lib/x86_64/libop_uniffi_core.so and /dev/null differ diff --git a/src/onepassword/lib/x86_64/op_uniffi_core.dll b/src/onepassword/lib/x86_64/op_uniffi_core.dll deleted file mode 100644 index 00847b2..0000000 Binary files a/src/onepassword/lib/x86_64/op_uniffi_core.dll and /dev/null differ diff --git a/src/onepassword/secrets.py b/src/onepassword/secrets.py index bdfc109..014533f 100644 --- a/src/onepassword/secrets.py +++ b/src/onepassword/secrets.py @@ -1,7 +1,7 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY -from .core import _invoke, _invoke_sync -from typing import Optional, List +from .core import InnerClient, UniffiCore +from typing import List from pydantic import TypeAdapter from .types import GeneratePasswordResponse, PasswordRecipe, ResolveAllResponse @@ -12,17 +12,17 @@ class Secrets: Use secret reference URIs to securely load secrets from 1Password: `op:///[/]/` """ - def __init__(self, client_id): - self.client_id = client_id + def __init__(self, inner_client: InnerClient): + self.inner_client = inner_client async def resolve(self, secret_reference: str) -> str: """ Resolve returns the secret the provided secret reference points to. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "SecretsResolve", "parameters": {"secret_reference": secret_reference}, @@ -38,10 +38,10 @@ 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( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, + "clientId": self.inner_client.client_id, "parameters": { "name": "SecretsResolveAll", "parameters": {"secret_references": secret_references}, @@ -58,7 +58,7 @@ def validate_secret_reference(secret_reference: str) -> None: """ Validate the secret reference to ensure there are no syntax errors. """ - response = _invoke_sync( + response = UniffiCore().invoke_sync( { "invocation": { "parameters": { @@ -73,7 +73,10 @@ def validate_secret_reference(secret_reference: str) -> None: @staticmethod def generate_password(recipe: PasswordRecipe) -> GeneratePasswordResponse: - response = _invoke_sync( + """ + Generate a password using the provided recipe. + """ + response = UniffiCore().invoke_sync( { "invocation": { "parameters": { diff --git a/src/onepassword/types.py b/src/onepassword/types.py index d640b9c..d5eb46e 100644 --- a/src/onepassword/types.py +++ b/src/onepassword/types.py @@ -140,6 +140,153 @@ class GeneratePasswordResponse(BaseModel): """ +class GroupType(str, Enum): + OWNERS = "owners" + """ + The owners group, which gives the following permissions: + - Do everything the Admin group can do + - See every vault other than the personal vaults + - Change people's names + - See billing + - Change billing + - Make other people owners + - Delete a person + """ + ADMINISTRATORS = "administrators" + """ + The administrators group, which gives the following permissions: + - Perform recovery + - Create new vaults + - Invite new members + - See vault metadata, including the vault name and who has access. + - Make other people admins + """ + RECOVERY = "recovery" + """ + The recovery group. It contains recovery keysets, and is added to every vault to allow for recovery. + + No one is added to this. + """ + EXTERNALACCOUNTMANAGERS = "externalAccountManagers" + """ + The external account managers group or EAM is a mandatory group for managed accounts that has + same permissions as the owners. + """ + TEAMMEMBERS = "teamMembers" + """ + Members of a team that a user is on. + """ + USERDEFINED = "userDefined" + """ + A custom, user defined group. + """ + UNSUPPORTED = "unsupported" + """ + Support for new or renamed group types + """ + + +class GroupState(str, Enum): + ACTIVE = "active" + """ + This group is active + """ + DELETED = "deleted" + """ + This group has been deleted + """ + UNSUPPORTED = "unsupported" + """ + This group is in an unknown state + """ + + +class VaultAccessorType(str, Enum): + USER = "user" + GROUP = "group" + + +class VaultAccess(BaseModel): + """ + Represents the vault access information. + """ + + model_config = ConfigDict(populate_by_name=True) + + vault_uuid: str = Field(alias="vaultUuid") + """ + The vault's UUID. + """ + accessor_type: VaultAccessorType = Field(alias="accessorType") + """ + The vault's accessor type. + """ + accessor_uuid: str = Field(alias="accessorUuid") + """ + The vault's accessor UUID. + """ + permissions: int + """ + The permissions granted to this vault + """ + + +class Group(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + id: str + title: str + description: str + group_type: GroupType = Field(alias="groupType") + state: GroupState + vault_access: Optional[List[VaultAccess]] = Field(alias="vaultAccess", default=None) + + +class GroupAccess(BaseModel): + """ + Represents a group's access to a 1Password vault. + This is used for granting permissions + """ + + model_config = ConfigDict(populate_by_name=True) + + group_id: str = Field(alias="groupId") + """ + The group's ID + """ + permissions: int + """ + The group's set of permissions for the vault + """ + + +class GroupGetParams(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + vault_permissions: Optional[bool] = Field(alias="vaultPermissions", default=None) + + +class GroupVaultAccess(BaseModel): + """ + Represents a group's access to a 1Password vault. + """ + + model_config = ConfigDict(populate_by_name=True) + + vault_id: str = Field(alias="vaultId") + """ + The vault's ID + """ + group_id: str = Field(alias="groupId") + """ + The group's ID + """ + permissions: int + """ + The group's set of permissions for the vault + """ + + class ItemCategory(str, Enum): LOGIN = "Login" SECURENOTE = "SecureNote" @@ -717,6 +864,147 @@ class ItemShareParams(BaseModel): """ +class Response(BaseModel, Generic[T, E]): + content: Optional[T] = Field(default=None) + error: Optional[E] = Field(default=None) + + +class ItemUpdateFailureReasonTypes(str, Enum): + ITEM_VALIDATION_ERROR = "itemValidationError" + ITEM_STATUS_PERMISSION_ERROR = "itemStatusPermissionError" + ITEM_STATUS_INCORRECT_ITEM_VERSION = "itemStatusIncorrectItemVersion" + ITEM_STATUS_FILE_NOT_FOUND = "itemStatusFileNotFound" + ITEM_STATUS_TOO_BIG = "itemStatusTooBig" + ITEM_NOT_FOUND = "itemNotFound" + INTERNAL = "internal" + + +class ItemUpdateFailureReasonItemValidationError(BaseModel): + """ + Item update operation failed due to bad user input. + """ + + type: Literal[ItemUpdateFailureReasonTypes.ITEM_VALIDATION_ERROR] = ( + ItemUpdateFailureReasonTypes.ITEM_VALIDATION_ERROR + ) + message: ErrorMessage + + +class ItemUpdateFailureReasonItemStatusPermissionError(BaseModel): + """ + Item update operation is forbidden, permission issue. Make sure you have the correct permissions to update items in this vault. + """ + + type: Literal[ItemUpdateFailureReasonTypes.ITEM_STATUS_PERMISSION_ERROR] = ( + ItemUpdateFailureReasonTypes.ITEM_STATUS_PERMISSION_ERROR + ) + + +class ItemUpdateFailureReasonItemStatusIncorrectItemVersion(BaseModel): + """ + Item update operation failed due to incorrect version. + """ + + type: Literal[ItemUpdateFailureReasonTypes.ITEM_STATUS_INCORRECT_ITEM_VERSION] = ( + ItemUpdateFailureReasonTypes.ITEM_STATUS_INCORRECT_ITEM_VERSION + ) + + +class ItemUpdateFailureReasonItemStatusFileNotFound(BaseModel): + """ + Item update operation failed because a file reference didn't match a known file. + """ + + type: Literal[ItemUpdateFailureReasonTypes.ITEM_STATUS_FILE_NOT_FOUND] = ( + ItemUpdateFailureReasonTypes.ITEM_STATUS_FILE_NOT_FOUND + ) + + +class ItemUpdateFailureReasonItemStatusTooBig(BaseModel): + """ + Item update request is too big to be sent to the server. + """ + + type: Literal[ItemUpdateFailureReasonTypes.ITEM_STATUS_TOO_BIG] = ( + ItemUpdateFailureReasonTypes.ITEM_STATUS_TOO_BIG + ) + + +class ItemUpdateFailureReasonItemNotFound(BaseModel): + """ + The item was not found + """ + + type: Literal[ItemUpdateFailureReasonTypes.ITEM_NOT_FOUND] = ( + ItemUpdateFailureReasonTypes.ITEM_NOT_FOUND + ) + + +class ItemUpdateFailureReasonInternal(BaseModel): + """ + Item update operation experienced an internal error. + """ + + type: Literal[ItemUpdateFailureReasonTypes.INTERNAL] = ( + ItemUpdateFailureReasonTypes.INTERNAL + ) + message: ErrorMessage + + +ItemUpdateFailureReason = Union[ + ItemUpdateFailureReasonItemValidationError, + ItemUpdateFailureReasonItemStatusPermissionError, + ItemUpdateFailureReasonItemStatusIncorrectItemVersion, + ItemUpdateFailureReasonItemStatusFileNotFound, + ItemUpdateFailureReasonItemStatusTooBig, + ItemUpdateFailureReasonItemNotFound, + ItemUpdateFailureReasonInternal, +] + + +class ItemsDeleteAllResponse(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + individual_responses: Dict[str, Response[None, ItemUpdateFailureReason]] = Field( + alias="individualResponses" + ) + + +class ItemsGetAllErrorTypes(str, Enum): + ITEM_NOT_FOUND = "itemNotFound" + INTERNAL = "internal" + + +class ItemsGetAllErrorItemNotFound(BaseModel): + type: Literal[ItemsGetAllErrorTypes.ITEM_NOT_FOUND] = ( + ItemsGetAllErrorTypes.ITEM_NOT_FOUND + ) + + +class ItemsGetAllErrorInternal(BaseModel): + type: Literal[ItemsGetAllErrorTypes.INTERNAL] = ItemsGetAllErrorTypes.INTERNAL + message: ErrorMessage + + +ItemsGetAllError = Union[ItemsGetAllErrorItemNotFound, ItemsGetAllErrorInternal] + + +class ItemsGetAllResponse(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + individual_responses: List[Response[Item, ItemsGetAllError]] = Field( + alias="individualResponses" + ) + + +class ItemsUpdateAllResponse(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + individual_responses: List[Response[Item, ItemUpdateFailureReason]] = Field( + alias="individualResponses" + ) + + class OtpFieldDetails(BaseModel): """ Additional attributes for OTP fields. @@ -734,11 +1022,6 @@ class OtpFieldDetails(BaseModel): """ -class Response(BaseModel, Generic[T, E]): - content: Optional[T] = Field(default=None) - error: Optional[E] = Field(default=None) - - class ResolvedReference(BaseModel): model_config = ConfigDict(populate_by_name=True) @@ -971,20 +1254,118 @@ class SshKeyAttributes(BaseModel): """ +class VaultType(str, Enum): + """ + Represents the vault type. + """ + + PERSONAL = "personal" + EVERYONE = "everyone" + TRANSFER = "transfer" + USERCREATED = "userCreated" + UNSUPPORTED = "unsupported" + + +class Vault(BaseModel): + """ + Represents regular vault information together with the vault's access information. + """ + + model_config = ConfigDict(populate_by_name=True) + + id: str + """ + The vault's ID. + """ + title: str + """ + The vault's title. + """ + description: str + """ + The description of the vault. + """ + vault_type: VaultType = Field(alias="vaultType") + """ + The type of the vault. + """ + active_item_count: int = Field(alias="activeItemCount") + """ + The number of active items within the vault. + """ + content_version: int = Field(alias="contentVersion") + """ + The content version number of the vault. It gets incremented whenever the state of the vault's contents changes (e.g. items from within the vault get created or updated). + """ + attribute_version: int = Field(alias="attributeVersion") + """ + The attribute version number of the vault. It gets incremented whenever vault presentation information changes, such as its name or icon. + """ + access: Optional[List[VaultAccess]] = Field(default=None) + """ + The access information associated with the vault. + """ + + +class VaultCreateParams(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + title: str + description: Optional[str] = Field(default=None) + allow_admins_access: Optional[bool] = Field(alias="allowAdminsAccess", default=None) + + +class VaultGetParams(BaseModel): + """ + Represents the possible query parameters used for retrieving extra information about a vault. + """ + + accessors: Optional[bool] = Field(default=None) + """ + The vault's accessor params. + """ + + +class VaultListParams(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + decrypt_details: Optional[bool] = Field(alias="decryptDetails", default=None) + + class VaultOverview(BaseModel): """ - Represents a decrypted 1Password vault. + Holds information about a 1Password Vault. """ model_config = ConfigDict(populate_by_name=True) id: str """ - The vault's ID + The vault's ID. """ title: str """ - The vault's title + The vault's title. + """ + description: str + """ + The description of this vault. + """ + vault_type: VaultType = Field(alias="vaultType") + """ + The type of the vault. + """ + active_item_count: int = Field(alias="activeItemCount") + """ + The number of active items within the vault. + """ + content_version: int = Field(alias="contentVersion") + """ + The content version number of the vault. It gets incremented whenever the state of the vault's contents changes (e.g. items from within the vault get created or updated). + """ + attribute_version: int = Field(alias="attributeVersion") + """ + The attribute version number of the vault. It gets incremented whenever vault presentation information changes, such as its name or icon. """ created_at: Annotated[ datetime, @@ -1004,6 +1385,11 @@ class VaultOverview(BaseModel): """ +class VaultUpdateParams(BaseModel): + title: Optional[str] = Field(default=None) + description: Optional[str] = Field(default=None) + + class ItemListFilterByStateInner(BaseModel): """ Generated type representing the anonymous struct variant `ByState` of the `ItemListFilter` Rust enum @@ -1159,3 +1545,19 @@ class WordListType(str, Enum): """ Three (random) letter "words" """ + + +ARCHIVE_ITEMS: int = 256 +CREATE_ITEMS: int = 128 +DELETE_ITEMS: int = 512 +EXPORT_ITEMS: int = 4194304 +IMPORT_ITEMS: int = 2097152 +MANAGE_VAULT: int = 2 +NO_ACCESS: int = 0 +PRINT_ITEMS: int = 8388608 +READ_ITEMS: int = 32 +RECOVER_VAULT: int = 1 +REVEAL_ITEM_PASSWORD: int = 16 +SEND_ITEMS: int = 1048576 +UPDATE_ITEMS: int = 64 +UPDATE_ITEM_HISTORY: int = 1024 diff --git a/src/onepassword/vaults.py b/src/onepassword/vaults.py index 2b066d5..402bbc7 100644 --- a/src/onepassword/vaults.py +++ b/src/onepassword/vaults.py @@ -1,9 +1,18 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY -from .core import _invoke, _invoke_sync -from typing import Optional, List +from .core import InnerClient +from typing import List, Optional from pydantic import TypeAdapter -from .types import VaultOverview +from .types import ( + GroupAccess, + GroupVaultAccess, + Vault, + VaultCreateParams, + VaultGetParams, + VaultListParams, + VaultOverview, + VaultUpdateParams, +) class Vaults: @@ -11,21 +20,199 @@ class Vaults: The Vaults API holds all the operations the SDK client can perform on 1Password vaults. """ - def __init__(self, client_id): - self.client_id = client_id + def __init__(self, inner_client: InnerClient): + self.inner_client = inner_client - async def list(self) -> List[VaultOverview]: + async def create(self, params: VaultCreateParams) -> Vault: """ - List all vaults + Create a new user vault. """ - response = await _invoke( + response = await self.inner_client.invoke( { "invocation": { - "clientId": self.client_id, - "parameters": {"name": "VaultsList", "parameters": {}}, + "clientId": self.inner_client.client_id, + "parameters": { + "name": "VaultsCreate", + "parameters": {"params": params.model_dump(by_alias=True)}, + }, + } + } + ) + + response = TypeAdapter(Vault).validate_json(response) + return response + + async def list( + self, params: Optional[VaultListParams] = None + ) -> List[VaultOverview]: + """ + List information about vaults that's configurable based on some input parameters. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "VaultsList", + "parameters": { + "params": ( + params.model_dump(by_alias=True) if params else None + ) + }, + }, } } ) response = TypeAdapter(List[VaultOverview]).validate_json(response) return response + + async def get_overview(self, vault_id: str) -> VaultOverview: + """ + Get an overview of a vault by its ID. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "VaultsGetOverview", + "parameters": {"vault_id": vault_id}, + }, + } + } + ) + + response = TypeAdapter(VaultOverview).validate_json(response) + return response + + async def get(self, vault_id: str, vault_params: VaultGetParams) -> Vault: + """ + Get detailed vault information by vault ID and parameters. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "VaultsGet", + "parameters": { + "vault_id": vault_id, + "vault_params": vault_params.model_dump(by_alias=True), + }, + }, + } + } + ) + + response = TypeAdapter(Vault).validate_json(response) + return response + + async def update(self, vault_id: str, params: VaultUpdateParams) -> Vault: + """ + Update a vault + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "VaultsUpdate", + "parameters": { + "vault_id": vault_id, + "params": params.model_dump(by_alias=True), + }, + }, + } + } + ) + + response = TypeAdapter(Vault).validate_json(response) + return response + + async def delete(self, vault_id: str) -> None: + """ + Delete a vault by its ID. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "VaultsDelete", + "parameters": {"vault_id": vault_id}, + }, + } + } + ) + + return None + + async def grant_group_permissions( + self, vault_id: str, group_permissions_list: List[GroupAccess] + ) -> None: + """ + Grant group permissions to a vault. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "VaultsGrantGroupPermissions", + "parameters": { + "vault_id": vault_id, + "group_permissions_list": [ + o.model_dump(by_alias=True) + for o in group_permissions_list + ], + }, + }, + } + } + ) + + return None + + async def update_group_permissions( + self, group_permissions_list: List[GroupVaultAccess] + ) -> None: + """ + Update group permissions for vaults. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "VaultsUpdateGroupPermissions", + "parameters": { + "group_permissions_list": [ + o.model_dump(by_alias=True) + for o in group_permissions_list + ] + }, + }, + } + } + ) + + return None + + async def revoke_group_permissions(self, vault_id: str, group_id: str) -> None: + """ + Revoke group permissions from a vault. + """ + response = await self.inner_client.invoke( + { + "invocation": { + "clientId": self.inner_client.client_id, + "parameters": { + "name": "VaultsRevokeGroupPermissions", + "parameters": {"vault_id": vault_id, "group_id": group_id}, + }, + } + } + ) + + return None