From 9d67fd0fb44790f90b4b67316e188ec30c52af32 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 13 Nov 2023 12:05:08 -0800 Subject: [PATCH 001/108] correct case-sensitive package name --- languages/python/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/python/setup.py b/languages/python/setup.py index 7976ebcba..b600dd84b 100644 --- a/languages/python/setup.py +++ b/languages/python/setup.py @@ -7,6 +7,6 @@ version="0.1", rust_extensions=[RustExtension( "bitwarden_py", path="../../crates/bitwarden-py/Cargo.toml", binding=Binding.PyO3)], - packages=['bitwardenclient'], + packages=['BitwardenClient'], zip_safe=False, ) From fae55d4f8786b759dede14c6ae62bb53e5adbdcc Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 13 Nov 2023 12:27:24 -0800 Subject: [PATCH 002/108] init python workflow --- .github/workflows/build-python-wheels.yml | 105 ++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 .github/workflows/build-python-wheels.yml diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml new file mode 100644 index 000000000..c6a452492 --- /dev/null +++ b/.github/workflows/build-python-wheels.yml @@ -0,0 +1,105 @@ +--- +name: Build Python Wheels + +on: + pull_request: + push: + # branches: + # - "master" + # - "rc" + # - "hotfix-rc" + workflow_dispatch: + +defaults: + run: + shell: bash + working-directory: languages/python + +jobs: + generate_schemas: + uses: ./.github/workflows/generate_schemas.yml + + setup: + name: Setup + runs-on: ubuntu-22.04 + outputs: + package_version: ${{ steps.retrieve-version.outputs.package_version }} + steps: + - name: Checkout repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Get Package Version + id: retrieve-version + run: | + VERSION="$(grep -o '^version = ".*"' ../../crates/bitwarden-py/Cargo.toml | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+")" + echo "package_version=$VERSION" >> $GITHUB_OUTPUT + + build: + name: Building Python wheel for - ${{ matrix.settings.os }} - ${{ matrix.settings.target }} + runs-on: ${{ matrix.settings.os || 'ubuntu-latest' }} + needs: + - generate_schemas + - setup + env: + _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + strategy: + fail-fast: false + matrix: + settings: + - os: macos-12 + target: x86_64-apple-darwin + + - os: macos-12 + target: aarch64-apple-darwin + + - os: windows-2022 + target: x86_64-pc-windows-msvc + + - os: windows-2022 + target: aarch64-pc-windows-msvc + + - os: ubuntu-22.04 + target: x86_64-unknown-linux-gnu + + - os: ubuntu-22.04 + target: aarch64-unknown-linux-gnu + steps: + - name: Checkout repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Setup Node + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0 + with: + node-version: 18 + + - name: Install rust + uses: dtolnay/rust-toolchain@439cf607258077187679211f12aa6f19af4a0af7 # stable + with: + toolchain: stable + targets: ${{ matrix.settings.target }} + + - name: Cache cargo registry + uses: Swatinem/rust-cache@3cf7f8cc28d1b4e7d01e3783be10a97d55d483c8 # v2.7.1 + with: + key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.os }} + + - name: Retrieve schemas + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: schemas.py + path: ${{ github.workspace }}/languages/python/BitwardenClient/schemas.py + + - name: Build + env: + TARGET: ${{ matrix.settings.target }} + run: | + python -m pip install setuptools setuptools_rust dateutils wheel + python ./setup.py develop + mv bitwarden_py*.so bitwarden_py.so + python ./setup.py sdist bdist_wheel --universal + + - name: Upload artifact + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + with: + name: BitwardenClient-$_PACKAGE_VERSION-${{ matrix.settings.target }} + path: ${{ github.workspace }}/languages/python/dist/BitwardenClient-*.whl From 887477eb912cac8ce66a3f5f490e402cc9e96ccf Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:34:20 -0800 Subject: [PATCH 003/108] replace deprecated setup script with pyproject --- languages/python/pyproject.toml | 24 ++++++++++++++++++++++++ languages/python/setup.py | 12 ------------ 2 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 languages/python/pyproject.toml delete mode 100644 languages/python/setup.py diff --git a/languages/python/pyproject.toml b/languages/python/pyproject.toml new file mode 100644 index 000000000..4f42118e3 --- /dev/null +++ b/languages/python/pyproject.toml @@ -0,0 +1,24 @@ +[build-system] +build-backend = "maturin" +requires = ["maturin>=1.0,<2.0", "setuptools_rust>=1.8.1"] + +[project] +authors = [{ name = "Bitwarden", email = "support@bitwarden.com" }] +classifiers = [ + # TODO: See https://pypi.org/classifiers/ +] +dependencies = ["dateutils >= 0.6.6"] +description = "A Bitwarden Client for python" +name = "bitwarden_sdk" +readme = "README.md" +requires-python = ">=2.7" +version = "0.1" + +[tool.maturin] +bindings = "pyo3" +compatibility = "manylinux2014" +include = [ + { path = "BitwardenClient/*.py", format = ["sdist", "wheel"] } +] +manifest-path = "../../crates/bitwarden-py/Cargo.toml" +python-packages = ["BitwardenClient"] diff --git a/languages/python/setup.py b/languages/python/setup.py deleted file mode 100644 index b600dd84b..000000000 --- a/languages/python/setup.py +++ /dev/null @@ -1,12 +0,0 @@ -from setuptools import setup -from setuptools_rust import Binding, RustExtension - -setup( - name="BitwardenClient", - description="A Bitwarden Client for python", - version="0.1", - rust_extensions=[RustExtension( - "bitwarden_py", path="../../crates/bitwarden-py/Cargo.toml", binding=Binding.PyO3)], - packages=['BitwardenClient'], - zip_safe=False, -) From fa70c285d902fb459db522a9014d03a317db78b2 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:34:39 -0800 Subject: [PATCH 004/108] add module init --- languages/python/BitwardenClient/__init__.py | 171 +++++++++++++++++++ 1 file changed, 171 insertions(+) diff --git a/languages/python/BitwardenClient/__init__.py b/languages/python/BitwardenClient/__init__.py index e69de29bb..335490f4a 100644 --- a/languages/python/BitwardenClient/__init__.py +++ b/languages/python/BitwardenClient/__init__.py @@ -0,0 +1,171 @@ +"""The official Bitwarden client library for Python.""" + +__version__ = "0.1.0" + +from .bitwarden_client import BitwardenClient, SecretsClient +from .schemas import ( + DeviceType, + ClientSettings, + AccessTokenLoginRequest, + APIKeyLoginRequest, + FingerprintRequest, + SecretVerificationRequest, + PurpleArgon2ID, + PurplePBKDF2, + PasswordLoginKdf, + TwoFactorProvider, + TwoFactorRequest, + PasswordLoginRequest, + ProjectCreateRequest, + ProjectsDeleteRequest, + ProjectGetRequest, + ProjectsListRequest, + ProjectPutRequest, + ProjectsCommand, + SecretCreateRequest, + SecretsDeleteRequest, + SecretGetRequest, + SecretsGetRequest, + SecretIdentifiersRequest, + SecretPutRequest, + SecretsCommand, + SyncRequest, + Command, + Attachment, + Card, + LinkedIDType, + FieldType, + Field, + Identity, + LocalData, + URIMatchType, + LoginURI, + Login, + PasswordHistory, + CipherRepromptType, + SecureNoteType, + SecureNote, + CipherType, + Cipher, + AttachmentView, + CardView, + FieldView, + IdentityView, + LocalDataView, + LoginURIView, + LoginView, + PasswordHistoryView, + SecureNoteView, + CipherView, + Collection, + EncryptedJSON, + ExportFormatClass, + ExportFormatEnum, + Folder, + FolderView, + FluffyArgon2ID, + FluffyPBKDF2, + InitCryptoRequestKdf, + InitCryptoRequest, + MasterPasswordPolicyOptions, + PassphraseGeneratorRequest, + PasswordGeneratorRequest, + SendFile, + SendText, + SendType, + Send, + SendListView, + SendFileView, + SendTextView, + SendView, + TotpResponse, + DocRef, + PurpleAuthenticator, + PurpleDuo, + PurpleEmail, + PurpleRemember, + PurpleWebAuthn, + PurpleYubiKey, + AccessTokenLoginResponseTwoFactorProviders, + AccessTokenLoginResponse, + ResponseForAccessTokenLoginResponse, + FluffyAuthenticator, + FluffyDuo, + FluffyEmail, + FluffyRemember, + FluffyWebAuthn, + FluffyYubiKey, + APIKeyLoginResponseTwoFactorProviders, + APIKeyLoginResponse, + ResponseForAPIKeyLoginResponse, + FingerprintResponse, + ResponseForFingerprintResponse, + CAPTCHAResponse, + TentacledAuthenticator, + TentacledDuo, + TentacledEmail, + TentacledRemember, + TentacledWebAuthn, + TentacledYubiKey, + PasswordLoginResponseTwoFactorProviders, + PasswordLoginResponse, + ResponseForPasswordLoginResponse, + ProjectResponse, + ResponseForProjectResponse, + ProjectDeleteResponse, + ProjectsDeleteResponse, + ResponseForProjectsDeleteResponse, + DatumElement, + ProjectsResponse, + ResponseForProjectsResponse, + SecretIdentifierResponse, + SecretIdentifiersResponse, + ResponseForSecretIdentifiersResponse, + SecretResponse, + ResponseForSecretResponse, + SecretDeleteResponse, + SecretsDeleteResponse, + ResponseForSecretsDeleteResponse, + DatumClass, + SecretsResponse, + ResponseForSecretsResponse, + CipherDetailsResponse, + ProfileOrganizationResponse, + ProfileResponse, + SyncResponse, + ResponseForSyncResponse, + UserAPIKeyResponse, + ResponseForUserAPIKeyResponse, + client_settings_from_dict, + client_settings_to_dict, + command_from_dict, + command_to_dict, + doc_ref_from_dict, + doc_ref_to_dict, + response_for_access_token_login_response_from_dict, + response_for_access_token_login_response_to_dict, + response_for_api_key_login_response_from_dict, + response_for_api_key_login_response_to_dict, + response_for_fingerprint_response_from_dict, + response_for_fingerprint_response_to_dict, + response_for_password_login_response_from_dict, + response_for_password_login_response_to_dict, + response_for_project_response_from_dict, + response_for_project_response_to_dict, + response_for_projects_delete_response_from_dict, + response_for_projects_delete_response_to_dict, + response_for_projects_response_from_dict, + response_for_projects_response_to_dict, + response_for_secret_identifiers_response_from_dict, + response_for_secret_identifiers_response_to_dict, + response_for_secret_response_from_dict, + response_for_secret_response_to_dict, + response_for_secrets_delete_response_from_dict, + response_for_secrets_delete_response_to_dict, + response_for_secrets_response_from_dict, + response_for_secrets_response_to_dict, + response_for_sync_response_from_dict, + response_for_sync_response_to_dict, + response_for_user_api_key_response_from_dict, + response_for_user_api_key_response_to_dict, +) From 02d1db0e31d670467c9982e25fe7ff39559283b9 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:43:10 -0800 Subject: [PATCH 005/108] fix package name --- languages/python/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/python/pyproject.toml b/languages/python/pyproject.toml index 4f42118e3..9360fb199 100644 --- a/languages/python/pyproject.toml +++ b/languages/python/pyproject.toml @@ -9,7 +9,7 @@ classifiers = [ ] dependencies = ["dateutils >= 0.6.6"] description = "A Bitwarden Client for python" -name = "bitwarden_sdk" +name = "BitwardenClient" readme = "README.md" requires-python = ">=2.7" version = "0.1" From 7d7d5dba0bb4fa6c489eaf5c0ced859d0940621b Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:43:14 -0800 Subject: [PATCH 006/108] use maturin for builds --- .github/workflows/build-python-wheels.yml | 25 +++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index c6a452492..adf87a3ac 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -4,10 +4,10 @@ name: Build Python Wheels on: pull_request: push: - # branches: - # - "master" - # - "rc" - # - "hotfix-rc" + branches: + - "master" + - "rc" + - "hotfix-rc" workflow_dispatch: defaults: @@ -89,17 +89,16 @@ jobs: name: schemas.py path: ${{ github.workspace }}/languages/python/BitwardenClient/schemas.py - - name: Build - env: - TARGET: ${{ matrix.settings.target }} - run: | - python -m pip install setuptools setuptools_rust dateutils wheel - python ./setup.py develop - mv bitwarden_py*.so bitwarden_py.so - python ./setup.py sdist bdist_wheel --universal + - name: Build wheels + uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 + with: + target: ${{ matrix.settings.target }} + args: --release --out dist --find-interpreter + sccache: 'true' + manylinux: auto - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: name: BitwardenClient-$_PACKAGE_VERSION-${{ matrix.settings.target }} - path: ${{ github.workspace }}/languages/python/dist/BitwardenClient-*.whl + path: ${{ github.workspace }}/target/wheels/BitwardenClient*.whl From 12de7b6b80e1a6d604ada4cef0d9954a81df21b8 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:48:08 -0800 Subject: [PATCH 007/108] add push trigger for easier testing --- .github/workflows/build-python-wheels.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index adf87a3ac..516bcb4d0 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -8,6 +8,7 @@ on: - "master" - "rc" - "hotfix-rc" + - "SM-989-create-build-and-publish-pipelines-for-the-python-language-wrapper" # TODO: remove this workflow_dispatch: defaults: From f448028b8a2afbb965a6b111ca448556a9914fd7 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:57:20 -0800 Subject: [PATCH 008/108] set working dir --- .github/workflows/build-python-wheels.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 516bcb4d0..023242064 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -94,9 +94,10 @@ jobs: uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: target: ${{ matrix.settings.target }} - args: --release --out dist --find-interpreter + args: --release --find-interpreter sccache: 'true' manylinux: auto + working-directory: ${{ github.workspace }}/languages/python - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From f16ebe80a912e5193ec61917847da51af3385774 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 14:43:30 -0800 Subject: [PATCH 009/108] troubleshoot schemas --- .github/workflows/build-python-wheels.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 023242064..fca085d21 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -90,14 +90,20 @@ jobs: name: schemas.py path: ${{ github.workspace }}/languages/python/BitwardenClient/schemas.py + - name: Ensure schemas # TODO: remove this + run: | + ls -hal ${{ github.workspace }}/languages/python/BitwardenClient/ + cat ${{ github.workspace }}/languages/python/BitwardenClient/schemas.py || exit 1 + - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: target: ${{ matrix.settings.target }} - args: --release --find-interpreter + args: --release --find-interpreter --sdist sccache: 'true' manylinux: auto working-directory: ${{ github.workspace }}/languages/python + # before-script-linux: | - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 5e5d32f64d18deb95a296f1905439db34726b282 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 14:50:18 -0800 Subject: [PATCH 010/108] fix schemas being a dir? --- .github/workflows/build-python-wheels.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index fca085d21..c8bc58adc 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -88,12 +88,12 @@ jobs: uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: schemas.py - path: ${{ github.workspace }}/languages/python/BitwardenClient/schemas.py + path: ${{ github.workspace }}/languages/python/BitwardenClient/ - name: Ensure schemas # TODO: remove this run: | - ls -hal ${{ github.workspace }}/languages/python/BitwardenClient/ - cat ${{ github.workspace }}/languages/python/BitwardenClient/schemas.py || exit 1 + cat ${{ github.workspace }}/languages/python/BitwardenClient/schemas.py + exit 1 - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 @@ -108,5 +108,5 @@ jobs: - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: - name: BitwardenClient-$_PACKAGE_VERSION-${{ matrix.settings.target }} + name: BitwardenClient-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} path: ${{ github.workspace }}/target/wheels/BitwardenClient*.whl From 5ce0c56c461e7db3c8398725556bced850e8ca7e Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 14:52:49 -0800 Subject: [PATCH 011/108] rm schema troubleshooting --- .github/workflows/build-python-wheels.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index c8bc58adc..68e7882ed 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -90,11 +90,6 @@ jobs: name: schemas.py path: ${{ github.workspace }}/languages/python/BitwardenClient/ - - name: Ensure schemas # TODO: remove this - run: | - cat ${{ github.workspace }}/languages/python/BitwardenClient/schemas.py - exit 1 - - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: From 57fb86a57f8bcdd44d452a6ed149f14769b06a3f Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 15:12:47 -0800 Subject: [PATCH 012/108] simpler init --- languages/python/BitwardenClient/__init__.py | 176 +------------------ 1 file changed, 9 insertions(+), 167 deletions(-) diff --git a/languages/python/BitwardenClient/__init__.py b/languages/python/BitwardenClient/__init__.py index 335490f4a..b2aeffea1 100644 --- a/languages/python/BitwardenClient/__init__.py +++ b/languages/python/BitwardenClient/__init__.py @@ -2,170 +2,12 @@ __version__ = "0.1.0" -from .bitwarden_client import BitwardenClient, SecretsClient -from .schemas import ( - DeviceType, - ClientSettings, - AccessTokenLoginRequest, - APIKeyLoginRequest, - FingerprintRequest, - SecretVerificationRequest, - PurpleArgon2ID, - PurplePBKDF2, - PasswordLoginKdf, - TwoFactorProvider, - TwoFactorRequest, - PasswordLoginRequest, - ProjectCreateRequest, - ProjectsDeleteRequest, - ProjectGetRequest, - ProjectsListRequest, - ProjectPutRequest, - ProjectsCommand, - SecretCreateRequest, - SecretsDeleteRequest, - SecretGetRequest, - SecretsGetRequest, - SecretIdentifiersRequest, - SecretPutRequest, - SecretsCommand, - SyncRequest, - Command, - Attachment, - Card, - LinkedIDType, - FieldType, - Field, - Identity, - LocalData, - URIMatchType, - LoginURI, - Login, - PasswordHistory, - CipherRepromptType, - SecureNoteType, - SecureNote, - CipherType, - Cipher, - AttachmentView, - CardView, - FieldView, - IdentityView, - LocalDataView, - LoginURIView, - LoginView, - PasswordHistoryView, - SecureNoteView, - CipherView, - Collection, - EncryptedJSON, - ExportFormatClass, - ExportFormatEnum, - Folder, - FolderView, - FluffyArgon2ID, - FluffyPBKDF2, - InitCryptoRequestKdf, - InitCryptoRequest, - MasterPasswordPolicyOptions, - PassphraseGeneratorRequest, - PasswordGeneratorRequest, - SendFile, - SendText, - SendType, - Send, - SendListView, - SendFileView, - SendTextView, - SendView, - TotpResponse, - DocRef, - PurpleAuthenticator, - PurpleDuo, - PurpleEmail, - PurpleRemember, - PurpleWebAuthn, - PurpleYubiKey, - AccessTokenLoginResponseTwoFactorProviders, - AccessTokenLoginResponse, - ResponseForAccessTokenLoginResponse, - FluffyAuthenticator, - FluffyDuo, - FluffyEmail, - FluffyRemember, - FluffyWebAuthn, - FluffyYubiKey, - APIKeyLoginResponseTwoFactorProviders, - APIKeyLoginResponse, - ResponseForAPIKeyLoginResponse, - FingerprintResponse, - ResponseForFingerprintResponse, - CAPTCHAResponse, - TentacledAuthenticator, - TentacledDuo, - TentacledEmail, - TentacledRemember, - TentacledWebAuthn, - TentacledYubiKey, - PasswordLoginResponseTwoFactorProviders, - PasswordLoginResponse, - ResponseForPasswordLoginResponse, - ProjectResponse, - ResponseForProjectResponse, - ProjectDeleteResponse, - ProjectsDeleteResponse, - ResponseForProjectsDeleteResponse, - DatumElement, - ProjectsResponse, - ResponseForProjectsResponse, - SecretIdentifierResponse, - SecretIdentifiersResponse, - ResponseForSecretIdentifiersResponse, - SecretResponse, - ResponseForSecretResponse, - SecretDeleteResponse, - SecretsDeleteResponse, - ResponseForSecretsDeleteResponse, - DatumClass, - SecretsResponse, - ResponseForSecretsResponse, - CipherDetailsResponse, - ProfileOrganizationResponse, - ProfileResponse, - SyncResponse, - ResponseForSyncResponse, - UserAPIKeyResponse, - ResponseForUserAPIKeyResponse, - client_settings_from_dict, - client_settings_to_dict, - command_from_dict, - command_to_dict, - doc_ref_from_dict, - doc_ref_to_dict, - response_for_access_token_login_response_from_dict, - response_for_access_token_login_response_to_dict, - response_for_api_key_login_response_from_dict, - response_for_api_key_login_response_to_dict, - response_for_fingerprint_response_from_dict, - response_for_fingerprint_response_to_dict, - response_for_password_login_response_from_dict, - response_for_password_login_response_to_dict, - response_for_project_response_from_dict, - response_for_project_response_to_dict, - response_for_projects_delete_response_from_dict, - response_for_projects_delete_response_to_dict, - response_for_projects_response_from_dict, - response_for_projects_response_to_dict, - response_for_secret_identifiers_response_from_dict, - response_for_secret_identifiers_response_to_dict, - response_for_secret_response_from_dict, - response_for_secret_response_to_dict, - response_for_secrets_delete_response_from_dict, - response_for_secrets_delete_response_to_dict, - response_for_secrets_response_from_dict, - response_for_secrets_response_to_dict, - response_for_sync_response_from_dict, - response_for_sync_response_to_dict, - response_for_user_api_key_response_from_dict, - response_for_user_api_key_response_to_dict, -) +from .bitwarden_client import * +from .schemas import * + +__doc__ = bitwarden_client.__doc__ +if hasattr(bitwarden_client, "__all__"): + __all__ = bitwarden_client.__all__ + +if hasattr(schemas, "__all__"): + __all__ += schemas.__all__ From 0b657da17bac2920e50a66c42355123d4f0e5fc4 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 15:13:04 -0800 Subject: [PATCH 013/108] try handling openssl dep for linux --- .github/workflows/build-python-wheels.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 68e7882ed..8b91c506a 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -98,7 +98,9 @@ jobs: sccache: 'true' manylinux: auto working-directory: ${{ github.workspace }}/languages/python - # before-script-linux: | + before-script-linux: | + sudo apt update + sudo apt-get install libssl-dev -y - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 8cdf7bb58185d8bd08df1536d917688751d3f51f Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 15:17:18 -0800 Subject: [PATCH 014/108] try building manylinux on host --- .github/workflows/build-python-wheels.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 8b91c506a..aaa51bbea 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -98,6 +98,7 @@ jobs: sccache: 'true' manylinux: auto working-directory: ${{ github.workspace }}/languages/python + container: off before-script-linux: | sudo apt update sudo apt-get install libssl-dev -y From ac05db6358c4c76e835b508ff8381686e3ae5f1a Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 15:30:32 -0800 Subject: [PATCH 015/108] revert building on Linux host; fails manylinux compat --- .github/workflows/build-python-wheels.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index aaa51bbea..8b91c506a 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -98,7 +98,6 @@ jobs: sccache: 'true' manylinux: auto working-directory: ${{ github.workspace }}/languages/python - container: off before-script-linux: | sudo apt update sudo apt-get install libssl-dev -y From 57563f85e478f0e0c4ab5c086b7e5b0bc39255bd Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:00:44 -0800 Subject: [PATCH 016/108] try setting openssl lib dir --- .github/workflows/build-python-wheels.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 8b91c506a..2093db48e 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -101,6 +101,8 @@ jobs: before-script-linux: | sudo apt update sudo apt-get install libssl-dev -y + export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu + export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 224f259b44adcf72a9740457052d1121cf7fc689 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:13:46 -0800 Subject: [PATCH 017/108] remove sudo? --- .github/workflows/build-python-wheels.yml | 4 +- scratch.md | 120 ++++++++++++++++++++++ 2 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 scratch.md diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 2093db48e..6bfa58342 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -99,8 +99,8 @@ jobs: manylinux: auto working-directory: ${{ github.workspace }}/languages/python before-script-linux: | - sudo apt update - sudo apt-get install libssl-dev -y + apt-get update + apt-get install libssl-dev -y export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu diff --git a/scratch.md b/scratch.md new file mode 100644 index 000000000..84abded41 --- /dev/null +++ b/scratch.md @@ -0,0 +1,120 @@ +# This file is autogenerated by maturin v1.3.2 +# To update, run +# +# maturin generate-ci github +# +name: CI + +on: + push: + branches: + - main + - master + tags: + - '*' + pull_request: + workflow_dispatch: + +permissions: + contents: read + +jobs: + linux: + runs-on: ubuntu-latest + strategy: + matrix: + target: [x86_64, x86, aarch64, armv7, s390x, ppc64le] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.target }} + args: --release --out dist --find-interpreter + sccache: 'true' + manylinux: auto + - name: Upload wheels + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + + windows: + runs-on: windows-latest + strategy: + matrix: + target: [x64, x86] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + architecture: ${{ matrix.target }} + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.target }} + args: --release --out dist --find-interpreter + sccache: 'true' + - name: Upload wheels + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + + macos: + runs-on: macos-latest + strategy: + matrix: + target: [x86_64, aarch64] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.target }} + args: --release --out dist --find-interpreter + sccache: 'true' + - name: Upload wheels + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + + sdist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build sdist + uses: PyO3/maturin-action@v1 + with: + command: sdist + args: --out dist + - name: Upload sdist + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + + release: + name: Release + runs-on: ubuntu-latest + if: "startsWith(github.ref, 'refs/tags/')" + needs: [linux, windows, macos, sdist] + steps: + - uses: actions/download-artifact@v3 + with: + name: wheels + - name: Publish to PyPI + uses: PyO3/maturin-action@v1 + env: + MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} + with: + command: upload + args: --non-interactive --skip-existing * \ No newline at end of file From d43a06102e132fef70084bac8f26283f9c866c0c Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:18:26 -0800 Subject: [PATCH 018/108] apt instead of apt-get; missing on amd64 runner --- .github/workflows/build-python-wheels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 6bfa58342..20b2a9458 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -99,8 +99,8 @@ jobs: manylinux: auto working-directory: ${{ github.workspace }}/languages/python before-script-linux: | - apt-get update - apt-get install libssl-dev -y + apt update + apt install libssl-dev -y export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu From 8b108dd716d4e32cb77426b6411a4116fb66aa26 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:23:11 -0800 Subject: [PATCH 019/108] configure libssl earlier --- .github/workflows/build-python-wheels.yml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 20b2a9458..4e300c746 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -61,9 +61,20 @@ jobs: - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu - + build: | + apt-get update + apt-get install libssl-dev -y + export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu + export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu + - os: ubuntu-22.04 target: aarch64-unknown-linux-gnu + build: | + apt-get update + apt-get install libssl-dev -y + export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu + export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu + steps: - name: Checkout repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -98,11 +109,7 @@ jobs: sccache: 'true' manylinux: auto working-directory: ${{ github.workspace }}/languages/python - before-script-linux: | - apt update - apt install libssl-dev -y - export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu - export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu + # before-script-linux: | - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From b6b17eb5aaeaa6b81b487604e5a22fcdf6b04efb Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:28:42 -0800 Subject: [PATCH 020/108] =?UTF-8?q?still=20trying=20to=20configure=20opens?= =?UTF-8?q?sl=20=C2=AF\=5F(=E3=83=84)=5F/=C2=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-python-wheels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 4e300c746..bcb602d22 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -64,8 +64,8 @@ jobs: build: | apt-get update apt-get install libssl-dev -y - export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu + export OPENSSL_DIR=/usr/lib/x86_64-linux-gnu - os: ubuntu-22.04 target: aarch64-unknown-linux-gnu @@ -73,7 +73,7 @@ jobs: apt-get update apt-get install libssl-dev -y export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu - export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu + export OPENSSL_DIR=/usr/lib/aarch64-linux-gnu steps: - name: Checkout repo From 5bc824fcb2b2c6a4571b5c4b81fea48181d94bad Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:34:27 -0800 Subject: [PATCH 021/108] add pkgconfig path --- .github/workflows/build-python-wheels.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index bcb602d22..2efcb35cd 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -66,6 +66,7 @@ jobs: apt-get install libssl-dev -y export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu export OPENSSL_DIR=/usr/lib/x86_64-linux-gnu + export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig - os: ubuntu-22.04 target: aarch64-unknown-linux-gnu @@ -74,6 +75,7 @@ jobs: apt-get install libssl-dev -y export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu export OPENSSL_DIR=/usr/lib/aarch64-linux-gnu + export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig steps: - name: Checkout repo From 79b3818be23ef13ac90dbf77feffc154188d5e71 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:43:15 -0800 Subject: [PATCH 022/108] append to existing pkgconfig path --- .github/workflows/build-python-wheels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 2efcb35cd..174aae116 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -66,7 +66,7 @@ jobs: apt-get install libssl-dev -y export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu export OPENSSL_DIR=/usr/lib/x86_64-linux-gnu - export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig/" - os: ubuntu-22.04 target: aarch64-unknown-linux-gnu @@ -75,7 +75,7 @@ jobs: apt-get install libssl-dev -y export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu export OPENSSL_DIR=/usr/lib/aarch64-linux-gnu - export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig/" steps: - name: Checkout repo From a37619887ad975d90d4995ec2dd042706c50a778 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:06:24 -0800 Subject: [PATCH 023/108] try all the pkgconfig paths --- .github/workflows/build-python-wheels.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 174aae116..20ec72406 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -66,7 +66,7 @@ jobs: apt-get install libssl-dev -y export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu export OPENSSL_DIR=/usr/lib/x86_64-linux-gnu - export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig/" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig/:/opt/_internal/cpython-3.10.13/lib/pkgconfig/:/usr/lib64/pkgconfig/:/usr/local/lib/pkgconfig/:/usr/share/pkgconfig/" - os: ubuntu-22.04 target: aarch64-unknown-linux-gnu @@ -75,7 +75,7 @@ jobs: apt-get install libssl-dev -y export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu export OPENSSL_DIR=/usr/lib/aarch64-linux-gnu - export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig/" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig/:/opt/_internal/cpython-3.10.13/lib/pkgconfig/:/usr/lib64/pkgconfig/:/usr/local/lib/pkgconfig/:/usr/share/pkgconfig/" steps: - name: Checkout repo @@ -111,7 +111,11 @@ jobs: sccache: 'true' manylinux: auto working-directory: ${{ github.workspace }}/languages/python - # before-script-linux: | + before-script-linux: | + export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu + export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu + export OPENSSL_DIR=/usr/lib/aarch64-linux-gnu + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig/:/opt/_internal/cpython-3.10.13/lib/pkgconfig/:/usr/lib64/pkgconfig/:/usr/local/lib/pkgconfig/:/usr/share/pkgconfig/" - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From c72e4bad629dcfbe1ea1be673c89b8315630030a Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:45:44 -0800 Subject: [PATCH 024/108] try vendored openssl in `bitwarden-py` --- crates/bitwarden-py/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bitwarden-py/Cargo.toml b/crates/bitwarden-py/Cargo.toml index 5d8d95575..1a4771d5b 100644 --- a/crates/bitwarden-py/Cargo.toml +++ b/crates/bitwarden-py/Cargo.toml @@ -14,6 +14,7 @@ pyo3 = { version = "0.19.1", features = ["extension-module"] } pyo3-log = "0.8.3" bitwarden-json = { path = "../bitwarden-json", features = ["secrets"] } +openssl = { version = "0.10", features = ["vendored"] } [build-dependencies] pyo3-build-config = { version = "0.19.1" } From ebd103ef89e44b8a2aa8246971831278eaaf28c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 20 Nov 2023 19:53:12 +0100 Subject: [PATCH 025/108] Add feature flag for RustTLS support --- Cargo.lock | 106 ++++++++++++++++++++++- crates/bitwarden-api-api/Cargo.toml | 1 + crates/bitwarden-api-identity/Cargo.toml | 1 + crates/bitwarden-json/Cargo.toml | 8 +- crates/bitwarden-py/Cargo.toml | 2 +- crates/bitwarden-uniffi/Cargo.toml | 3 - crates/bitwarden/Cargo.toml | 8 +- crates/bws/Cargo.toml | 3 - 8 files changed, 119 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c040eb279..e531227cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -446,7 +446,6 @@ dependencies = [ "bitwarden", "chrono", "env_logger", - "openssl", "schemars", "uniffi", ] @@ -538,7 +537,6 @@ dependencies = [ "directories", "env_logger", "log", - "openssl", "regex", "serde", "serde_json", @@ -1505,6 +1503,20 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -1678,7 +1690,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin", + "spin 0.5.2", ] [[package]] @@ -2557,6 +2569,7 @@ dependencies = [ "http", "http-body", "hyper", + "hyper-rustls", "hyper-tls", "ipnet", "js-sys", @@ -2567,17 +2580,21 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "system-configuration", "tokio", "tokio-native-tls", + "tokio-rustls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "winreg", ] @@ -2596,6 +2613,20 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom 0.2.11", + "libc", + "spin 0.9.8", + "untrusted", + "windows-sys 0.48.0", +] + [[package]] name = "rsa" version = "0.9.3" @@ -2635,6 +2666,37 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rustls" +version = "0.21.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -2730,6 +2792,16 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "sdk-schemas" version = "0.1.0" @@ -3002,6 +3074,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spki" version = "0.7.2" @@ -3267,6 +3345,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -3597,6 +3685,12 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.4.1" @@ -3781,6 +3875,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + [[package]] name = "weedle2" version = "4.0.0" diff --git a/crates/bitwarden-api-api/Cargo.toml b/crates/bitwarden-api-api/Cargo.toml index 518cc33ed..70bc17311 100644 --- a/crates/bitwarden-api-api/Cargo.toml +++ b/crates/bitwarden-api-api/Cargo.toml @@ -22,5 +22,6 @@ uuid = { version = "^1.3.3", features = ["serde"] } [dependencies.reqwest] version = "^0.11.18" features = ["json", "multipart"] +default-features = false [dev-dependencies] diff --git a/crates/bitwarden-api-identity/Cargo.toml b/crates/bitwarden-api-identity/Cargo.toml index 70be0560b..0513f8b9a 100644 --- a/crates/bitwarden-api-identity/Cargo.toml +++ b/crates/bitwarden-api-identity/Cargo.toml @@ -22,5 +22,6 @@ uuid = { version = "^1.3.3", features = ["serde"] } [dependencies.reqwest] version = "^0.11.18" features = ["json", "multipart"] +default-features = false [dev-dependencies] diff --git a/crates/bitwarden-json/Cargo.toml b/crates/bitwarden-json/Cargo.toml index 579a8bdab..2f6e031cf 100644 --- a/crates/bitwarden-json/Cargo.toml +++ b/crates/bitwarden-json/Cargo.toml @@ -14,13 +14,19 @@ edition = "2021" rust-version = "1.57" [features] +default = ["use_native_tls"] + internal = ["bitwarden/internal"] # Internal testing methods secrets = ["bitwarden/secrets"] # Secrets manager API +use_native_tls = ["bitwarden/use_native_tls"] +use_native_tls_vendored = ["bitwarden/use_native_tls_vendored"] +use_rustls = ["bitwarden/use_rustls"] + [dependencies] schemars = ">=0.8.12, <0.9" serde = { version = ">=1.0, <2.0", features = ["derive"] } serde_json = ">=1.0.96, <2.0" log = ">=0.4.18, <0.5" -bitwarden = { path = "../bitwarden" } +bitwarden = { path = "../bitwarden", default-features = false } diff --git a/crates/bitwarden-py/Cargo.toml b/crates/bitwarden-py/Cargo.toml index 613203c84..ca7947e06 100644 --- a/crates/bitwarden-py/Cargo.toml +++ b/crates/bitwarden-py/Cargo.toml @@ -13,7 +13,7 @@ crate-type = ["cdylib"] pyo3 = { version = "0.20.0", features = ["extension-module"] } pyo3-log = "0.9.0" -bitwarden-json = { path = "../bitwarden-json", features = ["secrets"] } +bitwarden-json = { path = "../bitwarden-json", features = ["secrets", "use_rustls"], default-features = false } [build-dependencies] pyo3-build-config = { version = "0.20.0" } diff --git a/crates/bitwarden-uniffi/Cargo.toml b/crates/bitwarden-uniffi/Cargo.toml index 53da0eb8d..154f152c3 100644 --- a/crates/bitwarden-uniffi/Cargo.toml +++ b/crates/bitwarden-uniffi/Cargo.toml @@ -25,6 +25,3 @@ bitwarden = { path = "../bitwarden", features = ["mobile", "internal"] } [build-dependencies] uniffi = { version = "=0.25.1", features = ["build"] } - -[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies] -openssl = { version = "0.10", features = ["vendored"] } diff --git a/crates/bitwarden/Cargo.toml b/crates/bitwarden/Cargo.toml index fea9a2fd7..23d713634 100644 --- a/crates/bitwarden/Cargo.toml +++ b/crates/bitwarden/Cargo.toml @@ -13,16 +13,20 @@ edition = "2021" rust-version = "1.57" [features] -default = ["secrets"] +default = ["secrets", "use_native_tls"] secrets = [] # Secrets manager API internal = [] # Internal testing methods mobile = ["uniffi", "internal"] # Mobile-specific features +use_native_tls = ["reqwest/native-tls"] +use_native_tls_vendored = ["reqwest/native-tls-vendored"] +use_rustls = ["reqwest/rustls-tls"] + [dependencies] base64 = ">=0.21.2, <0.22" lazy_static = ">=1.4.0, <2.0" -reqwest = { version = ">=0.11, <0.12", features = ["json"] } +reqwest = { version = ">=0.11, <0.12", features = ["json"], default-features = false } serde = { version = ">=1.0, <2.0", features = ["derive"] } serde_json = ">=1.0.96, <2.0" serde_qs = ">=0.12.0, <0.13" diff --git a/crates/bws/Cargo.toml b/crates/bws/Cargo.toml index 9ccd5c546..909c8736c 100644 --- a/crates/bws/Cargo.toml +++ b/crates/bws/Cargo.toml @@ -43,6 +43,3 @@ bitwarden = { path = "../bitwarden", version = "0.3.1", features = ["secrets"] } [dev-dependencies] tempfile = "3.5.0" - -[target.'cfg(target_os = "linux")'.dependencies] -openssl = { version = "0.10", features = ["vendored"] } From 2207d3524ae3697b5f855500d39015a60f7274c0 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:58:19 -0800 Subject: [PATCH 026/108] specialize build prep for Windows arm64 --- .github/workflows/build-python-wheels.yml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 20ec72406..617568c87 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -58,24 +58,15 @@ jobs: - os: windows-2022 target: aarch64-pc-windows-msvc + build: | + export PATH="$PATH:/c/Program Files (x86)/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/x64/bin" - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu - build: | - apt-get update - apt-get install libssl-dev -y - export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu - export OPENSSL_DIR=/usr/lib/x86_64-linux-gnu - export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig/:/opt/_internal/cpython-3.10.13/lib/pkgconfig/:/usr/lib64/pkgconfig/:/usr/local/lib/pkgconfig/:/usr/share/pkgconfig/" - os: ubuntu-22.04 target: aarch64-unknown-linux-gnu - build: | - apt-get update - apt-get install libssl-dev -y - export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu - export OPENSSL_DIR=/usr/lib/aarch64-linux-gnu - export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig/:/opt/_internal/cpython-3.10.13/lib/pkgconfig/:/usr/lib64/pkgconfig/:/usr/local/lib/pkgconfig/:/usr/share/pkgconfig/" + # build: | steps: - name: Checkout repo From 0cb4f6b5dc79a64903382356cc6cc08918dea6fa Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:18:29 -0800 Subject: [PATCH 027/108] set path in powershell --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 617568c87..923c430f4 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -59,7 +59,7 @@ jobs: - os: windows-2022 target: aarch64-pc-windows-msvc build: | - export PATH="$PATH:/c/Program Files (x86)/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/x64/bin" + $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu From 86c41d3c92a6e2fed9b54a234c35652c138070aa Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:32:26 -0800 Subject: [PATCH 028/108] try setting PATH at the wheel build step --- .github/workflows/build-python-wheels.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 923c430f4..dd4f1e7b3 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -58,8 +58,6 @@ jobs: - os: windows-2022 target: aarch64-pc-windows-msvc - build: | - $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu @@ -97,6 +95,7 @@ jobs: - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: + env: PATH="$PATH:/c/Program Files (x86)/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/x64/bin" target: ${{ matrix.settings.target }} args: --release --find-interpreter --sdist sccache: 'true' From c58fa70e9420e437066d746751efd847c2b8ce7d Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:44:45 -0800 Subject: [PATCH 029/108] =?UTF-8?q?try=20setting=20shell=20to=20bash=20?= =?UTF-8?q?=C2=AF\=5F(=E3=83=84)=5F/=C2=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index dd4f1e7b3..db9ba5982 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -58,13 +58,13 @@ jobs: - os: windows-2022 target: aarch64-pc-windows-msvc + shell: bash - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu - os: ubuntu-22.04 target: aarch64-unknown-linux-gnu - # build: | steps: - name: Checkout repo From 3685933cccf6c81aa11404470939f475771baaf1 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:13:37 -0800 Subject: [PATCH 030/108] delete file --- scratch.md | 120 ----------------------------------------------------- 1 file changed, 120 deletions(-) delete mode 100644 scratch.md diff --git a/scratch.md b/scratch.md deleted file mode 100644 index 84abded41..000000000 --- a/scratch.md +++ /dev/null @@ -1,120 +0,0 @@ -# This file is autogenerated by maturin v1.3.2 -# To update, run -# -# maturin generate-ci github -# -name: CI - -on: - push: - branches: - - main - - master - tags: - - '*' - pull_request: - workflow_dispatch: - -permissions: - contents: read - -jobs: - linux: - runs-on: ubuntu-latest - strategy: - matrix: - target: [x86_64, x86, aarch64, armv7, s390x, ppc64le] - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: '3.10' - - name: Build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.target }} - args: --release --out dist --find-interpreter - sccache: 'true' - manylinux: auto - - name: Upload wheels - uses: actions/upload-artifact@v3 - with: - name: wheels - path: dist - - windows: - runs-on: windows-latest - strategy: - matrix: - target: [x64, x86] - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: '3.10' - architecture: ${{ matrix.target }} - - name: Build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.target }} - args: --release --out dist --find-interpreter - sccache: 'true' - - name: Upload wheels - uses: actions/upload-artifact@v3 - with: - name: wheels - path: dist - - macos: - runs-on: macos-latest - strategy: - matrix: - target: [x86_64, aarch64] - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: '3.10' - - name: Build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.target }} - args: --release --out dist --find-interpreter - sccache: 'true' - - name: Upload wheels - uses: actions/upload-artifact@v3 - with: - name: wheels - path: dist - - sdist: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Build sdist - uses: PyO3/maturin-action@v1 - with: - command: sdist - args: --out dist - - name: Upload sdist - uses: actions/upload-artifact@v3 - with: - name: wheels - path: dist - - release: - name: Release - runs-on: ubuntu-latest - if: "startsWith(github.ref, 'refs/tags/')" - needs: [linux, windows, macos, sdist] - steps: - - uses: actions/download-artifact@v3 - with: - name: wheels - - name: Publish to PyPI - uses: PyO3/maturin-action@v1 - env: - MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} - with: - command: upload - args: --non-interactive --skip-existing * \ No newline at end of file From 6c9770d3d0e0f9d089b81b5e8446bccbc4efaeb9 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:42:08 -0800 Subject: [PATCH 031/108] try setting path var at system-level --- .github/workflows/build-python-wheels.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index db9ba5982..7c1093a45 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -58,7 +58,11 @@ jobs: - os: windows-2022 target: aarch64-pc-windows-msvc - shell: bash + build: | + [Environment]::SetEnvironmentVariable( + "Path", + [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin", + [EnvironmentVariableTarget]::Machine) - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu From 4c5ea059f9ec6d35c8c98e92a17b3aa7933ad29a Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:50:16 -0800 Subject: [PATCH 032/108] use workflow path --- .github/workflows/build-python-wheels.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 7c1093a45..d7ba3fc09 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -59,10 +59,8 @@ jobs: - os: windows-2022 target: aarch64-pc-windows-msvc build: | - [Environment]::SetEnvironmentVariable( - "Path", - [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin", - [EnvironmentVariableTarget]::Machine) + echo "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" >> $GITHUB_PATH + echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu @@ -99,7 +97,6 @@ jobs: - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: - env: PATH="$PATH:/c/Program Files (x86)/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/x64/bin" target: ${{ matrix.settings.target }} args: --release --find-interpreter --sdist sccache: 'true' From be0e5d84063e72ee7b883ba72ecb20b023ad1551 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 05:13:46 -0800 Subject: [PATCH 033/108] . --- .github/workflows/build-python-wheels.yml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index d7ba3fc09..1b422afba 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -58,9 +58,6 @@ jobs: - os: windows-2022 target: aarch64-pc-windows-msvc - build: | - echo "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" >> $GITHUB_PATH - echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu @@ -94,6 +91,12 @@ jobs: name: schemas.py path: ${{ github.workspace }}/languages/python/BitwardenClient/ + - if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} + run: | + echo "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" >> $GITHUB_PATH + echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV + shell: bash + - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: @@ -102,11 +105,11 @@ jobs: sccache: 'true' manylinux: auto working-directory: ${{ github.workspace }}/languages/python - before-script-linux: | - export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu - export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu - export OPENSSL_DIR=/usr/lib/aarch64-linux-gnu - export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig/:/opt/_internal/cpython-3.10.13/lib/pkgconfig/:/usr/lib64/pkgconfig/:/usr/local/lib/pkgconfig/:/usr/share/pkgconfig/" + # before-script-linux: | + # export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu + # export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu + # export OPENSSL_DIR=/usr/lib/aarch64-linux-gnu + # export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig/:/opt/_internal/cpython-3.10.13/lib/pkgconfig/:/usr/lib64/pkgconfig/:/usr/local/lib/pkgconfig/:/usr/share/pkgconfig/" - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 46f901250ccc4d7cd9ecc2c2dc0937176be2d8d1 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 05:28:16 -0800 Subject: [PATCH 034/108] try setting aarch64 linux linker --- crates/bitwarden-py/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/bitwarden-py/Cargo.toml b/crates/bitwarden-py/Cargo.toml index ca7947e06..f4ab1ad24 100644 --- a/crates/bitwarden-py/Cargo.toml +++ b/crates/bitwarden-py/Cargo.toml @@ -24,3 +24,6 @@ pyo3-asyncio = { version = "0.20.0", features = [ "attributes", "tokio-runtime", ] } + +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc" \ No newline at end of file From 4f4d2518559e90411e6efa2becad01887467373b Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 05:42:34 -0800 Subject: [PATCH 035/108] =?UTF-8?q?configure=20more=20vars=20=C2=AF\=5F(?= =?UTF-8?q?=E3=83=84)=5F/=C2=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-python-wheels.yml | 15 +++++++++------ crates/bitwarden-py/Cargo.toml | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 1b422afba..7b224593f 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -91,12 +91,20 @@ jobs: name: schemas.py path: ${{ github.workspace }}/languages/python/BitwardenClient/ - - if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} + - name: Configure ${{ matrix.settings.target }} builder + if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} run: | echo "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" >> $GITHUB_PATH echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV shell: bash + - name: Configure ${{ matrix.settings.target }} builder + if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' }} + run: | + echo 'CFLAGS_aarch64_unknown_linux_gnu="-D__ARM_ARCH=8"' >> $GITHUB_ENV + echo 'TARGET_CC=aarch64-linux-gnu-gcc' >> $GITHUB_ENV + echo 'TARGET_AR=aarch64-linux-gnu-ar' >> $GITHUB_ENV + - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: @@ -105,11 +113,6 @@ jobs: sccache: 'true' manylinux: auto working-directory: ${{ github.workspace }}/languages/python - # before-script-linux: | - # export X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu - # export AARCH64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu - # export OPENSSL_DIR=/usr/lib/aarch64-linux-gnu - # export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig/:/opt/_internal/cpython-3.10.13/lib/pkgconfig/:/usr/lib64/pkgconfig/:/usr/local/lib/pkgconfig/:/usr/share/pkgconfig/" - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 diff --git a/crates/bitwarden-py/Cargo.toml b/crates/bitwarden-py/Cargo.toml index f4ab1ad24..2eb6ff0cf 100644 --- a/crates/bitwarden-py/Cargo.toml +++ b/crates/bitwarden-py/Cargo.toml @@ -26,4 +26,4 @@ pyo3-asyncio = { version = "0.20.0", features = [ ] } [target.aarch64-unknown-linux-gnu] -linker = "aarch64-linux-gnu-gcc" \ No newline at end of file +linker = "aarch64-linux-gnu-gcc" From 94da33c2d8ecbe32559951bc6cccbc84b02bca52 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 05:53:38 -0800 Subject: [PATCH 036/108] update --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 7b224593f..dabe1255c 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -101,7 +101,7 @@ jobs: - name: Configure ${{ matrix.settings.target }} builder if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' }} run: | - echo 'CFLAGS_aarch64_unknown_linux_gnu="-D__ARM_ARCH=8"' >> $GITHUB_ENV + echo '__ARM_ARCH=8"' >> $GITHUB_ENV echo 'TARGET_CC=aarch64-linux-gnu-gcc' >> $GITHUB_ENV echo 'TARGET_AR=aarch64-linux-gnu-ar' >> $GITHUB_ENV From 8ee5f2c5ac51833328155b108f41c182be203969 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 05:59:56 -0800 Subject: [PATCH 037/108] update --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index dabe1255c..2dce939ca 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -101,7 +101,7 @@ jobs: - name: Configure ${{ matrix.settings.target }} builder if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' }} run: | - echo '__ARM_ARCH=8"' >> $GITHUB_ENV + echo '__ARM_ARCH=armv8-a"' >> $GITHUB_ENV echo 'TARGET_CC=aarch64-linux-gnu-gcc' >> $GITHUB_ENV echo 'TARGET_AR=aarch64-linux-gnu-ar' >> $GITHUB_ENV From 575664682a211526afe296d0b58c93dac7cb5af5 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 06:04:58 -0800 Subject: [PATCH 038/108] update --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 2dce939ca..f9997104b 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -110,7 +110,7 @@ jobs: with: target: ${{ matrix.settings.target }} args: --release --find-interpreter --sdist - sccache: 'true' + sccache: 'false' manylinux: auto working-directory: ${{ github.workspace }}/languages/python From 7ab8d1d7e851007a3468a3396d2ed3ea80f059a9 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 06:12:37 -0800 Subject: [PATCH 039/108] try setting arm var in container --- .github/workflows/build-python-wheels.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index f9997104b..ce32e877c 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -91,28 +91,29 @@ jobs: name: schemas.py path: ${{ github.workspace }}/languages/python/BitwardenClient/ - - name: Configure ${{ matrix.settings.target }} builder + - name: Configure aarch64-pc-windows-msvc builder if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} run: | echo "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" >> $GITHUB_PATH echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV shell: bash - - name: Configure ${{ matrix.settings.target }} builder - if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' }} - run: | - echo '__ARM_ARCH=armv8-a"' >> $GITHUB_ENV - echo 'TARGET_CC=aarch64-linux-gnu-gcc' >> $GITHUB_ENV - echo 'TARGET_AR=aarch64-linux-gnu-ar' >> $GITHUB_ENV + # - name: Configure aarch64-unknown-linux-gnu builder + # if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' }} + # run: | + # echo '__ARM_ARCH=armv8-a' >> $GITHUB_ENV + # echo 'TARGET_CC=aarch64-linux-gnu-gcc' >> $GITHUB_ENV + # echo 'TARGET_AR=aarch64-linux-gnu-ar' >> $GITHUB_ENV - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: target: ${{ matrix.settings.target }} args: --release --find-interpreter --sdist - sccache: 'false' + sccache: 'true' manylinux: auto working-directory: ${{ github.workspace }}/languages/python + docker-options: -e __ARM_ARCH=armv8-a - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 04048d4445ca939dbc391dc2f5529fccd70eb039 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 06:23:31 -0800 Subject: [PATCH 040/108] update --- .github/workflows/build-python-wheels.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index ce32e877c..fc7dc669e 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -114,6 +114,10 @@ jobs: manylinux: auto working-directory: ${{ github.workspace }}/languages/python docker-options: -e __ARM_ARCH=armv8-a + before-script-linux: | + yum install -y clang dbus-devel gtk3-devel libnotify-devel \ + libgnome-keyring-devel libcap-devel \ + cups-devel libXtst-devel python-dbusmock - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From d192c9adcbd5526bcf4e596c5982eb6a5f4355a1 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 06:29:15 -0800 Subject: [PATCH 041/108] update --- .github/workflows/build-python-wheels.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index fc7dc669e..8e95cf9a3 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -115,9 +115,8 @@ jobs: working-directory: ${{ github.workspace }}/languages/python docker-options: -e __ARM_ARCH=armv8-a before-script-linux: | - yum install -y clang dbus-devel gtk3-devel libnotify-devel \ - libgnome-keyring-devel libcap-devel \ - cups-devel libXtst-devel python-dbusmock + apt update + apt install -y qemu-user gcc-aarch64-linux-gnu libc6-dev-arm64-cross - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 126a20084fa3d12f2a0d95422220bc91d4169bc3 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 06:33:58 -0800 Subject: [PATCH 042/108] un-break amd64 linux --- .github/workflows/build-python-wheels.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 8e95cf9a3..5dbc3848a 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -114,9 +114,9 @@ jobs: manylinux: auto working-directory: ${{ github.workspace }}/languages/python docker-options: -e __ARM_ARCH=armv8-a - before-script-linux: | - apt update - apt install -y qemu-user gcc-aarch64-linux-gnu libc6-dev-arm64-cross + # before-script-linux: | + # apt update + # apt install -y qemu-user gcc-aarch64-linux-gnu libc6-dev-arm64-cross - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 1af3b463518129e9b61cbaecb2c9c928cc4cf23f Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 06:56:52 -0800 Subject: [PATCH 043/108] update --- .github/workflows/build-python-wheels.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 5dbc3848a..f1cbda366 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -98,12 +98,11 @@ jobs: echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV shell: bash - # - name: Configure aarch64-unknown-linux-gnu builder - # if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' }} - # run: | - # echo '__ARM_ARCH=armv8-a' >> $GITHUB_ENV - # echo 'TARGET_CC=aarch64-linux-gnu-gcc' >> $GITHUB_ENV - # echo 'TARGET_AR=aarch64-linux-gnu-ar' >> $GITHUB_ENV + - name: Configure Linux builder + if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu' }} + run: | + echo "TARGET_CC=$(uname -m)-linux-gnu-gcc" >> $GITHUB_ENV + echo "TARGET_AR=$(uname -m)-linux-gnu-ar" >> $GITHUB_ENV - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 @@ -113,7 +112,7 @@ jobs: sccache: 'true' manylinux: auto working-directory: ${{ github.workspace }}/languages/python - docker-options: -e __ARM_ARCH=armv8-a + docker-options: -e __ARM_ARCH=armv8-a -e TARGET_CC=$TARGET_CC -e TARGET_AR=$TARGET_AR # before-script-linux: | # apt update # apt install -y qemu-user gcc-aarch64-linux-gnu libc6-dev-arm64-cross From adaacdfe4c9535f421a3e9911311bff4bd35c9f7 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:30:26 -0800 Subject: [PATCH 044/108] Update build-python-wheels.yml --- .github/workflows/build-python-wheels.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index f1cbda366..7d357cac8 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -98,11 +98,11 @@ jobs: echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV shell: bash - - name: Configure Linux builder - if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu' }} - run: | - echo "TARGET_CC=$(uname -m)-linux-gnu-gcc" >> $GITHUB_ENV - echo "TARGET_AR=$(uname -m)-linux-gnu-ar" >> $GITHUB_ENV + # - name: Configure Linux builder + # if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu' }} + # run: | + # echo "TARGET_CC=$(uname -m)-linux-gnu-gcc" >> $GITHUB_ENV + # echo "TARGET_AR=$(uname -m)-linux-gnu-ar" >> $GITHUB_ENV - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 @@ -110,9 +110,9 @@ jobs: target: ${{ matrix.settings.target }} args: --release --find-interpreter --sdist sccache: 'true' - manylinux: auto + manylinux: '2_28' working-directory: ${{ github.workspace }}/languages/python - docker-options: -e __ARM_ARCH=armv8-a -e TARGET_CC=$TARGET_CC -e TARGET_AR=$TARGET_AR + docker-options: -e __ARM_ARCH=armv8-a #-e TARGET_CC=$TARGET_CC -e TARGET_AR=$TARGET_AR # before-script-linux: | # apt update # apt install -y qemu-user gcc-aarch64-linux-gnu libc6-dev-arm64-cross From e16511cbd465ca135e5029aa6d552e27ad76db2d Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:57:27 -0800 Subject: [PATCH 045/108] remove unused --- .github/workflows/build-python-wheels.yml | 17 ----------------- crates/bitwarden-py/Cargo.toml | 3 --- 2 files changed, 20 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 7d357cac8..74d1ee9cc 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -91,19 +91,6 @@ jobs: name: schemas.py path: ${{ github.workspace }}/languages/python/BitwardenClient/ - - name: Configure aarch64-pc-windows-msvc builder - if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} - run: | - echo "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" >> $GITHUB_PATH - echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV - shell: bash - - # - name: Configure Linux builder - # if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu' }} - # run: | - # echo "TARGET_CC=$(uname -m)-linux-gnu-gcc" >> $GITHUB_ENV - # echo "TARGET_AR=$(uname -m)-linux-gnu-ar" >> $GITHUB_ENV - - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: @@ -112,10 +99,6 @@ jobs: sccache: 'true' manylinux: '2_28' working-directory: ${{ github.workspace }}/languages/python - docker-options: -e __ARM_ARCH=armv8-a #-e TARGET_CC=$TARGET_CC -e TARGET_AR=$TARGET_AR - # before-script-linux: | - # apt update - # apt install -y qemu-user gcc-aarch64-linux-gnu libc6-dev-arm64-cross - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 diff --git a/crates/bitwarden-py/Cargo.toml b/crates/bitwarden-py/Cargo.toml index 2eb6ff0cf..ca7947e06 100644 --- a/crates/bitwarden-py/Cargo.toml +++ b/crates/bitwarden-py/Cargo.toml @@ -24,6 +24,3 @@ pyo3-asyncio = { version = "0.20.0", features = [ "attributes", "tokio-runtime", ] } - -[target.aarch64-unknown-linux-gnu] -linker = "aarch64-linux-gnu-gcc" From 4aa25157d6c380b7ccc87d50820373fd72098c4f Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:58:14 -0800 Subject: [PATCH 046/108] add comment for arm linux --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 74d1ee9cc..cc5c73729 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -97,7 +97,7 @@ jobs: target: ${{ matrix.settings.target }} args: --release --find-interpreter --sdist sccache: 'true' - manylinux: '2_28' + manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 working-directory: ${{ github.workspace }}/languages/python - name: Upload artifact From 8b6f3299b9adccbacbc1ba38dc30af9ea029f7ee Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:01:16 -0800 Subject: [PATCH 047/108] add ARM64 build tools and clang for win arm --- .github/workflows/build-python-wheels.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index cc5c73729..f7240a633 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -91,6 +91,12 @@ jobs: name: schemas.py path: ${{ github.workspace }}/languages/python/BitwardenClient/ + - name: Setup Windows ARM64 + if: ${{ contains(matrix.build, 'windows-msvc-arm64') }} + run: | + # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components + $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" + - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: From 3468b6c79b353de2cbe06b3e8a4091c3f5bc36ca Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:09:16 -0800 Subject: [PATCH 048/108] fix windows arm target --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index f7240a633..9c9328993 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -92,7 +92,7 @@ jobs: path: ${{ github.workspace }}/languages/python/BitwardenClient/ - name: Setup Windows ARM64 - if: ${{ contains(matrix.build, 'windows-msvc-arm64') }} + if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} run: | # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" From 09bb280d391a862bb6c023ce5d75313a2381fbe8 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:17:33 -0800 Subject: [PATCH 049/108] echo to `"$GITHUB_PATH"` --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 9c9328993..51505b776 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -95,7 +95,7 @@ jobs: if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} run: | # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components - $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" + echo 'C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin' >> "$GITHUB_PATH" - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 From 4cced58ef18f06d95007c0f55de615f6ae55ea3b Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:28:19 -0800 Subject: [PATCH 050/108] troubleshoot win arm --- .github/workflows/build-python-wheels.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 51505b776..16a48f76c 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -96,6 +96,13 @@ jobs: run: | # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components echo 'C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin' >> "$GITHUB_PATH" + echo 'Output GITHUB_PATH' + cat "$GITHUB_PATH" + echo 'Output PowerShell PATH' + pwsh -c '$env:Path' || true + echo 'Checking if build tools exist' + ls -hal 'C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin' + exit 1 # fail because we are testing - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 From 487a08bcb2a903220cf54f07ef101c6c276bb866 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:35:41 -0800 Subject: [PATCH 051/108] troubleshoot win arm --- .github/workflows/build-python-wheels.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 16a48f76c..d2a1b6bdd 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -93,15 +93,14 @@ jobs: - name: Setup Windows ARM64 if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} + shell: pwsh run: | # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components - echo 'C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin' >> "$GITHUB_PATH" - echo 'Output GITHUB_PATH' - cat "$GITHUB_PATH" + $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" echo 'Output PowerShell PATH' - pwsh -c '$env:Path' || true + pwsh -c '$env:Path' echo 'Checking if build tools exist' - ls -hal 'C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin' + bash -c 'ls -halR 'C:\Program Files (x86)\Microsoft Visual Studio'' exit 1 # fail because we are testing - name: Build wheels From 41b44dc4bf4f9b5565bd23d567a19311b5d5b255 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:42:59 -0800 Subject: [PATCH 052/108] use wildcard in bash path --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index d2a1b6bdd..277aa4186 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -100,7 +100,7 @@ jobs: echo 'Output PowerShell PATH' pwsh -c '$env:Path' echo 'Checking if build tools exist' - bash -c 'ls -halR 'C:\Program Files (x86)\Microsoft Visual Studio'' + bash -c 'ls -halR 'C:\Program Files *\Microsoft Visual Studio'' exit 1 # fail because we are testing - name: Build wheels From 9831906cd37f9b012e9030e782ac7092b7dc81f2 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:48:05 -0800 Subject: [PATCH 053/108] use pwsh to list build tool dir --- .github/workflows/build-python-wheels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 277aa4186..c7201d349 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -98,9 +98,9 @@ jobs: # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" echo 'Output PowerShell PATH' - pwsh -c '$env:Path' + $env:Path echo 'Checking if build tools exist' - bash -c 'ls -halR 'C:\Program Files *\Microsoft Visual Studio'' + Get-ChildItem -Recurse "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" exit 1 # fail because we are testing - name: Build wheels From 02a9b251acebd462a9afedf18846bfa4864c4242 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:53:12 -0800 Subject: [PATCH 054/108] try different build tools dir --- .github/workflows/build-python-wheels.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index c7201d349..831302104 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -96,12 +96,11 @@ jobs: shell: pwsh run: | # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components - $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" + $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin echo 'Output PowerShell PATH' $env:Path echo 'Checking if build tools exist' - Get-ChildItem -Recurse "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" - exit 1 # fail because we are testing + Get-ChildItem -Recurse "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 From f781bef6e9b582bc242e6fbf89dd9ff7f9080523 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:57:07 -0800 Subject: [PATCH 055/108] troubleshoot win arm --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 831302104..e02e94602 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -100,7 +100,7 @@ jobs: echo 'Output PowerShell PATH' $env:Path echo 'Checking if build tools exist' - Get-ChildItem -Recurse "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" + Get-ChildItem -Recurse 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin' - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 From 6167b1ef5dc9a991c88cc1360c1ddb48028a9220 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 13:00:32 -0800 Subject: [PATCH 056/108] close missing double-quote --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index e02e94602..09c042e6a 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -96,7 +96,7 @@ jobs: shell: pwsh run: | # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components - $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin + $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" echo 'Output PowerShell PATH' $env:Path echo 'Checking if build tools exist' From 03dd20dd2d03bc3ca9f4d67bf518f97142f3b5bc Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 21 Nov 2023 14:47:18 -0800 Subject: [PATCH 057/108] change arm win build target --- .github/workflows/build-python-wheels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 09c042e6a..074e48d67 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -57,7 +57,7 @@ jobs: target: x86_64-pc-windows-msvc - os: windows-2022 - target: aarch64-pc-windows-msvc + target: windows-msvc-arm64 - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu @@ -92,7 +92,7 @@ jobs: path: ${{ github.workspace }}/languages/python/BitwardenClient/ - name: Setup Windows ARM64 - if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} + if: ${{ matrix.settings.target == 'windows-msvc-arm64' }} shell: pwsh run: | # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components From 268f55b4cc4694e0bc8cfe46646c542b318299f8 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 22 Nov 2023 08:54:35 -0800 Subject: [PATCH 058/108] try multiple toolchains for win arm --- .github/workflows/build-python-wheels.yml | 27 ++++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 074e48d67..f5cf76927 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -57,7 +57,7 @@ jobs: target: x86_64-pc-windows-msvc - os: windows-2022 - target: windows-msvc-arm64 + target: aarch64-pc-windows-msvc - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu @@ -75,11 +75,19 @@ jobs: node-version: 18 - name: Install rust + if: ${{ matrix.settings.target != 'aarch64-pc-windows-msvc' }} uses: dtolnay/rust-toolchain@439cf607258077187679211f12aa6f19af4a0af7 # stable with: toolchain: stable targets: ${{ matrix.settings.target }} + - name: Install rust + if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} + uses: dtolnay/rust-toolchain@439cf607258077187679211f12aa6f19af4a0af7 # stable + with: + toolchain: stable + targets: ${{ matrix.settings.target }},x86_64-pc-windows-msvc + - name: Cache cargo registry uses: Swatinem/rust-cache@3cf7f8cc28d1b4e7d01e3783be10a97d55d483c8 # v2.7.1 with: @@ -92,17 +100,14 @@ jobs: path: ${{ github.workspace }}/languages/python/BitwardenClient/ - name: Setup Windows ARM64 - if: ${{ matrix.settings.target == 'windows-msvc-arm64' }} + if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} shell: pwsh run: | # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - echo 'Output PowerShell PATH' - $env:Path - echo 'Checking if build tools exist' - Get-ChildItem -Recurse 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin' - name: Build wheels + if: ${{ matrix.settings.target != 'aarch64-pc-windows-msvc' }} uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: target: ${{ matrix.settings.target }} @@ -111,6 +116,16 @@ jobs: manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 working-directory: ${{ github.workspace }}/languages/python + - name: Build wheels + if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} + uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 + with: + target: 'win32' + args: --release --find-interpreter --sdist + sccache: 'true' + manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 + working-directory: ${{ github.workspace }}/languages/python + - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: From ba584cdc55945d1d808194a7f9b263483527611e Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 22 Nov 2023 08:59:29 -0800 Subject: [PATCH 059/108] try space-separated target string --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index f5cf76927..fd8e8d1de 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -120,7 +120,7 @@ jobs: if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: - target: 'win32' + target: '${{ matrix.settings.target }} x86_64-pc-windows-msvc' args: --release --find-interpreter --sdist sccache: 'true' manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 From 4908d779b927ec44f185c77404db52fcf1315e8a Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:03:48 -0800 Subject: [PATCH 060/108] try YAML list --- .github/workflows/build-python-wheels.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index fd8e8d1de..6c009f31c 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -120,7 +120,9 @@ jobs: if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: - target: '${{ matrix.settings.target }} x86_64-pc-windows-msvc' + target: + - ${{ matrix.settings.target }} + - x86_64-pc-windows-msvc args: --release --find-interpreter --sdist sccache: 'true' manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 From 4c5354544ee7eaedd91feb1461a9e7cca88e660b Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:04:31 -0800 Subject: [PATCH 061/108] try unquoted target --- .github/workflows/build-python-wheels.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 6c009f31c..7cc378d4c 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -120,9 +120,7 @@ jobs: if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: - target: - - ${{ matrix.settings.target }} - - x86_64-pc-windows-msvc + target: ${{ matrix.settings.target }} x86_64-pc-windows-msvc args: --release --find-interpreter --sdist sccache: 'true' manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 From 784d549e04942c96d65860ff932d39d4b6efc39c Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:19:11 -0800 Subject: [PATCH 062/108] update --- .github/workflows/build-python-wheels.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 7cc378d4c..8aea874ea 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -107,7 +107,6 @@ jobs: $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - name: Build wheels - if: ${{ matrix.settings.target != 'aarch64-pc-windows-msvc' }} uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: target: ${{ matrix.settings.target }} @@ -115,16 +114,6 @@ jobs: sccache: 'true' manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 working-directory: ${{ github.workspace }}/languages/python - - - name: Build wheels - if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} - uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 - with: - target: ${{ matrix.settings.target }} x86_64-pc-windows-msvc - args: --release --find-interpreter --sdist - sccache: 'true' - manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 - working-directory: ${{ github.workspace }}/languages/python - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 7505afc7db59293db859b37bdf8c3b58939f658a Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:42:34 -0800 Subject: [PATCH 063/108] try x86 path for build tools --- .github/workflows/build-python-wheels.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 8aea874ea..4f6f20646 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -104,16 +104,16 @@ jobs: shell: pwsh run: | # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components - $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" + $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 - with: - target: ${{ matrix.settings.target }} - args: --release --find-interpreter --sdist - sccache: 'true' - manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 - working-directory: ${{ github.workspace }}/languages/python + with: + target: ${{ matrix.settings.target }} + args: --release --find-interpreter --sdist + sccache: 'true' + manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 + working-directory: ${{ github.workspace }}/languages/python - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From c9559da2bbdc73b032dfe9fa7fa1a4a4f53e661e Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:44:13 -0800 Subject: [PATCH 064/108] fix YAML indentation --- .github/workflows/build-python-wheels.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 4f6f20646..b6f1b17e7 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -108,12 +108,12 @@ jobs: - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 - with: - target: ${{ matrix.settings.target }} - args: --release --find-interpreter --sdist - sccache: 'true' - manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 - working-directory: ${{ github.workspace }}/languages/python + with: + target: ${{ matrix.settings.target }} + args: --release --find-interpreter --sdist + sccache: 'true' + manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 + working-directory: ${{ github.workspace }}/languages/python - name: Upload artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From e8eaf3a3db9d41384dcaada97723107706f485f0 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:59:22 -0800 Subject: [PATCH 065/108] plz work --- .github/workflows/build-python-wheels.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index b6f1b17e7..cb9171714 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -105,6 +105,7 @@ jobs: run: | # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" + cargo install cargo-xwin - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 From a5b5cadea759022935ccf82ba35d30c727e88a1e Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 22 Nov 2023 10:13:22 -0800 Subject: [PATCH 066/108] remove Win ARM builds; provide sdist --- .github/workflows/build-python-wheels.yml | 242 +++++++++++----------- 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index cb9171714..c30aed295 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -1,123 +1,123 @@ --- -name: Build Python Wheels - -on: - pull_request: - push: - branches: - - "master" - - "rc" - - "hotfix-rc" - - "SM-989-create-build-and-publish-pipelines-for-the-python-language-wrapper" # TODO: remove this - workflow_dispatch: - -defaults: - run: - shell: bash - working-directory: languages/python - -jobs: - generate_schemas: - uses: ./.github/workflows/generate_schemas.yml - - setup: - name: Setup - runs-on: ubuntu-22.04 - outputs: - package_version: ${{ steps.retrieve-version.outputs.package_version }} - steps: - - name: Checkout repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - name: Get Package Version - id: retrieve-version - run: | - VERSION="$(grep -o '^version = ".*"' ../../crates/bitwarden-py/Cargo.toml | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+")" - echo "package_version=$VERSION" >> $GITHUB_OUTPUT - - build: - name: Building Python wheel for - ${{ matrix.settings.os }} - ${{ matrix.settings.target }} - runs-on: ${{ matrix.settings.os || 'ubuntu-latest' }} - needs: - - generate_schemas - - setup - env: - _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} - strategy: - fail-fast: false - matrix: - settings: - - os: macos-12 - target: x86_64-apple-darwin - - - os: macos-12 - target: aarch64-apple-darwin - - - os: windows-2022 - target: x86_64-pc-windows-msvc - - - os: windows-2022 - target: aarch64-pc-windows-msvc - - - os: ubuntu-22.04 - target: x86_64-unknown-linux-gnu - - - os: ubuntu-22.04 - target: aarch64-unknown-linux-gnu - - steps: - - name: Checkout repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - name: Setup Node - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0 - with: - node-version: 18 - - - name: Install rust - if: ${{ matrix.settings.target != 'aarch64-pc-windows-msvc' }} - uses: dtolnay/rust-toolchain@439cf607258077187679211f12aa6f19af4a0af7 # stable - with: - toolchain: stable - targets: ${{ matrix.settings.target }} - - - name: Install rust - if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} - uses: dtolnay/rust-toolchain@439cf607258077187679211f12aa6f19af4a0af7 # stable - with: - toolchain: stable - targets: ${{ matrix.settings.target }},x86_64-pc-windows-msvc - - - name: Cache cargo registry - uses: Swatinem/rust-cache@3cf7f8cc28d1b4e7d01e3783be10a97d55d483c8 # v2.7.1 - with: - key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.os }} - - - name: Retrieve schemas - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: schemas.py - path: ${{ github.workspace }}/languages/python/BitwardenClient/ - - - name: Setup Windows ARM64 - if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} - shell: pwsh - run: | - # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components - $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - cargo install cargo-xwin - - - name: Build wheels - uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 - with: - target: ${{ matrix.settings.target }} - args: --release --find-interpreter --sdist - sccache: 'true' - manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 - working-directory: ${{ github.workspace }}/languages/python + name: Build Python Wheels + + on: + pull_request: + push: + branches: + - "master" + - "rc" + - "hotfix-rc" + - "SM-989-create-build-and-publish-pipelines-for-the-python-language-wrapper" # TODO: remove this + workflow_dispatch: + + defaults: + run: + shell: bash + working-directory: languages/python + + jobs: + generate_schemas: + uses: ./.github/workflows/generate_schemas.yml + + setup: + name: Setup + runs-on: ubuntu-22.04 + outputs: + package_version: ${{ steps.retrieve-version.outputs.package_version }} + steps: + - name: Checkout repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Get Package Version + id: retrieve-version + run: | + VERSION="$(grep -o '^version = ".*"' ../../crates/bitwarden-py/Cargo.toml | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+")" + echo "package_version=$VERSION" >> $GITHUB_OUTPUT + + build: + name: Building Python wheel for - ${{ matrix.settings.os }} - ${{ matrix.settings.target }} + runs-on: ${{ matrix.settings.os || 'ubuntu-latest' }} + needs: + - generate_schemas + - setup + env: + _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + strategy: + fail-fast: false + matrix: + settings: + - os: macos-12 + target: x86_64-apple-darwin + + - os: macos-12 + target: aarch64-apple-darwin + + - os: windows-2022 + target: x86_64-pc-windows-msvc + + # # Win ARM builds fail: https://github.com/bitwarden/sdk/actions/runs/6960684148/job/18940738400#step:9:175 + # - os: windows-2022 + # target: aarch64-pc-windows-msvc + + - os: ubuntu-22.04 + target: x86_64-unknown-linux-gnu + + - os: ubuntu-22.04 + target: aarch64-unknown-linux-gnu + + steps: + - name: Checkout repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Setup Node + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0 + with: + node-version: 18 + + - name: Install rust + uses: dtolnay/rust-toolchain@439cf607258077187679211f12aa6f19af4a0af7 # stable + with: + toolchain: stable + targets: ${{ matrix.settings.target }} - - name: Upload artifact - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 - with: - name: BitwardenClient-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} - path: ${{ github.workspace }}/target/wheels/BitwardenClient*.whl + - name: Cache cargo registry + uses: Swatinem/rust-cache@3cf7f8cc28d1b4e7d01e3783be10a97d55d483c8 # v2.7.1 + with: + key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.os }} + + - name: Retrieve schemas + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: schemas.py + path: ${{ github.workspace }}/languages/python/BitwardenClient/ + + # - name: Setup Windows ARM64 + # if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} + # shell: pwsh + # run: | + # # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components + # $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" + + - name: Build wheels + uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 + with: + target: ${{ matrix.settings.target }} + args: --release --find-interpreter --sdist + sccache: 'true' + manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 + working-directory: ${{ github.workspace }}/languages/python + + - name: Upload wheels + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + with: + name: BitwardenClient-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} + path: ${{ github.workspace }}/target/wheels/BitwardenClient*.whl + + - name: Upload sdists + if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} # we only need one sdist + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + with: + name: BitwardenClient-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} + path: ${{ github.workspace }}/target/wheels/BitwardenClient-*.tar.gz + \ No newline at end of file From 515ca7e1283afd6c2277c34a38164275deddf1ee Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 22 Nov 2023 10:24:02 -0800 Subject: [PATCH 067/108] fix sdist artifact name; rm push trigger --- .github/workflows/build-python-wheels.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index c30aed295..f9df032ab 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -8,7 +8,6 @@ - "master" - "rc" - "hotfix-rc" - - "SM-989-create-build-and-publish-pipelines-for-the-python-language-wrapper" # TODO: remove this workflow_dispatch: defaults: @@ -118,6 +117,6 @@ if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} # we only need one sdist uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: - name: BitwardenClient-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} + name: BitwardenClient-${{ env._PACKAGE_VERSION }}-sdist path: ${{ github.workspace }}/target/wheels/BitwardenClient-*.tar.gz \ No newline at end of file From bcdf143cc418f43953df364f2d4bdcf3345fdbf7 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 27 Nov 2023 17:51:42 +0000 Subject: [PATCH 068/108] Merge branch 'master' into SM-989... --- .github/renovate.json | 28 +- .vscode/tasks.json | 4 +- Cargo.lock | 29 +- crates/bitwarden-api-api/Cargo.toml | 14 +- crates/bitwarden-api-identity/Cargo.toml | 14 +- crates/bitwarden-c/Cargo.toml | 1 - crates/bitwarden-cli/Cargo.toml | 4 +- crates/bitwarden-json/Cargo.toml | 2 +- crates/bitwarden-napi/Cargo.toml | 8 +- crates/bitwarden-py/Cargo.toml | 3 +- crates/bitwarden-uniffi/Cargo.toml | 6 +- crates/bitwarden-uniffi/src/crypto.rs | 13 + crates/bitwarden-wasm/Cargo.toml | 9 +- crates/bitwarden/Cargo.toml | 57 ++- crates/bitwarden/src/auth/api/request/mod.rs | 4 +- crates/bitwarden/src/client/client.rs | 17 + .../src/client/encryption_settings.rs | 38 +- crates/bitwarden/src/crypto/aes_ops.rs | 111 ++++- crates/bitwarden/src/crypto/enc_string.rs | 12 +- crates/bitwarden/src/crypto/master_key.rs | 11 +- crates/bitwarden/src/crypto/rsa.rs | 4 +- crates/bitwarden/src/mobile/client_crypto.rs | 8 +- crates/bitwarden/src/mobile/crypto.rs | 24 +- crates/bw/Cargo.toml | 12 +- crates/bws/Cargo.toml | 35 +- crates/sdk-schemas/Cargo.toml | 6 +- crates/sdk-schemas/src/main.rs | 1 + languages/kotlin/app/build.gradle | 1 + .../com/bitwarden/myapplication/Biometrics.kt | 132 ++++++ .../bitwarden/myapplication/MainActivity.kt | 369 +++++++++++----- languages/kotlin/doc.md | 32 ++ .../BitwardenClient/bitwarden_client.py | 90 ++-- languages/python/README.md | 6 +- languages/python/example.py | 44 ++ languages/python/login.py | 24 -- .../swift/iOS/App.xcodeproj/project.pbxproj | 12 +- languages/swift/iOS/App/Biometrics.swift | 92 ++++ languages/swift/iOS/App/ContentView.swift | 405 +++++++++++------- 38 files changed, 1186 insertions(+), 496 deletions(-) create mode 100644 languages/kotlin/app/src/main/java/com/bitwarden/myapplication/Biometrics.kt create mode 100644 languages/python/example.py delete mode 100644 languages/python/login.py create mode 100644 languages/swift/iOS/App/Biometrics.swift diff --git a/.github/renovate.json b/.github/renovate.json index 71e131e43..16222e52c 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -2,44 +2,26 @@ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "config:base", - "schedule:weekends", ":combinePatchMinorReleases", ":dependencyDashboard", ":maintainLockFilesWeekly", ":prConcurrentLimit10", ":rebaseStalePrs", - ":separateMajorReleases" + ":separateMajorReleases", + "group:monorepos", + "schedule:weekends" ], "separateMajorMinor": true, "enabledManagers": ["cargo", "github-actions", "npm", "nuget"], + "commitMessagePrefix": "[deps]:", + "commitMessageTopic": "{{depName}}", "packageRules": [ - { - "groupName": "npm minor", - "matchManagers": ["npm"], - "matchUpdateTypes": ["minor", "patch"] - }, - { - "matchManagers": ["cargo"], - "matchUpdateTypes": ["patch"], - "enabled": false - }, - { - "matchManagers": ["cargo"], - "matchUpdateTypes": ["minor"], - "matchCurrentVersion": ">=1.0.0", - "enabled": false - }, { "matchManagers": ["cargo"], "matchPackagePatterns": ["pyo3*"], "matchUpdateTypes": ["minor", "patch"], "groupName": "pyo3 non-major" }, - { - "groupName": "nuget minor", - "matchManagers": ["nuget"], - "matchUpdateTypes": ["minor", "patch"] - }, { "groupName": "gh minor", "matchManagers": ["github-actions"], diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 55dc10eb2..fa97b8fc7 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,7 +6,7 @@ "command": "build", "problemMatcher": ["$rustc"], "options": { - "cwd": "${workspaceFolder}/bitwarden-c/" + "cwd": "${workspaceFolder}/crates/bitwarden-c/" }, "group": { "kind": "build", @@ -19,7 +19,7 @@ "command": "build", "args": ["--release"], "options": { - "cwd": "${workspaceFolder}/bitwarden-c/" + "cwd": "${workspaceFolder}/crates/bitwarden-c/" }, "problemMatcher": ["$rustc"], "label": "rust: bitwarden-c release build" diff --git a/Cargo.lock b/Cargo.lock index e531227cf..5b6e3c19e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -203,11 +203,11 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.1.1" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655b9c7fe787d3b25cc0f804a1a8401790f0c5bc395beb5a64dc77d8de079105" +checksum = "dea8b3453dd7cc96711834b75400d671b73e3656975fa68d9f277163b7f7e316" dependencies = [ - "event-listener 3.1.0", + "event-listener 4.0.0", "event-listener-strategy", "pin-project-lite", ] @@ -351,6 +351,7 @@ dependencies = [ "serde_repr", "sha1", "sha2", + "subtle", "thiserror", "tokio", "uniffi", @@ -1062,9 +1063,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.1.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" dependencies = [ "concurrent-queue", "parking", @@ -1073,11 +1074,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96b852f1345da36d551b9473fa1e2b1eb5c5195585c6c018118bc92a8d91160" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" dependencies = [ - "event-listener 3.1.0", + "event-listener 4.0.0", "pin-project-lite", ] @@ -2849,18 +2850,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -3711,9 +3712,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58fe91d841bc04822c9801002db4ea904b9e4b8e6bbad25127b46eff8dc516b" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ "serde", ] diff --git a/crates/bitwarden-api-api/Cargo.toml b/crates/bitwarden-api-api/Cargo.toml index 70bc17311..ee96864dd 100644 --- a/crates/bitwarden-api-api/Cargo.toml +++ b/crates/bitwarden-api-api/Cargo.toml @@ -13,14 +13,14 @@ categories = ["api-bindings"] edition = "2018" [dependencies] -serde = "^1.0.163" -serde_derive = "^1.0.163" -serde_json = "^1.0.96" -serde_repr = "^0.1.12" -url = "^2.3.1" -uuid = { version = "^1.3.3", features = ["serde"] } +serde = ">=1.0.163, <2" +serde_derive = ">=1.0.163, <2" +serde_json = ">=1.0.96, <2" +serde_repr = ">=0.1.12, <0.2" +url = ">=2.3.1, <3" +uuid = { version = ">=1.3.3, <2", features = ["serde"] } [dependencies.reqwest] -version = "^0.11.18" +version = ">=0.11.18, <0.12" features = ["json", "multipart"] default-features = false diff --git a/crates/bitwarden-api-identity/Cargo.toml b/crates/bitwarden-api-identity/Cargo.toml index 0513f8b9a..5e650a034 100644 --- a/crates/bitwarden-api-identity/Cargo.toml +++ b/crates/bitwarden-api-identity/Cargo.toml @@ -13,14 +13,14 @@ categories = ["api-bindings"] edition = "2018" [dependencies] -serde = "^1.0.163" -serde_derive = "^1.0.163" -serde_json = "^1.0.96" -serde_repr = "^0.1.12" -url = "^2.3.1" -uuid = { version = "^1.3.3", features = ["serde"] } +serde = ">=1.0.163, <2" +serde_derive = ">=1.0.163, <2" +serde_json = ">=1.0.96, <2" +serde_repr = ">=0.1.12, <0.2" +url = ">=2.3.1, <3" +uuid = { version = ">=1.3.3, <2", features = ["serde"] } [dependencies.reqwest] -version = "^0.11.18" +version = ">=0.11.18, <0.12" features = ["json", "multipart"] default-features = false diff --git a/crates/bitwarden-c/Cargo.toml b/crates/bitwarden-c/Cargo.toml index 9181bedae..20f3f5229 100644 --- a/crates/bitwarden-c/Cargo.toml +++ b/crates/bitwarden-c/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2021" rust-version = "1.57" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] crate-type = ["lib", "staticlib", "cdylib"] bench = false diff --git a/crates/bitwarden-cli/Cargo.toml b/crates/bitwarden-cli/Cargo.toml index 606e24856..0966f7885 100644 --- a/crates/bitwarden-cli/Cargo.toml +++ b/crates/bitwarden-cli/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" rust-version = "1.57" [dependencies] -clap = { version = "4.3.0", features = ["derive"] } +clap = { version = "4.4.8", features = ["derive"] } color-eyre = "0.6" inquire = "0.6.2" -supports-color = "2.0.0" +supports-color = "2.1.0" diff --git a/crates/bitwarden-json/Cargo.toml b/crates/bitwarden-json/Cargo.toml index 2f6e031cf..22922882b 100644 --- a/crates/bitwarden-json/Cargo.toml +++ b/crates/bitwarden-json/Cargo.toml @@ -24,9 +24,9 @@ use_native_tls_vendored = ["bitwarden/use_native_tls_vendored"] use_rustls = ["bitwarden/use_rustls"] [dependencies] +log = ">=0.4.18, <0.5" schemars = ">=0.8.12, <0.9" serde = { version = ">=1.0, <2.0", features = ["derive"] } serde_json = ">=1.0.96, <2.0" -log = ">=0.4.18, <0.5" bitwarden = { path = "../bitwarden", default-features = false } diff --git a/crates/bitwarden-napi/Cargo.toml b/crates/bitwarden-napi/Cargo.toml index 505b68e57..63eae2b8b 100644 --- a/crates/bitwarden-napi/Cargo.toml +++ b/crates/bitwarden-napi/Cargo.toml @@ -16,15 +16,15 @@ rust-version = "1.57" crate-type = ["cdylib", "rlib"] [dependencies] -napi = {version="2", features=["async"]} +env_logger = "0.10.1" +log = "0.4.20" +napi = { version = "2", features = ["async"] } napi-derive = "2" -log = "0.4.18" -env_logger="0.10.0" bitwarden-json = { path = "../bitwarden-json", version = "0.3.0", features = ["secrets"] } [build-dependencies] -napi-build = "2.0.1" +napi-build = "2.1.0" [profile.release] lto = true diff --git a/crates/bitwarden-py/Cargo.toml b/crates/bitwarden-py/Cargo.toml index ca7947e06..f8dee7d4c 100644 --- a/crates/bitwarden-py/Cargo.toml +++ b/crates/bitwarden-py/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2021" rust-version = "1.57" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] name = "bitwarden_py" crate-type = ["cdylib"] @@ -19,7 +18,7 @@ bitwarden-json = { path = "../bitwarden-json", features = ["secrets", "use_rustl pyo3-build-config = { version = "0.20.0" } [target.'cfg(not(target_arch="wasm32"))'.dependencies] -tokio = { version = "1.28.2", features = ["rt-multi-thread", "macros"] } +tokio = { version = "1.34.0", features = ["rt-multi-thread", "macros"] } pyo3-asyncio = { version = "0.20.0", features = [ "attributes", "tokio-runtime", diff --git a/crates/bitwarden-uniffi/Cargo.toml b/crates/bitwarden-uniffi/Cargo.toml index 154f152c3..2f56e0441 100644 --- a/crates/bitwarden-uniffi/Cargo.toml +++ b/crates/bitwarden-uniffi/Cargo.toml @@ -12,14 +12,14 @@ crate-type = ["lib", "staticlib", "cdylib"] bench = false [dependencies] -async-lock = "3.0.0" +async-lock = "3.1.2" chrono = { version = ">=0.4.26, <0.5", features = [ "serde", "std", ], default-features = false } -env_logger = "0.10.0" -uniffi = "=0.25.1" +env_logger = "0.10.1" schemars = { version = ">=0.8, <0.9", optional = true } +uniffi = "=0.25.1" bitwarden = { path = "../bitwarden", features = ["mobile", "internal"] } diff --git a/crates/bitwarden-uniffi/src/crypto.rs b/crates/bitwarden-uniffi/src/crypto.rs index 1792a5bbc..804202e2f 100644 --- a/crates/bitwarden-uniffi/src/crypto.rs +++ b/crates/bitwarden-uniffi/src/crypto.rs @@ -32,4 +32,17 @@ impl ClientCrypto { .initialize_org_crypto(req) .await?) } + + /// Get the uses's decrypted encryption key. Note: It's very important + /// to keep this key safe, as it can be used to decrypt all of the user's data + pub async fn get_user_encryption_key(&self) -> Result { + Ok(self + .0 + .0 + .write() + .await + .crypto() + .get_user_encryption_key() + .await?) + } } diff --git a/crates/bitwarden-wasm/Cargo.toml b/crates/bitwarden-wasm/Cargo.toml index add03f0f3..7ad0d1c3e 100644 --- a/crates/bitwarden-wasm/Cargo.toml +++ b/crates/bitwarden-wasm/Cargo.toml @@ -4,18 +4,17 @@ version = "0.1.0" edition = "2021" rust-version = "1.57" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] crate-type = ["cdylib", "rlib"] [dependencies] +console_error_panic_hook = "0.1.7" +console_log = { version = "1.0.0", features = ["color"] } js-sys = "0.3.63" -serde = {version = "1.0.163", features = ["derive"] } +log = "0.4.20" +serde = { version = "1.0.193", features = ["derive"] } wasm-bindgen = { version = "=0.2.87", features = ["serde-serialize"] } wasm-bindgen-futures = "0.4.36" -console_error_panic_hook = "0.1.7" -console_log = { version = "1.0.0", features = ["color"] } -log = "0.4.18" bitwarden-json = { path = "../bitwarden-json", features = ["secrets"] } diff --git a/crates/bitwarden/Cargo.toml b/crates/bitwarden/Cargo.toml index 23d713634..0e333b334 100644 --- a/crates/bitwarden/Cargo.toml +++ b/crates/bitwarden/Cargo.toml @@ -24,45 +24,44 @@ use_native_tls_vendored = ["reqwest/native-tls-vendored"] use_rustls = ["reqwest/rustls-tls"] [dependencies] +aes = ">=0.8.2, <0.9" +argon2 = { version = ">=0.5.0, <0.6", features = [ + "alloc", +], default-features = false } +assert_matches = ">=1.5.0, <2.0" base64 = ">=0.21.2, <0.22" +bitwarden-api-api = { path = "../bitwarden-api-api", version = "=0.2.2" } +bitwarden-api-identity = { path = "../bitwarden-api-identity", version = "=0.2.2" } +cbc = { version = ">=0.1.2, <0.2", features = ["alloc"] } +chrono = { version = ">=0.4.26, <0.5", features = [ + "serde", + "std", +], default-features = false } +# We don't use this directly (it's used by rand), but we need it here to enable WASM support +getrandom = { version = ">=0.2.9, <0.3", features = ["js"] } +hkdf = ">=0.12.3, <0.13" +hmac = ">=0.12.1, <0.13" lazy_static = ">=1.4.0, <2.0" +log = ">=0.4.18, <0.5" +num-bigint = ">=0.4, <0.5" +num-traits = ">=0.2.15, <0.3" +pbkdf2 = { version = ">=0.12.1, <0.13", default-features = false } +rand = ">=0.8.5, <0.9" reqwest = { version = ">=0.11, <0.12", features = ["json"], default-features = false } +rsa = ">=0.9.2, <0.10" +schemars = { version = ">=0.8, <0.9", features = ["uuid1", "chrono"] } serde = { version = ">=1.0, <2.0", features = ["derive"] } serde_json = ">=1.0.96, <2.0" serde_qs = ">=0.12.0, <0.13" serde_repr = ">=0.1.12, <0.2" -schemars = { version = ">=0.8, <0.9", features = ["uuid1", "chrono"] } -log = ">=0.4.18, <0.5" -assert_matches = ">=1.5.0, <2.0" -thiserror = ">=1.0.40, <2.0" -aes = ">=0.8.2, <0.9" -cbc = { version = ">=0.1.2, <0.2", features = ["alloc"] } -hkdf = ">=0.12.3, <0.13" -hmac = ">=0.12.1, <0.13" -rsa = ">=0.9.2, <0.10" sha1 = ">=0.10.5, <0.11" sha2 = ">=0.10.6, <0.11" -pbkdf2 = { version = ">=0.12.1, <0.13", default-features = false } -argon2 = { version = ">=0.5.0, <0.6", features = [ - "alloc", -], default-features = false } -rand = ">=0.8.5, <0.9" -num-bigint = ">=0.4, <0.5" -num-traits = ">=0.2.15, <0.3" -uuid = { version = ">=1.3.3, <2.0", features = ["serde"] } -chrono = { version = ">=0.4.26, <0.5", features = [ - "serde", - "std", -], default-features = false } +subtle = ">=2.5.0, <3.0" +thiserror = ">=1.0.40, <2.0" uniffi = { version = "=0.25.1", optional = true } - -# We don't use this directly (it's used by rand), but we need it here to enable WASM support -getrandom = { version = ">=0.2.9", features = ["js"] } - -bitwarden-api-identity = { path = "../bitwarden-api-identity", version = "=0.2.2" } -bitwarden-api-api = { path = "../bitwarden-api-api", version = "=0.2.2" } +uuid = { version = ">=1.3.3, <2.0", features = ["serde"] } [dev-dependencies] rand_chacha = "0.3.1" -tokio = { version = "1.28.2", features = ["rt", "macros"] } -wiremock = "0.5.18" +tokio = { version = "1.34.0", features = ["rt", "macros"] } +wiremock = "0.5.21" diff --git a/crates/bitwarden/src/auth/api/request/mod.rs b/crates/bitwarden/src/auth/api/request/mod.rs index 1277fa969..85b36a983 100644 --- a/crates/bitwarden/src/auth/api/request/mod.rs +++ b/crates/bitwarden/src/auth/api/request/mod.rs @@ -35,10 +35,10 @@ async fn send_identity_connect_request( &configurations.identity.base_path )) .header( - "Content-Type", + reqwest::header::CONTENT_TYPE, "application/x-www-form-urlencoded; charset=utf-8", ) - .header("Accept", "application/json") + .header(reqwest::header::ACCEPT, "application/json") .header("Device-Type", configurations.device_type as usize); if let Some(ref user_agent) = configurations.identity.user_agent { diff --git a/crates/bitwarden/src/client/client.rs b/crates/bitwarden/src/client/client.rs index 213a12fb2..960ca9bda 100644 --- a/crates/bitwarden/src/client/client.rs +++ b/crates/bitwarden/src/client/client.rs @@ -222,6 +222,23 @@ impl Client { Ok(self.encryption_settings.as_ref().unwrap()) } + #[cfg(feature = "mobile")] + pub(crate) fn initialize_user_crypto_decrypted_key( + &mut self, + decrypted_user_key: &str, + private_key: EncString, + ) -> Result<&EncryptionSettings> { + let user_key = decrypted_user_key.parse::()?; + self.encryption_settings = Some(EncryptionSettings::new_decrypted_key( + user_key, + private_key, + )?); + Ok(self + .encryption_settings + .as_ref() + .expect("It was initialized on the previous line")) + } + pub(crate) fn initialize_crypto_single_key( &mut self, key: SymmetricCryptoKey, diff --git a/crates/bitwarden/src/client/encryption_settings.rs b/crates/bitwarden/src/client/encryption_settings.rs index 6533c7d2e..7c16725e7 100644 --- a/crates/bitwarden/src/client/encryption_settings.rs +++ b/crates/bitwarden/src/client/encryption_settings.rs @@ -27,6 +27,7 @@ impl std::fmt::Debug for EncryptionSettings { } impl EncryptionSettings { + /// Initialize the encryption settings with the user password and their encrypted keys #[cfg(feature = "internal")] pub(crate) fn new( login_method: &UserLoginMethod, @@ -45,24 +46,33 @@ impl EncryptionSettings { // Decrypt the user key let user_key = master_key.decrypt_user_key(user_key)?; - // Decrypt the private key with the user key - let private_key = { - let dec: Vec = private_key.decrypt_with_key(&user_key)?; - Some( - rsa::RsaPrivateKey::from_pkcs8_der(&dec) - .map_err(|_| CryptoError::InvalidKey)?, - ) - }; - - Ok(EncryptionSettings { - user_key, - private_key, - org_keys: HashMap::new(), - }) + Self::new_decrypted_key(user_key, private_key) } } } + /// Initialize the encryption settings with the decrypted user key and the encrypted user private key + /// This should only be used when unlocking the vault via biometrics or when the vault is set to lock: "never" + /// Otherwise handling the decrypted user key is dangerous and discouraged + #[cfg(feature = "internal")] + pub(crate) fn new_decrypted_key( + user_key: SymmetricCryptoKey, + private_key: EncString, + ) -> Result { + let private_key = { + let dec: Vec = private_key.decrypt_with_key(&user_key)?; + Some(rsa::RsaPrivateKey::from_pkcs8_der(&dec).map_err(|_| CryptoError::InvalidKey)?) + }; + + Ok(EncryptionSettings { + user_key, + private_key, + org_keys: HashMap::new(), + }) + } + + /// Initialize the encryption settings with only a single decrypted key. + /// This is used only for logging in Secrets Manager with an access token pub(crate) fn new_single_key(key: SymmetricCryptoKey) -> Self { EncryptionSettings { user_key: key, diff --git a/crates/bitwarden/src/crypto/aes_ops.rs b/crates/bitwarden/src/crypto/aes_ops.rs index 132718349..182986c3b 100644 --- a/crates/bitwarden/src/crypto/aes_ops.rs +++ b/crates/bitwarden/src/crypto/aes_ops.rs @@ -13,10 +13,10 @@ use aes::cipher::{ BlockEncryptMut, KeyIvInit, }; use hmac::Mac; -use rand::RngCore; +use subtle::ConstantTimeEq; use crate::{ - crypto::{EncString, PbkdfSha256Hmac, PBKDF_SHA256_HMAC_OUT_SIZE}, + crypto::{PbkdfSha256Hmac, PBKDF_SHA256_HMAC_OUT_SIZE}, error::{CryptoError, Result}, }; @@ -48,8 +48,8 @@ pub fn decrypt_aes256_hmac( mac_key: GenericArray, key: GenericArray, ) -> Result> { - let res = validate_mac(&mac_key, iv, &data)?; - if res != *mac { + let res = generate_mac(&mac_key, iv, &data)?; + if res.ct_ne(mac).into() { return Err(CryptoError::InvalidMac.into()); } decrypt_aes256(iv, data, key) @@ -63,10 +63,11 @@ pub fn decrypt_aes256_hmac( /// /// A AesCbc256_B64 EncString #[allow(unused)] -pub fn encrypt_aes256(data_dec: &[u8], key: GenericArray) -> Result { - let (iv, data) = encrypt_aes256_internal(data_dec, key); +pub fn encrypt_aes256(data_dec: &[u8], key: GenericArray) -> ([u8; 16], Vec) { + let rng = rand::thread_rng(); + let (iv, data) = encrypt_aes256_internal(rng, data_dec, key); - Ok(EncString::AesCbc256_B64 { iv, data }) + (iv, data) } /// Encrypt using AES-256 in CBC mode with MAC. @@ -80,11 +81,12 @@ pub fn encrypt_aes256_hmac( data_dec: &[u8], mac_key: GenericArray, key: GenericArray, -) -> Result { - let (iv, data) = encrypt_aes256_internal(data_dec, key); - let mac = validate_mac(&mac_key, &iv, &data)?; +) -> Result<([u8; 16], [u8; 32], Vec)> { + let rng = rand::thread_rng(); + let (iv, data) = encrypt_aes256_internal(rng, data_dec, key); + let mac = generate_mac(&mac_key, &iv, &data)?; - Ok(EncString::AesCbc256_HmacSha256_B64 { iv, mac, data }) + Ok((iv, mac, data)) } /// Encrypt using AES-256 in CBC mode. @@ -92,17 +94,21 @@ pub fn encrypt_aes256_hmac( /// Used internally by: /// - [encrypt_aes256] /// - [encrypt_aes256_hmac] -fn encrypt_aes256_internal(data_dec: &[u8], key: GenericArray) -> ([u8; 16], Vec) { +fn encrypt_aes256_internal( + mut rng: impl rand::RngCore, + data_dec: &[u8], + key: GenericArray, +) -> ([u8; 16], Vec) { let mut iv = [0u8; 16]; - rand::thread_rng().fill_bytes(&mut iv); + rng.fill_bytes(&mut iv); let data = cbc::Encryptor::::new(&key, &iv.into()) .encrypt_padded_vec_mut::(data_dec); (iv, data) } -/// Validate a MAC using HMAC-SHA256. -fn validate_mac(mac_key: &[u8], iv: &[u8], data: &[u8]) -> Result<[u8; 32]> { +/// Generate a MAC using HMAC-SHA256. +fn generate_mac(mac_key: &[u8], iv: &[u8], data: &[u8]) -> Result<[u8; 32]> { let mut hmac = PbkdfSha256Hmac::new_from_slice(mac_key).expect("HMAC can take key of any size"); hmac.update(iv); hmac.update(data); @@ -112,3 +118,78 @@ fn validate_mac(mac_key: &[u8], iv: &[u8], data: &[u8]) -> Result<[u8; 32]> { Ok(mac) } + +#[cfg(test)] +mod tests { + use aes::cipher::generic_array::sequence::GenericSequence; + use base64::Engine; + use rand::SeedableRng; + + use crate::util::BASE64_ENGINE; + + use super::*; + + /// Helper function for generating a `GenericArray` of size 32 with each element being + /// a multiple of a given increment, starting from a given offset. + fn generate_generic_array(offset: u8, increment: u8) -> GenericArray { + GenericArray::generate(|i| offset + i as u8 * increment) + } + + /// Helper function for generating a vector of a given size with each element being + /// a multiple of a given increment, starting from a given offset. + fn generate_vec(length: usize, offset: u8, increment: u8) -> Vec { + (0..length).map(|i| offset + i as u8 * increment).collect() + } + + #[test] + fn test_encrypt_aes256_internal() { + let key = generate_generic_array(0, 1); + + let rng = rand_chacha::ChaCha8Rng::from_seed([0u8; 32]); + let result = encrypt_aes256_internal(rng, "EncryptMe!".as_bytes(), key); + assert_eq!( + result, + ( + [62, 0, 239, 47, 137, 95, 64, 214, 127, 91, 184, 232, 31, 9, 165, 161], + vec![214, 76, 187, 97, 58, 146, 212, 140, 95, 164, 177, 204, 179, 133, 172, 148] + ) + ); + } + + #[test] + fn test_generate_mac() { + let mac_key = generate_vec(16, 0, 16); + + let iv = generate_vec(16, 0, 16); + let data = generate_vec(16, 0, 16); + + let result = generate_mac(&mac_key, &iv, &data); + + assert!(result.is_ok()); + let mac = result.unwrap(); + assert_eq!(mac.len(), 32); + } + + #[test] + fn test_decrypt_aes256() { + let iv = generate_vec(16, 0, 1); + let iv: &[u8; 16] = iv.as_slice().try_into().unwrap(); + let key = generate_generic_array(0, 1); + let data = BASE64_ENGINE.decode("ByUF8vhyX4ddU9gcooznwA==").unwrap(); + + let decrypted = decrypt_aes256(iv, data, key).unwrap(); + + assert_eq!(String::from_utf8(decrypted).unwrap(), "EncryptMe!"); + } + + #[test] + fn test_encrypt_decrypt_aes256() { + let key = generate_generic_array(0, 1); + let data = "EncryptMe!"; + + let (iv, encrypted) = encrypt_aes256(data.as_bytes(), key); + let decrypted = decrypt_aes256(&iv, encrypted, key).unwrap(); + + assert_eq!(String::from_utf8(decrypted).unwrap(), "EncryptMe!"); + } +} diff --git a/crates/bitwarden/src/crypto/enc_string.rs b/crates/bitwarden/src/crypto/enc_string.rs index ac7f3fc6b..09f877c50 100644 --- a/crates/bitwarden/src/crypto/enc_string.rs +++ b/crates/bitwarden/src/crypto/enc_string.rs @@ -1,5 +1,6 @@ use std::{fmt::Display, str::FromStr}; +use aes::cipher::{generic_array::GenericArray, typenum::U32}; use base64::Engine; use serde::{de::Visitor, Deserialize}; @@ -331,6 +332,15 @@ impl serde::Serialize for EncString { } impl EncString { + pub(crate) fn encrypt_aes256_hmac( + data_dec: &[u8], + mac_key: GenericArray, + key: GenericArray, + ) -> Result { + let (iv, mac, data) = super::encrypt_aes256_hmac(data_dec, mac_key, key)?; + Ok(EncString::AesCbc256_HmacSha256_B64 { iv, mac, data }) + } + /// The numerical representation of the encryption type of the [EncString]. const fn enc_type(&self) -> u8 { match self { @@ -357,7 +367,7 @@ fn invalid_len_error(expected: usize) -> impl Fn(Vec) -> EncStringParseError impl LocateKey for EncString {} impl KeyEncryptable for &[u8] { fn encrypt_with_key(self, key: &SymmetricCryptoKey) -> Result { - super::encrypt_aes256_hmac(self, key.mac_key.ok_or(CryptoError::InvalidMac)?, key.key) + EncString::encrypt_aes256_hmac(self, key.mac_key.ok_or(CryptoError::InvalidMac)?, key.key) } } diff --git a/crates/bitwarden/src/crypto/master_key.rs b/crates/bitwarden/src/crypto/master_key.rs index b2c8e6e5f..fdcf93dde 100644 --- a/crates/bitwarden/src/crypto/master_key.rs +++ b/crates/bitwarden/src/crypto/master_key.rs @@ -4,8 +4,8 @@ use rand::Rng; use sha2::Digest; use super::{ - encrypt_aes256_hmac, hkdf_expand, EncString, KeyDecryptable, PbkdfSha256Hmac, - SymmetricCryptoKey, UserKey, PBKDF_SHA256_HMAC_OUT_SIZE, + hkdf_expand, EncString, KeyDecryptable, PbkdfSha256Hmac, SymmetricCryptoKey, UserKey, + PBKDF_SHA256_HMAC_OUT_SIZE, }; use crate::{client::kdf::Kdf, error::Result, util::BASE64_ENGINE}; @@ -61,8 +61,11 @@ fn make_user_key( rng.fill(&mut user_key); let stretched_key = stretch_master_key(master_key)?; - let protected = - encrypt_aes256_hmac(&user_key, stretched_key.mac_key.unwrap(), stretched_key.key)?; + let protected = EncString::encrypt_aes256_hmac( + &user_key, + stretched_key.mac_key.unwrap(), + stretched_key.key, + )?; let u: &[u8] = &user_key; Ok((UserKey::new(SymmetricCryptoKey::try_from(u)?), protected)) diff --git a/crates/bitwarden/src/crypto/rsa.rs b/crates/bitwarden/src/crypto/rsa.rs index 0d2d135b9..f105dbfe2 100644 --- a/crates/bitwarden/src/crypto/rsa.rs +++ b/crates/bitwarden/src/crypto/rsa.rs @@ -5,7 +5,7 @@ use rsa::{ }; use crate::{ - crypto::{encrypt_aes256_hmac, EncString, SymmetricCryptoKey}, + crypto::{EncString, SymmetricCryptoKey}, error::{Error, Result}, util::BASE64_ENGINE, }; @@ -33,7 +33,7 @@ pub(super) fn make_key_pair(key: &SymmetricCryptoKey) -> Result { .to_pkcs8_der() .map_err(|_| Error::Internal("unable to create private key"))?; - let protected = encrypt_aes256_hmac(pkcs.as_bytes(), key.mac_key.unwrap(), key.key)?; + let protected = EncString::encrypt_aes256_hmac(pkcs.as_bytes(), key.mac_key.unwrap(), key.key)?; Ok(RsaKeyPair { public: b64, diff --git a/crates/bitwarden/src/mobile/client_crypto.rs b/crates/bitwarden/src/mobile/client_crypto.rs index c0edb1982..118e02726 100644 --- a/crates/bitwarden/src/mobile/client_crypto.rs +++ b/crates/bitwarden/src/mobile/client_crypto.rs @@ -3,7 +3,8 @@ use crate::Client; use crate::{ error::Result, mobile::crypto::{ - initialize_org_crypto, initialize_user_crypto, InitOrgCryptoRequest, InitUserCryptoRequest, + get_user_encryption_key, initialize_org_crypto, initialize_user_crypto, + InitOrgCryptoRequest, InitUserCryptoRequest, }, }; @@ -21,6 +22,11 @@ impl<'a> ClientCrypto<'a> { pub async fn initialize_org_crypto(&mut self, req: InitOrgCryptoRequest) -> Result<()> { initialize_org_crypto(self.client, req).await } + + #[cfg(feature = "internal")] + pub async fn get_user_encryption_key(&mut self) -> Result { + get_user_encryption_key(self.client).await + } } impl<'a> Client { diff --git a/crates/bitwarden/src/mobile/crypto.rs b/crates/bitwarden/src/mobile/crypto.rs index 2cf850279..9c2c8478f 100644 --- a/crates/bitwarden/src/mobile/crypto.rs +++ b/crates/bitwarden/src/mobile/crypto.rs @@ -3,7 +3,12 @@ use std::collections::HashMap; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::{client::kdf::Kdf, crypto::EncString, error::Result, Client}; +use crate::{ + client::kdf::Kdf, + crypto::EncString, + error::{Error, Result}, + Client, +}; #[cfg(feature = "internal")] #[derive(Serialize, Deserialize, Debug, JsonSchema)] @@ -31,6 +36,10 @@ pub enum InitUserCryptoMethod { /// The user's encrypted symmetric crypto key user_key: String, }, + DecryptedKey { + /// The user's decrypted encryption key, obtained using `get_user_encryption_key` + decrypted_user_key: String, + }, } #[cfg(feature = "internal")] @@ -49,6 +58,9 @@ pub async fn initialize_user_crypto(client: &mut Client, req: InitUserCryptoRequ let user_key: EncString = user_key.parse()?; client.initialize_user_crypto(&password, user_key, private_key)?; } + InitUserCryptoMethod::DecryptedKey { decrypted_user_key } => { + client.initialize_user_crypto_decrypted_key(&decrypted_user_key, private_key)?; + } } Ok(()) @@ -69,3 +81,13 @@ pub async fn initialize_org_crypto(client: &mut Client, req: InitOrgCryptoReques client.initialize_org_crypto(organization_keys)?; Ok(()) } + +#[cfg(feature = "internal")] +pub async fn get_user_encryption_key(client: &mut Client) -> Result { + let user_key = client + .get_encryption_settings()? + .get_key(&None) + .ok_or(Error::VaultLocked)?; + + Ok(user_key.to_base64()) +} diff --git a/crates/bw/Cargo.toml b/crates/bw/Cargo.toml index 0793470b3..9ceb2b153 100644 --- a/crates/bw/Cargo.toml +++ b/crates/bw/Cargo.toml @@ -12,15 +12,13 @@ Bitwarden Password Manager CLI """ keywords = ["bitwarden", "password-manager", "cli"] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -clap = { version = "4.3.0", features = ["derive", "env"] } -tokio = { version = "1.28.2", features = ["rt-multi-thread", "macros"] } -log = "0.4.18" -env_logger = "0.10.0" +clap = { version = "4.4.8", features = ["derive", "env"] } color-eyre = "0.6" +env_logger = "0.10.1" inquire = "0.6.2" +log = "0.4.20" +tokio = { version = "1.34.0", features = ["rt-multi-thread", "macros"] } bitwarden = { path = "../bitwarden", version = "0.3.1", features = [ "internal", @@ -29,4 +27,4 @@ bitwarden = { path = "../bitwarden", version = "0.3.1", features = [ bitwarden-cli = { path = "../bitwarden-cli", version = "0.1.0" } [dev-dependencies] -tempfile = "3.5.0" +tempfile = "3.8.1" diff --git a/crates/bws/Cargo.toml b/crates/bws/Cargo.toml index 909c8736c..a57ea1e3c 100644 --- a/crates/bws/Cargo.toml +++ b/crates/bws/Cargo.toml @@ -12,34 +12,35 @@ Bitwarden Secrets Manager CLI """ keywords = ["bitwarden", "secrets-manager", "cli"] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] bat = { version = "0.24.0", features = [ "regex-onig", ], default-features = false } -chrono = { version = "0.4.26", features = [ +chrono = { version = "0.4.31", features = [ "clock", "std", ], default-features = false } -clap = { version = "4.3.0", features = ["derive", "env", "string"] } -clap_complete = "4.3.2" +clap = { version = "4.4.8", features = ["derive", "env", "string"] } +clap_complete = "4.4.4" color-eyre = "0.6" -comfy-table = "^7.0.1" +comfy-table = "^7.1.0" directories = "5.0.1" -env_logger = "0.10.0" -log = "0.4.18" -serde = "^1.0.163" -serde_json = "^1.0.96" +env_logger = "0.10.1" +log = "0.4.20" +regex = { version = "1.10.2", features = [ + "std", + "perf", +], default-features = false } +serde = "^1.0.193" +serde_json = "^1.0.108" serde_yaml = "0.9" -supports-color = "2.0.0" -thiserror = "1.0.40" -tokio = { version = "1.28.2", features = ["rt-multi-thread", "macros"] } -toml = "0.8.0" -uuid = { version = "^1.3.3", features = ["serde"] } -regex = { version = "1.10.2", features=["std", "perf"], default-features=false } +supports-color = "2.1.0" +thiserror = "1.0.50" +tokio = { version = "1.34.0", features = ["rt-multi-thread", "macros"] } +toml = "0.8.8" +uuid = { version = "^1.6.1", features = ["serde"] } bitwarden = { path = "../bitwarden", version = "0.3.1", features = ["secrets"] } [dev-dependencies] -tempfile = "3.5.0" +tempfile = "3.8.1" diff --git a/crates/sdk-schemas/Cargo.toml b/crates/sdk-schemas/Cargo.toml index 64ce34274..2e7706200 100644 --- a/crates/sdk-schemas/Cargo.toml +++ b/crates/sdk-schemas/Cargo.toml @@ -12,10 +12,10 @@ internal = [ ] [dependencies] -schemars = { version = "0.8.12", features = ["preserve_order"] } -serde_json = "1.0.96" -anyhow = "1.0.71" +anyhow = "1.0.75" itertools = "0.12.0" +schemars = { version = "0.8.16", features = ["preserve_order"] } +serde_json = "1.0.108" bitwarden = { path = "../bitwarden" } bitwarden-json = { path = "../bitwarden-json" } diff --git a/crates/sdk-schemas/src/main.rs b/crates/sdk-schemas/src/main.rs index 9d7e52a47..ef7a2db83 100644 --- a/crates/sdk-schemas/src/main.rs +++ b/crates/sdk-schemas/src/main.rs @@ -99,6 +99,7 @@ fn main() -> Result<()> { write_schema_for_response! { bitwarden::auth::login::ApiKeyLoginResponse, bitwarden::auth::login::PasswordLoginResponse, + bitwarden::auth::login::AccessTokenLoginResponse, bitwarden::secrets_manager::secrets::SecretIdentifiersResponse, bitwarden::secrets_manager::secrets::SecretResponse, bitwarden::secrets_manager::secrets::SecretsResponse, diff --git a/languages/kotlin/app/build.gradle b/languages/kotlin/app/build.gradle index 709e32889..ef42d43bb 100644 --- a/languages/kotlin/app/build.gradle +++ b/languages/kotlin/app/build.gradle @@ -60,6 +60,7 @@ dependencies { implementation 'androidx.compose.ui:ui-graphics' implementation 'androidx.compose.ui:ui-tooling-preview' implementation 'androidx.compose.material3:material3' + implementation "androidx.biometric:biometric:1.1.0" implementation "io.ktor:ktor-client-core:2.3.3" implementation "io.ktor:ktor-client-cio:2.3.3" implementation "io.ktor:ktor-client-content-negotiation:2.3.3" diff --git a/languages/kotlin/app/src/main/java/com/bitwarden/myapplication/Biometrics.kt b/languages/kotlin/app/src/main/java/com/bitwarden/myapplication/Biometrics.kt new file mode 100644 index 000000000..8f8115e8d --- /dev/null +++ b/languages/kotlin/app/src/main/java/com/bitwarden/myapplication/Biometrics.kt @@ -0,0 +1,132 @@ +package com.bitwarden.myapplication + +import android.os.Build +import android.security.keystore.KeyGenParameterSpec +import android.security.keystore.KeyProperties +import android.util.Log +import androidx.biometric.BiometricManager +import androidx.biometric.BiometricManager.Authenticators +import androidx.biometric.BiometricPrompt +import androidx.biometric.BiometricPrompt.CryptoObject +import androidx.core.content.ContextCompat +import androidx.fragment.app.FragmentActivity +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import java.security.KeyStore +import java.util.Base64 +import javax.crypto.Cipher +import javax.crypto.KeyGenerator +import javax.crypto.SecretKey +import javax.crypto.spec.GCMParameterSpec + +/** + * IMPORTANT: This file is provided only for the purpose of demostrating the use of the biometric unlock functionality. + * It hasn't gone through a throrough security review and should not be considered production ready. It also doesn't + * handle a lot of errors and edge cases that a production application would need to deal with. + * Developers are encouraged to review and improve the code as needed to meet their security requirements. + * Additionally, we recommend to consult with security experts and conduct thorough testing before using the code in production. + */ + +class Biometric(private var activity: FragmentActivity) { + private var promptInfo: BiometricPrompt.PromptInfo = + BiometricPrompt.PromptInfo.Builder().setTitle("Unlock") + .setSubtitle("Bitwarden biometric unlock") + .setDescription("Confirm biometric to continue").setConfirmationRequired(true) + .setNegativeButtonText("Use account password").build() + + suspend fun encryptString( + keyName: String, plaintext: String, callback: (String, String) -> Unit + ) { + if (canAuthenticate()) { + val cipher = getCipher() + cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(keyName)) + + val bio = createBiometricPrompt { + val ciphertext = it.cipher!!.doFinal(plaintext.toByteArray()) + callback( + String(Base64.getEncoder().encode(ciphertext)), + String(Base64.getEncoder().encode(cipher.iv)) + ) + } + CoroutineScope(Dispatchers.Main).async { + bio.authenticate(promptInfo, CryptoObject(cipher)) + }.await() + } + } + + suspend fun decryptString( + keyName: String, encrypted: String, initializationVector: String, callback: (String) -> Unit + ) { + if (canAuthenticate()) { + val enc = Base64.getDecoder().decode(encrypted) + val iv = Base64.getDecoder().decode(initializationVector) + + val cipher = getCipher() + cipher.init(Cipher.DECRYPT_MODE, getSecretKey(keyName), GCMParameterSpec(128, iv)) + + val bio = createBiometricPrompt { + callback(String(it.cipher!!.doFinal(enc))) + } + + CoroutineScope(Dispatchers.Main).async { + bio.authenticate(promptInfo, CryptoObject(cipher)) + }.await() + } + } + + private fun canAuthenticate() = BiometricManager.from(activity) + .canAuthenticate(Authenticators.BIOMETRIC_STRONG) == BiometricManager.BIOMETRIC_SUCCESS + + private fun createBiometricPrompt(processData: (CryptoObject) -> Unit): BiometricPrompt { + return BiometricPrompt(activity, + ContextCompat.getMainExecutor(activity), + object : BiometricPrompt.AuthenticationCallback() { + override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { + super.onAuthenticationError(errorCode, errString) + Log.e("Biometric", "$errorCode :: $errString") + } + + override fun onAuthenticationFailed() { + super.onAuthenticationFailed() + Log.e("Biometric", "Authentication failed for an unknown reason") + } + + override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { + super.onAuthenticationSucceeded(result) + processData(result.cryptoObject!!) + } + }) + } + + private fun getCipher(): Cipher { + val transform = + "${KeyProperties.KEY_ALGORITHM_AES}/${KeyProperties.BLOCK_MODE_GCM}/${KeyProperties.ENCRYPTION_PADDING_NONE}" + return Cipher.getInstance(transform) + } + + private fun getSecretKey(keyName: String): SecretKey { + // If the SecretKey exists, return it + val keyStore = KeyStore.getInstance("AndroidKeyStore") + keyStore.load(null) + keyStore.getKey(keyName, null)?.let { return it as SecretKey } + + // Otherwise, we generate a new one + val keyGenParams = KeyGenParameterSpec.Builder( + keyName, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT + ).apply { + setBlockModes(KeyProperties.BLOCK_MODE_GCM) + setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) + setKeySize(256) + setUserAuthenticationRequired(true) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + setUserAuthenticationParameters(0, KeyProperties.AUTH_BIOMETRIC_STRONG) + } + }.build() + + val keyGenerator = + KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore") + keyGenerator.init(keyGenParams) + return keyGenerator.generateKey() + } +} diff --git a/languages/kotlin/app/src/main/java/com/bitwarden/myapplication/MainActivity.kt b/languages/kotlin/app/src/main/java/com/bitwarden/myapplication/MainActivity.kt index 13dec7d0e..3c03c6bca 100644 --- a/languages/kotlin/app/src/main/java/com/bitwarden/myapplication/MainActivity.kt +++ b/languages/kotlin/app/src/main/java/com/bitwarden/myapplication/MainActivity.kt @@ -1,15 +1,27 @@ package com.bitwarden.myapplication +import android.content.Context import android.os.Bundle -import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.Checkbox +import androidx.compose.material3.Divider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text -import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.fragment.app.FragmentActivity import com.bitwarden.core.DateTime import com.bitwarden.core.Folder import com.bitwarden.core.InitOrgCryptoRequest @@ -44,151 +56,272 @@ import java.security.cert.X509Certificate import java.util.Base64 import javax.net.ssl.X509TrustManager -class MainActivity : ComponentActivity() { +/** + * IMPORTANT: This file is provided only for the purpose of demostrating the use of the SDK functionality. + * It hasn't gone through a throrough security review and should not be considered production ready. It also doesn't + * handle a lot of errors and edge cases that a production application would need to deal with. + * Developers are encouraged to review and improve the code as needed to meet their security requirements. + * Additionally, we recommend to consult with security experts and conduct thorough testing before using the code in production. + */ + +const val SERVER_URL = "https://10.0.2.2:8080/" +const val API_URL = SERVER_URL + "api/" +const val IDENTITY_URL = SERVER_URL + "identity/" + +const val EMAIL = "test@bitwarden.com" +const val PASSWORD = "asdfasdfasdf" + +// We should separate keys for each user by appending the user_id +const val BIOMETRIC_KEY = "biometric_key" + +class MainActivity : FragmentActivity() { + private lateinit var biometric: Biometric + private lateinit var client: Client + private lateinit var http: HttpClient + + private var accessToken = "" + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + biometric = Biometric(this) + client = Client(null) + http = httpClient() + + setContent { + MyApplicationTheme { + // A surface container using the 'background' color from the theme + Surface( + modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally + ) { - val SERVER_URL = "https://10.0.2.2:8080/" - val API_URL = SERVER_URL + "api/" - val IDENTITY_URL = SERVER_URL + "identity/" + val setupBiometrics = remember { mutableStateOf(true) } + val outputText = remember { mutableStateOf("") } - val EMAIL = "test@bitwarden.com" - val PASSWORD = "asdfasdfasdf" + Row { + Checkbox(checked = setupBiometrics.value, + onCheckedChange = { isChecked -> + setupBiometrics.value = isChecked + }) + Text( + "Setup biometric unlock after login", + modifier = Modifier.align(CenterVertically) + ) + } - GlobalScope.launch { - var client = Client(null) - val http = httpClient() + Button({ + GlobalScope.launch { + clientExamplePassword( + client, http, outputText, setupBiometrics.value + ) + } + }) { + Text("Login with username + password") + } - ///////////////////////////// Get master password hash ///////////////////////////// - @Serializable - data class PreloginRequest(val email: String) + Divider( + color = Color.Black, + thickness = 1.dp, + modifier = Modifier.padding(30.dp) + ) - @Serializable - data class PreloginResponse( - val kdf: UInt, - val kdfIterations: UInt, - val kdfMemory: UInt?, - val kdfParallelism: UInt? - ) + Button({ + GlobalScope.launch { + clientExampleBiometrics(client, http, outputText) + } + }) { + Text("Unlock with biometrics") + } - val prelogin_body = http.post(IDENTITY_URL + "accounts/prelogin") { - contentType(ContentType.Application.Json) - setBody(PreloginRequest(EMAIL)) - }.body() - val kdf = if (prelogin_body.kdf == 0u) { - Kdf.Pbkdf2(prelogin_body.kdfIterations) - } else { - Kdf.Argon2id( - prelogin_body.kdfIterations, - prelogin_body.kdfMemory!!, - prelogin_body.kdfParallelism!! - ) + Button({ + GlobalScope.launch { + client.destroy() + client = Client(null) + outputText.value = "OK" + } + }) { + Text("Lock & reset client") + } + + Text( + "Output: " + outputText.value, + modifier = Modifier.padding(vertical = 10.dp) + ) + } + } } - val masterPasswordHash = client.auth().hashPassword(EMAIL, PASSWORD, kdf) + } + } + + private suspend fun clientExamplePassword( + client: Client, http: HttpClient, outputText: MutableState, setupBiometrics: Boolean + ) { + println("### Logging in with username and password ###") + ///////////////////////////// Get master password hash ///////////////////////////// + @Serializable + data class PreloginRequest(val email: String) - ///////////////////////////// Login ///////////////////////////// + @Serializable + data class PreloginResponse( + val kdf: UInt, val kdfIterations: UInt, val kdfMemory: UInt?, val kdfParallelism: UInt? + ) - @Serializable - data class LoginResponse( - val Key: String, - val PrivateKey: String, - val access_token: String, - val refresh_token: String, + val prelogin_body = http.post(IDENTITY_URL + "accounts/prelogin") { + contentType(ContentType.Application.Json) + setBody(PreloginRequest(EMAIL)) + }.body() + val kdf = if (prelogin_body.kdf == 0u) { + Kdf.Pbkdf2(prelogin_body.kdfIterations) + } else { + Kdf.Argon2id( + prelogin_body.kdfIterations, + prelogin_body.kdfMemory!!, + prelogin_body.kdfParallelism!! ) + } + val masterPasswordHash = client.auth().hashPassword(EMAIL, PASSWORD, kdf) - val loginBody = http.post(IDENTITY_URL + "connect/token") { - contentType(ContentType.Application.Json) - header("Auth-Email", Base64.getEncoder().encodeToString(EMAIL.toByteArray())) - setBody(FormDataContent(Parameters.build { - append("scope", "api offline_access") - append("client_id", "web") - append("deviceType", "12") - append("deviceIdentifier", "0745d426-8dab-484a-9816-4959721d77c7") - append("deviceName", "edge") - - append("grant_type", "password") - append("username", EMAIL) - append("password", masterPasswordHash) - })) - }.body() - - ///////////////////////////// Sync ///////////////////////////// - - val syncBody = http.get(API_URL + "sync?excludeDomains=true") { - bearerAuth(loginBody.access_token) - }.body() - - val folders = (syncBody["folders"] as JsonArray).map { - val o = it as JsonObject - Folder( - (o["id"] as JsonPrimitive).content, - (o["name"] as JsonPrimitive).content, - DateTime.parse( - (o["revisionDate"] as JsonPrimitive).content - ) - ) - } + ///////////////////////////// Login ///////////////////////////// - ///////////////////////////// Initialize crypto ///////////////////////////// - val orgs = ((syncBody["profile"] as JsonObject)["organizations"]) as JsonArray - val orgKeys = HashMap() + @Serializable + data class LoginResponse( + val Key: String, + val PrivateKey: String, + val access_token: String, + val refresh_token: String, + ) - for (org in orgs) { - val o = org as JsonObject - orgKeys[(o["id"] as JsonPrimitive).content] = (o["key"] as JsonPrimitive).content - } + val loginBody = http.post(IDENTITY_URL + "connect/token") { + contentType(ContentType.Application.Json) + header("Auth-Email", Base64.getEncoder().encodeToString(EMAIL.toByteArray())) + setBody(FormDataContent(Parameters.build { + append("scope", "api offline_access") + append("client_id", "web") + append("deviceType", "12") + append("deviceIdentifier", "0745d426-8dab-484a-9816-4959721d77c7") + append("deviceName", "edge") - client.crypto().initializeUserCrypto( - InitUserCryptoRequest( - kdfParams = kdf, - email = EMAIL, - privateKey = loginBody.PrivateKey, - method = InitUserCryptoMethod.Password( - password = PASSWORD, - userKey = loginBody.Key - ) - ) - ) + append("grant_type", "password") + append("username", EMAIL) + append("password", masterPasswordHash) + })) + }.body() - client.crypto().initializeOrgCrypto( - InitOrgCryptoRequest( - organizationKeys = orgKeys + client.crypto().initializeUserCrypto( + InitUserCryptoRequest( + kdfParams = kdf, + email = EMAIL, + privateKey = loginBody.PrivateKey, + method = InitUserCryptoMethod.Password( + password = PASSWORD, userKey = loginBody.Key ) ) + ) - ///////////////////////////// Decrypt some folders ///////////////////////////// + accessToken = loginBody.access_token - val decryptedFolders = client.vault().folders().decryptList(folders) + decryptVault(client, http, outputText) - println(decryptedFolders) + if (setupBiometrics) { + // Save values for future logins + val sharedPref = getPreferences(Context.MODE_PRIVATE) + with(sharedPref.edit()) { + putString("accessToken", accessToken) + putString("privateKey", loginBody.PrivateKey) - } + putInt("kdfType", prelogin_body.kdf.toInt()) + putInt("kdfIterations", prelogin_body.kdfIterations.toInt()) + putInt("kdfMemory", (prelogin_body.kdfMemory ?: 0u).toInt()) + putInt("kdfParallelism", (prelogin_body.kdfParallelism ?: 0u).toInt()) - setContent { - MyApplicationTheme { - // A surface container using the 'background' color from the theme - Surface( - modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background - ) { - Greeting("Hey") + // TODO: This should be protected by Android's secure KeyStore + val decryptedKey = client.crypto().getUserEncryptionKey() + + biometric.encryptString(BIOMETRIC_KEY, decryptedKey) { key, iv -> + putString("encryptedUserKey", key) + putString("encryptedUserKeyIv", iv) + apply() } } } } -} -@Composable -fun Greeting(name: String, modifier: Modifier = Modifier) { - Text( - text = "Hello $name!", modifier = modifier - ) -} + private suspend fun clientExampleBiometrics( + client: Client, http: HttpClient, outputText: MutableState + ) { + println("### Unlocking with Biometrics ###") + + val pref = getPreferences(Context.MODE_PRIVATE) + accessToken = pref.getString("accessToken", "").orEmpty() + val privateKey = pref.getString("privateKey", "") + + val kdf = if (pref.getInt("kdfType", 0) == 0) { + Kdf.Pbkdf2(pref.getInt("kdfIterations", 0).toUInt()) + } else { + Kdf.Argon2id( + pref.getInt("kdfIterations", 0).toUInt(), + pref.getInt("kdfMemory", 0).toUInt(), + pref.getInt("kdfParallelism", 0).toUInt() + ) + } + + val encryptedUserKey = pref.getString("encryptedUserKey", "")!! + val encryptedUserKeyIv = pref.getString("encryptedUserKeyIv", "")!! + + biometric.decryptString( + BIOMETRIC_KEY, encryptedUserKey, encryptedUserKeyIv + ) { key -> + GlobalScope.launch { + client.crypto().initializeUserCrypto( + InitUserCryptoRequest( + kdfParams = kdf, + email = EMAIL, + privateKey = privateKey!!, + method = InitUserCryptoMethod.DecryptedKey(decryptedUserKey = key) + ) + ) + + decryptVault(client, http, outputText) + } + } + } + + suspend fun decryptVault(client: Client, http: HttpClient, outputText: MutableState) { + ///////////////////////////// Sync ///////////////////////////// + + val syncBody = http.get(API_URL + "sync?excludeDomains=true") { + bearerAuth(accessToken) + }.body() + + val folders = (syncBody["folders"] as JsonArray).map { + val o = it as JsonObject + Folder( + (o["id"] as JsonPrimitive).content, + (o["name"] as JsonPrimitive).content, + DateTime.parse( + (o["revisionDate"] as JsonPrimitive).content + ) + ) + } + + ///////////////////////////// Initialize org crypto ///////////////////////////// + val orgs = ((syncBody["profile"] as JsonObject)["organizations"]) as JsonArray + val orgKeys = HashMap() + + for (org in orgs) { + val o = org as JsonObject + orgKeys[(o["id"] as JsonPrimitive).content] = (o["key"] as JsonPrimitive).content + } + + client.crypto().initializeOrgCrypto(InitOrgCryptoRequest(organizationKeys = orgKeys)) + + ///////////////////////////// Decrypt some folders ///////////////////////////// -@Preview(showBackground = true) -@Composable -fun GreetingPreview() { - MyApplicationTheme { - Greeting("Sdk") + val decryptedFolders = client.vault().folders().decryptList(folders) + outputText.value = decryptedFolders.toString() + println(decryptedFolders) } } diff --git a/languages/kotlin/doc.md b/languages/kotlin/doc.md index 70446bd8f..fd65c7b71 100644 --- a/languages/kotlin/doc.md +++ b/languages/kotlin/doc.md @@ -205,6 +205,17 @@ Initialization method for the organization crypto. Needs to be called after **Output**: std::result::Result<,BitwardenError> +### `get_user_encryption_key` + +Get the uses's decrypted encryption key. Note: It's very important to keep this key safe, +as it can be used to decrypt all of the user's data + +**Arguments**: + +- self: + +**Output**: std::result::Result + ## ClientExporters ### `export_vault` @@ -906,6 +917,27 @@ implementations. + + decryptedKey + object + + + + + + + + + + + + + + + +
KeyTypeDescription
decrypted_user_keystringThe user's decrypted encryption key, obtained using `get_user_encryption_key`
+ + ## `InitUserCryptoRequest` diff --git a/languages/python/BitwardenClient/bitwarden_client.py b/languages/python/BitwardenClient/bitwarden_client.py index 6a0a77ed8..cb669a40e 100644 --- a/languages/python/BitwardenClient/bitwarden_client.py +++ b/languages/python/BitwardenClient/bitwarden_client.py @@ -1,8 +1,8 @@ import json -from typing import Any, List +from typing import Any, List, Optional +from uuid import UUID import bitwarden_py -from .schemas import ClientSettings, Command, PasswordLoginRequest, PasswordLoginResponse, ResponseForPasswordLoginResponse, ResponseForSecretIdentifiersResponse, ResponseForSecretResponse, ResponseForSecretsDeleteResponse, ResponseForSyncResponse, ResponseForUserAPIKeyResponse, SecretCreateRequest, SecretGetRequest, SecretIdentifiersRequest, SecretIdentifiersResponse, SecretPutRequest, SecretResponse, SecretVerificationRequest, SecretsCommand, SecretsDeleteRequest, SecretsDeleteResponse, SyncRequest, SyncResponse, UserAPIKeyResponse - +from .schemas import ClientSettings, Command, ResponseForSecretIdentifiersResponse, ResponseForSecretResponse, ResponseForSecretsDeleteResponse, SecretCreateRequest, SecretGetRequest, SecretIdentifiersRequest, SecretIdentifiersResponse, SecretPutRequest, SecretResponse, SecretsCommand, SecretsDeleteRequest, SecretsDeleteResponse, AccessTokenLoginRequest, AccessTokenLoginResponse, ResponseForAccessTokenLoginResponse, ResponseForProjectResponse, ProjectsCommand, ProjectCreateRequest, ProjectGetRequest, ProjectPutRequest, ProjectsListRequest, ResponseForProjectsResponse, ResponseForProjectsDeleteResponse, ProjectsDeleteRequest class BitwardenClient: def __init__(self, settings: ClientSettings = None): @@ -12,32 +12,25 @@ def __init__(self, settings: ClientSettings = None): settings_json = json.dumps(settings.to_dict()) self.inner = bitwarden_py.BitwardenClient(settings_json) - def password_login(self, email: str, password: str) -> ResponseForPasswordLoginResponse: - result = self._run_command( - Command(password_login=PasswordLoginRequest(email, password)) - ) - return ResponseForPasswordLoginResponse.from_dict(result) - - def get_user_api_key(self, secret: str, is_otp: bool = False) -> ResponseForUserAPIKeyResponse: - result = self._run_command( - Command(get_user_api_key=SecretVerificationRequest( - secret if not is_otp else None, secret if is_otp else None)) + def access_token_login(self, access_token: str): + self._run_command( + Command(access_token_login=AccessTokenLoginRequest(access_token)) ) - return ResponseForUserAPIKeyResponse.from_dict(result) - - def sync(self, exclude_subdomains: bool = False) -> ResponseForSyncResponse: - result = self._run_command( - Command(sync=SyncRequest(exclude_subdomains)) - ) - return ResponseForSyncResponse.from_dict(result) def secrets(self): return SecretsClient(self) + def projects(self): + return ProjectsClient(self) + def _run_command(self, command: Command) -> Any: response_json = self.inner.run_command(json.dumps(command.to_dict())) - return json.loads(response_json) + response = json.loads(response_json) + if response["success"] == False: + raise Exception(response["errorMessage"]) + + return response class SecretsClient: def __init__(self, client: BitwardenClient): @@ -52,10 +45,12 @@ def get(self, id: str) -> ResponseForSecretResponse: def create(self, key: str, note: str, organization_id: str, - value: str) -> ResponseForSecretResponse: + value: str, + project_ids: Optional[List[UUID]] = None + ) -> ResponseForSecretResponse: result = self.client._run_command( Command(secrets=SecretsCommand( - create=SecretCreateRequest(key, note, organization_id, value))) + create=SecretCreateRequest(key, note, organization_id, value, project_ids))) ) return ResponseForSecretResponse.from_dict(result) @@ -70,10 +65,12 @@ def update(self, id: str, key: str, note: str, organization_id: str, - value: str) -> ResponseForSecretResponse: + value: str, + project_ids: Optional[List[UUID]] = None + ) -> ResponseForSecretResponse: result = self.client._run_command( Command(secrets=SecretsCommand(update=SecretPutRequest( - id, key, note, organization_id, value))) + id, key, note, organization_id, value, project_ids))) ) return ResponseForSecretResponse.from_dict(result) @@ -82,3 +79,46 @@ def delete(self, ids: List[str]) -> ResponseForSecretsDeleteResponse: Command(secrets=SecretsCommand(delete=SecretsDeleteRequest(ids))) ) return ResponseForSecretsDeleteResponse.from_dict(result) + +class ProjectsClient: + def __init__(self, client: BitwardenClient): + self.client = client + + def get(self, id: str) -> ResponseForProjectResponse: + result = self.client._run_command( + Command(projects=ProjectsCommand(get=ProjectGetRequest(id))) + ) + return ResponseForProjectResponse.from_dict(result) + + def create(self, + name: str, + organization_id: str, + ) -> ResponseForProjectResponse: + result = self.client._run_command( + Command(projects=ProjectsCommand( + create=ProjectCreateRequest(name, organization_id))) + ) + return ResponseForProjectResponse.from_dict(result) + + def list(self, organization_id: str) -> ResponseForProjectsResponse: + result = self.client._run_command( + Command(projects=ProjectsCommand( + list=ProjectsListRequest(organization_id))) + ) + return ResponseForProjectsResponse.from_dict(result) + + def update(self, id: str, + name: str, + organization_id: str, + ) -> ResponseForProjectResponse: + result = self.client._run_command( + Command(projects=ProjectsCommand(update=ProjectPutRequest( + id, name, organization_id))) + ) + return ResponseForProjectResponse.from_dict(result) + + def delete(self, ids: List[str]) -> ResponseForProjectsDeleteResponse: + result = self.client._run_command( + Command(projects=ProjectsCommand(delete=ProjectsDeleteRequest(ids))) + ) + return ResponseForProjectsDeleteResponse.from_dict(result) diff --git a/languages/python/README.md b/languages/python/README.md index 03a4ce572..871be274f 100644 --- a/languages/python/README.md +++ b/languages/python/README.md @@ -9,6 +9,10 @@ ```bash pip install setuptools_rust ``` +- dateutil + ```bash + pip install python-dateutil + ``` # Installation @@ -18,7 +22,7 @@ From the `languages/python/` directory, python3 ./setup.py develop ``` -Move the the resulting `.so` file to `bitwarden_py.so`, if it isn't already there. +Rename the the resulting `.so` file to `bitwarden_py.so`, if it isn't already there. # Run diff --git a/languages/python/example.py b/languages/python/example.py new file mode 100644 index 000000000..2ee1cb280 --- /dev/null +++ b/languages/python/example.py @@ -0,0 +1,44 @@ +import json +import logging +import sys +from BitwardenClient.bitwarden_client import BitwardenClient +from BitwardenClient.schemas import client_settings_from_dict, DeviceType + +# Create the BitwardenClient, which is used to interact with the SDK +client = BitwardenClient(client_settings_from_dict({ + "apiUrl": "http://localhost:4000", + "deviceType": DeviceType.SDK, + "identityUrl": "http://localhost:33656", + "userAgent": "Python", +})) + +# Add some logging & set the org id +logging.basicConfig(level=logging.DEBUG) +organization_id = "org_id_here" + +# Attempt to authenticate with the Secrets Manager Access Token +client.access_token_login("access_token_here") + +# -- Example Project Commands -- + +project = client.projects().create("ProjectName", organization_id) +project2 = client.projects().create("Project - Don't Delete Me!", organization_id) +updated_project = client.projects().update(project.data.id, "Cool New Project Name", organization_id) +get_that_project = client.projects().get(project.data.id) + +input("Press Enter to delete the project...") +client.projects().delete([project.data.id]) + +print(client.projects().list(organization_id)) + +# -- Example Secret Commands -- + +secret = client.secrets().create("TEST_SECRET", "This is a test secret", organization_id, "Secret1234!", [project2.data.id]) +secret2 = client.secrets().create("Secret - Don't Delete Me!", "This is a test secret that will stay", organization_id, "Secret1234!", [project2.data.id]) +secret_updated = client.secrets().update(secret.data.id, "TEST_SECRET_UPDATED", "This as an updated test secret", organization_id, "Secret1234!_updated", [project2.data.id]) +secret_retrieved = client.secrets().get(secret.data.id) + +input("Press Enter to delete the secret...") +client.secrets().delete([secret.data.id]) + +print(client.secrets().list(organization_id)) diff --git a/languages/python/login.py b/languages/python/login.py deleted file mode 100644 index 9b756a005..000000000 --- a/languages/python/login.py +++ /dev/null @@ -1,24 +0,0 @@ -import json -import logging -from BitwardenClient.bitwarden_client import BitwardenClient -from BitwardenClient.schemas import client_settings_from_dict - -client = BitwardenClient(client_settings_from_dict({ - "api_url": "http://localhost:4000", - "identity_url": "http://localhost:33656", - "user_agent": "Python", -})) - -logging.basicConfig(level=logging.DEBUG) - -result = client.password_login("test@bitwarden.com", "asdfasdf") -print(result) -print(client.get_user_api_key("asdfasdf")) - -sync = client.sync() - -secret = client.secrets().create("TEST_SECRET", "This is a test secret", - sync.data.profile.organizations[0].id, "Secret1234!") -print(secret) - -client.secrets().delete([secret.data.id]) diff --git a/languages/swift/iOS/App.xcodeproj/project.pbxproj b/languages/swift/iOS/App.xcodeproj/project.pbxproj index 003c09c0d..e8b3519fd 100644 --- a/languages/swift/iOS/App.xcodeproj/project.pbxproj +++ b/languages/swift/iOS/App.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 33F2B0502B0511C700E1E91C /* Biometrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33F2B04F2B0511C700E1E91C /* Biometrics.swift */; }; 55B6153E2A8678B300BE93F4 /* testApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55B6153D2A8678B300BE93F4 /* testApp.swift */; }; 55B615402A8678B300BE93F4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55B6153F2A8678B300BE93F4 /* ContentView.swift */; }; 55B615422A8678B400BE93F4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 55B615412A8678B400BE93F4 /* Assets.xcassets */; }; @@ -15,6 +16,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 33F2B04F2B0511C700E1E91C /* Biometrics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Biometrics.swift; sourceTree = ""; }; 55B6153A2A8678B300BE93F4 /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; 55B6153D2A8678B300BE93F4 /* testApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = testApp.swift; sourceTree = ""; }; 55B6153F2A8678B300BE93F4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -60,6 +62,7 @@ 55B6153F2A8678B300BE93F4 /* ContentView.swift */, 55B615412A8678B400BE93F4 /* Assets.xcassets */, 55B615432A8678B400BE93F4 /* Preview Content */, + 33F2B04F2B0511C700E1E91C /* Biometrics.swift */, ); path = App; sourceTree = ""; @@ -118,7 +121,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1420; - LastUpgradeCheck = 1420; + LastUpgradeCheck = 1500; TargetAttributes = { 55B615392A8678B300BE93F4 = { CreatedOnToolsVersion = 14.2; @@ -160,6 +163,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 33F2B0502B0511C700E1E91C /* Biometrics.swift in Sources */, 55B615402A8678B300BE93F4 /* ContentView.swift in Sources */, 55B6153E2A8678B300BE93F4 /* testApp.swift in Sources */, ); @@ -172,6 +176,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; @@ -204,6 +209,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -232,6 +238,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; @@ -264,6 +271,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -293,6 +301,7 @@ DEVELOPMENT_TEAM = LTZ2PFU5D6; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSFaceIDUsageDescription = "Unlock vault with biometrics"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; @@ -323,6 +332,7 @@ DEVELOPMENT_TEAM = LTZ2PFU5D6; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSFaceIDUsageDescription = "Unlock vault with biometrics"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; diff --git a/languages/swift/iOS/App/Biometrics.swift b/languages/swift/iOS/App/Biometrics.swift new file mode 100644 index 000000000..2fc5ef2a3 --- /dev/null +++ b/languages/swift/iOS/App/Biometrics.swift @@ -0,0 +1,92 @@ +// +// Biometrics.swift +// App +// +// Created by Dani on 15/11/23. +// + +/** + * IMPORTANT: This file is provided only for the purpose of demostrating the use of the biometric unlock functionality. + * It hasn't gone through a throrough security review and should not be considered production ready. It also doesn't + * handle a lot of errors and edge cases that a production application would need to deal with. + * Developers are encouraged to review and improve the code as needed to meet their security requirements. + * Additionally, we recommend to consult with security experts and conduct thorough testing before using the code in production. + */ + +import Foundation +import LocalAuthentication + +let SERVICE: String = "com.example.app" + +// We should separate keys for each user by appending the user_id +let KEY: String = "biometric_key" + + +func biometricStoreValue(value: String) { + var error: Unmanaged? + let accessControl = SecAccessControlCreateWithFlags( + nil, + kSecAttrAccessibleWhenUnlockedThisDeviceOnly, + .biometryCurrentSet, + &error) + + guard accessControl != nil && error == nil else { + fatalError("SecAccessControlCreateWithFlags failed") + } + + let query = [ + kSecClass: kSecClassGenericPassword, + kSecAttrService: SERVICE, + kSecAttrAccount: KEY, + kSecValueData: value.data(using: .utf8)!, + kSecAttrAccessControl: accessControl as Any + ] as CFDictionary + + // Try to delete the previous secret, if it exists + // Otherwise we get `errSecDuplicateItem` + SecItemDelete(query) + + let status = SecItemAdd(query, nil) + guard status == errSecSuccess else { + fatalError("Unable to store the secret: " + errToString(status: status)) + } +} + +private func errToString(status: OSStatus) -> String { + if let err = SecCopyErrorMessageString(status, nil) as String? { + err + } else { + "Unknown error" + } +} + +func biometricRetrieveValue() -> String? { + let searchQuery = [ + kSecClass: kSecClassGenericPassword, + kSecAttrService: SERVICE, + kSecAttrAccount: KEY, + kSecMatchLimit: kSecMatchLimitOne, + kSecReturnData: true, + kSecReturnAttributes: true, + ] as CFDictionary + + var item: AnyObject? + let status = SecItemCopyMatching(searchQuery, &item) + + // If the item is not found, we just return nil + if status == errSecItemNotFound { + return nil + } + + // TODO: We probably want to handle these errors better + guard status == noErr else { + fatalError("Unable to retrieve the secret: " + errToString(status: status)) + } + + if let resultDictionary = item as? [String: Any], + let data = resultDictionary[kSecValueData as String] as? Data { + return String(decoding: data, as: UTF8.self) + } + + return nil +} diff --git a/languages/swift/iOS/App/ContentView.swift b/languages/swift/iOS/App/ContentView.swift index 484caf14f..5df7dc3fd 100644 --- a/languages/swift/iOS/App/ContentView.swift +++ b/languages/swift/iOS/App/ContentView.swift @@ -8,176 +8,261 @@ import BitwardenSdk import SwiftUI -struct ContentView: View { - - @State private var msg: String - - init() { - let client = Client(settings: nil) +/** + * IMPORTANT: This file is provided only for the purpose of demostrating the use of the SDK functionality. + * It hasn't gone through a throrough security review and should not be considered production ready. It also doesn't + * handle a lot of errors and edge cases that a production application would need to deal with. + * Developers are encouraged to review and improve the code as needed to meet their security requirements. + * Additionally, we recommend to consult with security experts and conduct thorough testing before using the code in production. + */ - _msg = State(initialValue: client.echo(msg: "Sdk")) +let SERVER_URL = "https://localhost:8080/" +let API_URL = SERVER_URL + "api/" +let IDENTITY_URL = SERVER_URL + "identity/" - let SERVER_URL = "https://localhost:8080/" - let API_URL = SERVER_URL + "api/" - let IDENTITY_URL = SERVER_URL + "identity/" - - let EMAIL = "test@bitwarden.com" - let PASSWORD = "asdfasdfasdf" +let EMAIL = "test@bitwarden.com" +let PASSWORD = "asdfasdfasdf" +struct ContentView: View { + private var http: URLSession + + @State private var client: Client + + @State private var accessToken: String = "" + + init() { // Disable SSL Cert validation. Don't do this in production - let ignoreHttpsDelegate = IgnoreHttpsDelegate() - let http = URLSession( - configuration: URLSessionConfiguration.default, delegate: ignoreHttpsDelegate, + http = URLSession( + configuration: URLSessionConfiguration.default, delegate: IgnoreHttpsDelegate(), delegateQueue: nil) - - Task { - - ////////////////////////////// Get master password hash ////////////////////////////// - - struct PreloginRequest: Codable { let email: String } - struct PreloginResponse: Codable { - let kdf: UInt32 - let kdfIterations: UInt32 - let kdfMemory: UInt32? - let kdfParallelism: UInt32? - - } - - let (preloginDataJson, _) = try await http.data( - for: request( - method: "POST", url: IDENTITY_URL + "accounts/prelogin", - fn: { r in - r.setValue("application/json", forHTTPHeaderField: "Content-Type") - r.httpBody = try JSONEncoder().encode(PreloginRequest(email: EMAIL)) - })) - let preloginData = try JSONDecoder().decode( - PreloginResponse.self, from: preloginDataJson) - - let kdf: Kdf - if preloginData.kdf == 0 { - kdf = Kdf.pbkdf2(iterations: preloginData.kdfIterations) - } else { - kdf = Kdf.argon2id( - iterations: preloginData.kdfIterations, memory: preloginData.kdfMemory!, - parallelism: preloginData.kdfParallelism!) - } - - let passwordHash = try await client.auth().hashPassword( - email: EMAIL, password: PASSWORD, kdfParams: kdf) - - ///////////////////////////// Login ///////////////////////////// - - struct LoginResponse: Codable { - let Key: String - let PrivateKey: String - let access_token: String - let refresh_token: String - } - - let (loginDataJson, _) = try await http.data( - for: request( - method: "POST", url: IDENTITY_URL + "connect/token", - fn: { r in - r.setValue( - EMAIL.data(using: .utf8)?.base64EncodedString(), - forHTTPHeaderField: "Auth-Email") - r.setValue( - "application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") - - var comp = URLComponents() - comp.queryItems = [ - URLQueryItem(name: "scope", value: "api offline_access"), - URLQueryItem(name: "client_id", value: "web"), - URLQueryItem(name: "deviceType", value: "12"), - URLQueryItem( - name: "deviceIdentifier", - value: "0745d426-8dab-484a-9816-4959721d77c7"), - URLQueryItem(name: "deviceName", value: "edge"), - URLQueryItem(name: "grant_type", value: "password"), - URLQueryItem(name: "username", value: EMAIL), - URLQueryItem(name: "password", value: passwordHash), - ] - r.httpBody = comp.percentEncodedQuery! - .replacingOccurrences(of: "@", with: "%40") - .replacingOccurrences(of: "+", with: "%2B") - .data(using: .utf8) - })) - let loginData = try JSONDecoder().decode(LoginResponse.self, from: loginDataJson) - - ///////////////////////////// Sync ///////////////////////////// - - struct SyncOrganization: Codable { - let id: String - let key: String - } - struct SyncProfile: Codable { - let organizations: [SyncOrganization] - - } - struct SyncFolder: Codable { - let id: String - let name: String - let revisionDate: String - } - struct SyncResponse: Codable { - let profile: SyncProfile - let folders: [SyncFolder] - } - - let (syncDataJson, _) = try await http.data( - for: request( - method: "GET", url: API_URL + "sync?excludeDomains=true", - fn: { r in - r.setValue( - "Bearer " + loginData.access_token, forHTTPHeaderField: "Authorization") - })) - - let syncData = try JSONDecoder().decode(SyncResponse.self, from: syncDataJson) - - ///////////////////////////// Initialize crypto ///////////////////////////// - - try await client.crypto().initializeUserCrypto( - req: InitUserCryptoRequest( - kdfParams: kdf, - email: EMAIL, - privateKey: loginData.PrivateKey, - method: InitUserCryptoMethod.password( - password: PASSWORD, - userKey: loginData.Key - ) - )) - - try await client.crypto().initializeOrgCrypto( - req: InitOrgCryptoRequest( - organizationKeys: Dictionary.init( - uniqueKeysWithValues: syncData.profile.organizations.map { ($0.id, $0.key) } - ) - )) - - ///////////////////////////// Decrypt some folders ///////////////////////////// - - let dateFormatter = ISO8601DateFormatter() - dateFormatter.formatOptions = [.withFractionalSeconds] - - let decryptedFolders = try await client.vault().folders().decryptList( - folders: syncData.folders.map { - Folder( - id: $0.id, name: $0.name, - revisionDate: dateFormatter.date(from: $0.revisionDate)!) - }) - print(decryptedFolders) - } + + client = Client(settings: nil) } - + + @State var setupBiometrics: Bool = true + @State var outputText: String = "" + var body: some View { VStack { - Image(systemName: "globe") - .imageScale(.large) - .foregroundColor(.accentColor) - Text("Hello " + msg) + Toggle("Setup biometric unlock after login", isOn: $setupBiometrics).padding(.init(top: 0, leading: 20, bottom: 0, trailing: 20)) + + Button(action: { + Task { + do { + try await clientExamplePassword(clientAuth: client.auth(), clientCrypto: client.crypto(), setupBiometrics: setupBiometrics) + try await decryptVault(clientCrypto: client.crypto(), clientVault: client.vault()) + } catch { + print("ERROR:", error) + } + } + }, label: { + Text("Login with username + password") + }) + + Divider().padding(30) + + Button(action: { + Task { + do { + try await clientExampleBiometrics(clientCrypto: client.crypto()) + try await decryptVault(clientCrypto: client.crypto(), clientVault: client.vault()) + } catch { + print("ERROR:", error) + } + } + }, label: { + Text("Unlock with biometrics") + }) + + Button(action: { + client = Client(settings: nil) + }, label: { + Text("Lock & reset client") + }).padding() + + Text("Output: " + outputText).padding(.top) } .padding() } + + func clientExamplePassword(clientAuth: ClientAuthProtocol, clientCrypto: ClientCryptoProtocol, setupBiometrics: Bool) async throws { + ////////////////////////////// Get master password hash ////////////////////////////// + + struct PreloginRequest: Codable { let email: String } + struct PreloginResponse: Codable { + let kdf: UInt32 + let kdfIterations: UInt32 + let kdfMemory: UInt32? + let kdfParallelism: UInt32? + + } + + let (preloginDataJson, _) = try await http.data( + for: request( + method: "POST", url: IDENTITY_URL + "accounts/prelogin", + fn: { r in + r.setValue("application/json", forHTTPHeaderField: "Content-Type") + r.httpBody = try JSONEncoder().encode(PreloginRequest(email: EMAIL)) + })) + let preloginData = try JSONDecoder().decode( + PreloginResponse.self, from: preloginDataJson) + + let kdf: Kdf + if preloginData.kdf == 0 { + kdf = Kdf.pbkdf2(iterations: preloginData.kdfIterations) + } else { + kdf = Kdf.argon2id( + iterations: preloginData.kdfIterations, memory: preloginData.kdfMemory!, + parallelism: preloginData.kdfParallelism!) + } + + let passwordHash = try await clientAuth.hashPassword( + email: EMAIL, password: PASSWORD, kdfParams: kdf) + + ///////////////////////////// Login ///////////////////////////// + + struct LoginResponse: Codable { + let Key: String + let PrivateKey: String + let access_token: String + let refresh_token: String + } + + let (loginDataJson, _) = try await http.data( + for: request( + method: "POST", url: IDENTITY_URL + "connect/token", + fn: { r in + r.setValue( + EMAIL.data(using: .utf8)?.base64EncodedString(), + forHTTPHeaderField: "Auth-Email") + r.setValue( + "application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") + + var comp = URLComponents() + comp.queryItems = [ + URLQueryItem(name: "scope", value: "api offline_access"), + URLQueryItem(name: "client_id", value: "web"), + URLQueryItem(name: "deviceType", value: "12"), + URLQueryItem( + name: "deviceIdentifier", + value: "0745d426-8dab-484a-9816-4959721d77c7"), + URLQueryItem(name: "deviceName", value: "edge"), + URLQueryItem(name: "grant_type", value: "password"), + URLQueryItem(name: "username", value: EMAIL), + URLQueryItem(name: "password", value: passwordHash), + ] + r.httpBody = comp.percentEncodedQuery! + .replacingOccurrences(of: "@", with: "%40") + .replacingOccurrences(of: "+", with: "%2B") + .data(using: .utf8) + })) + let loginData = try JSONDecoder().decode(LoginResponse.self, from: loginDataJson) + + try await clientCrypto.initializeUserCrypto( + req: InitUserCryptoRequest( + kdfParams: kdf, + email: EMAIL, + privateKey: loginData.PrivateKey, + method: InitUserCryptoMethod.password( + password: PASSWORD, + userKey: loginData.Key + ) + )) + + accessToken = loginData.access_token + + if (setupBiometrics) { + let defaults = UserDefaults.standard + defaults.set(loginData.PrivateKey, forKey: "privateKey") + defaults.set(preloginData.kdf, forKey: "kdfType") + defaults.set(preloginData.kdfIterations, forKey: "kdfIterations") + defaults.set(preloginData.kdfMemory, forKey: "kdfMemory") + defaults.set(preloginData.kdfParallelism, forKey: "kdfParallelism") + defaults.synchronize() + + let key = try await clientCrypto.getUserEncryptionKey() + biometricStoreValue(value: key) + } + } + + func clientExampleBiometrics(clientCrypto: ClientCryptoProtocol) async throws { + let defaults = UserDefaults.standard + let privateKey = defaults.string(forKey: "privateKey")! + let kdf = if defaults.integer(forKey: "kdfType") == 0 { + Kdf.pbkdf2(iterations: UInt32(defaults.integer(forKey: "kdfIterations"))) + } else { + Kdf.argon2id( + iterations: UInt32(defaults.integer(forKey: "kdfIterations")), + memory: UInt32(defaults.integer(forKey: "kdfMemory")), + parallelism: UInt32(defaults.integer(forKey: "kdfParallelism")) + ) + } + + let key = biometricRetrieveValue()! + + try await clientCrypto.initializeUserCrypto(req: InitUserCryptoRequest( + kdfParams: kdf, + email: EMAIL, + privateKey: privateKey, + method: InitUserCryptoMethod.decryptedKey( + decryptedUserKey: key + ) + )) + } + + func decryptVault(clientCrypto: ClientCryptoProtocol, clientVault: ClientVaultProtocol) async throws { + ///////////////////////////// Sync ///////////////////////////// + + struct SyncOrganization: Codable { + let id: String + let key: String + } + struct SyncProfile: Codable { + let organizations: [SyncOrganization] + + } + struct SyncFolder: Codable { + let id: String + let name: String + let revisionDate: String + } + struct SyncResponse: Codable { + let profile: SyncProfile + let folders: [SyncFolder] + } + + let (syncDataJson, _) = try await http.data( + for: request( + method: "GET", url: API_URL + "sync?excludeDomains=true", + fn: { r in + r.setValue( + "Bearer " + accessToken, forHTTPHeaderField: "Authorization") + })) + + let syncData = try JSONDecoder().decode(SyncResponse.self, from: syncDataJson) + + ///////////////////////////// Initialize org crypto ///////////////////////////// + + try await clientCrypto.initializeOrgCrypto( + req: InitOrgCryptoRequest( + organizationKeys: Dictionary.init( + uniqueKeysWithValues: syncData.profile.organizations.map { ($0.id, $0.key) } + ) + )) + + ///////////////////////////// Decrypt some folders ///////////////////////////// + + let dateFormatter = ISO8601DateFormatter() + dateFormatter.formatOptions = [.withFractionalSeconds] + + let decryptedFolders = try await clientVault.folders().decryptList( + folders: syncData.folders.map { + Folder( + id: $0.id, name: $0.name, + revisionDate: dateFormatter.date(from: $0.revisionDate)!) + }) + print(decryptedFolders) + } } struct ContentView_Previews: PreviewProvider { @@ -202,7 +287,7 @@ extension IgnoreHttpsDelegate: URLSessionDelegate { ) { //Trust the certificate even if not valid let urlCredential = URLCredential(trust: challenge.protectionSpace.serverTrust!) - + completionHandler(.useCredential, urlCredential) } } From b79fc6fc0ad7945e7940fcd2ebc0e1ff18d127e8 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:21:52 +0000 Subject: [PATCH 069/108] prettier --- .github/workflows/build-python-wheels.yml | 241 +++++++++++----------- 1 file changed, 120 insertions(+), 121 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index f9df032ab..9d8084618 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -1,122 +1,121 @@ --- - name: Build Python Wheels - - on: - pull_request: - push: - branches: - - "master" - - "rc" - - "hotfix-rc" - workflow_dispatch: - - defaults: - run: - shell: bash - working-directory: languages/python - - jobs: - generate_schemas: - uses: ./.github/workflows/generate_schemas.yml - - setup: - name: Setup - runs-on: ubuntu-22.04 - outputs: - package_version: ${{ steps.retrieve-version.outputs.package_version }} - steps: - - name: Checkout repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - name: Get Package Version - id: retrieve-version - run: | - VERSION="$(grep -o '^version = ".*"' ../../crates/bitwarden-py/Cargo.toml | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+")" - echo "package_version=$VERSION" >> $GITHUB_OUTPUT - - build: - name: Building Python wheel for - ${{ matrix.settings.os }} - ${{ matrix.settings.target }} - runs-on: ${{ matrix.settings.os || 'ubuntu-latest' }} - needs: - - generate_schemas - - setup - env: - _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} - strategy: - fail-fast: false - matrix: - settings: - - os: macos-12 - target: x86_64-apple-darwin - - - os: macos-12 - target: aarch64-apple-darwin - - - os: windows-2022 - target: x86_64-pc-windows-msvc - - # # Win ARM builds fail: https://github.com/bitwarden/sdk/actions/runs/6960684148/job/18940738400#step:9:175 - # - os: windows-2022 - # target: aarch64-pc-windows-msvc - - - os: ubuntu-22.04 - target: x86_64-unknown-linux-gnu - - - os: ubuntu-22.04 - target: aarch64-unknown-linux-gnu - - steps: - - name: Checkout repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - name: Setup Node - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0 - with: - node-version: 18 - - - name: Install rust - uses: dtolnay/rust-toolchain@439cf607258077187679211f12aa6f19af4a0af7 # stable - with: - toolchain: stable - targets: ${{ matrix.settings.target }} - - - name: Cache cargo registry - uses: Swatinem/rust-cache@3cf7f8cc28d1b4e7d01e3783be10a97d55d483c8 # v2.7.1 - with: - key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.os }} - - - name: Retrieve schemas - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: schemas.py - path: ${{ github.workspace }}/languages/python/BitwardenClient/ - - # - name: Setup Windows ARM64 - # if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} - # shell: pwsh - # run: | - # # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components - # $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - - - name: Build wheels - uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 - with: - target: ${{ matrix.settings.target }} - args: --release --find-interpreter --sdist - sccache: 'true' - manylinux: '2_28' # https://github.com/pola-rs/polars/pull/12211 - working-directory: ${{ github.workspace }}/languages/python - - - name: Upload wheels - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 - with: - name: BitwardenClient-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} - path: ${{ github.workspace }}/target/wheels/BitwardenClient*.whl - - - name: Upload sdists - if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} # we only need one sdist - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 - with: - name: BitwardenClient-${{ env._PACKAGE_VERSION }}-sdist - path: ${{ github.workspace }}/target/wheels/BitwardenClient-*.tar.gz - \ No newline at end of file +name: Build Python Wheels + +on: + pull_request: + push: + branches: + - "master" + - "rc" + - "hotfix-rc" + workflow_dispatch: + +defaults: + run: + shell: bash + working-directory: languages/python + +jobs: + generate_schemas: + uses: ./.github/workflows/generate_schemas.yml + + setup: + name: Setup + runs-on: ubuntu-22.04 + outputs: + package_version: ${{ steps.retrieve-version.outputs.package_version }} + steps: + - name: Checkout repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Get Package Version + id: retrieve-version + run: | + VERSION="$(grep -o '^version = ".*"' ../../crates/bitwarden-py/Cargo.toml | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+")" + echo "package_version=$VERSION" >> $GITHUB_OUTPUT + + build: + name: Building Python wheel for - ${{ matrix.settings.os }} - ${{ matrix.settings.target }} + runs-on: ${{ matrix.settings.os || 'ubuntu-latest' }} + needs: + - generate_schemas + - setup + env: + _PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }} + strategy: + fail-fast: false + matrix: + settings: + - os: macos-12 + target: x86_64-apple-darwin + + - os: macos-12 + target: aarch64-apple-darwin + + - os: windows-2022 + target: x86_64-pc-windows-msvc + + # # Win ARM builds fail: https://github.com/bitwarden/sdk/actions/runs/6960684148/job/18940738400#step:9:175 + # - os: windows-2022 + # target: aarch64-pc-windows-msvc + + - os: ubuntu-22.04 + target: x86_64-unknown-linux-gnu + + - os: ubuntu-22.04 + target: aarch64-unknown-linux-gnu + + steps: + - name: Checkout repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Setup Node + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0 + with: + node-version: 18 + + - name: Install rust + uses: dtolnay/rust-toolchain@439cf607258077187679211f12aa6f19af4a0af7 # stable + with: + toolchain: stable + targets: ${{ matrix.settings.target }} + + - name: Cache cargo registry + uses: Swatinem/rust-cache@3cf7f8cc28d1b4e7d01e3783be10a97d55d483c8 # v2.7.1 + with: + key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.os }} + + - name: Retrieve schemas + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: schemas.py + path: ${{ github.workspace }}/languages/python/BitwardenClient/ + + # - name: Setup Windows ARM64 + # if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} + # shell: pwsh + # run: | + # # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components + # $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" + + - name: Build wheels + uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 + with: + target: ${{ matrix.settings.target }} + args: --release --find-interpreter --sdist + sccache: "true" + manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 + working-directory: ${{ github.workspace }}/languages/python + + - name: Upload wheels + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + with: + name: BitwardenClient-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} + path: ${{ github.workspace }}/target/wheels/BitwardenClient*.whl + + - name: Upload sdists + if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} # we only need one sdist + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + with: + name: BitwardenClient-${{ env._PACKAGE_VERSION }}-sdist + path: ${{ github.workspace }}/target/wheels/BitwardenClient-*.tar.gz From 27bfff8562f4d71eb3ae7a3a2993103771842960 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 27 Nov 2023 21:07:48 +0000 Subject: [PATCH 070/108] fix version number --- languages/python/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/python/pyproject.toml b/languages/python/pyproject.toml index 9360fb199..adfe165a2 100644 --- a/languages/python/pyproject.toml +++ b/languages/python/pyproject.toml @@ -12,7 +12,7 @@ description = "A Bitwarden Client for python" name = "BitwardenClient" readme = "README.md" requires-python = ">=2.7" -version = "0.1" +version = "0.1.0" [tool.maturin] bindings = "pyo3" From ffc8cf2624c1c89f05b3306344ef8fa962515cf9 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 27 Nov 2023 21:08:37 +0000 Subject: [PATCH 071/108] update example --- languages/python/example.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/languages/python/example.py b/languages/python/example.py index 2ee1cb280..30a63015c 100644 --- a/languages/python/example.py +++ b/languages/python/example.py @@ -1,23 +1,23 @@ import json import logging +import os import sys -from BitwardenClient.bitwarden_client import BitwardenClient -from BitwardenClient.schemas import client_settings_from_dict, DeviceType +import bitwarden_py +import BitwardenClient as bw -# Create the BitwardenClient, which is used to interact with the SDK -client = BitwardenClient(client_settings_from_dict({ +client = bw.BitwardenClient(bw.client_settings_from_dict({ "apiUrl": "http://localhost:4000", - "deviceType": DeviceType.SDK, + "deviceType": bw.DeviceType.SDK, "identityUrl": "http://localhost:33656", "userAgent": "Python", })) # Add some logging & set the org id logging.basicConfig(level=logging.DEBUG) -organization_id = "org_id_here" +organization_id = os.getenv("BWS_ORG_ID") # Attempt to authenticate with the Secrets Manager Access Token -client.access_token_login("access_token_here") +client.access_token_login(os.getenv("BWS_ACCESS_TOKEN")) # -- Example Project Commands -- From 2b5c6cef4b074383631bbd0c314ab903e7fd6e90 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 27 Nov 2023 21:08:55 +0000 Subject: [PATCH 072/108] update with new build instructions --- languages/python/README.md | 45 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/languages/python/README.md b/languages/python/README.md index 871be274f..1e534740c 100644 --- a/languages/python/README.md +++ b/languages/python/README.md @@ -1,31 +1,32 @@ -# Requirements - -- Python3 -- setuptools - ```bash - pip install setuptools - ``` -- setuptools_rust - ```bash - pip install setuptools_rust - ``` -- dateutil - ```bash - pip install python-dateutil - ``` - -# Installation - -From the `languages/python/` directory, +# Build locally +## Requirements +- Python 3 +- `maturin` (install with `pip install maturin[patchelf]`) +- `npm` + +## Build + +From the root of the repository: ```bash -python3 ./setup.py develop +npm run schemas # generate schemas.py + +cd languages/python/ +maturin develop ``` -Rename the the resulting `.so` file to `bitwarden_py.so`, if it isn't already there. +You can now import `BitwardenClient` and `bitwarden_py` in your Python code. + +# Use without building locally + +```bash +pip install BitwardenClient +``` # Run +Set the `BWS_ORG_ID` and `BWS_ACCESS_TOKEN` environment variables to your organization ID and access token, respectively. + ```bash -python3 ./login.py +python3 ./example.py ``` From bf3772d7d94fe984a4fa0cfb55abf5a9f1715cab Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 27 Nov 2023 21:40:21 +0000 Subject: [PATCH 073/108] simplify imports --- languages/python/example.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/languages/python/example.py b/languages/python/example.py index 30a63015c..8ece40be6 100644 --- a/languages/python/example.py +++ b/languages/python/example.py @@ -3,11 +3,11 @@ import os import sys import bitwarden_py -import BitwardenClient as bw +from BitwardenClient import BitwardenClient, DeviceType, client_settings_from_dict -client = bw.BitwardenClient(bw.client_settings_from_dict({ +client = BitwardenClient(client_settings_from_dict({ "apiUrl": "http://localhost:4000", - "deviceType": bw.DeviceType.SDK, + "deviceType": DeviceType.SDK, "identityUrl": "http://localhost:33656", "userAgent": "Python", })) From 34364a4bedf15f53d8ad73fe223eaf55a97de2cd Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:16:04 -0800 Subject: [PATCH 074/108] optimize imports; apply PEP formatting --- languages/python/example.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/languages/python/example.py b/languages/python/example.py index 8ece40be6..c237f2fed 100644 --- a/languages/python/example.py +++ b/languages/python/example.py @@ -1,8 +1,6 @@ -import json import logging import os -import sys -import bitwarden_py + from BitwardenClient import BitwardenClient, DeviceType, client_settings_from_dict client = BitwardenClient(client_settings_from_dict({ @@ -33,9 +31,14 @@ # -- Example Secret Commands -- -secret = client.secrets().create("TEST_SECRET", "This is a test secret", organization_id, "Secret1234!", [project2.data.id]) -secret2 = client.secrets().create("Secret - Don't Delete Me!", "This is a test secret that will stay", organization_id, "Secret1234!", [project2.data.id]) -secret_updated = client.secrets().update(secret.data.id, "TEST_SECRET_UPDATED", "This as an updated test secret", organization_id, "Secret1234!_updated", [project2.data.id]) +secret = client.secrets().create( + "TEST_SECRET", "This is a test secret", organization_id, "Secret1234!", [project2.data.id]) +secret2 = client.secrets().create( + "Secret - Don't Delete Me!", "This is a test secret that will stay", organization_id, "Secret1234!", + [project2.data.id]) +secret_updated = client.secrets().update( + secret.data.id, "TEST_SECRET_UPDATED", "This as an updated test secret", organization_id, "Secret1234!_updated", + [project2.data.id]) secret_retrieved = client.secrets().get(secret.data.id) input("Press Enter to delete the secret...") From 2b3fb0bf5d201810491035cd4a70eafc65dcbe84 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:16:52 -0800 Subject: [PATCH 075/108] re-add comment --- languages/python/example.py | 1 + 1 file changed, 1 insertion(+) diff --git a/languages/python/example.py b/languages/python/example.py index c237f2fed..4d627342f 100644 --- a/languages/python/example.py +++ b/languages/python/example.py @@ -3,6 +3,7 @@ from BitwardenClient import BitwardenClient, DeviceType, client_settings_from_dict +# Create the BitwardenClient, which is used to interact with the SDK client = BitwardenClient(client_settings_from_dict({ "apiUrl": "http://localhost:4000", "deviceType": DeviceType.SDK, From 2440843dc2fd8d8618872d698e94ec4ba3cdc9a7 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:18:36 -0800 Subject: [PATCH 076/108] update min python version --- languages/python/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/python/pyproject.toml b/languages/python/pyproject.toml index adfe165a2..ee65c8c22 100644 --- a/languages/python/pyproject.toml +++ b/languages/python/pyproject.toml @@ -11,7 +11,7 @@ dependencies = ["dateutils >= 0.6.6"] description = "A Bitwarden Client for python" name = "BitwardenClient" readme = "README.md" -requires-python = ">=2.7" +requires-python = ">=3.0" version = "0.1.0" [tool.maturin] From a0c73672054cf172b6485c4f2b74a40c43282ecc Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 27 Nov 2023 15:36:41 -0800 Subject: [PATCH 077/108] Update README.md --- languages/python/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/python/README.md b/languages/python/README.md index 1e534740c..00babf86a 100644 --- a/languages/python/README.md +++ b/languages/python/README.md @@ -15,7 +15,7 @@ cd languages/python/ maturin develop ``` -You can now import `BitwardenClient` and `bitwarden_py` in your Python code. +You can now import `BitwardenClient` in your Python code. # Use without building locally From f8ef3a118df94cf99591c8bba46000cb2ba235f4 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 28 Nov 2023 05:40:13 -0800 Subject: [PATCH 078/108] add classifiers --- languages/python/pyproject.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/languages/python/pyproject.toml b/languages/python/pyproject.toml index ee65c8c22..f83e22efa 100644 --- a/languages/python/pyproject.toml +++ b/languages/python/pyproject.toml @@ -5,7 +5,11 @@ requires = ["maturin>=1.0,<2.0", "setuptools_rust>=1.8.1"] [project] authors = [{ name = "Bitwarden", email = "support@bitwarden.com" }] classifiers = [ - # TODO: See https://pypi.org/classifiers/ + "Intended Audience :: Developers", + "License :: Other/Proprietary License", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Rust", + "Topic :: Security", ] dependencies = ["dateutils >= 0.6.6"] description = "A Bitwarden Client for python" From b7da7005fde8a44acad5ef999c5e76753ff8d9d0 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 28 Nov 2023 06:43:22 -0800 Subject: [PATCH 079/108] add beta classifier --- languages/python/pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/languages/python/pyproject.toml b/languages/python/pyproject.toml index f83e22efa..8c2c6a3fd 100644 --- a/languages/python/pyproject.toml +++ b/languages/python/pyproject.toml @@ -5,6 +5,7 @@ requires = ["maturin>=1.0,<2.0", "setuptools_rust>=1.8.1"] [project] authors = [{ name = "Bitwarden", email = "support@bitwarden.com" }] classifiers = [ + "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: Other/Proprietary License", "Programming Language :: Python :: 3 :: Only", From 0399eae5af1da1173f0e5fb41d8f67fd4d457810 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:23:49 -0800 Subject: [PATCH 080/108] revert to openssl for ARM Linux; builds are failing --- crates/bws/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/bws/Cargo.toml b/crates/bws/Cargo.toml index a57ea1e3c..95dbef003 100644 --- a/crates/bws/Cargo.toml +++ b/crates/bws/Cargo.toml @@ -44,3 +44,6 @@ bitwarden = { path = "../bitwarden", version = "0.3.1", features = ["secrets"] } [dev-dependencies] tempfile = "3.8.1" + +[target.'cfg(target_os = "linux")'.dependencies] +openssl = { version = "0.10", features = ["vendored"] } From ac133f9a86862ced9cbadc14d2c7dfcd42fb839d Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:46:11 -0800 Subject: [PATCH 081/108] fix pip not found --- .github/workflows/build-python-wheels.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 9d8084618..9d289a036 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -106,6 +106,9 @@ jobs: sccache: "true" manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 working-directory: ${{ github.workspace }}/languages/python + before-script-linux: | + apt update + apt install python3-pip - name: Upload wheels uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 6795ea8043c1cef781d4bd0608304a0d38e7e76e Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:51:02 -0800 Subject: [PATCH 082/108] add -y --- .github/workflows/build-python-wheels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 9d289a036..57f0ea214 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -107,8 +107,8 @@ jobs: manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 working-directory: ${{ github.workspace }}/languages/python before-script-linux: | - apt update - apt install python3-pip + apt-get update + apt-get install python3-pip -y - name: Upload wheels uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From b704cd0671f15dc3366ce1ecf06a59454f9b3e16 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 29 Nov 2023 18:14:14 +0000 Subject: [PATCH 083/108] try pinned container tag for amd linux --- .github/workflows/build-python-wheels.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 57f0ea214..5eecf1764 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -98,6 +98,17 @@ jobs: # # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components # $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" + - name: Build wheels + uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 + if: ${{ matrix.settings.target != 'x86_64-unknown-linux-gnu' }} + with: + target: ${{ matrix.settings.target }} + args: --release --find-interpreter --sdist + container: quay.io/pypa/manylinux_2_28_x86_64:2023-10-30-2d1b8c5 + sccache: "true" + manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 + working-directory: ${{ github.workspace }}/languages/python + - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: @@ -106,9 +117,6 @@ jobs: sccache: "true" manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 working-directory: ${{ github.workspace }}/languages/python - before-script-linux: | - apt-get update - apt-get install python3-pip -y - name: Upload wheels uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 90a7eba6df71789f573f0c8a08114fe835603898 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:00:51 +0000 Subject: [PATCH 084/108] revert separate builds for amd64 linux --- .github/workflows/build-python-wheels.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 5eecf1764..9d8084618 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -98,17 +98,6 @@ jobs: # # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components # $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - - name: Build wheels - uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 - if: ${{ matrix.settings.target != 'x86_64-unknown-linux-gnu' }} - with: - target: ${{ matrix.settings.target }} - args: --release --find-interpreter --sdist - container: quay.io/pypa/manylinux_2_28_x86_64:2023-10-30-2d1b8c5 - sccache: "true" - manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 - working-directory: ${{ github.workspace }}/languages/python - - name: Build wheels uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: From 25c050670f1db7a72b089bc89e7a963d214146af Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:16:53 +0000 Subject: [PATCH 085/108] install pip for LInux x86_64 --- .github/workflows/build-python-wheels.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 9d8084618..15fbb72d6 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -99,6 +99,7 @@ jobs: # $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - name: Build wheels + if: ${{ matrix.settings.target != 'x86_64-unknown-linux-gnu' }} uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 with: target: ${{ matrix.settings.target }} @@ -107,6 +108,18 @@ jobs: manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 working-directory: ${{ github.workspace }}/languages/python + - name: Build wheels (Linux - x86_64) + if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} + uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7 + with: + target: ${{ matrix.settings.target }} + args: --release --find-interpreter --sdist + sccache: "true" + manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 + working-directory: ${{ github.workspace }}/languages/python + before-linux-script: | + dnf install python3-pip -y + - name: Upload wheels uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: From e1d4424e9283f6b7e9328fc721b0aaa5d4ec7dce Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:26:33 +0000 Subject: [PATCH 086/108] use tagged container image --- .github/workflows/build-python-wheels.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 15fbb72d6..49b537967 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -114,11 +114,10 @@ jobs: with: target: ${{ matrix.settings.target }} args: --release --find-interpreter --sdist + container: quay.io/pypa/manylinux_2_28_x86_64:2023-11-20-745eb52 sccache: "true" manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 working-directory: ${{ github.workspace }}/languages/python - before-linux-script: | - dnf install python3-pip -y - name: Upload wheels uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From d415251653bfa15d913023dcb5ddc5e573ee9cf5 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Thu, 30 Nov 2023 18:19:12 +0000 Subject: [PATCH 087/108] use openssl in cli --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 5b6e3c19e..a1f089632 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -538,6 +538,7 @@ dependencies = [ "directories", "env_logger", "log", + "openssl", "regex", "serde", "serde_json", From ee2ce66525d68b70ff94dc0fcf003acfc572a36c Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Thu, 30 Nov 2023 18:19:58 +0000 Subject: [PATCH 088/108] rename to "bitwarden_sdk" --- .github/workflows/build-python-wheels.yml | 10 +++++----- .github/workflows/generate_schemas.yml | 2 +- .gitignore | 2 +- .../{BitwardenClient => bitwarden_sdk}/__init__.py | 0 .../bitwarden_client.py | 0 languages/python/example.py | 2 +- languages/python/pyproject.toml | 6 +++--- 7 files changed, 11 insertions(+), 11 deletions(-) rename languages/python/{BitwardenClient => bitwarden_sdk}/__init__.py (100%) rename languages/python/{BitwardenClient => bitwarden_sdk}/bitwarden_client.py (100%) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 49b537967..f5e193b91 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -89,7 +89,7 @@ jobs: uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: schemas.py - path: ${{ github.workspace }}/languages/python/BitwardenClient/ + path: ${{ github.workspace }}/languages/python/bitwarden_sdk/ # - name: Setup Windows ARM64 # if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} @@ -122,12 +122,12 @@ jobs: - name: Upload wheels uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: - name: BitwardenClient-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} - path: ${{ github.workspace }}/target/wheels/BitwardenClient*.whl + name: bitwarden_sdk-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} + path: ${{ github.workspace }}/target/wheels/bitwarden_sdk*.whl - name: Upload sdists if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} # we only need one sdist uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: - name: BitwardenClient-${{ env._PACKAGE_VERSION }}-sdist - path: ${{ github.workspace }}/target/wheels/BitwardenClient-*.tar.gz + name: bitwarden_sdk-${{ env._PACKAGE_VERSION }}-sdist + path: ${{ github.workspace }}/target/wheels/bitwarden_sdk-*.tar.gz diff --git a/.github/workflows/generate_schemas.yml b/.github/workflows/generate_schemas.yml index 675f53c1e..89e5620a8 100644 --- a/.github/workflows/generate_schemas.yml +++ b/.github/workflows/generate_schemas.yml @@ -54,7 +54,7 @@ jobs: uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: name: schemas.py - path: ${{ github.workspace }}/languages/python/BitwardenClient/schemas.py + path: ${{ github.workspace }}/languages/python/bitwarden_sdk/schemas.py if-no-files-found: error - name: Upload json schemas artifact diff --git a/.gitignore b/.gitignore index 38b074349..1f296cf63 100644 --- a/.gitignore +++ b/.gitignore @@ -48,5 +48,5 @@ support/schemas crates/bitwarden-napi/src-ts/bitwarden_client/schemas.ts languages/csharp/Bitwarden.Sdk/schemas.cs languages/js_webassembly/bitwarden_client/schemas.ts -languages/python/BitwardenClient/schemas.py +languages/python/bitwarden_sdk/schemas.py languages/java/src/main/java/com/bitwarden/sdk/schema diff --git a/languages/python/BitwardenClient/__init__.py b/languages/python/bitwarden_sdk/__init__.py similarity index 100% rename from languages/python/BitwardenClient/__init__.py rename to languages/python/bitwarden_sdk/__init__.py diff --git a/languages/python/BitwardenClient/bitwarden_client.py b/languages/python/bitwarden_sdk/bitwarden_client.py similarity index 100% rename from languages/python/BitwardenClient/bitwarden_client.py rename to languages/python/bitwarden_sdk/bitwarden_client.py diff --git a/languages/python/example.py b/languages/python/example.py index 4d627342f..ce7143798 100644 --- a/languages/python/example.py +++ b/languages/python/example.py @@ -1,7 +1,7 @@ import logging import os -from BitwardenClient import BitwardenClient, DeviceType, client_settings_from_dict +from bitwarden_sdk import BitwardenClient, DeviceType, client_settings_from_dict # Create the BitwardenClient, which is used to interact with the SDK client = BitwardenClient(client_settings_from_dict({ diff --git a/languages/python/pyproject.toml b/languages/python/pyproject.toml index 8c2c6a3fd..30cc6e63d 100644 --- a/languages/python/pyproject.toml +++ b/languages/python/pyproject.toml @@ -14,7 +14,7 @@ classifiers = [ ] dependencies = ["dateutils >= 0.6.6"] description = "A Bitwarden Client for python" -name = "BitwardenClient" +name = "bitwarden_sdk" readme = "README.md" requires-python = ">=3.0" version = "0.1.0" @@ -23,7 +23,7 @@ version = "0.1.0" bindings = "pyo3" compatibility = "manylinux2014" include = [ - { path = "BitwardenClient/*.py", format = ["sdist", "wheel"] } + { path = "bitwarden_sdk/*.py", format = ["sdist", "wheel"] } ] manifest-path = "../../crates/bitwarden-py/Cargo.toml" -python-packages = ["BitwardenClient"] +python-packages = ["bitwarden_sdk"] From b238851c40ab6fcf67f949d4e6964f68f085c89a Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Thu, 30 Nov 2023 18:28:29 +0000 Subject: [PATCH 089/108] Merge branch 'master' into SM-989-create-build-and-publish-pipelines-for-the-python-language-wrapper --- .github/workflows/generate_schemas.yml | 6 + .github/workflows/golang-release.yml | 73 ++++++++ .gitignore | 3 + Cargo.lock | 63 +++++-- Cargo.toml | 10 +- README.md | 28 +-- .../.openapi-generator/FILES | 11 +- crates/bitwarden-api-api/README.md | 18 +- .../src/apis/auth_requests_api.rs | 51 ++++++ .../bitwarden-api-api/src/apis/devices_api.rs | 151 +++++++++++----- crates/bitwarden-api-api/src/apis/mod.rs | 3 +- .../src/apis/organization_users_api.rs | 18 +- .../src/apis/organizations_api.rs | 170 ++++++++++++------ .../src/apis/service_accounts_api.rs | 7 +- .../src/models/attachment_response_model.rs | 2 +- .../src/models/billing_customer_discount.rs | 26 +++ .../models/cipher_details_response_model.rs | 3 + .../cipher_mini_details_response_model.rs | 3 + .../src/models/cipher_mini_response_model.rs | 3 + .../src/models/cipher_request_model.rs | 3 + .../src/models/cipher_response_model.rs | 3 + .../models/cipher_with_id_request_model.rs | 3 + .../device_keys_update_request_model.rs | 29 +++ .../src/models/device_response_model.rs | 15 +- .../src/models/event_type.rs | 6 + .../src/models/global_domains.rs | 2 +- crates/bitwarden-api-api/src/models/mod.rs | 22 ++- .../organization_public_key_response_model.rs | 26 +++ ...rganization_subscription_response_model.rs | 3 + ...reset_password_enrollment_request_model.rs | 15 -- .../other_device_keys_update_request_model.rs | 33 ++++ .../models/protected_device_response_model.rs | 44 +++++ ...secrets_manager_subscribe_request_model.rs | 29 +++ ..._account_secrets_details_response_model.rs | 41 +++++ ...ails_response_model_list_response_model.rs | 29 +++ .../src/models/subscription_response_model.rs | 3 + .../update_devices_trust_request_model.rs | 43 +++++ crates/bitwarden-uniffi/Cargo.toml | 7 +- crates/bitwarden-uniffi/src/docs.rs | 4 + crates/bitwarden-uniffi/src/lib.rs | 6 + crates/bitwarden-uniffi/src/platform/mod.rs | 16 ++ crates/bitwarden/Cargo.toml | 2 +- crates/bitwarden/src/client/client.rs | 2 +- .../src/platform/generate_fingerprint.rs | 1 + crates/uniffi-bindgen/Cargo.toml | 2 +- languages/cpp/CMakeBuild.md | 33 ++++ languages/cpp/CMakeLists.txt | 36 ++++ languages/cpp/ExampleUse.md | 70 ++++++++ languages/cpp/README.md | 97 ++++++++++ languages/cpp/examples/Wrapper.cpp | 73 ++++++++ languages/cpp/include/BitwardenClient.h | 36 ++++ languages/cpp/include/BitwardenLibrary.h | 27 +++ languages/cpp/include/BitwardenSettings.h | 19 ++ languages/cpp/include/CommandRunner.h | 45 +++++ languages/cpp/include/Projects.h | 19 ++ languages/cpp/include/Secrets.h | 20 +++ languages/cpp/src/BitwardenClient.cpp | 145 +++++++++++++++ languages/cpp/src/BitwardenLibrary.cpp | 107 +++++++++++ languages/cpp/src/CommandRunner.cpp | 49 +++++ languages/cpp/src/Projects.cpp | 132 ++++++++++++++ languages/cpp/src/Secrets.cpp | 149 +++++++++++++++ languages/go/README.md | 113 ++++++++++++ languages/go/bitwarden_client.go | 63 +++++++ languages/go/command_runner.go | 37 ++++ languages/go/example/example.go | 86 +++++++++ languages/go/example/go.mod | 10 ++ languages/go/example/go.sum | 2 + languages/go/go.mod | 5 + languages/go/go.sum | 2 + .../internal/cinterface/bitwarden_library.go | 55 ++++++ languages/go/project.go | 107 +++++++++++ languages/go/secrets.go | 114 ++++++++++++ languages/go/util.go | 33 ++++ languages/kotlin/doc.md | 33 ++++ support/docs/docs.ts | 1 + support/scripts/schemas.ts | 27 +++ 76 files changed, 2580 insertions(+), 203 deletions(-) create mode 100644 .github/workflows/golang-release.yml create mode 100644 crates/bitwarden-api-api/src/models/billing_customer_discount.rs create mode 100644 crates/bitwarden-api-api/src/models/device_keys_update_request_model.rs create mode 100644 crates/bitwarden-api-api/src/models/organization_public_key_response_model.rs create mode 100644 crates/bitwarden-api-api/src/models/other_device_keys_update_request_model.rs create mode 100644 crates/bitwarden-api-api/src/models/protected_device_response_model.rs create mode 100644 crates/bitwarden-api-api/src/models/secrets_manager_subscribe_request_model.rs create mode 100644 crates/bitwarden-api-api/src/models/service_account_secrets_details_response_model.rs create mode 100644 crates/bitwarden-api-api/src/models/service_account_secrets_details_response_model_list_response_model.rs create mode 100644 crates/bitwarden-api-api/src/models/update_devices_trust_request_model.rs create mode 100644 crates/bitwarden-uniffi/src/platform/mod.rs create mode 100644 languages/cpp/CMakeBuild.md create mode 100644 languages/cpp/CMakeLists.txt create mode 100644 languages/cpp/ExampleUse.md create mode 100644 languages/cpp/README.md create mode 100644 languages/cpp/examples/Wrapper.cpp create mode 100644 languages/cpp/include/BitwardenClient.h create mode 100644 languages/cpp/include/BitwardenLibrary.h create mode 100644 languages/cpp/include/BitwardenSettings.h create mode 100644 languages/cpp/include/CommandRunner.h create mode 100644 languages/cpp/include/Projects.h create mode 100644 languages/cpp/include/Secrets.h create mode 100644 languages/cpp/src/BitwardenClient.cpp create mode 100644 languages/cpp/src/BitwardenLibrary.cpp create mode 100644 languages/cpp/src/CommandRunner.cpp create mode 100644 languages/cpp/src/Projects.cpp create mode 100644 languages/cpp/src/Secrets.cpp create mode 100644 languages/go/README.md create mode 100644 languages/go/bitwarden_client.go create mode 100644 languages/go/command_runner.go create mode 100644 languages/go/example/example.go create mode 100644 languages/go/example/go.mod create mode 100644 languages/go/example/go.sum create mode 100644 languages/go/go.mod create mode 100644 languages/go/go.sum create mode 100644 languages/go/internal/cinterface/bitwarden_library.go create mode 100644 languages/go/project.go create mode 100644 languages/go/secrets.go create mode 100644 languages/go/util.go diff --git a/.github/workflows/generate_schemas.yml b/.github/workflows/generate_schemas.yml index 89e5620a8..bf109797a 100644 --- a/.github/workflows/generate_schemas.yml +++ b/.github/workflows/generate_schemas.yml @@ -64,6 +64,12 @@ jobs: path: ${{ github.workspace }}/support/schemas/* if-no-files-found: error + - name: Upload Go schemas artifact + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + with: + name: schemas.go + path: ${{ github.workspace }}/languages/go/schema.go + - name: Upload java schemas artifact uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: diff --git a/.github/workflows/golang-release.yml b/.github/workflows/golang-release.yml new file mode 100644 index 000000000..6f41bcd3e --- /dev/null +++ b/.github/workflows/golang-release.yml @@ -0,0 +1,73 @@ +name: Go Release + +on: + workflow_dispatch: + inputs: + version_number: + description: "New Version" + required: true + +env: + GO111MODULE: on + GO_VERSION: "^1.18" + +jobs: + build_rust: + uses: ./.github/workflows/build-rust-cross-platform.yml + + generate-schemas: + uses: ./.github/workflows/generate_schemas.yml + + build: + name: Build + needs: + - build_rust + - generate-schemas + runs-on: ubuntu-22.04 + steps: + - name: Checkout Repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Setup Go environment + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Cache dependencies + uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Build + run: go build -v ./... + + - name: Test + run: go test -v ./... + + release: + name: Release + needs: build + runs-on: ubuntu-22.04 + steps: + - name: Checkout Repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Setup Go environment + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Set release version + run: echo "VERSION=${{ github.event.inputs.version_number }}" >> $GITHUB_ENV + + - name: Install Goreleaser + run: go install github.com/goreleaser/goreleaser@v1.21.2 + + - name: Run Goreleaser + run: goreleaser release --rm-dist --skip-validate + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ env.VERSION }} diff --git a/.gitignore b/.gitignore index 1f296cf63..dc79bfa4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /target .DS_Store .pytest_cache +.vscode/c_cpp_properties.json # Build results [Dd]ebug/ @@ -49,4 +50,6 @@ crates/bitwarden-napi/src-ts/bitwarden_client/schemas.ts languages/csharp/Bitwarden.Sdk/schemas.cs languages/js_webassembly/bitwarden_client/schemas.ts languages/python/bitwarden_sdk/schemas.py +languages/cpp/include/schemas.hpp +languages/go/schema.go languages/java/src/main/java/com/bitwarden/sdk/schema diff --git a/Cargo.lock b/Cargo.lock index a1f089632..4c956a925 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3050,6 +3050,12 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + [[package]] name = "socket2" version = "0.4.10" @@ -3235,6 +3241,17 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.50" @@ -3524,6 +3541,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + [[package]] name = "unicode-normalization" version = "0.1.22" @@ -3547,8 +3570,8 @@ checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "uniffi" -version = "0.25.1" -source = "git+https://github.com/mozilla/uniffi-rs?rev=0a03b713306d6ce3de033157fc2ce92a238c2e24#0a03b713306d6ce3de033157fc2ce92a238c2e24" +version = "0.25.2" +source = "git+https://github.com/mozilla/uniffi-rs?rev=23711c8151bbb794369aa1f9d383db386792dff9#23711c8151bbb794369aa1f9d383db386792dff9" dependencies = [ "anyhow", "camino", @@ -3568,8 +3591,8 @@ dependencies = [ [[package]] name = "uniffi_bindgen" -version = "0.25.1" -source = "git+https://github.com/mozilla/uniffi-rs?rev=0a03b713306d6ce3de033157fc2ce92a238c2e24#0a03b713306d6ce3de033157fc2ce92a238c2e24" +version = "0.25.2" +source = "git+https://github.com/mozilla/uniffi-rs?rev=23711c8151bbb794369aa1f9d383db386792dff9#23711c8151bbb794369aa1f9d383db386792dff9" dependencies = [ "anyhow", "askama", @@ -3583,6 +3606,7 @@ dependencies = [ "once_cell", "paste", "serde", + "textwrap", "toml 0.5.11", "uniffi_meta", "uniffi_testing", @@ -3591,8 +3615,8 @@ dependencies = [ [[package]] name = "uniffi_build" -version = "0.25.1" -source = "git+https://github.com/mozilla/uniffi-rs?rev=0a03b713306d6ce3de033157fc2ce92a238c2e24#0a03b713306d6ce3de033157fc2ce92a238c2e24" +version = "0.25.2" +source = "git+https://github.com/mozilla/uniffi-rs?rev=23711c8151bbb794369aa1f9d383db386792dff9#23711c8151bbb794369aa1f9d383db386792dff9" dependencies = [ "anyhow", "camino", @@ -3601,8 +3625,8 @@ dependencies = [ [[package]] name = "uniffi_checksum_derive" -version = "0.25.1" -source = "git+https://github.com/mozilla/uniffi-rs?rev=0a03b713306d6ce3de033157fc2ce92a238c2e24#0a03b713306d6ce3de033157fc2ce92a238c2e24" +version = "0.25.2" +source = "git+https://github.com/mozilla/uniffi-rs?rev=23711c8151bbb794369aa1f9d383db386792dff9#23711c8151bbb794369aa1f9d383db386792dff9" dependencies = [ "quote", "syn 2.0.39", @@ -3610,8 +3634,8 @@ dependencies = [ [[package]] name = "uniffi_core" -version = "0.25.1" -source = "git+https://github.com/mozilla/uniffi-rs?rev=0a03b713306d6ce3de033157fc2ce92a238c2e24#0a03b713306d6ce3de033157fc2ce92a238c2e24" +version = "0.25.2" +source = "git+https://github.com/mozilla/uniffi-rs?rev=23711c8151bbb794369aa1f9d383db386792dff9#23711c8151bbb794369aa1f9d383db386792dff9" dependencies = [ "anyhow", "bytes", @@ -3625,8 +3649,8 @@ dependencies = [ [[package]] name = "uniffi_macros" -version = "0.25.1" -source = "git+https://github.com/mozilla/uniffi-rs?rev=0a03b713306d6ce3de033157fc2ce92a238c2e24#0a03b713306d6ce3de033157fc2ce92a238c2e24" +version = "0.25.2" +source = "git+https://github.com/mozilla/uniffi-rs?rev=23711c8151bbb794369aa1f9d383db386792dff9#23711c8151bbb794369aa1f9d383db386792dff9" dependencies = [ "bincode", "camino", @@ -3643,8 +3667,8 @@ dependencies = [ [[package]] name = "uniffi_meta" -version = "0.25.1" -source = "git+https://github.com/mozilla/uniffi-rs?rev=0a03b713306d6ce3de033157fc2ce92a238c2e24#0a03b713306d6ce3de033157fc2ce92a238c2e24" +version = "0.25.2" +source = "git+https://github.com/mozilla/uniffi-rs?rev=23711c8151bbb794369aa1f9d383db386792dff9#23711c8151bbb794369aa1f9d383db386792dff9" dependencies = [ "anyhow", "bytes", @@ -3654,8 +3678,8 @@ dependencies = [ [[package]] name = "uniffi_testing" -version = "0.25.1" -source = "git+https://github.com/mozilla/uniffi-rs?rev=0a03b713306d6ce3de033157fc2ce92a238c2e24#0a03b713306d6ce3de033157fc2ce92a238c2e24" +version = "0.25.2" +source = "git+https://github.com/mozilla/uniffi-rs?rev=23711c8151bbb794369aa1f9d383db386792dff9#23711c8151bbb794369aa1f9d383db386792dff9" dependencies = [ "anyhow", "camino", @@ -3666,10 +3690,11 @@ dependencies = [ [[package]] name = "uniffi_udl" -version = "0.25.1" -source = "git+https://github.com/mozilla/uniffi-rs?rev=0a03b713306d6ce3de033157fc2ce92a238c2e24#0a03b713306d6ce3de033157fc2ce92a238c2e24" +version = "0.25.2" +source = "git+https://github.com/mozilla/uniffi-rs?rev=23711c8151bbb794369aa1f9d383db386792dff9#23711c8151bbb794369aa1f9d383db386792dff9" dependencies = [ "anyhow", + "textwrap", "uniffi_meta", "uniffi_testing", "weedle2", @@ -3886,7 +3911,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "weedle2" version = "4.0.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=0a03b713306d6ce3de033157fc2ce92a238c2e24#0a03b713306d6ce3de033157fc2ce92a238c2e24" +source = "git+https://github.com/mozilla/uniffi-rs?rev=23711c8151bbb794369aa1f9d383db386792dff9#23711c8151bbb794369aa1f9d383db386792dff9" dependencies = [ "nom", ] diff --git a/Cargo.toml b/Cargo.toml index c7c2906dc..f841f07c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,8 @@ codegen-units = 1 # Using git dependency temporarily to add support for immutable records in generated code [patch.crates-io] -uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "0a03b713306d6ce3de033157fc2ce92a238c2e24" } -uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "0a03b713306d6ce3de033157fc2ce92a238c2e24" } -uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "0a03b713306d6ce3de033157fc2ce92a238c2e24" } -uniffi_core = { git = "https://github.com/mozilla/uniffi-rs", rev = "0a03b713306d6ce3de033157fc2ce92a238c2e24" } -uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "0a03b713306d6ce3de033157fc2ce92a238c2e24" } +uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "23711c8151bbb794369aa1f9d383db386792dff9" } +uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "23711c8151bbb794369aa1f9d383db386792dff9" } +uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "23711c8151bbb794369aa1f9d383db386792dff9" } +uniffi_core = { git = "https://github.com/mozilla/uniffi-rs", rev = "23711c8151bbb794369aa1f9d383db386792dff9" } +uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "23711c8151bbb794369aa1f9d383db386792dff9" } diff --git a/README.md b/README.md index 18613d4dc..2de94b09c 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,10 @@ The first step is to generate the swagger documents from the server repository. ```bash # src/Api -dotnet swagger tofile --output ../../api.json .\bin\Debug\net6.0\Api.dll internal +dotnet swagger tofile --output ../../api.json ./bin/Debug/net6.0/Api.dll internal # src/Identity -dotnet swagger tofile --output ../../identity.json .\bin\Debug\net6.0\Identity.dll v1 +ASPNETCORE_ENVIRONMENT=development dotnet swagger tofile --output ../../identity.json ./bin/Debug/net6.0/Identity.dll v1 ``` ### OpenApi Generator @@ -68,20 +68,20 @@ dotnet swagger tofile --output ../../identity.json .\bin\Debug\net6.0\Identity.d Runs from the root of the SDK project. ```bash -npx openapi-generator-cli generate ` - -i ../server/api.json ` - -g rust ` - -o crates/bitwarden-api-api ` - --package-name bitwarden-api-api ` - -t ./support/openapi-template ` +npx openapi-generator-cli generate \ + -i ../server/api.json \ + -g rust \ + -o crates/bitwarden-api-api \ + --package-name bitwarden-api-api \ + -t ./support/openapi-template \ --additional-properties=packageVersion=1.0.0 -npx openapi-generator-cli generate ` - -i ../server/identity.json ` - -g rust ` - -o crates/bitwarden-api-identity ` - --package-name bitwarden-api-identity ` - -t ./support/openapi-template ` +npx openapi-generator-cli generate \ + -i ../server/identity.json \ + -g rust \ + -o crates/bitwarden-api-identity \ + --package-name bitwarden-api-identity \ + -t ./support/openapi-template \ --additional-properties=packageVersion=1.0.0 ``` diff --git a/crates/bitwarden-api-api/.openapi-generator/FILES b/crates/bitwarden-api-api/.openapi-generator/FILES index 4fbc2fbf9..586d4f2db 100644 --- a/crates/bitwarden-api-api/.openapi-generator/FILES +++ b/crates/bitwarden-api-api/.openapi-generator/FILES @@ -69,6 +69,7 @@ src/models/authenticator_attestation_raw_response.rs src/models/base_access_policy_response_model.rs src/models/base_secret_response_model.rs src/models/base_secret_response_model_list_response_model.rs +src/models/billing_customer_discount.rs src/models/billing_history_response_model.rs src/models/billing_invoice.rs src/models/billing_payment_response_model.rs @@ -122,6 +123,7 @@ src/models/collection_with_id_request_model.rs src/models/config_response_model.rs src/models/delete_recover_request_model.rs src/models/device_keys_request_model.rs +src/models/device_keys_update_request_model.rs src/models/device_request_model.rs src/models/device_response_model.rs src/models/device_response_model_list_response_model.rs @@ -201,10 +203,10 @@ src/models/organization_domain_response_model.rs src/models/organization_domain_response_model_list_response_model.rs src/models/organization_domain_sso_details_request_model.rs src/models/organization_domain_sso_details_response_model.rs -src/models/organization_enroll_secrets_manager_request_model.rs src/models/organization_keys_request_model.rs src/models/organization_keys_response_model.rs src/models/organization_license.rs +src/models/organization_public_key_response_model.rs src/models/organization_response_model.rs src/models/organization_seat_request_model.rs src/models/organization_sponsorship_create_request_model.rs @@ -241,6 +243,7 @@ src/models/organization_user_update_request_model.rs src/models/organization_user_user_details_response_model.rs src/models/organization_user_user_details_response_model_list_response_model.rs src/models/organization_verify_bank_request_model.rs +src/models/other_device_keys_update_request_model.rs src/models/password_hint_request_model.rs src/models/password_request_model.rs src/models/payment_method_type.rs @@ -272,6 +275,7 @@ src/models/project_create_request_model.rs src/models/project_response_model.rs src/models/project_response_model_list_response_model.rs src/models/project_update_request_model.rs +src/models/protected_device_response_model.rs src/models/provider_organization_add_request_model.rs src/models/provider_organization_create_request_model.rs src/models/provider_organization_organization_details_response_model.rs @@ -316,6 +320,7 @@ src/models/secret_update_request_model.rs src/models/secret_verification_request_model.rs src/models/secret_with_projects_inner_project.rs src/models/secret_with_projects_list_response_model.rs +src/models/secrets_manager_subscribe_request_model.rs src/models/secrets_manager_subscription_update_request_model.rs src/models/secrets_with_projects_inner_secret.rs src/models/secure_note_type.rs @@ -337,7 +342,8 @@ src/models/service_account_create_request_model.rs src/models/service_account_project_access_policy_response_model.rs src/models/service_account_project_access_policy_response_model_list_response_model.rs src/models/service_account_response_model.rs -src/models/service_account_response_model_list_response_model.rs +src/models/service_account_secrets_details_response_model.rs +src/models/service_account_secrets_details_response_model_list_response_model.rs src/models/service_account_update_request_model.rs src/models/set_key_connector_key_request_model.rs src/models/set_password_request_model.rs @@ -370,6 +376,7 @@ src/models/two_factor_web_authn_request_model.rs src/models/two_factor_web_authn_response_model.rs src/models/two_factor_yubi_key_response_model.rs src/models/update_avatar_request_model.rs +src/models/update_devices_trust_request_model.rs src/models/update_domains_request_model.rs src/models/update_key_request_model.rs src/models/update_profile_request_model.rs diff --git a/crates/bitwarden-api-api/README.md b/crates/bitwarden-api-api/README.md index 255041dc5..43cbc40e8 100644 --- a/crates/bitwarden-api-api/README.md +++ b/crates/bitwarden-api-api/README.md @@ -86,6 +86,7 @@ All URIs are relative to _http://localhost_ | _AccountsApi_ | [**accounts_verify_password_post**](docs/AccountsApi.md#accounts_verify_password_post) | **POST** /accounts/verify-password | | _AccountsBillingApi_ | [**accounts_billing_history_get**](docs/AccountsBillingApi.md#accounts_billing_history_get) | **GET** /accounts/billing/history | | _AccountsBillingApi_ | [**accounts_billing_payment_method_get**](docs/AccountsBillingApi.md#accounts_billing_payment_method_get) | **GET** /accounts/billing/payment-method | +| _AuthRequestsApi_ | [**auth_requests_admin_request_post**](docs/AuthRequestsApi.md#auth_requests_admin_request_post) | **POST** /auth-requests/admin-request | | _AuthRequestsApi_ | [**auth_requests_get**](docs/AuthRequestsApi.md#auth_requests_get) | **GET** /auth-requests | | _AuthRequestsApi_ | [**auth_requests_id_get**](docs/AuthRequestsApi.md#auth_requests_id_get) | **GET** /auth-requests/{id} | | _AuthRequestsApi_ | [**auth_requests_id_put**](docs/AuthRequestsApi.md#auth_requests_id_put) | **PUT** /auth-requests/{id} | @@ -162,7 +163,6 @@ All URIs are relative to _http://localhost_ | _CollectionsApi_ | [**organizations_org_id_collections_id_users_put**](docs/CollectionsApi.md#organizations_org_id_collections_id_users_put) | **PUT** /organizations/{orgId}/collections/{id}/users | | _CollectionsApi_ | [**organizations_org_id_collections_post**](docs/CollectionsApi.md#organizations_org_id_collections_post) | **POST** /organizations/{orgId}/collections | | _ConfigApi_ | [**config_get**](docs/ConfigApi.md#config_get) | **GET** /config | -| _DevicesApi_ | [**devices_exist_by_types_post**](docs/DevicesApi.md#devices_exist_by_types_post) | **POST** /devices/exist-by-types | | _DevicesApi_ | [**devices_get**](docs/DevicesApi.md#devices_get) | **GET** /devices | | _DevicesApi_ | [**devices_id_delete**](docs/DevicesApi.md#devices_id_delete) | **DELETE** /devices/{id} | | _DevicesApi_ | [**devices_id_delete_post**](docs/DevicesApi.md#devices_id_delete_post) | **POST** /devices/{id}/delete | @@ -176,9 +176,11 @@ All URIs are relative to _http://localhost_ | _DevicesApi_ | [**devices_identifier_identifier_token_put**](docs/DevicesApi.md#devices_identifier_identifier_token_put) | **PUT** /devices/identifier/{identifier}/token | | _DevicesApi_ | [**devices_identifier_keys_post**](docs/DevicesApi.md#devices_identifier_keys_post) | **POST** /devices/{identifier}/keys | | _DevicesApi_ | [**devices_identifier_keys_put**](docs/DevicesApi.md#devices_identifier_keys_put) | **PUT** /devices/{identifier}/keys | +| _DevicesApi_ | [**devices_identifier_retrieve_keys_post**](docs/DevicesApi.md#devices_identifier_retrieve_keys_post) | **POST** /devices/{identifier}/retrieve-keys | | _DevicesApi_ | [**devices_knowndevice_email_identifier_get**](docs/DevicesApi.md#devices_knowndevice_email_identifier_get) | **GET** /devices/knowndevice/{email}/{identifier} | | _DevicesApi_ | [**devices_knowndevice_get**](docs/DevicesApi.md#devices_knowndevice_get) | **GET** /devices/knowndevice | | _DevicesApi_ | [**devices_post**](docs/DevicesApi.md#devices_post) | **POST** /devices | +| _DevicesApi_ | [**devices_update_trust_post**](docs/DevicesApi.md#devices_update_trust_post) | **POST** /devices/update-trust | | _EmergencyAccessApi_ | [**emergency_access_granted_get**](docs/EmergencyAccessApi.md#emergency_access_granted_get) | **GET** /emergency-access/granted | | _EmergencyAccessApi_ | [**emergency_access_id_accept_post**](docs/EmergencyAccessApi.md#emergency_access_id_accept_post) | **POST** /emergency-access/{id}/accept | | _EmergencyAccessApi_ | [**emergency_access_id_approve_post**](docs/EmergencyAccessApi.md#emergency_access_id_approve_post) | **POST** /emergency-access/{id}/approve | @@ -304,7 +306,6 @@ All URIs are relative to _http://localhost_ | _OrganizationsApi_ | [**organizations_id_cancel_post**](docs/OrganizationsApi.md#organizations_id_cancel_post) | **POST** /organizations/{id}/cancel | | _OrganizationsApi_ | [**organizations_id_delete**](docs/OrganizationsApi.md#organizations_id_delete) | **DELETE** /organizations/{id} | | _OrganizationsApi_ | [**organizations_id_delete_post**](docs/OrganizationsApi.md#organizations_id_delete_post) | **POST** /organizations/{id}/delete | -| _OrganizationsApi_ | [**organizations_id_enroll_secrets_manager_post**](docs/OrganizationsApi.md#organizations_id_enroll_secrets_manager_post) | **POST** /organizations/{id}/enroll-secrets-manager | | _OrganizationsApi_ | [**organizations_id_get**](docs/OrganizationsApi.md#organizations_id_get) | **GET** /organizations/{id} | | _OrganizationsApi_ | [**organizations_id_import_post**](docs/OrganizationsApi.md#organizations_id_import_post) | **POST** /organizations/{id}/import | | _OrganizationsApi_ | [**organizations_id_keys_get**](docs/OrganizationsApi.md#organizations_id_keys_get) | **GET** /organizations/{id}/keys | @@ -313,6 +314,7 @@ All URIs are relative to _http://localhost_ | _OrganizationsApi_ | [**organizations_id_license_get**](docs/OrganizationsApi.md#organizations_id_license_get) | **GET** /organizations/{id}/license | | _OrganizationsApi_ | [**organizations_id_payment_post**](docs/OrganizationsApi.md#organizations_id_payment_post) | **POST** /organizations/{id}/payment | | _OrganizationsApi_ | [**organizations_id_post**](docs/OrganizationsApi.md#organizations_id_post) | **POST** /organizations/{id} | +| _OrganizationsApi_ | [**organizations_id_public_key_get**](docs/OrganizationsApi.md#organizations_id_public_key_get) | **GET** /organizations/{id}/public-key | | _OrganizationsApi_ | [**organizations_id_put**](docs/OrganizationsApi.md#organizations_id_put) | **PUT** /organizations/{id} | | _OrganizationsApi_ | [**organizations_id_reinstate_post**](docs/OrganizationsApi.md#organizations_id_reinstate_post) | **POST** /organizations/{id}/reinstate | | _OrganizationsApi_ | [**organizations_id_rotate_api_key_post**](docs/OrganizationsApi.md#organizations_id_rotate_api_key_post) | **POST** /organizations/{id}/rotate-api-key | @@ -321,6 +323,7 @@ All URIs are relative to _http://localhost_ | _OrganizationsApi_ | [**organizations_id_sso_get**](docs/OrganizationsApi.md#organizations_id_sso_get) | **GET** /organizations/{id}/sso | | _OrganizationsApi_ | [**organizations_id_sso_post**](docs/OrganizationsApi.md#organizations_id_sso_post) | **POST** /organizations/{id}/sso | | _OrganizationsApi_ | [**organizations_id_storage_post**](docs/OrganizationsApi.md#organizations_id_storage_post) | **POST** /organizations/{id}/storage | +| _OrganizationsApi_ | [**organizations_id_subscribe_secrets_manager_post**](docs/OrganizationsApi.md#organizations_id_subscribe_secrets_manager_post) | **POST** /organizations/{id}/subscribe-secrets-manager | | _OrganizationsApi_ | [**organizations_id_subscription_get**](docs/OrganizationsApi.md#organizations_id_subscription_get) | **GET** /organizations/{id}/subscription | | _OrganizationsApi_ | [**organizations_id_subscription_post**](docs/OrganizationsApi.md#organizations_id_subscription_post) | **POST** /organizations/{id}/subscription | | _OrganizationsApi_ | [**organizations_id_tax_get**](docs/OrganizationsApi.md#organizations_id_tax_get) | **GET** /organizations/{id}/tax | @@ -472,6 +475,7 @@ All URIs are relative to _http://localhost_ - [BaseAccessPolicyResponseModel](docs/BaseAccessPolicyResponseModel.md) - [BaseSecretResponseModel](docs/BaseSecretResponseModel.md) - [BaseSecretResponseModelListResponseModel](docs/BaseSecretResponseModelListResponseModel.md) +- [BillingCustomerDiscount](docs/BillingCustomerDiscount.md) - [BillingHistoryResponseModel](docs/BillingHistoryResponseModel.md) - [BillingInvoice](docs/BillingInvoice.md) - [BillingPaymentResponseModel](docs/BillingPaymentResponseModel.md) @@ -525,6 +529,7 @@ All URIs are relative to _http://localhost_ - [ConfigResponseModel](docs/ConfigResponseModel.md) - [DeleteRecoverRequestModel](docs/DeleteRecoverRequestModel.md) - [DeviceKeysRequestModel](docs/DeviceKeysRequestModel.md) +- [DeviceKeysUpdateRequestModel](docs/DeviceKeysUpdateRequestModel.md) - [DeviceRequestModel](docs/DeviceRequestModel.md) - [DeviceResponseModel](docs/DeviceResponseModel.md) - [DeviceResponseModelListResponseModel](docs/DeviceResponseModelListResponseModel.md) @@ -603,10 +608,10 @@ All URIs are relative to _http://localhost_ - [OrganizationDomainResponseModelListResponseModel](docs/OrganizationDomainResponseModelListResponseModel.md) - [OrganizationDomainSsoDetailsRequestModel](docs/OrganizationDomainSsoDetailsRequestModel.md) - [OrganizationDomainSsoDetailsResponseModel](docs/OrganizationDomainSsoDetailsResponseModel.md) -- [OrganizationEnrollSecretsManagerRequestModel](docs/OrganizationEnrollSecretsManagerRequestModel.md) - [OrganizationKeysRequestModel](docs/OrganizationKeysRequestModel.md) - [OrganizationKeysResponseModel](docs/OrganizationKeysResponseModel.md) - [OrganizationLicense](docs/OrganizationLicense.md) +- [OrganizationPublicKeyResponseModel](docs/OrganizationPublicKeyResponseModel.md) - [OrganizationResponseModel](docs/OrganizationResponseModel.md) - [OrganizationSeatRequestModel](docs/OrganizationSeatRequestModel.md) - [OrganizationSponsorshipCreateRequestModel](docs/OrganizationSponsorshipCreateRequestModel.md) @@ -644,6 +649,7 @@ All URIs are relative to _http://localhost_ - [OrganizationUserUserDetailsResponseModel](docs/OrganizationUserUserDetailsResponseModel.md) - [OrganizationUserUserDetailsResponseModelListResponseModel](docs/OrganizationUserUserDetailsResponseModelListResponseModel.md) - [OrganizationVerifyBankRequestModel](docs/OrganizationVerifyBankRequestModel.md) +- [OtherDeviceKeysUpdateRequestModel](docs/OtherDeviceKeysUpdateRequestModel.md) - [PasswordHintRequestModel](docs/PasswordHintRequestModel.md) - [PasswordRequestModel](docs/PasswordRequestModel.md) - [PaymentMethodType](docs/PaymentMethodType.md) @@ -675,6 +681,7 @@ All URIs are relative to _http://localhost_ - [ProjectResponseModel](docs/ProjectResponseModel.md) - [ProjectResponseModelListResponseModel](docs/ProjectResponseModelListResponseModel.md) - [ProjectUpdateRequestModel](docs/ProjectUpdateRequestModel.md) +- [ProtectedDeviceResponseModel](docs/ProtectedDeviceResponseModel.md) - [ProviderOrganizationAddRequestModel](docs/ProviderOrganizationAddRequestModel.md) - [ProviderOrganizationCreateRequestModel](docs/ProviderOrganizationCreateRequestModel.md) - [ProviderOrganizationOrganizationDetailsResponseModel](docs/ProviderOrganizationOrganizationDetailsResponseModel.md) @@ -719,6 +726,7 @@ All URIs are relative to _http://localhost_ - [SecretVerificationRequestModel](docs/SecretVerificationRequestModel.md) - [SecretWithProjectsInnerProject](docs/SecretWithProjectsInnerProject.md) - [SecretWithProjectsListResponseModel](docs/SecretWithProjectsListResponseModel.md) +- [SecretsManagerSubscribeRequestModel](docs/SecretsManagerSubscribeRequestModel.md) - [SecretsManagerSubscriptionUpdateRequestModel](docs/SecretsManagerSubscriptionUpdateRequestModel.md) - [SecretsWithProjectsInnerSecret](docs/SecretsWithProjectsInnerSecret.md) - [SecureNoteType](docs/SecureNoteType.md) @@ -740,7 +748,8 @@ All URIs are relative to _http://localhost_ - [ServiceAccountProjectAccessPolicyResponseModel](docs/ServiceAccountProjectAccessPolicyResponseModel.md) - [ServiceAccountProjectAccessPolicyResponseModelListResponseModel](docs/ServiceAccountProjectAccessPolicyResponseModelListResponseModel.md) - [ServiceAccountResponseModel](docs/ServiceAccountResponseModel.md) -- [ServiceAccountResponseModelListResponseModel](docs/ServiceAccountResponseModelListResponseModel.md) +- [ServiceAccountSecretsDetailsResponseModel](docs/ServiceAccountSecretsDetailsResponseModel.md) +- [ServiceAccountSecretsDetailsResponseModelListResponseModel](docs/ServiceAccountSecretsDetailsResponseModelListResponseModel.md) - [ServiceAccountUpdateRequestModel](docs/ServiceAccountUpdateRequestModel.md) - [SetKeyConnectorKeyRequestModel](docs/SetKeyConnectorKeyRequestModel.md) - [SetPasswordRequestModel](docs/SetPasswordRequestModel.md) @@ -773,6 +782,7 @@ All URIs are relative to _http://localhost_ - [TwoFactorWebAuthnResponseModel](docs/TwoFactorWebAuthnResponseModel.md) - [TwoFactorYubiKeyResponseModel](docs/TwoFactorYubiKeyResponseModel.md) - [UpdateAvatarRequestModel](docs/UpdateAvatarRequestModel.md) +- [UpdateDevicesTrustRequestModel](docs/UpdateDevicesTrustRequestModel.md) - [UpdateDomainsRequestModel](docs/UpdateDomainsRequestModel.md) - [UpdateKeyRequestModel](docs/UpdateKeyRequestModel.md) - [UpdateProfileRequestModel](docs/UpdateProfileRequestModel.md) diff --git a/crates/bitwarden-api-api/src/apis/auth_requests_api.rs b/crates/bitwarden-api-api/src/apis/auth_requests_api.rs index 476a94129..39c4dd7b4 100644 --- a/crates/bitwarden-api-api/src/apis/auth_requests_api.rs +++ b/crates/bitwarden-api-api/src/apis/auth_requests_api.rs @@ -13,6 +13,13 @@ use reqwest; use super::{configuration, Error}; use crate::apis::ResponseContent; +/// struct for typed errors of method [`auth_requests_admin_request_post`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum AuthRequestsAdminRequestPostError { + UnknownValue(serde_json::Value), +} + /// struct for typed errors of method [`auth_requests_get`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -48,6 +55,50 @@ pub enum AuthRequestsPostError { UnknownValue(serde_json::Value), } +pub async fn auth_requests_admin_request_post( + configuration: &configuration::Configuration, + auth_request_create_request_model: Option, +) -> Result> { + let local_var_configuration = configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/auth-requests/admin-request", + local_var_configuration.base_path + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); + + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = + local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = local_var_req_builder.json(&auth_request_create_request_model); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + serde_json::from_str(&local_var_content).map_err(Error::from) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } +} + pub async fn auth_requests_get( configuration: &configuration::Configuration, ) -> Result> { diff --git a/crates/bitwarden-api-api/src/apis/devices_api.rs b/crates/bitwarden-api-api/src/apis/devices_api.rs index e7be0685e..95564464a 100644 --- a/crates/bitwarden-api-api/src/apis/devices_api.rs +++ b/crates/bitwarden-api-api/src/apis/devices_api.rs @@ -13,13 +13,6 @@ use reqwest; use super::{configuration, Error}; use crate::apis::ResponseContent; -/// struct for typed errors of method [`devices_exist_by_types_post`] -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(untagged)] -pub enum DevicesExistByTypesPostError { - UnknownValue(serde_json::Value), -} - /// struct for typed errors of method [`devices_get`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -111,6 +104,13 @@ pub enum DevicesIdentifierKeysPutError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`devices_identifier_retrieve_keys_post`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum DevicesIdentifierRetrieveKeysPostError { + UnknownValue(serde_json::Value), +} + /// struct for typed errors of method [`devices_knowndevice_email_identifier_get`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -132,48 +132,11 @@ pub enum DevicesPostError { UnknownValue(serde_json::Value), } -pub async fn devices_exist_by_types_post( - configuration: &configuration::Configuration, - device_type: Option>, -) -> Result> { - let local_var_configuration = configuration; - - let local_var_client = &local_var_configuration.client; - - let local_var_uri_str = format!( - "{}/devices/exist-by-types", - local_var_configuration.base_path - ); - let mut local_var_req_builder = - local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); - - if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { - local_var_req_builder = - local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); - } - if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { - local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); - }; - local_var_req_builder = local_var_req_builder.json(&device_type); - - let local_var_req = local_var_req_builder.build()?; - let local_var_resp = local_var_client.execute(local_var_req).await?; - - let local_var_status = local_var_resp.status(); - let local_var_content = local_var_resp.text().await?; - - if !local_var_status.is_client_error() && !local_var_status.is_server_error() { - serde_json::from_str(&local_var_content).map_err(Error::from) - } else { - let local_var_entity: Option = - serde_json::from_str(&local_var_content).ok(); - let local_var_error = ResponseContent { - status: local_var_status, - content: local_var_content, - entity: local_var_entity, - }; - Err(Error::ResponseError(local_var_error)) - } +/// struct for typed errors of method [`devices_update_trust_post`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum DevicesUpdateTrustPostError { + UnknownValue(serde_json::Value), } pub async fn devices_get( @@ -755,6 +718,55 @@ pub async fn devices_identifier_keys_put( } } +pub async fn devices_identifier_retrieve_keys_post( + configuration: &configuration::Configuration, + identifier: &str, + secret_verification_request_model: Option, +) -> Result< + crate::models::ProtectedDeviceResponseModel, + Error, +> { + let local_var_configuration = configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/devices/{identifier}/retrieve-keys", + local_var_configuration.base_path, + identifier = crate::apis::urlencode(identifier.to_string()) + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); + + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = + local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = local_var_req_builder.json(&secret_verification_request_model); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + serde_json::from_str(&local_var_content).map_err(Error::from) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } +} + pub async fn devices_knowndevice_email_identifier_get( configuration: &configuration::Configuration, email: &str, @@ -890,3 +902,44 @@ pub async fn devices_post( Err(Error::ResponseError(local_var_error)) } } + +pub async fn devices_update_trust_post( + configuration: &configuration::Configuration, + update_devices_trust_request_model: Option, +) -> Result<(), Error> { + let local_var_configuration = configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!("{}/devices/update-trust", local_var_configuration.base_path); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); + + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = + local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = local_var_req_builder.json(&update_devices_trust_request_model); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + Ok(()) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } +} diff --git a/crates/bitwarden-api-api/src/apis/mod.rs b/crates/bitwarden-api-api/src/apis/mod.rs index 623d5d0b6..492680582 100644 --- a/crates/bitwarden-api-api/src/apis/mod.rs +++ b/crates/bitwarden-api-api/src/apis/mod.rs @@ -1,5 +1,4 @@ -use std::error; -use std::fmt; +use std::{error, fmt}; #[derive(Debug, Clone)] pub struct ResponseContent { diff --git a/crates/bitwarden-api-api/src/apis/organization_users_api.rs b/crates/bitwarden-api-api/src/apis/organization_users_api.rs index f81290a86..5a8e99916 100644 --- a/crates/bitwarden-api-api/src/apis/organization_users_api.rs +++ b/crates/bitwarden-api-api/src/apis/organization_users_api.rs @@ -391,10 +391,7 @@ pub async fn organizations_org_id_users_enable_secrets_manager_patch( configuration: &configuration::Configuration, org_id: uuid::Uuid, organization_user_bulk_request_model: Option, -) -> Result< - crate::models::OrganizationUserBulkResponseModelListResponseModel, - Error, -> { +) -> Result<(), Error> { let local_var_configuration = configuration; let local_var_client = &local_var_configuration.client; @@ -423,7 +420,7 @@ pub async fn organizations_org_id_users_enable_secrets_manager_patch( let local_var_content = local_var_resp.text().await?; if !local_var_status.is_client_error() && !local_var_status.is_server_error() { - serde_json::from_str(&local_var_content).map_err(Error::from) + Ok(()) } else { let local_var_entity: Option = serde_json::from_str(&local_var_content).ok(); @@ -440,10 +437,7 @@ pub async fn organizations_org_id_users_enable_secrets_manager_put( configuration: &configuration::Configuration, org_id: uuid::Uuid, organization_user_bulk_request_model: Option, -) -> Result< - crate::models::OrganizationUserBulkResponseModelListResponseModel, - Error, -> { +) -> Result<(), Error> { let local_var_configuration = configuration; let local_var_client = &local_var_configuration.client; @@ -472,7 +466,7 @@ pub async fn organizations_org_id_users_enable_secrets_manager_put( let local_var_content = local_var_resp.text().await?; if !local_var_status.is_client_error() && !local_var_status.is_server_error() { - serde_json::from_str(&local_var_content).map_err(Error::from) + Ok(()) } else { let local_var_entity: Option = serde_json::from_str(&local_var_content).ok(); @@ -1761,8 +1755,8 @@ pub async fn organizations_org_id_users_revoke_put( pub async fn organizations_org_id_users_user_id_reset_password_enrollment_put( configuration: &configuration::Configuration, - org_id: &str, - user_id: &str, + org_id: uuid::Uuid, + user_id: uuid::Uuid, organization_user_reset_password_enrollment_request_model: Option< crate::models::OrganizationUserResetPasswordEnrollmentRequestModel, >, diff --git a/crates/bitwarden-api-api/src/apis/organizations_api.rs b/crates/bitwarden-api-api/src/apis/organizations_api.rs index 1cd531b2f..6377ef6bf 100644 --- a/crates/bitwarden-api-api/src/apis/organizations_api.rs +++ b/crates/bitwarden-api-api/src/apis/organizations_api.rs @@ -62,13 +62,6 @@ pub enum OrganizationsIdDeletePostError { UnknownValue(serde_json::Value), } -/// struct for typed errors of method [`organizations_id_enroll_secrets_manager_post`] -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(untagged)] -pub enum OrganizationsIdEnrollSecretsManagerPostError { - UnknownValue(serde_json::Value), -} - /// struct for typed errors of method [`organizations_id_get`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -125,6 +118,13 @@ pub enum OrganizationsIdPostError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`organizations_id_public_key_get`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum OrganizationsIdPublicKeyGetError { + UnknownValue(serde_json::Value), +} + /// struct for typed errors of method [`organizations_id_put`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -181,6 +181,13 @@ pub enum OrganizationsIdStoragePostError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`organizations_id_subscribe_secrets_manager_post`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum OrganizationsIdSubscribeSecretsManagerPostError { + UnknownValue(serde_json::Value), +} + /// struct for typed errors of method [`organizations_id_subscription_get`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -549,55 +556,6 @@ pub async fn organizations_id_delete_post( } } -pub async fn organizations_id_enroll_secrets_manager_post( - configuration: &configuration::Configuration, - id: uuid::Uuid, - organization_enroll_secrets_manager_request_model: Option< - crate::models::OrganizationEnrollSecretsManagerRequestModel, - >, -) -> Result<(), Error> { - let local_var_configuration = configuration; - - let local_var_client = &local_var_configuration.client; - - let local_var_uri_str = format!( - "{}/organizations/{id}/enroll-secrets-manager", - local_var_configuration.base_path, - id = crate::apis::urlencode(id.to_string()) - ); - let mut local_var_req_builder = - local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); - - if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { - local_var_req_builder = - local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); - } - if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { - local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); - }; - local_var_req_builder = - local_var_req_builder.json(&organization_enroll_secrets_manager_request_model); - - let local_var_req = local_var_req_builder.build()?; - let local_var_resp = local_var_client.execute(local_var_req).await?; - - let local_var_status = local_var_resp.status(); - let local_var_content = local_var_resp.text().await?; - - if !local_var_status.is_client_error() && !local_var_status.is_server_error() { - Ok(()) - } else { - let local_var_entity: Option = - serde_json::from_str(&local_var_content).ok(); - let local_var_error = ResponseContent { - status: local_var_status, - content: local_var_content, - entity: local_var_entity, - }; - Err(Error::ResponseError(local_var_error)) - } -} - pub async fn organizations_id_get( configuration: &configuration::Configuration, id: &str, @@ -693,7 +651,7 @@ pub async fn organizations_id_import_post( pub async fn organizations_id_keys_get( configuration: &configuration::Configuration, id: &str, -) -> Result> { +) -> Result> { let local_var_configuration = configuration; let local_var_client = &local_var_configuration.client; @@ -965,6 +923,53 @@ pub async fn organizations_id_post( } } +pub async fn organizations_id_public_key_get( + configuration: &configuration::Configuration, + id: &str, +) -> Result< + crate::models::OrganizationPublicKeyResponseModel, + Error, +> { + let local_var_configuration = configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/organizations/{id}/public-key", + local_var_configuration.base_path, + id = crate::apis::urlencode(id.to_string()) + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str()); + + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = + local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + serde_json::from_str(&local_var_content).map_err(Error::from) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } +} + pub async fn organizations_id_put( configuration: &configuration::Configuration, id: &str, @@ -1332,6 +1337,57 @@ pub async fn organizations_id_storage_post( } } +pub async fn organizations_id_subscribe_secrets_manager_post( + configuration: &configuration::Configuration, + id: uuid::Uuid, + secrets_manager_subscribe_request_model: Option< + crate::models::SecretsManagerSubscribeRequestModel, + >, +) -> Result< + crate::models::ProfileOrganizationResponseModel, + Error, +> { + let local_var_configuration = configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/organizations/{id}/subscribe-secrets-manager", + local_var_configuration.base_path, + id = crate::apis::urlencode(id.to_string()) + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); + + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = + local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = local_var_req_builder.json(&secrets_manager_subscribe_request_model); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + serde_json::from_str(&local_var_content).map_err(Error::from) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } +} + pub async fn organizations_id_subscription_get( configuration: &configuration::Configuration, id: &str, diff --git a/crates/bitwarden-api-api/src/apis/service_accounts_api.rs b/crates/bitwarden-api-api/src/apis/service_accounts_api.rs index 511fb3674..47045b475 100644 --- a/crates/bitwarden-api-api/src/apis/service_accounts_api.rs +++ b/crates/bitwarden-api-api/src/apis/service_accounts_api.rs @@ -72,8 +72,9 @@ pub enum ServiceAccountsIdPutError { pub async fn organizations_organization_id_service_accounts_get( configuration: &configuration::Configuration, organization_id: uuid::Uuid, + include_access_to_secrets: Option, ) -> Result< - crate::models::ServiceAccountResponseModelListResponseModel, + crate::models::ServiceAccountSecretsDetailsResponseModelListResponseModel, Error, > { let local_var_configuration = configuration; @@ -88,6 +89,10 @@ pub async fn organizations_organization_id_service_accounts_get( let mut local_var_req_builder = local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str()); + if let Some(ref local_var_str) = include_access_to_secrets { + local_var_req_builder = + local_var_req_builder.query(&[("includeAccessToSecrets", &local_var_str.to_string())]); + } if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); diff --git a/crates/bitwarden-api-api/src/models/attachment_response_model.rs b/crates/bitwarden-api-api/src/models/attachment_response_model.rs index 86637a161..c9066488d 100644 --- a/crates/bitwarden-api-api/src/models/attachment_response_model.rs +++ b/crates/bitwarden-api-api/src/models/attachment_response_model.rs @@ -21,7 +21,7 @@ pub struct AttachmentResponseModel { #[serde(rename = "key", skip_serializing_if = "Option::is_none")] pub key: Option, #[serde(rename = "size", skip_serializing_if = "Option::is_none")] - pub size: Option, + pub size: Option, #[serde(rename = "sizeName", skip_serializing_if = "Option::is_none")] pub size_name: Option, } diff --git a/crates/bitwarden-api-api/src/models/billing_customer_discount.rs b/crates/bitwarden-api-api/src/models/billing_customer_discount.rs new file mode 100644 index 000000000..61f695d70 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/billing_customer_discount.rs @@ -0,0 +1,26 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct BillingCustomerDiscount { + #[serde(rename = "id", skip_serializing_if = "Option::is_none")] + pub id: Option, + #[serde(rename = "active", skip_serializing_if = "Option::is_none")] + pub active: Option, +} + +impl BillingCustomerDiscount { + pub fn new() -> BillingCustomerDiscount { + BillingCustomerDiscount { + id: None, + active: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/cipher_details_response_model.rs b/crates/bitwarden-api-api/src/models/cipher_details_response_model.rs index 448712702..289169e41 100644 --- a/crates/bitwarden-api-api/src/models/cipher_details_response_model.rs +++ b/crates/bitwarden-api-api/src/models/cipher_details_response_model.rs @@ -51,6 +51,8 @@ pub struct CipherDetailsResponseModel { pub deleted_date: Option, #[serde(rename = "reprompt", skip_serializing_if = "Option::is_none")] pub reprompt: Option, + #[serde(rename = "key", skip_serializing_if = "Option::is_none")] + pub key: Option, #[serde(rename = "folderId", skip_serializing_if = "Option::is_none")] pub folder_id: Option, #[serde(rename = "favorite", skip_serializing_if = "Option::is_none")] @@ -85,6 +87,7 @@ impl CipherDetailsResponseModel { creation_date: None, deleted_date: None, reprompt: None, + key: None, folder_id: None, favorite: None, edit: None, diff --git a/crates/bitwarden-api-api/src/models/cipher_mini_details_response_model.rs b/crates/bitwarden-api-api/src/models/cipher_mini_details_response_model.rs index 28dafcdbb..1aa5b8e3b 100644 --- a/crates/bitwarden-api-api/src/models/cipher_mini_details_response_model.rs +++ b/crates/bitwarden-api-api/src/models/cipher_mini_details_response_model.rs @@ -51,6 +51,8 @@ pub struct CipherMiniDetailsResponseModel { pub deleted_date: Option, #[serde(rename = "reprompt", skip_serializing_if = "Option::is_none")] pub reprompt: Option, + #[serde(rename = "key", skip_serializing_if = "Option::is_none")] + pub key: Option, #[serde(rename = "collectionIds", skip_serializing_if = "Option::is_none")] pub collection_ids: Option>, } @@ -77,6 +79,7 @@ impl CipherMiniDetailsResponseModel { creation_date: None, deleted_date: None, reprompt: None, + key: None, collection_ids: None, } } diff --git a/crates/bitwarden-api-api/src/models/cipher_mini_response_model.rs b/crates/bitwarden-api-api/src/models/cipher_mini_response_model.rs index 8ea52926d..c96ddfd18 100644 --- a/crates/bitwarden-api-api/src/models/cipher_mini_response_model.rs +++ b/crates/bitwarden-api-api/src/models/cipher_mini_response_model.rs @@ -51,6 +51,8 @@ pub struct CipherMiniResponseModel { pub deleted_date: Option, #[serde(rename = "reprompt", skip_serializing_if = "Option::is_none")] pub reprompt: Option, + #[serde(rename = "key", skip_serializing_if = "Option::is_none")] + pub key: Option, } impl CipherMiniResponseModel { @@ -75,6 +77,7 @@ impl CipherMiniResponseModel { creation_date: None, deleted_date: None, reprompt: None, + key: None, } } } diff --git a/crates/bitwarden-api-api/src/models/cipher_request_model.rs b/crates/bitwarden-api-api/src/models/cipher_request_model.rs index 4ac3f62d7..2e445802b 100644 --- a/crates/bitwarden-api-api/src/models/cipher_request_model.rs +++ b/crates/bitwarden-api-api/src/models/cipher_request_model.rs @@ -20,6 +20,8 @@ pub struct CipherRequestModel { pub favorite: Option, #[serde(rename = "reprompt", skip_serializing_if = "Option::is_none")] pub reprompt: Option, + #[serde(rename = "key", skip_serializing_if = "Option::is_none")] + pub key: Option, #[serde(rename = "name")] pub name: String, #[serde(rename = "notes", skip_serializing_if = "Option::is_none")] @@ -56,6 +58,7 @@ impl CipherRequestModel { folder_id: None, favorite: None, reprompt: None, + key: None, name, notes: None, fields: None, diff --git a/crates/bitwarden-api-api/src/models/cipher_response_model.rs b/crates/bitwarden-api-api/src/models/cipher_response_model.rs index 62a930e1f..59831e6fb 100644 --- a/crates/bitwarden-api-api/src/models/cipher_response_model.rs +++ b/crates/bitwarden-api-api/src/models/cipher_response_model.rs @@ -51,6 +51,8 @@ pub struct CipherResponseModel { pub deleted_date: Option, #[serde(rename = "reprompt", skip_serializing_if = "Option::is_none")] pub reprompt: Option, + #[serde(rename = "key", skip_serializing_if = "Option::is_none")] + pub key: Option, #[serde(rename = "folderId", skip_serializing_if = "Option::is_none")] pub folder_id: Option, #[serde(rename = "favorite", skip_serializing_if = "Option::is_none")] @@ -83,6 +85,7 @@ impl CipherResponseModel { creation_date: None, deleted_date: None, reprompt: None, + key: None, folder_id: None, favorite: None, edit: None, diff --git a/crates/bitwarden-api-api/src/models/cipher_with_id_request_model.rs b/crates/bitwarden-api-api/src/models/cipher_with_id_request_model.rs index db4c3604f..093d2e5d9 100644 --- a/crates/bitwarden-api-api/src/models/cipher_with_id_request_model.rs +++ b/crates/bitwarden-api-api/src/models/cipher_with_id_request_model.rs @@ -20,6 +20,8 @@ pub struct CipherWithIdRequestModel { pub favorite: Option, #[serde(rename = "reprompt", skip_serializing_if = "Option::is_none")] pub reprompt: Option, + #[serde(rename = "key", skip_serializing_if = "Option::is_none")] + pub key: Option, #[serde(rename = "name")] pub name: String, #[serde(rename = "notes", skip_serializing_if = "Option::is_none")] @@ -58,6 +60,7 @@ impl CipherWithIdRequestModel { folder_id: None, favorite: None, reprompt: None, + key: None, name, notes: None, fields: None, diff --git a/crates/bitwarden-api-api/src/models/device_keys_update_request_model.rs b/crates/bitwarden-api-api/src/models/device_keys_update_request_model.rs new file mode 100644 index 000000000..65d82513c --- /dev/null +++ b/crates/bitwarden-api-api/src/models/device_keys_update_request_model.rs @@ -0,0 +1,29 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct DeviceKeysUpdateRequestModel { + #[serde(rename = "encryptedPublicKey")] + pub encrypted_public_key: String, + #[serde(rename = "encryptedUserKey")] + pub encrypted_user_key: String, +} + +impl DeviceKeysUpdateRequestModel { + pub fn new( + encrypted_public_key: String, + encrypted_user_key: String, + ) -> DeviceKeysUpdateRequestModel { + DeviceKeysUpdateRequestModel { + encrypted_public_key, + encrypted_user_key, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/device_response_model.rs b/crates/bitwarden-api-api/src/models/device_response_model.rs index 463d6f104..c6dc76d96 100644 --- a/crates/bitwarden-api-api/src/models/device_response_model.rs +++ b/crates/bitwarden-api-api/src/models/device_response_model.rs @@ -22,15 +22,8 @@ pub struct DeviceResponseModel { pub identifier: Option, #[serde(rename = "creationDate", skip_serializing_if = "Option::is_none")] pub creation_date: Option, - #[serde(rename = "encryptedUserKey", skip_serializing_if = "Option::is_none")] - pub encrypted_user_key: Option, - #[serde(rename = "encryptedPublicKey", skip_serializing_if = "Option::is_none")] - pub encrypted_public_key: Option, - #[serde( - rename = "encryptedPrivateKey", - skip_serializing_if = "Option::is_none" - )] - pub encrypted_private_key: Option, + #[serde(rename = "isTrusted", skip_serializing_if = "Option::is_none")] + pub is_trusted: Option, } impl DeviceResponseModel { @@ -42,9 +35,7 @@ impl DeviceResponseModel { r#type: None, identifier: None, creation_date: None, - encrypted_user_key: None, - encrypted_public_key: None, - encrypted_private_key: None, + is_trusted: None, } } } diff --git a/crates/bitwarden-api-api/src/models/event_type.rs b/crates/bitwarden-api-api/src/models/event_type.rs index 3988c656f..f0cea8ebc 100644 --- a/crates/bitwarden-api-api/src/models/event_type.rs +++ b/crates/bitwarden-api-api/src/models/event_type.rs @@ -24,6 +24,7 @@ pub enum EventType { Variant1007 = 1007, Variant1008 = 1008, Variant1009 = 1009, + Variant1010 = 1010, Variant1100 = 1100, Variant1101 = 1101, Variant1102 = 1102, @@ -61,6 +62,8 @@ pub enum EventType { Variant1510 = 1510, Variant1511 = 1511, Variant1512 = 1512, + Variant1513 = 1513, + Variant1514 = 1514, Variant1600 = 1600, Variant1601 = 1601, Variant1602 = 1602, @@ -99,6 +102,7 @@ impl ToString for EventType { Self::Variant1007 => String::from("1007"), Self::Variant1008 => String::from("1008"), Self::Variant1009 => String::from("1009"), + Self::Variant1010 => String::from("1010"), Self::Variant1100 => String::from("1100"), Self::Variant1101 => String::from("1101"), Self::Variant1102 => String::from("1102"), @@ -136,6 +140,8 @@ impl ToString for EventType { Self::Variant1510 => String::from("1510"), Self::Variant1511 => String::from("1511"), Self::Variant1512 => String::from("1512"), + Self::Variant1513 => String::from("1513"), + Self::Variant1514 => String::from("1514"), Self::Variant1600 => String::from("1600"), Self::Variant1601 => String::from("1601"), Self::Variant1602 => String::from("1602"), diff --git a/crates/bitwarden-api-api/src/models/global_domains.rs b/crates/bitwarden-api-api/src/models/global_domains.rs index f0582caa4..10a943482 100644 --- a/crates/bitwarden-api-api/src/models/global_domains.rs +++ b/crates/bitwarden-api-api/src/models/global_domains.rs @@ -11,7 +11,7 @@ #[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] pub struct GlobalDomains { #[serde(rename = "type", skip_serializing_if = "Option::is_none")] - pub r#type: Option, + pub r#type: Option, #[serde(rename = "domains", skip_serializing_if = "Option::is_none")] pub domains: Option>, #[serde(rename = "excluded", skip_serializing_if = "Option::is_none")] diff --git a/crates/bitwarden-api-api/src/models/mod.rs b/crates/bitwarden-api-api/src/models/mod.rs index 9d2aa9ae8..db4702827 100644 --- a/crates/bitwarden-api-api/src/models/mod.rs +++ b/crates/bitwarden-api-api/src/models/mod.rs @@ -42,6 +42,8 @@ pub mod base_secret_response_model; pub use self::base_secret_response_model::BaseSecretResponseModel; pub mod base_secret_response_model_list_response_model; pub use self::base_secret_response_model_list_response_model::BaseSecretResponseModelListResponseModel; +pub mod billing_customer_discount; +pub use self::billing_customer_discount::BillingCustomerDiscount; pub mod billing_history_response_model; pub use self::billing_history_response_model::BillingHistoryResponseModel; pub mod billing_invoice; @@ -148,6 +150,8 @@ pub mod delete_recover_request_model; pub use self::delete_recover_request_model::DeleteRecoverRequestModel; pub mod device_keys_request_model; pub use self::device_keys_request_model::DeviceKeysRequestModel; +pub mod device_keys_update_request_model; +pub use self::device_keys_update_request_model::DeviceKeysUpdateRequestModel; pub mod device_request_model; pub use self::device_request_model::DeviceRequestModel; pub mod device_response_model; @@ -304,14 +308,14 @@ pub mod organization_domain_sso_details_request_model; pub use self::organization_domain_sso_details_request_model::OrganizationDomainSsoDetailsRequestModel; pub mod organization_domain_sso_details_response_model; pub use self::organization_domain_sso_details_response_model::OrganizationDomainSsoDetailsResponseModel; -pub mod organization_enroll_secrets_manager_request_model; -pub use self::organization_enroll_secrets_manager_request_model::OrganizationEnrollSecretsManagerRequestModel; pub mod organization_keys_request_model; pub use self::organization_keys_request_model::OrganizationKeysRequestModel; pub mod organization_keys_response_model; pub use self::organization_keys_response_model::OrganizationKeysResponseModel; pub mod organization_license; pub use self::organization_license::OrganizationLicense; +pub mod organization_public_key_response_model; +pub use self::organization_public_key_response_model::OrganizationPublicKeyResponseModel; pub mod organization_response_model; pub use self::organization_response_model::OrganizationResponseModel; pub mod organization_seat_request_model; @@ -386,6 +390,8 @@ pub mod organization_user_user_details_response_model_list_response_model; pub use self::organization_user_user_details_response_model_list_response_model::OrganizationUserUserDetailsResponseModelListResponseModel; pub mod organization_verify_bank_request_model; pub use self::organization_verify_bank_request_model::OrganizationVerifyBankRequestModel; +pub mod other_device_keys_update_request_model; +pub use self::other_device_keys_update_request_model::OtherDeviceKeysUpdateRequestModel; pub mod password_hint_request_model; pub use self::password_hint_request_model::PasswordHintRequestModel; pub mod password_request_model; @@ -448,6 +454,8 @@ pub mod project_response_model_list_response_model; pub use self::project_response_model_list_response_model::ProjectResponseModelListResponseModel; pub mod project_update_request_model; pub use self::project_update_request_model::ProjectUpdateRequestModel; +pub mod protected_device_response_model; +pub use self::protected_device_response_model::ProtectedDeviceResponseModel; pub mod provider_organization_add_request_model; pub use self::provider_organization_add_request_model::ProviderOrganizationAddRequestModel; pub mod provider_organization_create_request_model; @@ -536,6 +544,8 @@ pub mod secret_with_projects_inner_project; pub use self::secret_with_projects_inner_project::SecretWithProjectsInnerProject; pub mod secret_with_projects_list_response_model; pub use self::secret_with_projects_list_response_model::SecretWithProjectsListResponseModel; +pub mod secrets_manager_subscribe_request_model; +pub use self::secrets_manager_subscribe_request_model::SecretsManagerSubscribeRequestModel; pub mod secrets_manager_subscription_update_request_model; pub use self::secrets_manager_subscription_update_request_model::SecretsManagerSubscriptionUpdateRequestModel; pub mod secrets_with_projects_inner_secret; @@ -578,8 +588,10 @@ pub mod service_account_project_access_policy_response_model_list_response_model pub use self::service_account_project_access_policy_response_model_list_response_model::ServiceAccountProjectAccessPolicyResponseModelListResponseModel; pub mod service_account_response_model; pub use self::service_account_response_model::ServiceAccountResponseModel; -pub mod service_account_response_model_list_response_model; -pub use self::service_account_response_model_list_response_model::ServiceAccountResponseModelListResponseModel; +pub mod service_account_secrets_details_response_model; +pub use self::service_account_secrets_details_response_model::ServiceAccountSecretsDetailsResponseModel; +pub mod service_account_secrets_details_response_model_list_response_model; +pub use self::service_account_secrets_details_response_model_list_response_model::ServiceAccountSecretsDetailsResponseModelListResponseModel; pub mod service_account_update_request_model; pub use self::service_account_update_request_model::ServiceAccountUpdateRequestModel; pub mod set_key_connector_key_request_model; @@ -644,6 +656,8 @@ pub mod two_factor_yubi_key_response_model; pub use self::two_factor_yubi_key_response_model::TwoFactorYubiKeyResponseModel; pub mod update_avatar_request_model; pub use self::update_avatar_request_model::UpdateAvatarRequestModel; +pub mod update_devices_trust_request_model; +pub use self::update_devices_trust_request_model::UpdateDevicesTrustRequestModel; pub mod update_domains_request_model; pub use self::update_domains_request_model::UpdateDomainsRequestModel; pub mod update_key_request_model; diff --git a/crates/bitwarden-api-api/src/models/organization_public_key_response_model.rs b/crates/bitwarden-api-api/src/models/organization_public_key_response_model.rs new file mode 100644 index 000000000..c5849d3e6 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/organization_public_key_response_model.rs @@ -0,0 +1,26 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct OrganizationPublicKeyResponseModel { + #[serde(rename = "object", skip_serializing_if = "Option::is_none")] + pub object: Option, + #[serde(rename = "publicKey", skip_serializing_if = "Option::is_none")] + pub public_key: Option, +} + +impl OrganizationPublicKeyResponseModel { + pub fn new() -> OrganizationPublicKeyResponseModel { + OrganizationPublicKeyResponseModel { + object: None, + public_key: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/organization_subscription_response_model.rs b/crates/bitwarden-api-api/src/models/organization_subscription_response_model.rs index c3789f17a..b08184d43 100644 --- a/crates/bitwarden-api-api/src/models/organization_subscription_response_model.rs +++ b/crates/bitwarden-api-api/src/models/organization_subscription_response_model.rs @@ -102,6 +102,8 @@ pub struct OrganizationSubscriptionResponseModel { pub storage_name: Option, #[serde(rename = "storageGb", skip_serializing_if = "Option::is_none")] pub storage_gb: Option, + #[serde(rename = "discount", skip_serializing_if = "Option::is_none")] + pub discount: Option>, #[serde(rename = "subscription", skip_serializing_if = "Option::is_none")] pub subscription: Option>, #[serde(rename = "upcomingInvoice", skip_serializing_if = "Option::is_none")] @@ -162,6 +164,7 @@ impl OrganizationSubscriptionResponseModel { max_autoscale_sm_service_accounts: None, storage_name: None, storage_gb: None, + discount: None, subscription: None, upcoming_invoice: None, expiration_without_grace_period: None, diff --git a/crates/bitwarden-api-api/src/models/organization_user_reset_password_enrollment_request_model.rs b/crates/bitwarden-api-api/src/models/organization_user_reset_password_enrollment_request_model.rs index c21020f96..7287c58a3 100644 --- a/crates/bitwarden-api-api/src/models/organization_user_reset_password_enrollment_request_model.rs +++ b/crates/bitwarden-api-api/src/models/organization_user_reset_password_enrollment_request_model.rs @@ -10,17 +10,6 @@ #[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] pub struct OrganizationUserResetPasswordEnrollmentRequestModel { - #[serde(rename = "masterPasswordHash", skip_serializing_if = "Option::is_none")] - pub master_password_hash: Option, - #[serde(rename = "otp", skip_serializing_if = "Option::is_none")] - pub otp: Option, - #[serde( - rename = "authRequestAccessCode", - skip_serializing_if = "Option::is_none" - )] - pub auth_request_access_code: Option, - #[serde(rename = "secret", skip_serializing_if = "Option::is_none")] - pub secret: Option, #[serde(rename = "resetPasswordKey", skip_serializing_if = "Option::is_none")] pub reset_password_key: Option, } @@ -28,10 +17,6 @@ pub struct OrganizationUserResetPasswordEnrollmentRequestModel { impl OrganizationUserResetPasswordEnrollmentRequestModel { pub fn new() -> OrganizationUserResetPasswordEnrollmentRequestModel { OrganizationUserResetPasswordEnrollmentRequestModel { - master_password_hash: None, - otp: None, - auth_request_access_code: None, - secret: None, reset_password_key: None, } } diff --git a/crates/bitwarden-api-api/src/models/other_device_keys_update_request_model.rs b/crates/bitwarden-api-api/src/models/other_device_keys_update_request_model.rs new file mode 100644 index 000000000..c163a4343 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/other_device_keys_update_request_model.rs @@ -0,0 +1,33 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct OtherDeviceKeysUpdateRequestModel { + #[serde(rename = "encryptedPublicKey")] + pub encrypted_public_key: String, + #[serde(rename = "encryptedUserKey")] + pub encrypted_user_key: String, + #[serde(rename = "deviceId")] + pub device_id: uuid::Uuid, +} + +impl OtherDeviceKeysUpdateRequestModel { + pub fn new( + encrypted_public_key: String, + encrypted_user_key: String, + device_id: uuid::Uuid, + ) -> OtherDeviceKeysUpdateRequestModel { + OtherDeviceKeysUpdateRequestModel { + encrypted_public_key, + encrypted_user_key, + device_id, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/protected_device_response_model.rs b/crates/bitwarden-api-api/src/models/protected_device_response_model.rs new file mode 100644 index 000000000..f34e1128d --- /dev/null +++ b/crates/bitwarden-api-api/src/models/protected_device_response_model.rs @@ -0,0 +1,44 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct ProtectedDeviceResponseModel { + #[serde(rename = "object", skip_serializing_if = "Option::is_none")] + pub object: Option, + #[serde(rename = "id", skip_serializing_if = "Option::is_none")] + pub id: Option, + #[serde(rename = "name", skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(rename = "type", skip_serializing_if = "Option::is_none")] + pub r#type: Option, + #[serde(rename = "identifier", skip_serializing_if = "Option::is_none")] + pub identifier: Option, + #[serde(rename = "creationDate", skip_serializing_if = "Option::is_none")] + pub creation_date: Option, + #[serde(rename = "encryptedUserKey", skip_serializing_if = "Option::is_none")] + pub encrypted_user_key: Option, + #[serde(rename = "encryptedPublicKey", skip_serializing_if = "Option::is_none")] + pub encrypted_public_key: Option, +} + +impl ProtectedDeviceResponseModel { + pub fn new() -> ProtectedDeviceResponseModel { + ProtectedDeviceResponseModel { + object: None, + id: None, + name: None, + r#type: None, + identifier: None, + creation_date: None, + encrypted_user_key: None, + encrypted_public_key: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/secrets_manager_subscribe_request_model.rs b/crates/bitwarden-api-api/src/models/secrets_manager_subscribe_request_model.rs new file mode 100644 index 000000000..2510d8f2c --- /dev/null +++ b/crates/bitwarden-api-api/src/models/secrets_manager_subscribe_request_model.rs @@ -0,0 +1,29 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct SecretsManagerSubscribeRequestModel { + #[serde(rename = "additionalSmSeats")] + pub additional_sm_seats: i32, + #[serde(rename = "additionalServiceAccounts")] + pub additional_service_accounts: i32, +} + +impl SecretsManagerSubscribeRequestModel { + pub fn new( + additional_sm_seats: i32, + additional_service_accounts: i32, + ) -> SecretsManagerSubscribeRequestModel { + SecretsManagerSubscribeRequestModel { + additional_sm_seats, + additional_service_accounts, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/service_account_secrets_details_response_model.rs b/crates/bitwarden-api-api/src/models/service_account_secrets_details_response_model.rs new file mode 100644 index 000000000..5be4d8bb1 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/service_account_secrets_details_response_model.rs @@ -0,0 +1,41 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct ServiceAccountSecretsDetailsResponseModel { + #[serde(rename = "object", skip_serializing_if = "Option::is_none")] + pub object: Option, + #[serde(rename = "id", skip_serializing_if = "Option::is_none")] + pub id: Option, + #[serde(rename = "organizationId", skip_serializing_if = "Option::is_none")] + pub organization_id: Option, + #[serde(rename = "name", skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(rename = "creationDate", skip_serializing_if = "Option::is_none")] + pub creation_date: Option, + #[serde(rename = "revisionDate", skip_serializing_if = "Option::is_none")] + pub revision_date: Option, + #[serde(rename = "accessToSecrets", skip_serializing_if = "Option::is_none")] + pub access_to_secrets: Option, +} + +impl ServiceAccountSecretsDetailsResponseModel { + pub fn new() -> ServiceAccountSecretsDetailsResponseModel { + ServiceAccountSecretsDetailsResponseModel { + object: None, + id: None, + organization_id: None, + name: None, + creation_date: None, + revision_date: None, + access_to_secrets: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/service_account_secrets_details_response_model_list_response_model.rs b/crates/bitwarden-api-api/src/models/service_account_secrets_details_response_model_list_response_model.rs new file mode 100644 index 000000000..5edfbefba --- /dev/null +++ b/crates/bitwarden-api-api/src/models/service_account_secrets_details_response_model_list_response_model.rs @@ -0,0 +1,29 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct ServiceAccountSecretsDetailsResponseModelListResponseModel { + #[serde(rename = "object", skip_serializing_if = "Option::is_none")] + pub object: Option, + #[serde(rename = "data", skip_serializing_if = "Option::is_none")] + pub data: Option>, + #[serde(rename = "continuationToken", skip_serializing_if = "Option::is_none")] + pub continuation_token: Option, +} + +impl ServiceAccountSecretsDetailsResponseModelListResponseModel { + pub fn new() -> ServiceAccountSecretsDetailsResponseModelListResponseModel { + ServiceAccountSecretsDetailsResponseModelListResponseModel { + object: None, + data: None, + continuation_token: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/subscription_response_model.rs b/crates/bitwarden-api-api/src/models/subscription_response_model.rs index 2ebba2a44..c21cbdbea 100644 --- a/crates/bitwarden-api-api/src/models/subscription_response_model.rs +++ b/crates/bitwarden-api-api/src/models/subscription_response_model.rs @@ -22,6 +22,8 @@ pub struct SubscriptionResponseModel { pub upcoming_invoice: Option>, #[serde(rename = "subscription", skip_serializing_if = "Option::is_none")] pub subscription: Option>, + #[serde(rename = "discount", skip_serializing_if = "Option::is_none")] + pub discount: Option>, #[serde(rename = "license", skip_serializing_if = "Option::is_none")] pub license: Option>, #[serde(rename = "expiration", skip_serializing_if = "Option::is_none")] @@ -39,6 +41,7 @@ impl SubscriptionResponseModel { max_storage_gb: None, upcoming_invoice: None, subscription: None, + discount: None, license: None, expiration: None, using_in_app_purchase: None, diff --git a/crates/bitwarden-api-api/src/models/update_devices_trust_request_model.rs b/crates/bitwarden-api-api/src/models/update_devices_trust_request_model.rs new file mode 100644 index 000000000..e4d381d51 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/update_devices_trust_request_model.rs @@ -0,0 +1,43 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct UpdateDevicesTrustRequestModel { + #[serde(rename = "masterPasswordHash", skip_serializing_if = "Option::is_none")] + pub master_password_hash: Option, + #[serde(rename = "otp", skip_serializing_if = "Option::is_none")] + pub otp: Option, + #[serde( + rename = "authRequestAccessCode", + skip_serializing_if = "Option::is_none" + )] + pub auth_request_access_code: Option, + #[serde(rename = "secret", skip_serializing_if = "Option::is_none")] + pub secret: Option, + #[serde(rename = "currentDevice")] + pub current_device: Box, + #[serde(rename = "otherDevices", skip_serializing_if = "Option::is_none")] + pub other_devices: Option>, +} + +impl UpdateDevicesTrustRequestModel { + pub fn new( + current_device: crate::models::DeviceKeysUpdateRequestModel, + ) -> UpdateDevicesTrustRequestModel { + UpdateDevicesTrustRequestModel { + master_password_hash: None, + otp: None, + auth_request_access_code: None, + secret: None, + current_device: Box::new(current_device), + other_devices: None, + } + } +} diff --git a/crates/bitwarden-uniffi/Cargo.toml b/crates/bitwarden-uniffi/Cargo.toml index 2f56e0441..c1a47ea29 100644 --- a/crates/bitwarden-uniffi/Cargo.toml +++ b/crates/bitwarden-uniffi/Cargo.toml @@ -19,9 +19,12 @@ chrono = { version = ">=0.4.26, <0.5", features = [ ], default-features = false } env_logger = "0.10.1" schemars = { version = ">=0.8, <0.9", optional = true } -uniffi = "=0.25.1" +uniffi = "=0.25.2" bitwarden = { path = "../bitwarden", features = ["mobile", "internal"] } [build-dependencies] -uniffi = { version = "=0.25.1", features = ["build"] } +uniffi = { version = "=0.25.2", features = ["build"] } + +[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies] +openssl = { version = "0.10", features = ["vendored"] } diff --git a/crates/bitwarden-uniffi/src/docs.rs b/crates/bitwarden-uniffi/src/docs.rs index 45fabb0b7..d66c78002 100644 --- a/crates/bitwarden-uniffi/src/docs.rs +++ b/crates/bitwarden-uniffi/src/docs.rs @@ -2,6 +2,7 @@ use bitwarden::{ auth::password::MasterPasswordPolicyOptions, client::kdf::Kdf, mobile::crypto::{InitOrgCryptoRequest, InitUserCryptoRequest}, + platform::FingerprintRequest, tool::{ExportFormat, PassphraseGeneratorRequest, PasswordGeneratorRequest}, vault::{ Cipher, CipherView, Collection, Folder, FolderView, Send, SendListView, SendView, @@ -34,6 +35,9 @@ pub enum DocRef { // Exporters ExportFormat(ExportFormat), + // Platform + FingerprintRequest(FingerprintRequest), + // Auth MasterPasswordPolicyOptions(MasterPasswordPolicyOptions), diff --git a/crates/bitwarden-uniffi/src/lib.rs b/crates/bitwarden-uniffi/src/lib.rs index 5035f22b9..13253d9a6 100644 --- a/crates/bitwarden-uniffi/src/lib.rs +++ b/crates/bitwarden-uniffi/src/lib.rs @@ -9,6 +9,7 @@ use bitwarden::client::client_settings::ClientSettings; pub mod auth; pub mod crypto; mod error; +pub mod platform; pub mod tool; mod uniffi_support; pub mod vault; @@ -18,6 +19,7 @@ pub mod docs; use crypto::ClientCrypto; use error::Result; +use platform::ClientPlatform; use tool::ClientGenerators; use vault::ClientVault; @@ -42,6 +44,10 @@ impl Client { Arc::new(ClientVault(self)) } + pub fn platform(self: Arc) -> Arc { + Arc::new(ClientPlatform(self)) + } + /// Generator operations pub fn generators(self: Arc) -> Arc { Arc::new(ClientGenerators(self)) diff --git a/crates/bitwarden-uniffi/src/platform/mod.rs b/crates/bitwarden-uniffi/src/platform/mod.rs new file mode 100644 index 000000000..f4eaaa095 --- /dev/null +++ b/crates/bitwarden-uniffi/src/platform/mod.rs @@ -0,0 +1,16 @@ +use std::sync::Arc; + +use bitwarden::platform::FingerprintRequest; + +use crate::{error::Result, Client}; + +#[derive(uniffi::Object)] +pub struct ClientPlatform(pub(crate) Arc); + +#[uniffi::export] +impl ClientPlatform { + /// Fingerprint + pub async fn fingerprint(&self, req: FingerprintRequest) -> Result { + Ok(self.0 .0.read().await.fingerprint(&req)?.fingerprint) + } +} diff --git a/crates/bitwarden/Cargo.toml b/crates/bitwarden/Cargo.toml index 0e333b334..5051a33d7 100644 --- a/crates/bitwarden/Cargo.toml +++ b/crates/bitwarden/Cargo.toml @@ -58,7 +58,7 @@ sha1 = ">=0.10.5, <0.11" sha2 = ">=0.10.6, <0.11" subtle = ">=2.5.0, <3.0" thiserror = ">=1.0.40, <2.0" -uniffi = { version = "=0.25.1", optional = true } +uniffi = { version = "=0.25.2", optional = true } uuid = { version = ">=1.3.3, <2.0", features = ["serde"] } [dev-dependencies] diff --git a/crates/bitwarden/src/client/client.rs b/crates/bitwarden/src/client/client.rs index 960ca9bda..5133a5c01 100644 --- a/crates/bitwarden/src/client/client.rs +++ b/crates/bitwarden/src/client/client.rs @@ -262,7 +262,7 @@ impl Client { } #[cfg(feature = "internal")] - pub fn fingerprint(&mut self, input: &FingerprintRequest) -> Result { + pub fn fingerprint(&self, input: &FingerprintRequest) -> Result { generate_fingerprint(input) } } diff --git a/crates/bitwarden/src/platform/generate_fingerprint.rs b/crates/bitwarden/src/platform/generate_fingerprint.rs index 800d6e847..e9562ab34 100644 --- a/crates/bitwarden/src/platform/generate_fingerprint.rs +++ b/crates/bitwarden/src/platform/generate_fingerprint.rs @@ -7,6 +7,7 @@ use crate::{crypto::fingerprint, error::Result, util::BASE64_ENGINE}; #[derive(Serialize, Deserialize, Debug, JsonSchema)] #[serde(rename_all = "camelCase", deny_unknown_fields)] +#[cfg_attr(feature = "mobile", derive(uniffi::Record))] pub struct FingerprintRequest { /// The input material, used in the fingerprint generation process. pub fingerprint_material: String, diff --git a/crates/uniffi-bindgen/Cargo.toml b/crates/uniffi-bindgen/Cargo.toml index 825f923e3..cfbb5b554 100644 --- a/crates/uniffi-bindgen/Cargo.toml +++ b/crates/uniffi-bindgen/Cargo.toml @@ -10,4 +10,4 @@ name = "uniffi-bindgen" path = "uniffi-bindgen.rs" [dependencies] -uniffi = { version = "=0.25.1", features = ["cli"] } +uniffi = { version = "=0.25.2", features = ["cli"] } diff --git a/languages/cpp/CMakeBuild.md b/languages/cpp/CMakeBuild.md new file mode 100644 index 000000000..4c7c29814 --- /dev/null +++ b/languages/cpp/CMakeBuild.md @@ -0,0 +1,33 @@ +# CMAKE build + +## INTRODUCTION + +Cmake is used to build the c++ Bitwarden client library. Output should be placed in the build directory. The output contains two dynamic libraries: one that we are building `BitwardenClient` and another that the building library uses `bitwarden_c`. + +## PREREQUISITES + +- Cmake installed, minimum version 3.15 +- `schemas.hpp` generated into `include` directory +- installed `nlohmann-json` library +- installed `boost` library + +## BUILD commands + +One should be in the root directory of the c++ wrapper (the same level where is CMakeLists.txt placed). Paths of the three libraries should be placed inside the cmake build command: + +$ mkdir build +$ cd build +$ cmake .. -DNLOHMANN=/path/to/include/nlohmann -DBOOST=/path/to/include/boost -DTARGET=relative/path/to/libbitwarden_c +$ cmake --build . + + + +## Example + +macOS: + +$ mkdir build +$ cd build +$ cmake .. -DNLOHMANN=/opt/hombrew/include -DBOOST=/opt/homebrew/include -DTARGET=../../target/release/libbitwarden_c.dylib +$ cmake --build . + diff --git a/languages/cpp/CMakeLists.txt b/languages/cpp/CMakeLists.txt new file mode 100644 index 000000000..e513a32ed --- /dev/null +++ b/languages/cpp/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.15) +project(BitwardenClient) + +set(CMAKE_CXX_STANDARD 20) + +# Set placeholders to be passed from command line +set(NLOHMANN_JSON_INCLUDE_DIR_PLACEHOLDER ${NLOHMANN}) +set(BOOST_INCLUDE_DIR_PLACEHOLDER ${BOOST}) +set(TARGET_INCLUDE_DIR_PLACEHOLDER ${TARGET}) + +# Specify the locations of nlohmann.json and Boost libraries +find_path(NLOHMANN_JSON_INCLUDE_DIR nlohmann/json.hpp HINTS ${NLOHMANN_JSON_INCLUDE_DIR_PLACEHOLDER}) +find_path(BOOST_INCLUDE_DIR boost/optional.hpp HINTS ${BOOST_INCLUDE_DIR_PLACEHOLDER}) + +# Include directories for library +include_directories(include ${NLOHMANN_JSON_INCLUDE_DIR} ${BOOST_INCLUDE_DIR}) + +# Add library source files +file(GLOB SOURCES "src/*.cpp") + +# Add library source files along with the schemas.cpp file +add_library(BitwardenClient SHARED ${SOURCES} ${SCHEMAS_SOURCE}) + +# Set path for native library loading +set(LIB_BITWARDEN_C "${CMAKE_SOURCE_DIR}/${TARGET}") + +# Copy the library to the build directory before building +add_custom_command( + TARGET BitwardenClient PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${LIB_BITWARDEN_C} + $ +) + +# Link libraries +target_link_libraries(BitwardenClient PRIVATE ${LIB_BITWARDEN_C}) diff --git a/languages/cpp/ExampleUse.md b/languages/cpp/ExampleUse.md new file mode 100644 index 000000000..579cd0e67 --- /dev/null +++ b/languages/cpp/ExampleUse.md @@ -0,0 +1,70 @@ +# EXAMPLES + + +## PREREQUISITES + +### BITWARDEN Libraries +One should have two libraries at the same path: +- `BitwardeClient` +- `bitwarden_c` + +It should look like `libBitwardeClient.dylib` and `libbitwarden_c.dylib` for the macOS. + +For Linux: `libBitwardeClient.so` and `libbitwarden_c.so` +For Windows: `BitwardeClient.dll` and `bitwarden_c.dll` + +### INCLUDE directory + +`include` directory contains: +- `BitwardenLibrary.h` +- `BitwardenClient.h` +- `BitwardenSettings.h` +- `CommandRunner.h` +- `Projects.h` +- `Secrets.h` +- `schemas.hpp` + +### Other libraries +- `nlohmann-json` (https://github.com/nlohmann/json) +- `boost` (https://www.boost.org/) + + +### COMPILING + +One could use g++/clang++ for compiling. +Example of the folder structure (macOS): + +--root + --build + `libBitwardenClient.dylib` + `libbitwarden_c.dylib` + --include + --`BitwardenLibrary.h` + --`BitwardenClient.h` + --`BitwardenSettings.h` + --`CommandRunner.h` + --`Projects.h` + --`Secrets.h` + --`schemas.hpp` + --examples + --`Wrapper.cpp` + + +1. $ export ACCESS_TOKEN=<"access-token"> +2. $ export ORGANIZATION_ID=<"organization-id"> +3. $ export DYLD_LIBRARY_PATH=/path/to/your/library:$DYLD_LIBRARY_PATH + +The last step is neccessary to add the path for the dynamic library (macOS). +For the Linux one should use: +$ export LD_LIBRARY_PATH=/path/to/your/library:$LD_LIBRARY_PATH +For the Windows: +$ set PATH=%PATH%;C:\path\to\your\library + +4. $ cd examples +5. $ clang++ -std=c++20 -I../include -I/path/to/include/nlohmann -I/path/to/include/boost -L../build/ -o MyBitwardenApp Wrapper.cpp -lBitwardenClient -ldl + +for Windows `-ldl` should be excluded, + +The result is `MyBitwardenApp` in the `examples` directory, and one can run it from the `examples` directory: + +6. $ ./MyBitwardenApp diff --git a/languages/cpp/README.md b/languages/cpp/README.md new file mode 100644 index 000000000..23b59ac76 --- /dev/null +++ b/languages/cpp/README.md @@ -0,0 +1,97 @@ +# Bitwarden Secrets Manager SDK + +C++ bindings for interacting with the [Bitwarden Secrets Manager]. This is a beta release and might be missing some functionality. + +## Create access token + +Review the help documentation on [Access Tokens] + +## Usage code snippets + +### Client settings + +```c++ +// Optional - if not stressed, then default values are used +BitwardenSettings bitwardenSettings; +bitwardenSettings.set_api_url(""); +bitwardenSettings.set_identity_url(""); +``` + + +### Create new Bitwarden client + +```c++ +std::string accessToken = ""; +// Optional - argument in BitwardenClient +BitwardenClient bitwardenClient = BitwardenClient(bitwardenSettings); +bitwardenClient.accessTokenLogin(accessToken); +``` + +### Create new project + +```c++ +boost::uuids::uuid organizationUuid = boost::uuids::string_generator()(""); +ProjectResponse projectResponseCreate = bitwardenClient.createProject(organizationUuid, "TestProject"); +``` + +### List all projects + +```c++ +ProjectsResponse projectResponseList = bitwardenClient.listProjects(organizationUuid); +``` + +### Get project details + +```c++ +boost::uuids::uuid projectId = boost::uuids::string_generator()(projectResponseCreate.get_id()); +ProjectResponse projectResponseGet = bitwardenClient.getProject(projectId); +``` + +### Update project + +```c++ +boost::uuids::uuid projectId = boost::uuids::string_generator()(projectResponseCreate.get_id()); +ProjectResponse projectResponseUpdate = bitwardenClient.updateProject(projectId, organizationUuid, "TestProjectUpdated"); +``` + +### Delete projects + +```c++ +SecretsDeleteResponse secretsDeleteResponse = bitwardenClient.deleteSecrets({secretId}); +``` + +### Add new secret + +```c++ +std::string key = "key"; +std::string value = "value"; +std::string note = "note"; +SecretResponse secretResponseCreate = bitwardenClient.createSecret(key, value, note, organizationUuid, {projectId}); +``` + +### List secrets + +```c++ +SecretIdentifiersResponse secretIdentifiersResponse = bitwardenClient.listSecrets(organizationUuid); +``` + +### Get secret details + +``` +boost::uuids::uuid secretId = boost::uuids::string_generator()(secretResponseCreate.get_id()); +SecretResponse secretResponseGet = bitwardenClient.getSecret(secretId); +``` + +### Update secret +```c++ +SecretResponse secretResponseUpdate = bitwardenClient.updateSecret(secretId, "key2", "value2", "note2", organizationUuid, {projectId}); +``` + +# Delete secrets + +```c++ +SecretsDeleteResponse secretsDeleteResponse = bitwardenClient.deleteSecrets({secretId}); +``` + +[Access Tokens]: https://bitwarden.com/help/access-tokens/ +[Bitwarden Secrets Manager]: https://bitwarden.com/products/secrets-manager/ diff --git a/languages/cpp/examples/Wrapper.cpp b/languages/cpp/examples/Wrapper.cpp new file mode 100644 index 000000000..df4aa164c --- /dev/null +++ b/languages/cpp/examples/Wrapper.cpp @@ -0,0 +1,73 @@ +#include "BitwardenClient.h" +#include +#include + +int main() { + // Retrieve access token and organization ID from environment variables + const char* accessTokenEnv = std::getenv("ACCESS_TOKEN"); + const char* organizationIdEnv = std::getenv("ORGANIZATION_ID"); + + if (!accessTokenEnv || !organizationIdEnv) { + std::cerr << "Error: Environment variables ACCESS_TOKEN or ORGANIZATION_ID not set." << std::endl; + return 1; + } + + std::string accessToken = accessTokenEnv; + std::string organizationId = organizationIdEnv; + + + + // Optional - commented to use default values + // BitwardenSettings bitwardenSettings; + // bitwardenSettings.set_api_url(""); + // bitwardenSettings.set_identity_url(""); + + // Create a Bitwarden client instance + BitwardenClient bitwardenClient = BitwardenClient(); + // // Access token login + bitwardenClient.accessTokenLogin(accessToken); + // Organization ID + boost::uuids::uuid organizationUuid = boost::uuids::string_generator()(organizationId); + + // // Create a new project + ProjectResponse projectResponseCreate = bitwardenClient.createProject(organizationUuid, "NewTestProject"); + boost::uuids::uuid projectId = boost::uuids::string_generator()(projectResponseCreate.get_id()); + + // List projects + ProjectsResponse projectResponseList = bitwardenClient.listProjects(organizationUuid); + + // Get project details + ProjectResponse projectResponseGet = bitwardenClient.getProject(projectId); + + // Update project + ProjectResponse ProjectResponseUpdate = bitwardenClient.updateProject(projectId, organizationUuid, "NewTestProject2"); + + // Secrets + std::string key = "key"; + std::string value = "value"; + std::string note = "note"; + + // Create a new secret + SecretResponse secretResponseCreate = bitwardenClient.createSecret(key, value, note, organizationUuid, {projectId}); + boost::uuids::uuid secretId = boost::uuids::string_generator()(secretResponseCreate.get_id()); + + // List secrets + SecretIdentifiersResponse secretIdentifiersResponse = bitwardenClient.listSecrets(organizationUuid); + + // Get secret details + SecretResponse secretResponseGet = bitwardenClient.getSecret(secretId); + + // Update secret + key = "key2"; + value = "value2"; + note = "note2"; + SecretResponse responseForSecretResponseUpdate = bitwardenClient.updateSecret(secretId, key, value, note, organizationUuid, {projectId}); + + // Delete secrets + SecretsDeleteResponse secretsDeleteResponse = bitwardenClient.deleteSecrets({secretId}); + + // Delete projects + ProjectsDeleteResponse projectsDeleteResponse = bitwardenClient.deleteProjects({projectId}); + + return 0; +} diff --git a/languages/cpp/include/BitwardenClient.h b/languages/cpp/include/BitwardenClient.h new file mode 100644 index 000000000..a5cf72475 --- /dev/null +++ b/languages/cpp/include/BitwardenClient.h @@ -0,0 +1,36 @@ +#pragma once + +#include "CommandRunner.h" +#include "BitwardenSettings.h" +#include "Projects.h" +#include "Secrets.h" +#include +#include + +class BitwardenClient { +public: + BitwardenClient(const BitwardenSettings& bitwardenSettings = BitwardenSettings()); + ~BitwardenClient(); + + void accessTokenLogin(const std::string& accessToken); + ProjectResponse getProject(const boost::uuids::uuid& id); + ProjectResponse createProject(const boost::uuids::uuid& organizationId, const std::string& name); + ProjectResponse updateProject(const boost::uuids::uuid& id, const boost::uuids::uuid& organizationId, const std::string& name); + ProjectsDeleteResponse deleteProjects(const std::vector& ids); + ProjectsResponse listProjects(const boost::uuids::uuid &organizationId); + SecretResponse getSecret(const boost::uuids::uuid& id); + SecretResponse createSecret(const std::string& key, const std::string& value, const std::string& note, const boost::uuids::uuid& organizationId, const std::vector& projectIds); + SecretResponse updateSecret(const boost::uuids::uuid& id, const std::string& key, const std::string& value, const std::string& note, const boost::uuids::uuid& organizationId, const std::vector& projectIds); + SecretsDeleteResponse deleteSecrets(const std::vector& ids); + SecretIdentifiersResponse listSecrets(const boost::uuids::uuid& organizationId); + +private: + BitwardenLibrary* library; + void* client; + CommandRunner* commandRunner; + Projects projects; + Secrets secrets; + bool isClientOpen; + ClientSettings clientSettings; + +}; diff --git a/languages/cpp/include/BitwardenLibrary.h b/languages/cpp/include/BitwardenLibrary.h new file mode 100644 index 000000000..5fee78726 --- /dev/null +++ b/languages/cpp/include/BitwardenLibrary.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +class BitwardenLibrary { +public: + BitwardenLibrary(const std::string& providedLibraryPath); + ~BitwardenLibrary(); + + void* init(const char* clientSettingsJson); + void free_mem(void* client); + const char* run_command(const char* commandJson, void* client); + +private: +#ifdef _WIN32 + HMODULE libraryHandle; +#else + void* libraryHandle; +#endif +}; + diff --git a/languages/cpp/include/BitwardenSettings.h b/languages/cpp/include/BitwardenSettings.h new file mode 100644 index 000000000..4d075ed0a --- /dev/null +++ b/languages/cpp/include/BitwardenSettings.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +class BitwardenSettings { +public: + BitwardenSettings() = default; + ~BitwardenSettings() = default; + + const std::string& get_api_url() const { return api_url; } + void set_api_url(const std::string& value) { api_url = value; } + + const std::string& get_identity_url() const { return identity_url; } + void set_identity_url(const std::string& value) { identity_url = value; } + +private: + std::string api_url; + std::string identity_url; +}; diff --git a/languages/cpp/include/CommandRunner.h b/languages/cpp/include/CommandRunner.h new file mode 100644 index 000000000..9aa6cbe9c --- /dev/null +++ b/languages/cpp/include/CommandRunner.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include "BitwardenLibrary.h" +#include "schemas.hpp" +#include + +using namespace Bitwarden::Sdk; + +class CommandRunner { +public: + CommandRunner(BitwardenLibrary* library, void* client); + + template + R runCommand(const Command& command, Func deserializer); + + + +private: + BitwardenLibrary* library; + void* client; + + std::string commandToString(const Command& command); + nlohmann::json filterNullObjects(const nlohmann::json& input); +}; + +template +R CommandRunner::runCommand(const Command& command, Func deserializer) { + // Serialize the Command object to a JSON string + std::string jsonString = commandToString(command); + const char* jsonCStr = jsonString.c_str(); + const char* response = library->run_command(jsonCStr, client); + + // Deserialize the response using the provided deserializer function + T deserialized = deserializer(response); + + // Unwrap the response and throw an exception if it was not successful + if (!deserialized.get_success()) { + throw std::runtime_error(*deserialized.get_error_message()); + } + + return deserialized.get_data().get(); +} + diff --git a/languages/cpp/include/Projects.h b/languages/cpp/include/Projects.h new file mode 100644 index 000000000..9bef19b9c --- /dev/null +++ b/languages/cpp/include/Projects.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +#include "CommandRunner.h" + +class Projects { +public: + Projects(CommandRunner* commandRunner); + + ProjectResponse get(const boost::uuids::uuid& id); + ProjectResponse create(const boost::uuids::uuid& organizationId, const std::string& name); + ProjectResponse update(const boost::uuids::uuid& id, const boost::uuids::uuid& organizationId, const std::string& name); + ProjectsDeleteResponse deleteProjects(const std::vector& ids); + ProjectsResponse list(const boost::uuids::uuid& organizationId); + +private: + CommandRunner* commandRunner; +}; diff --git a/languages/cpp/include/Secrets.h b/languages/cpp/include/Secrets.h new file mode 100644 index 000000000..024ec3692 --- /dev/null +++ b/languages/cpp/include/Secrets.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include "CommandRunner.h" + +class Secrets { +public: + Secrets(CommandRunner* commandRunner); + + SecretResponse get(const boost::uuids::uuid& id); + SecretResponse create(const std::string& key, const std::string& value, const std::string& note, const boost::uuids::uuid& organizationId, const std::vector& projectIds); + SecretResponse update(const boost::uuids::uuid& id, const std::string& key, const std::string& value, const std::string& note, const boost::uuids::uuid& organizationId, const std::vector& projectIds); + SecretsDeleteResponse deleteSecrets(const std::vector& ids); + SecretIdentifiersResponse list(const boost::uuids::uuid& organizationId); + +private: + CommandRunner* commandRunner; +}; + diff --git a/languages/cpp/src/BitwardenClient.cpp b/languages/cpp/src/BitwardenClient.cpp new file mode 100644 index 000000000..fef9ea267 --- /dev/null +++ b/languages/cpp/src/BitwardenClient.cpp @@ -0,0 +1,145 @@ +#include "BitwardenClient.h" +#include +#include + +BitwardenClient::BitwardenClient(const BitwardenSettings& bitwardenSettings) + : library(nullptr), commandRunner(nullptr), isClientOpen(false), projects(nullptr), secrets(nullptr) { + + // Set default values for optional strings + boost::optional apiUrl = bitwardenSettings.get_api_url().empty() + ? boost::optional("https://api.bitwarden.com") + : boost::optional(bitwardenSettings.get_api_url()); + + boost::optional identityUrl = bitwardenSettings.get_identity_url().empty() + ? boost::optional("https://identity.bitwarden.com") + : boost::optional(bitwardenSettings.get_identity_url()); + + boost::optional user_agent = boost::optional("Bitwarden CPP-SDK"); + + // Set values in clientSettings + clientSettings.set_device_type(Bitwarden::Sdk::DeviceType::SDK); + clientSettings.set_user_agent(user_agent); + clientSettings.set_api_url(apiUrl); + clientSettings.set_identity_url(identityUrl); + + nlohmann::json jsonClientSettings; + Bitwarden::Sdk::to_json(jsonClientSettings, clientSettings); + + std::string jsonClientSettingsString = jsonClientSettings.dump(); + const char* jsonClientSettingsCStr = jsonClientSettingsString.c_str(); + + try { + library = new BitwardenLibrary("./"); + client = library->init(jsonClientSettingsCStr); + commandRunner = new CommandRunner(library, client); + projects = Projects(commandRunner); + secrets = Secrets(commandRunner); + isClientOpen = true; + } catch (const std::exception& ex) { + std::cerr << "Failed to initialize: " << ex.what() << std::endl; + throw ex; + } +} + +BitwardenClient::~BitwardenClient() { + if (library) { + delete commandRunner; + library->free_mem(client); + delete library; + isClientOpen = false; + } +} + +void BitwardenClient::accessTokenLogin(const std::string& accessToken) { + Command command; + AccessTokenLoginRequest accessTokenLoginRequest; + accessTokenLoginRequest.set_access_token(accessToken); + command.set_access_token_login(accessTokenLoginRequest); + + auto deserializer = [](const char* response) -> ResponseForApiKeyLoginResponse { + nlohmann::json jsonResponse = nlohmann::json::parse(response); + ResponseForApiKeyLoginResponse loginResponse; + Bitwarden::Sdk::from_json(jsonResponse, loginResponse); + return loginResponse; + }; + try { + commandRunner->runCommand(command, deserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in accessTokenLogin: " << ex.what() << std::endl; + throw ex; + } +} + +ProjectResponse BitwardenClient::getProject(const boost::uuids::uuid& id){ + if (!isClientOpen) { + throw std::runtime_error("Client is not open."); + } + return projects.get(id); +} + +ProjectResponse BitwardenClient::createProject(const boost::uuids::uuid& organizationId, const std::string& name){ + if (!isClientOpen) { + throw std::runtime_error("Client is not open."); + } + return projects.create(organizationId, name); +} + +ProjectResponse BitwardenClient::updateProject(const boost::uuids::uuid& id, const boost::uuids::uuid& organizationId, const std::string& name){ + if (!isClientOpen) { + throw std::runtime_error("Client is not open."); + } + return projects.update(id, organizationId, name); +} + +ProjectsDeleteResponse BitwardenClient::deleteProjects(const std::vector& ids) { + if (!isClientOpen) { + throw std::runtime_error("Client is not open."); + } + return projects.deleteProjects(ids); + +} + +ProjectsResponse BitwardenClient::listProjects(const boost::uuids::uuid &organizationId) { + if (!isClientOpen) { + throw std::runtime_error("Client is not open."); + } + return projects.list(organizationId); + +} + +SecretResponse BitwardenClient::getSecret(const boost::uuids::uuid& id){ + if (!isClientOpen) { + throw std::runtime_error("Client is not open."); + } + return secrets.get(id); +} + +SecretResponse BitwardenClient::createSecret(const std::string& key, const std::string& value, const std::string& note, const boost::uuids::uuid& organizationId, const std::vector& projectIds){ + if (!isClientOpen) { + throw std::runtime_error("Client is not open."); + } + return secrets.create(key, value, note, organizationId, projectIds); +} + +SecretResponse BitwardenClient::updateSecret(const boost::uuids::uuid& id, const std::string& key, const std::string& value, const std::string& note, const boost::uuids::uuid& organizationId, const std::vector& projectIds){ + if (!isClientOpen) { + throw std::runtime_error("Client is not open."); + } + return secrets.update(id, key, value, note, organizationId, projectIds); +} + +SecretsDeleteResponse BitwardenClient::deleteSecrets(const std::vector& ids) { + if (!isClientOpen) { + throw std::runtime_error("Client is not open."); + } + return secrets.deleteSecrets(ids); + +} + +SecretIdentifiersResponse BitwardenClient::listSecrets(const boost::uuids::uuid &organizationId) { + if (!isClientOpen) { + throw std::runtime_error("Client is not open."); + } + return secrets.list(organizationId); + +} diff --git a/languages/cpp/src/BitwardenLibrary.cpp b/languages/cpp/src/BitwardenLibrary.cpp new file mode 100644 index 000000000..0af592786 --- /dev/null +++ b/languages/cpp/src/BitwardenLibrary.cpp @@ -0,0 +1,107 @@ +#include "BitwardenLibrary.h" +#include + +BitwardenLibrary::BitwardenLibrary(const std::string& providedLibraryPath) : libraryHandle(nullptr) { + std::string libraryExtension; + std::string libraryNameUnix = "libbitwarden_c"; + std::string libraryNameWin = "bitwarden_c"; +#if defined(_WIN32) + libraryExtension = ".dll"; +#elif defined(__linux__) + libraryExtension = ".so"; +#elif defined(__APPLE__) + libraryExtension = ".dylib"; +#else + // Unsupported platform + std::cerr << "Unsupported platform." << std::endl; + return; +#endif + + // Load the dynamic library +#ifdef _WIN32 + std::string libraryPath = providedLibraryPath + libraryNameWin + libraryExtension; + // Load the dynamic library on Windows + libraryHandle = LoadLibraryA(libraryPath.c_str()); + + if (!libraryHandle) { + std::cerr << "Failed to load the Bitwarden library." << std::endl; + } +#else + std::string libraryPath = providedLibraryPath + libraryNameUnix + libraryExtension; + // Load the dynamic library on Unix-based systems (Linux, macOS) + libraryHandle = dlopen(libraryPath.c_str(), RTLD_NOW); + + if (!libraryHandle) { + std::cerr << "Failed to load the Bitwarden library: " << dlerror() << std::endl; + } +#endif +} + +BitwardenLibrary::~BitwardenLibrary() { + if (libraryHandle) { +#ifdef _WIN32 + FreeLibrary(libraryHandle); +#else + dlclose(libraryHandle); +#endif + } +} + +void* BitwardenLibrary::init(const char* clientSettingsJson) { + typedef void* (*InitFunction)(const char*); + InitFunction initFunction = nullptr; + +#ifdef _WIN32 + // Get the address of the init function on Windows + initFunction = reinterpret_cast(GetProcAddress(libraryHandle, "init")); +#else + // Get the address of the init function on Unix-based systems + initFunction = reinterpret_cast(dlsym(libraryHandle, "init")); +#endif + + if (initFunction) { + return initFunction(clientSettingsJson); + } + + std::cerr << "Failed to load init function from the Bitwarden library: " << std::endl; + return nullptr; +} + +void BitwardenLibrary::free_mem(void* client) { + typedef void (*FreeMemFunction)(void*); + FreeMemFunction freeMemFunction = nullptr; + +#ifdef _WIN32 + // Get the address of the free_mem function on Windows + freeMemFunction = reinterpret_cast(GetProcAddress(libraryHandle, "free_mem")); +#else + // Get the address of the free_mem function on Unix-based systems + freeMemFunction = reinterpret_cast(dlsym(libraryHandle, "free_mem")); +#endif + + if (freeMemFunction) { + freeMemFunction(client); + } else { + std::cerr << "Failed to load free_mem function from the Bitwarden library." << std::endl; + } +} + +const char* BitwardenLibrary::run_command(const char* commandJson, void* client) { + typedef const char* (*RunCommandFunction)(const char*, void*); + RunCommandFunction runCommandFunction = nullptr; + +#ifdef _WIN32 + // Get the address of the run_command function on Windows + runCommandFunction = reinterpret_cast(GetProcAddress(libraryHandle, "run_command")); +#else + // Get the address of the run_command function on Unix-based systems + runCommandFunction = reinterpret_cast(dlsym(libraryHandle, "run_command")); +#endif + + if (runCommandFunction) { + return runCommandFunction(commandJson, client); + } + + std::cerr << "Failed to load run_command function from the Bitwarden library." << std::endl; + return nullptr; +} diff --git a/languages/cpp/src/CommandRunner.cpp b/languages/cpp/src/CommandRunner.cpp new file mode 100644 index 000000000..032347f34 --- /dev/null +++ b/languages/cpp/src/CommandRunner.cpp @@ -0,0 +1,49 @@ +#include "CommandRunner.h" +#include +#include +#include + + +CommandRunner::CommandRunner(BitwardenLibrary* library, void* client) : library(library), client(client) {} + +// Function to recursively filter out objects with all null values +nlohmann::json CommandRunner::filterNullObjects(const nlohmann::json& input) { + nlohmann::json result; + + for (auto it = input.begin(); it != input.end(); ++it) { + if (!it.value().is_null()) { + if (it.value().is_object()) { + // Recursively filter nested objects + json nestedFiltered = filterNullObjects(it.value()); + if (!nestedFiltered.empty()) { + result[it.key()] = nestedFiltered; + } + } else { + result[it.key()] = it.value(); + } + } + } + + return result; +} + +// Implement the commandToString function +std::string CommandRunner::commandToString(const Command& command) { + try { + // Create an nlohmann::json object from the Command object + nlohmann::json jsonCommand; + nlohmann::json filteredJsonCommand; + + Bitwarden::Sdk::to_json(jsonCommand, command); + + filteredJsonCommand = filterNullObjects(jsonCommand); + + // Convert the JSON to a string + std::string jsonCommandString = filteredJsonCommand.dump(); + + return jsonCommandString; + } catch (const std::exception& ex) { + std::cerr << "Error: " << ex.what() << std::endl; + throw ex; + } +} diff --git a/languages/cpp/src/Projects.cpp b/languages/cpp/src/Projects.cpp new file mode 100644 index 000000000..d0aa6ed49 --- /dev/null +++ b/languages/cpp/src/Projects.cpp @@ -0,0 +1,132 @@ +#include "Projects.h" +#include +#include +#include +#include +#include + +Projects::Projects(CommandRunner* commandRunner) : commandRunner(commandRunner) {} + +auto projectsDeserializer = [](const char* response) -> ResponseForProjectResponse { + nlohmann::json jsonResponse = nlohmann::json::parse(response); + ResponseForProjectResponse projectResponse; + Bitwarden::Sdk::from_json(jsonResponse, projectResponse); + return projectResponse; +}; + +auto deleteProjectsDeserializer = [](const char* response) -> ResponseForProjectsDeleteResponse { + nlohmann::json jsonResponse = nlohmann::json::parse(response); + ResponseForProjectsDeleteResponse deleteProjectsResponse; + Bitwarden::Sdk::from_json(jsonResponse, deleteProjectsResponse); + return deleteProjectsResponse; +}; + +auto projectListDeserializer = [](const char* response) -> ResponseForProjectsResponse { + nlohmann::json jsonResponse = nlohmann::json::parse(response); + ResponseForProjectsResponse listResponse; + Bitwarden::Sdk::from_json(jsonResponse, listResponse); + return listResponse; +}; + +ProjectResponse Projects::get(const boost::uuids::uuid& id) { + Command command; + ProjectsCommand projectsCommand; + ProjectGetRequest projectGetRequest; + + std::string idStr = boost::uuids::to_string(id); + projectGetRequest.set_id(idStr); + + projectsCommand.set_get(projectGetRequest); + command.set_projects(projectsCommand); + + try { + return commandRunner->runCommand(command, projectsDeserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in getProject: " << ex.what() << std::endl; + throw ex; + } +} + +ProjectResponse Projects::create(const boost::uuids::uuid& organizationId, const std::string& name) { + Command command; + ProjectsCommand projectsCommand; + ProjectCreateRequest projectCreateRequest; + + std::string orgIdStr = boost::uuids::to_string(organizationId); + projectCreateRequest.set_organization_id(orgIdStr); + + projectCreateRequest.set_name(name); + projectsCommand.set_create(projectCreateRequest); + command.set_projects(projectsCommand); + + try { + return commandRunner->runCommand(command, projectsDeserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in createProject: " << ex.what() << std::endl; + throw ex; + } +} + +ProjectResponse Projects::update(const boost::uuids::uuid& id, const boost::uuids::uuid& organizationId, const std::string& name) { + Command command; + ProjectsCommand projectsCommand; + ProjectPutRequest projectPutRequest; + + std::string idStr = boost::uuids::to_string(id); + projectPutRequest.set_id(idStr); + + std::string orgIdStr = boost::uuids::to_string(organizationId); + projectPutRequest.set_organization_id(orgIdStr); + + projectPutRequest.set_name(name); + projectsCommand.set_update(projectPutRequest); + command.set_projects(projectsCommand); + + try { + return commandRunner->runCommand(command, projectsDeserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in updateProject: " << ex.what() << std::endl; + throw ex; + } +} + +ProjectsDeleteResponse Projects::deleteProjects(const std::vector& ids) { + Command command; + ProjectsCommand projectsCommand; + ProjectsDeleteRequest projectsDeleteRequest; + + std::vector idStrs; + for (const auto& id : ids) { + idStrs.push_back(boost::uuids::to_string(id)); + } + projectsDeleteRequest.set_ids(idStrs); + + projectsCommand.set_projects_command_delete(projectsDeleteRequest); + command.set_projects(projectsCommand); + + try { + return commandRunner->runCommand(command, deleteProjectsDeserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in deleteProjects: " << ex.what() << std::endl; + throw ex; + } +} + +ProjectsResponse Projects::list(const boost::uuids::uuid& organizationId) { + Command command; + ProjectsCommand projectsCommand; + ProjectsListRequest projectsListRequest; + + std::string orgIdStr = boost::uuids::to_string(organizationId); + projectsListRequest.set_organization_id(orgIdStr); + + projectsCommand.set_list(projectsListRequest); + command.set_projects(projectsCommand); + + try { + return commandRunner->runCommand(command, projectListDeserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in listProjects: " << ex.what() << std::endl; + throw ex; + } +} diff --git a/languages/cpp/src/Secrets.cpp b/languages/cpp/src/Secrets.cpp new file mode 100644 index 000000000..e153ea7f1 --- /dev/null +++ b/languages/cpp/src/Secrets.cpp @@ -0,0 +1,149 @@ +#include "Secrets.h" +#include +#include +#include +#include + +Secrets::Secrets(CommandRunner* commandRunner) : commandRunner(commandRunner) {} + +auto secretsDeserializer = [](const std::string& response) -> ResponseForSecretResponse { + nlohmann::json jsonResponse = nlohmann::json::parse(response); + ResponseForSecretResponse secretResponse; + Bitwarden::Sdk::from_json(jsonResponse, secretResponse); + return secretResponse; +}; + +auto deleteSecretsDeserializer = [](const std::string& response) -> ResponseForSecretsDeleteResponse { + nlohmann::json jsonResponse = nlohmann::json::parse(response); + ResponseForSecretsDeleteResponse deleteSecretsResponse; + Bitwarden::Sdk::from_json(jsonResponse, deleteSecretsResponse); + return deleteSecretsResponse; +}; + +auto secretListDeserializer = [](const std::string& response) -> ResponseForSecretIdentifiersResponse { + nlohmann::json jsonResponse = nlohmann::json::parse(response); + ResponseForSecretIdentifiersResponse listResponse; + Bitwarden::Sdk::from_json(jsonResponse, listResponse); + return listResponse; +}; + +SecretResponse Secrets::get(const boost::uuids::uuid& id) { + Command command; + SecretsCommand secretsCommand; + SecretGetRequest secretGetRequest; + + std::string idStr = boost::uuids::to_string(id); + secretGetRequest.set_id(idStr); + + secretsCommand.set_get(secretGetRequest); + command.set_secrets(secretsCommand); + + try { + return commandRunner->runCommand(command, secretsDeserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in getSecret: " << ex.what() << std::endl; + throw ex; + } +} + +SecretResponse Secrets::create(const std::string& key, const std::string& value, const std::string& note, const boost::uuids::uuid& organizationId, const std::vector& projectIds) { + Command command; + SecretsCommand secretsCommand; + SecretCreateRequest secretCreateRequest; + + std::string orgIdStr = boost::uuids::to_string(organizationId); + secretCreateRequest.set_organization_id(orgIdStr); + + secretCreateRequest.set_key(key); + secretCreateRequest.set_value(value); + secretCreateRequest.set_note(note); + + std::vector projectIdsStr; + for (const auto& projectId : projectIds) { + projectIdsStr.push_back(boost::uuids::to_string(projectId)); + } + secretCreateRequest.set_project_ids(projectIdsStr); + + secretsCommand.set_create(secretCreateRequest); + command.set_secrets(secretsCommand); + + try { + return commandRunner->runCommand(command, secretsDeserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in createSecret: " << ex.what() << std::endl; + throw ex; + } +} + +SecretResponse Secrets::update(const boost::uuids::uuid& id, const std::string& key, const std::string& value, const std::string& note, const boost::uuids::uuid& organizationId, const std::vector& projectIds) { + Command command; + SecretsCommand secretsCommand; + SecretPutRequest secretPutRequest; + + std::string idStr = boost::uuids::to_string(id); + secretPutRequest.set_id(idStr); + + std::string orgIdStr = boost::uuids::to_string(organizationId); + secretPutRequest.set_organization_id(orgIdStr); + + secretPutRequest.set_key(key); + secretPutRequest.set_value(value); + secretPutRequest.set_note(note); + + std::vector projectIdsStr; + for (const auto& projectId : projectIds) { + projectIdsStr.push_back(boost::uuids::to_string(projectId)); + } + secretPutRequest.set_project_ids(projectIdsStr); + + secretsCommand.set_update(secretPutRequest); + command.set_secrets(secretsCommand); + + try { + return commandRunner->runCommand(command, secretsDeserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in updateSecret: " << ex.what() << std::endl; + throw ex; + } +} + +SecretsDeleteResponse Secrets::deleteSecrets(const std::vector& ids) { + Command command; + SecretsCommand secretsCommand; + SecretsDeleteRequest secretsDeleteRequest; + + std::vector idsStr; + for (const auto& id : ids) { + idsStr.push_back(boost::uuids::to_string(id)); + } + secretsDeleteRequest.set_ids(idsStr); + + secretsCommand.set_secrets_command_delete(secretsDeleteRequest); + command.set_secrets(secretsCommand); + + try { + return commandRunner->runCommand(command, deleteSecretsDeserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in deleteSecrets: " << ex.what() << std::endl; + throw ex; + } +} + +SecretIdentifiersResponse Secrets::list(const boost::uuids::uuid& organizationId) { + Command command; + SecretsCommand secretsCommand; + SecretIdentifiersRequest secretIdentifiersRequest; + + std::string orgIdStr = boost::uuids::to_string(organizationId); + secretIdentifiersRequest.set_organization_id(orgIdStr); + + secretsCommand.set_list(secretIdentifiersRequest); + command.set_secrets(secretsCommand); + + try { + return commandRunner->runCommand(command, secretListDeserializer); + } catch (const std::exception& ex) { + std::cerr << "Error in listSecret: " << ex.what() << std::endl; + throw ex; + } +} diff --git a/languages/go/README.md b/languages/go/README.md new file mode 100644 index 000000000..e57badf7e --- /dev/null +++ b/languages/go/README.md @@ -0,0 +1,113 @@ +# Bitwarden SDK in Go + +This SDK is designed to interact with Bitwarden services in Go. It includes implementations for +managing projects and secrets, as well as a client interface to facilitate operations like login. + +## Prerequisites + +- Go installed +- C environment to run CGO + +## Installation + +Download the SDK files and place them in your Go project directory. + +## Table of Contents + +- [Initialization](#initialization) +- [Login](#login) +- [Projects](#projects) +- [Secrets](#secrets) +- [Close Client](#close-client) + +--- + +### Initialization + +To initialize the client, you need to import the SDK and create a new `BitwardenClient` instance. + +```go +import "github.com/bitwarden/sdk/languages/go" + +bitwardenClient, _ := sdk.NewBitwardenClient(&apiURL, &identityURL) +``` + +--- + +### Login + +To login using an access token: + +```go +apiKeyLogin, err := bitwardenClient.AccessTokenLogin(accessToken) +``` + +--- + +### Projects + +#### Create a Project + +```go +project, err := client.Projects.Create("organization_id", "project_name") +``` + +#### List Projects + +```go +projects, err := client.Projects.List("organization_id") +``` + +#### Update a Project + +```go +project, err := client.Projects.Update("project_id", "organization_id", "new_project_name") +``` + +#### Delete Projects + +```go +project, err := client.Projects.Delete([]string{"project_id_1", "project_id_2"}) +``` + +--- + +### Secrets + +#### Create a Secret + +```go +secret, err := client.Secrets.Create("key", "value", "note", "organization_id", []string{"project_id"}) +``` + +#### List Secrets + +```go +secrets, err := client.Secrets.List("organization_id") +``` + +#### Update a Secret + +```go +secret, err := client.Secrets.Update("secret_id", "new_key", "new_value", "new_note", "organization_id", []string{"project_id"}) +``` + +#### Delete Secrets + +```go +secret, err := client.Secrets.Delete([]string{"secret_id_1", "secret_id_2"}) +``` + +--- + +### Close Client + +To free up resources: + +```go +defer bitwardenClient.Close() +``` + +--- + +For more detailed information, refer to the code comments and method signatures. diff --git a/languages/go/bitwarden_client.go b/languages/go/bitwarden_client.go new file mode 100644 index 000000000..5e1108ce1 --- /dev/null +++ b/languages/go/bitwarden_client.go @@ -0,0 +1,63 @@ +package sdk + +import ( + "encoding/json" + + "github.com/bitwarden/sdk/languages/go/internal/cinterface" +) + +type BitwardenClient struct { + client cinterface.ClientPointer + lib cinterface.BitwardenLibrary + commandRunner CommandRunnerInterface + Projects ProjectsInterface + Secrets SecretsInterface +} + +func NewBitwardenClient(apiURL *string, identityURL *string) (*BitwardenClient, error) { + deviceType := DeviceType("SDK") + userAgent := "Bitwarden GOLANG-SDK" + clientSettings := ClientSettings{ + APIURL: apiURL, + IdentityURL: identityURL, + UserAgent: &userAgent, + DeviceType: &deviceType, + } + + settingsJSON, err := json.Marshal(clientSettings) + if err != nil { + return nil, err + } + + lib := cinterface.NewBitwardenLibrary() + client, err := lib.Init(string(settingsJSON)) + if err != nil { + return nil, err + } + runner := NewCommandRunner(client, lib) + + return &BitwardenClient{ + lib: lib, + client: client, + commandRunner: runner, + Projects: NewProjects(runner), + Secrets: NewSecrets(runner), + }, nil +} + +func (c *BitwardenClient) AccessTokenLogin(accessToken string) error { + req := AccessTokenLoginRequest{AccessToken: accessToken} + command := Command{AccessTokenLogin: &req} + + responseStr, err := c.commandRunner.RunCommand(command) + if err != nil { + return err + } + + var response APIKeyLoginResponse + return checkSuccessAndError(responseStr, &response) +} + +func (c *BitwardenClient) Close() { + c.lib.FreeMem(c.client) +} diff --git a/languages/go/command_runner.go b/languages/go/command_runner.go new file mode 100644 index 000000000..3f79f7149 --- /dev/null +++ b/languages/go/command_runner.go @@ -0,0 +1,37 @@ +package sdk + +import ( + "encoding/json" + + "github.com/bitwarden/sdk/languages/go/internal/cinterface" +) + +type CommandRunnerInterface interface { + RunCommand(command Command) (string, error) +} + +type CommandRunner struct { + client cinterface.ClientPointer + lib cinterface.BitwardenLibrary +} + +func NewCommandRunner(client cinterface.ClientPointer, lib cinterface.BitwardenLibrary) *CommandRunner { + return &CommandRunner{ + client: client, + lib: lib, + } +} + +func (c *CommandRunner) RunCommand(command Command) (string, error) { + commandJSON, err := json.Marshal(command) + if err != nil { + return "", err + } + + responseStr, err := c.lib.RunCommand(string(commandJSON), c.client) + if err != nil { + return "", err + } + + return responseStr, nil +} diff --git a/languages/go/example/example.go b/languages/go/example/example.go new file mode 100644 index 000000000..5935d8002 --- /dev/null +++ b/languages/go/example/example.go @@ -0,0 +1,86 @@ +package main + +import ( + "fmt" + "os" + + sdk "github.com/bitwarden/sdk/languages/go" + "github.com/gofrs/uuid" +) + +func main() { + apiURL := os.Getenv("API_URL") + identityURL := os.Getenv("IDENTITY_URL") + + bitwardenClient, _ := sdk.NewBitwardenClient(&apiURL, &identityURL) + + accessToken := os.Getenv("ACCESS_TOKEN") + organizationIDStr := os.Getenv("ORGANIZATION_ID") + projectName := os.Getenv("PROJECT_NAME") + + if projectName == "" { + projectName = "NewTestProject" // default value + } + + err := bitwardenClient.AccessTokenLogin(accessToken) + if err != nil { + panic(err) + } + + organizationID, err := uuid.FromString(organizationIDStr) + if err != nil { + panic(err) + } + + project, err := bitwardenClient.Projects.Create(organizationID.String(), projectName) + if err != nil { + panic(err) + } + fmt.Println(project) + projectID := project.ID + fmt.Println(projectID) + + if _, err = bitwardenClient.Projects.List(organizationID.String()); err != nil { + panic(err) + } + + if _, err = bitwardenClient.Projects.Get(projectID); err != nil { + panic(err) + } + + if _, err = bitwardenClient.Projects.Update(projectID, organizationID.String(), projectName+"2"); err != nil { + panic(err) + } + + key := "key" + value := "value" + note := "note" + + secret, err := bitwardenClient.Secrets.Create(key, value, note, organizationID.String(), []string{projectID}) + if err != nil { + panic(err) + } + secretID := secret.ID + + if _, err = bitwardenClient.Secrets.List(organizationID.String()); err != nil { + panic(err) + } + + if _, err = bitwardenClient.Secrets.Get(secretID); err != nil { + panic(err) + } + + if _, err = bitwardenClient.Secrets.Update(secretID, key, value, note, organizationID.String(), []string{projectID}); err != nil { + panic(err) + } + + if _, err = bitwardenClient.Secrets.Delete([]string{secretID}); err != nil { + panic(err) + } + + if _, err = bitwardenClient.Projects.Delete([]string{projectID}); err != nil { + panic(err) + } + + defer bitwardenClient.Close() +} diff --git a/languages/go/example/go.mod b/languages/go/example/go.mod new file mode 100644 index 000000000..bbde28fd5 --- /dev/null +++ b/languages/go/example/go.mod @@ -0,0 +1,10 @@ +module example + +replace github.com/bitwarden/sdk/languages/go => ../ + +go 1.20 + +require ( + github.com/bitwarden/sdk/languages/go v0.0.0-00010101000000-000000000000 + github.com/gofrs/uuid v4.4.0+incompatible +) diff --git a/languages/go/example/go.sum b/languages/go/example/go.sum new file mode 100644 index 000000000..c0ad68738 --- /dev/null +++ b/languages/go/example/go.sum @@ -0,0 +1,2 @@ +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= diff --git a/languages/go/go.mod b/languages/go/go.mod new file mode 100644 index 000000000..a9e125453 --- /dev/null +++ b/languages/go/go.mod @@ -0,0 +1,5 @@ +module github.com/bitwarden/sdk/languages/go + +go 1.18 + +require github.com/gofrs/uuid v4.4.0+incompatible diff --git a/languages/go/go.sum b/languages/go/go.sum new file mode 100644 index 000000000..c0ad68738 --- /dev/null +++ b/languages/go/go.sum @@ -0,0 +1,2 @@ +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= diff --git a/languages/go/internal/cinterface/bitwarden_library.go b/languages/go/internal/cinterface/bitwarden_library.go new file mode 100644 index 000000000..42327adb2 --- /dev/null +++ b/languages/go/internal/cinterface/bitwarden_library.go @@ -0,0 +1,55 @@ +package cinterface + +import ( + "fmt" + "unsafe" +) + +/* +#cgo LDFLAGS: -lbitwarden_c +#cgo linux LDFLAGS: -L/usr/local/lib -L/usr/lib -L ./lib +#cgo darwin LDFLAGS: -L/usr/local/lib -L/usr/lib -L ./lib +#include +typedef void* ClientPtr; +extern char* run_command(const char *command, ClientPtr client); +extern ClientPtr init(const char *clientSettings); +extern void free_mem(ClientPtr client); +*/ +import "C" + +type ClientPointer struct { + Pointer C.ClientPtr +} + +type BitwardenLibrary interface { + Init(clientSettings string) (ClientPointer, error) + FreeMem(client ClientPointer) + RunCommand(command string, client ClientPointer) (string, error) +} + +type BitwardenLibraryImpl struct{} + +func NewBitwardenLibrary() BitwardenLibrary { + return &BitwardenLibraryImpl{} +} + +func (b *BitwardenLibraryImpl) Init(clientSettings string) (ClientPointer, error) { + ptr := C.init(C.CString(clientSettings)) + if ptr == nil { + return ClientPointer{}, fmt.Errorf("initialization failed") + } + return ClientPointer{Pointer: ptr}, nil +} + +func (b *BitwardenLibraryImpl) FreeMem(client ClientPointer) { + C.free_mem(client.Pointer) +} + +func (b *BitwardenLibraryImpl) RunCommand(command string, client ClientPointer) (string, error) { + cstr := C.run_command(C.CString(command), client.Pointer) + if cstr == nil { + return "", fmt.Errorf("run command failed") + } + defer C.free(unsafe.Pointer(cstr)) + return C.GoString(cstr), nil +} diff --git a/languages/go/project.go b/languages/go/project.go new file mode 100644 index 000000000..24a30a7ac --- /dev/null +++ b/languages/go/project.go @@ -0,0 +1,107 @@ +package sdk + +type ProjectsInterface interface { + Create(organizationID string, name string) (*ProjectResponse, error) + List(organizationID string) (*ProjectsResponse, error) + Get(projectID string) (*ProjectResponse, error) + Update(projectID string, organizationID string, name string) (*ProjectResponse, error) + Delete(projectIDs []string) (*ProjectsDeleteResponse, error) +} + +type Projects struct { + CommandRunner CommandRunnerInterface +} + +func NewProjects(commandRunner CommandRunnerInterface) *Projects { + return &Projects{CommandRunner: commandRunner} +} + +func (p *Projects) Get(id string) (*ProjectResponse, error) { + command := Command{ + Projects: &ProjectsCommand{ + Get: &ProjectGetRequest{ + ID: id, + }, + }, + } + var response ProjectResponse + if err := p.executeCommand(command, &response); err != nil { + return nil, err + } + return &response, nil +} + +func (p *Projects) Create(organizationID string, name string) (*ProjectResponse, error) { + command := Command{ + Projects: &ProjectsCommand{ + Create: &ProjectCreateRequest{ + OrganizationID: organizationID, + Name: name, + }, + }, + } + + var response ProjectResponse + if err := p.executeCommand(command, &response); err != nil { + return nil, err + } + return &response, nil +} + +func (p *Projects) List(organizationID string) (*ProjectsResponse, error) { + command := Command{ + Projects: &ProjectsCommand{ + List: &ProjectsListRequest{ + OrganizationID: organizationID, + }, + }, + } + + var response ProjectsResponse + if err := p.executeCommand(command, &response); err != nil { + return nil, err + } + return &response, nil +} + +func (p *Projects) Update(projectID, organizationID, name string) (*ProjectResponse, error) { + command := Command{ + Projects: &ProjectsCommand{ + Update: &ProjectPutRequest{ + ID: projectID, + OrganizationID: organizationID, + Name: name, + }, + }, + } + + var response ProjectResponse + if err := p.executeCommand(command, &response); err != nil { + return nil, err + } + return &response, nil +} + +func (p *Projects) Delete(projectIDs []string) (*ProjectsDeleteResponse, error) { + command := Command{ + Projects: &ProjectsCommand{ + Delete: &ProjectsDeleteRequest{ + IDS: projectIDs, + }, + }, + } + + var response ProjectsDeleteResponse + if err := p.executeCommand(command, &response); err != nil { + return nil, err + } + return &response, nil +} + +func (p *Projects) executeCommand(command Command, target interface{}) error { + responseStr, err := p.CommandRunner.RunCommand(command) + if err != nil { + return err + } + return checkSuccessAndError(responseStr, target) +} diff --git a/languages/go/secrets.go b/languages/go/secrets.go new file mode 100644 index 000000000..e6863c459 --- /dev/null +++ b/languages/go/secrets.go @@ -0,0 +1,114 @@ +package sdk + +type SecretsInterface interface { + Create(key, value, note string, organizationID string, projectIDs []string) (*SecretResponse, error) + List(organizationID string) (*SecretIdentifiersResponse, error) + Get(secretID string) (*SecretResponse, error) + Update(secretID string, key, value, note string, organizationID string, projectIDs []string) (*SecretResponse, error) + Delete(secretIDs []string) (*SecretsDeleteResponse, error) +} + +type Secrets struct { + CommandRunner CommandRunnerInterface +} + +func NewSecrets(commandRunner CommandRunnerInterface) *Secrets { + return &Secrets{CommandRunner: commandRunner} +} + +func (s *Secrets) executeCommand(command Command, target interface{}) error { + responseStr, err := s.CommandRunner.RunCommand(command) + if err != nil { + return err + } + return checkSuccessAndError(responseStr, target) +} + +func (s *Secrets) Create(key, value, note string, organizationID string, projectIDs []string) (*SecretResponse, error) { + command := Command{ + Secrets: &SecretsCommand{ + Create: &SecretCreateRequest{ + Key: key, + Value: value, + Note: note, + OrganizationID: organizationID, + ProjectIDS: projectIDs, + }, + }, + } + + var response SecretResponse + if err := s.executeCommand(command, &response); err != nil { + return nil, err + } + return &response, nil +} + +func (s *Secrets) List(organizationID string) (*SecretIdentifiersResponse, error) { + command := Command{ + Secrets: &SecretsCommand{ + List: &SecretIdentifiersRequest{ + OrganizationID: organizationID, + }, + }, + } + + var response SecretIdentifiersResponse + if err := s.executeCommand(command, &response); err != nil { + return nil, err + } + return &response, nil +} + +func (s *Secrets) Get(id string) (*SecretResponse, error) { + command := Command{ + Secrets: &SecretsCommand{ + Get: &SecretGetRequest{ + ID: id, + }, + }, + } + + var response SecretResponse + if err := s.executeCommand(command, &response); err != nil { + return nil, err + } + return &response, nil +} + +func (s *Secrets) Update(id string, key, value, note string, organizationID string, projectIDs []string) (*SecretResponse, error) { + command := Command{ + Secrets: &SecretsCommand{ + Update: &SecretPutRequest{ + ID: id, + Key: key, + Value: value, + Note: note, + OrganizationID: organizationID, + ProjectIDS: projectIDs, + }, + }, + } + + var response SecretResponse + if err := s.executeCommand(command, &response); err != nil { + return nil, err + } + return &response, nil +} + +func (s *Secrets) Delete(ids []string) (*SecretsDeleteResponse, error) { + command := Command{ + Secrets: &SecretsCommand{ + Delete: &SecretsDeleteRequest{ + IDS: ids, + }, + }, + } + + var response SecretsDeleteResponse + if err := s.executeCommand(command, &response); err != nil { + return nil, err + } + return &response, nil +} diff --git a/languages/go/util.go b/languages/go/util.go new file mode 100644 index 000000000..01ab3578d --- /dev/null +++ b/languages/go/util.go @@ -0,0 +1,33 @@ +package sdk + +import ( + "encoding/json" + "fmt" +) + +func checkSuccessAndError(responseStr string, v interface{}) error { + var wrapper struct { + Success bool `json:"success"` + ErrorMessage *string `json:"errorMessage"` + Data *json.RawMessage `json:"data"` + } + + err := json.Unmarshal([]byte(responseStr), &wrapper) + if err != nil { + return fmt.Errorf("failed to unmarshal wrapper response: %v", err) + } + + if !wrapper.Success { + if wrapper.ErrorMessage != nil { + return fmt.Errorf("API error: %s", *wrapper.ErrorMessage) + } + return fmt.Errorf("API error: unknown") + } + + err = json.Unmarshal(*wrapper.Data, &v) + if err != nil { + return fmt.Errorf("failed to unmarshal response: %v", err) + } + + return nil +} diff --git a/languages/kotlin/doc.md b/languages/kotlin/doc.md index fd65c7b71..652e09813 100644 --- a/languages/kotlin/doc.md +++ b/languages/kotlin/doc.md @@ -327,6 +327,19 @@ Decrypt password history **Output**: std::result::Result +## ClientPlatform + +### `fingerprint` + +Fingerprint + +**Arguments**: + +- self: +- req: [FingerprintRequest](#fingerprintrequest) + +**Output**: std::result::Result + ## ClientSends ### `encrypt` @@ -818,6 +831,26 @@ implementations. +## `FingerprintRequest` + + + + + + + + + + + + + + + + + +
KeyTypeDescription
fingerprintMaterialstringThe input material, used in the fingerprint generation process.
publicKeystringThe user's public key encoded with base64.
+ ## `Folder` diff --git a/support/docs/docs.ts b/support/docs/docs.ts index 14603dd57..b547b4502 100644 --- a/support/docs/docs.ts +++ b/support/docs/docs.ts @@ -28,6 +28,7 @@ const rootElements = [ "ClientFolders", "ClientGenerators", "ClientPasswordHistory", + "ClientPlatform", "ClientSends", "ClientVault", ]; diff --git a/support/scripts/schemas.ts b/support/scripts/schemas.ts index 7181d6010..2958efc18 100644 --- a/support/scripts/schemas.ts +++ b/support/scripts/schemas.ts @@ -70,6 +70,33 @@ async function main() { writeToFile("./languages/csharp/Bitwarden.Sdk/schemas.cs", csharp.lines); + const cpp = await quicktype({ + inputData, + lang: "cpp", + rendererOptions: { + namespace: "Bitwarden::Sdk", + "include-location": "global-include", + }, + }); + + cpp.lines.forEach((line, idx) => { + // Replace DOMAIN for URI_DOMAIN, because DOMAIN is an already defined macro + cpp.lines[idx] = line.replace(/DOMAIN/g, "URI_DOMAIN"); + }); + + writeToFile("./languages/cpp/include/schemas.hpp", cpp.lines); + + const go = await quicktype({ + inputData, + lang: "go", + rendererOptions: { + package: "sdk", + "just-types-and-package": true, + }, + }); + + writeToFile("./languages/go/schema.go", go.lines); + const java = await quicktypeMultiFile({ inputData, lang: "java", From 0a259f339bd1d7d325893e056f4f1955227f9158 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:56:51 +0000 Subject: [PATCH 090/108] Revert "Add feature flag for RustTLS support" This reverts commit ebd103ef89e44b8a2aa8246971831278eaaf28c5. --- Cargo.lock | 105 +---------------------- crates/bitwarden-api-api/Cargo.toml | 1 - crates/bitwarden-api-identity/Cargo.toml | 1 - crates/bitwarden-json/Cargo.toml | 8 +- crates/bitwarden-py/Cargo.toml | 2 +- crates/bitwarden-uniffi/Cargo.toml | 2 +- crates/bitwarden/Cargo.toml | 15 +--- crates/bws/Cargo.toml | 2 +- 8 files changed, 8 insertions(+), 128 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c956a925..50e263401 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -447,6 +447,7 @@ dependencies = [ "bitwarden", "chrono", "env_logger", + "openssl", "schemars", "uniffi", ] @@ -1505,20 +1506,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls", - "tokio", - "tokio-rustls", -] - [[package]] name = "hyper-tls" version = "0.5.0" @@ -1692,7 +1679,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin 0.5.2", + "spin", ] [[package]] @@ -2571,7 +2558,6 @@ dependencies = [ "http", "http-body", "hyper", - "hyper-rustls", "hyper-tls", "ipnet", "js-sys", @@ -2582,21 +2568,17 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", - "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "system-configuration", "tokio", "tokio-native-tls", - "tokio-rustls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", "winreg", ] @@ -2615,20 +2597,6 @@ dependencies = [ "bytemuck", ] -[[package]] -name = "ring" -version = "0.17.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" -dependencies = [ - "cc", - "getrandom 0.2.11", - "libc", - "spin 0.9.8", - "untrusted", - "windows-sys 0.48.0", -] - [[package]] name = "rsa" version = "0.9.3" @@ -2668,37 +2636,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "rustls" -version = "0.21.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.5", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "rustversion" version = "1.0.14" @@ -2794,16 +2731,6 @@ dependencies = [ "syn 2.0.39", ] -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "sdk-schemas" version = "0.1.0" @@ -3082,12 +3009,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "spki" version = "0.7.2" @@ -3364,16 +3285,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] - [[package]] name = "tokio-util" version = "0.7.10" @@ -3712,12 +3623,6 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" version = "2.4.1" @@ -3902,12 +3807,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - [[package]] name = "weedle2" version = "4.0.0" diff --git a/crates/bitwarden-api-api/Cargo.toml b/crates/bitwarden-api-api/Cargo.toml index ee96864dd..2e05088e0 100644 --- a/crates/bitwarden-api-api/Cargo.toml +++ b/crates/bitwarden-api-api/Cargo.toml @@ -22,6 +22,5 @@ uuid = { version = ">=1.3.3, <2", features = ["serde"] } [dependencies.reqwest] version = ">=0.11.18, <0.12" features = ["json", "multipart"] -default-features = false [dev-dependencies] diff --git a/crates/bitwarden-api-identity/Cargo.toml b/crates/bitwarden-api-identity/Cargo.toml index 5e650a034..7207c5f8e 100644 --- a/crates/bitwarden-api-identity/Cargo.toml +++ b/crates/bitwarden-api-identity/Cargo.toml @@ -22,6 +22,5 @@ uuid = { version = ">=1.3.3, <2", features = ["serde"] } [dependencies.reqwest] version = ">=0.11.18, <0.12" features = ["json", "multipart"] -default-features = false [dev-dependencies] diff --git a/crates/bitwarden-json/Cargo.toml b/crates/bitwarden-json/Cargo.toml index 22922882b..f7c0fd58d 100644 --- a/crates/bitwarden-json/Cargo.toml +++ b/crates/bitwarden-json/Cargo.toml @@ -14,19 +14,13 @@ edition = "2021" rust-version = "1.57" [features] -default = ["use_native_tls"] - internal = ["bitwarden/internal"] # Internal testing methods secrets = ["bitwarden/secrets"] # Secrets manager API -use_native_tls = ["bitwarden/use_native_tls"] -use_native_tls_vendored = ["bitwarden/use_native_tls_vendored"] -use_rustls = ["bitwarden/use_rustls"] - [dependencies] log = ">=0.4.18, <0.5" schemars = ">=0.8.12, <0.9" serde = { version = ">=1.0, <2.0", features = ["derive"] } serde_json = ">=1.0.96, <2.0" -bitwarden = { path = "../bitwarden", default-features = false } +bitwarden = { path = "../bitwarden" } diff --git a/crates/bitwarden-py/Cargo.toml b/crates/bitwarden-py/Cargo.toml index f8dee7d4c..94e9e6a43 100644 --- a/crates/bitwarden-py/Cargo.toml +++ b/crates/bitwarden-py/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib"] pyo3 = { version = "0.20.0", features = ["extension-module"] } pyo3-log = "0.9.0" -bitwarden-json = { path = "../bitwarden-json", features = ["secrets", "use_rustls"], default-features = false } +bitwarden-json = { path = "../bitwarden-json", features = ["secrets"] } [build-dependencies] pyo3-build-config = { version = "0.20.0" } diff --git a/crates/bitwarden-uniffi/Cargo.toml b/crates/bitwarden-uniffi/Cargo.toml index c1a47ea29..a44d46e79 100644 --- a/crates/bitwarden-uniffi/Cargo.toml +++ b/crates/bitwarden-uniffi/Cargo.toml @@ -24,7 +24,7 @@ uniffi = "=0.25.2" bitwarden = { path = "../bitwarden", features = ["mobile", "internal"] } [build-dependencies] -uniffi = { version = "=0.25.2", features = ["build"] } +uniffi = { version = "=0.25.1", features = ["build"] } [target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies] openssl = { version = "0.10", features = ["vendored"] } diff --git a/crates/bitwarden/Cargo.toml b/crates/bitwarden/Cargo.toml index 5051a33d7..053c36059 100644 --- a/crates/bitwarden/Cargo.toml +++ b/crates/bitwarden/Cargo.toml @@ -13,16 +13,12 @@ edition = "2021" rust-version = "1.57" [features] -default = ["secrets", "use_native_tls"] +default = ["secrets"] secrets = [] # Secrets manager API internal = [] # Internal testing methods mobile = ["uniffi", "internal"] # Mobile-specific features -use_native_tls = ["reqwest/native-tls"] -use_native_tls_vendored = ["reqwest/native-tls-vendored"] -use_rustls = ["reqwest/rustls-tls"] - [dependencies] aes = ">=0.8.2, <0.9" argon2 = { version = ">=0.5.0, <0.6", features = [ @@ -42,14 +38,7 @@ getrandom = { version = ">=0.2.9, <0.3", features = ["js"] } hkdf = ">=0.12.3, <0.13" hmac = ">=0.12.1, <0.13" lazy_static = ">=1.4.0, <2.0" -log = ">=0.4.18, <0.5" -num-bigint = ">=0.4, <0.5" -num-traits = ">=0.2.15, <0.3" -pbkdf2 = { version = ">=0.12.1, <0.13", default-features = false } -rand = ">=0.8.5, <0.9" -reqwest = { version = ">=0.11, <0.12", features = ["json"], default-features = false } -rsa = ">=0.9.2, <0.10" -schemars = { version = ">=0.8, <0.9", features = ["uuid1", "chrono"] } +reqwest = { version = ">=0.11, <0.12", features = ["json"] } serde = { version = ">=1.0, <2.0", features = ["derive"] } serde_json = ">=1.0.96, <2.0" serde_qs = ">=0.12.0, <0.13" diff --git a/crates/bws/Cargo.toml b/crates/bws/Cargo.toml index 95dbef003..bcc273f9a 100644 --- a/crates/bws/Cargo.toml +++ b/crates/bws/Cargo.toml @@ -43,7 +43,7 @@ uuid = { version = "^1.6.1", features = ["serde"] } bitwarden = { path = "../bitwarden", version = "0.3.1", features = ["secrets"] } [dev-dependencies] -tempfile = "3.8.1" +tempfile = "3.5.0" [target.'cfg(target_os = "linux")'.dependencies] openssl = { version = "0.10", features = ["vendored"] } From 3011f4b19d2aac71825fb7c20f5b006097b4fea3 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:01:57 +0000 Subject: [PATCH 091/108] Revert "rename to "bitwarden_sdk"" This reverts commit ee2ce66525d68b70ff94dc0fcf003acfc572a36c. --- .github/workflows/build-python-wheels.yml | 10 +++++----- .github/workflows/generate_schemas.yml | 2 +- .gitignore | 2 +- .../{bitwarden_sdk => BitwardenClient}/__init__.py | 0 .../bitwarden_client.py | 0 languages/python/example.py | 2 +- languages/python/pyproject.toml | 6 +++--- 7 files changed, 11 insertions(+), 11 deletions(-) rename languages/python/{bitwarden_sdk => BitwardenClient}/__init__.py (100%) rename languages/python/{bitwarden_sdk => BitwardenClient}/bitwarden_client.py (100%) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index f5e193b91..49b537967 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -89,7 +89,7 @@ jobs: uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: schemas.py - path: ${{ github.workspace }}/languages/python/bitwarden_sdk/ + path: ${{ github.workspace }}/languages/python/BitwardenClient/ # - name: Setup Windows ARM64 # if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} @@ -122,12 +122,12 @@ jobs: - name: Upload wheels uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: - name: bitwarden_sdk-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} - path: ${{ github.workspace }}/target/wheels/bitwarden_sdk*.whl + name: BitwardenClient-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} + path: ${{ github.workspace }}/target/wheels/BitwardenClient*.whl - name: Upload sdists if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} # we only need one sdist uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: - name: bitwarden_sdk-${{ env._PACKAGE_VERSION }}-sdist - path: ${{ github.workspace }}/target/wheels/bitwarden_sdk-*.tar.gz + name: BitwardenClient-${{ env._PACKAGE_VERSION }}-sdist + path: ${{ github.workspace }}/target/wheels/BitwardenClient-*.tar.gz diff --git a/.github/workflows/generate_schemas.yml b/.github/workflows/generate_schemas.yml index 6f4fd56df..b0517ea36 100644 --- a/.github/workflows/generate_schemas.yml +++ b/.github/workflows/generate_schemas.yml @@ -54,7 +54,7 @@ jobs: uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: name: schemas.py - path: ${{ github.workspace }}/languages/python/bitwarden_sdk/schemas.py + path: ${{ github.workspace }}/languages/python/BitwardenClient/schemas.py if-no-files-found: error - name: Upload ruby schemas artifact diff --git a/.gitignore b/.gitignore index dc79bfa4f..007c3e839 100644 --- a/.gitignore +++ b/.gitignore @@ -49,7 +49,7 @@ support/schemas crates/bitwarden-napi/src-ts/bitwarden_client/schemas.ts languages/csharp/Bitwarden.Sdk/schemas.cs languages/js_webassembly/bitwarden_client/schemas.ts -languages/python/bitwarden_sdk/schemas.py +languages/python/BitwardenClient/schemas.py languages/cpp/include/schemas.hpp languages/go/schema.go languages/java/src/main/java/com/bitwarden/sdk/schema diff --git a/languages/python/bitwarden_sdk/__init__.py b/languages/python/BitwardenClient/__init__.py similarity index 100% rename from languages/python/bitwarden_sdk/__init__.py rename to languages/python/BitwardenClient/__init__.py diff --git a/languages/python/bitwarden_sdk/bitwarden_client.py b/languages/python/BitwardenClient/bitwarden_client.py similarity index 100% rename from languages/python/bitwarden_sdk/bitwarden_client.py rename to languages/python/BitwardenClient/bitwarden_client.py diff --git a/languages/python/example.py b/languages/python/example.py index ce7143798..4d627342f 100644 --- a/languages/python/example.py +++ b/languages/python/example.py @@ -1,7 +1,7 @@ import logging import os -from bitwarden_sdk import BitwardenClient, DeviceType, client_settings_from_dict +from BitwardenClient import BitwardenClient, DeviceType, client_settings_from_dict # Create the BitwardenClient, which is used to interact with the SDK client = BitwardenClient(client_settings_from_dict({ diff --git a/languages/python/pyproject.toml b/languages/python/pyproject.toml index 30cc6e63d..8c2c6a3fd 100644 --- a/languages/python/pyproject.toml +++ b/languages/python/pyproject.toml @@ -14,7 +14,7 @@ classifiers = [ ] dependencies = ["dateutils >= 0.6.6"] description = "A Bitwarden Client for python" -name = "bitwarden_sdk" +name = "BitwardenClient" readme = "README.md" requires-python = ">=3.0" version = "0.1.0" @@ -23,7 +23,7 @@ version = "0.1.0" bindings = "pyo3" compatibility = "manylinux2014" include = [ - { path = "bitwarden_sdk/*.py", format = ["sdist", "wheel"] } + { path = "BitwardenClient/*.py", format = ["sdist", "wheel"] } ] manifest-path = "../../crates/bitwarden-py/Cargo.toml" -python-packages = ["bitwarden_sdk"] +python-packages = ["BitwardenClient"] From 489df2976b15768d4bb6d26b8755aca066e6e3a7 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:09:55 +0000 Subject: [PATCH 092/108] satisfy version req --- crates/bitwarden-uniffi/Cargo.toml | 2 +- crates/bitwarden/Cargo.toml | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/bitwarden-uniffi/Cargo.toml b/crates/bitwarden-uniffi/Cargo.toml index 78253b962..ecde30a4b 100644 --- a/crates/bitwarden-uniffi/Cargo.toml +++ b/crates/bitwarden-uniffi/Cargo.toml @@ -24,7 +24,7 @@ uniffi = "=0.25.2" bitwarden = { path = "../bitwarden", features = ["mobile", "internal"] } [build-dependencies] -uniffi = { version = "=0.25.1", features = ["build"] } +uniffi = { version = "=0.25.2", features = ["build"] } [target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies] openssl = { version = "0.10", features = ["vendored"] } diff --git a/crates/bitwarden/Cargo.toml b/crates/bitwarden/Cargo.toml index cd300997a..a9e432c27 100644 --- a/crates/bitwarden/Cargo.toml +++ b/crates/bitwarden/Cargo.toml @@ -40,7 +40,14 @@ getrandom = { version = ">=0.2.9, <0.3", features = ["js"] } hkdf = ">=0.12.3, <0.13" hmac = ">=0.12.1, <0.13" lazy_static = ">=1.4.0, <2.0" +log = ">=0.4.18, <0.5" +num-bigint = ">=0.4, <0.5" +num-traits = ">=0.2.15, <0.3" +pbkdf2 = { version = ">=0.12.1, <0.13", default-features = false } +rand = ">=0.8.5, <0.9" reqwest = { version = ">=0.11, <0.12", features = ["json"] } +rsa = ">=0.9.2, <0.10" +schemars = { version = ">=0.8, <0.9", features = ["uuid1", "chrono"] } serde = { version = ">=1.0, <2.0", features = ["derive"] } serde_json = ">=1.0.96, <2.0" serde_qs = ">=0.12.0, <0.13" From 060f1c979940253b9aa4f6ea0001e7b76e103d64 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:10:39 +0000 Subject: [PATCH 093/108] add shebang --- languages/python/example.py | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 languages/python/example.py diff --git a/languages/python/example.py b/languages/python/example.py old mode 100644 new mode 100755 index 4d627342f..f266b0d9f --- a/languages/python/example.py +++ b/languages/python/example.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import logging import os From fe9e6840f7761dd0ed0b6b6a9bc52ebb74a05730 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:11:16 +0000 Subject: [PATCH 094/108] target 2_28 manylinux to match workflow --- languages/python/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/python/pyproject.toml b/languages/python/pyproject.toml index 8c2c6a3fd..9418a689f 100644 --- a/languages/python/pyproject.toml +++ b/languages/python/pyproject.toml @@ -21,7 +21,7 @@ version = "0.1.0" [tool.maturin] bindings = "pyo3" -compatibility = "manylinux2014" +compatibility = "2_28" include = [ { path = "BitwardenClient/*.py", format = ["sdist", "wheel"] } ] From 0b32f0692b51000c4919c03acf946e4e4fb56aa1 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:27:35 +0000 Subject: [PATCH 095/108] update tempfile --- crates/bws/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bws/Cargo.toml b/crates/bws/Cargo.toml index 8cce8d50e..cef520b1a 100644 --- a/crates/bws/Cargo.toml +++ b/crates/bws/Cargo.toml @@ -43,7 +43,7 @@ uuid = { version = "^1.6.1", features = ["serde"] } bitwarden = { path = "../bitwarden", version = "0.3.1", features = ["secrets"] } [dev-dependencies] -tempfile = "3.5.0" +tempfile = "3.8.1" [target.'cfg(target_os = "linux")'.dependencies] openssl = { version = "0.10", features = ["vendored"] } From 85490df47b8b01e5c78030dc6cb1b311a5d2d134 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Thu, 7 Dec 2023 05:15:32 -0800 Subject: [PATCH 096/108] try workaround for python3 python3 bin does not exist on newer container images --- .github/workflows/build-python-wheels.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 49b537967..73abdcfcf 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -114,10 +114,13 @@ jobs: with: target: ${{ matrix.settings.target }} args: --release --find-interpreter --sdist - container: quay.io/pypa/manylinux_2_28_x86_64:2023-11-20-745eb52 + # container: quay.io/pypa/manylinux_2_28_x86_64:2023-11-20-745eb52 sccache: "true" manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 working-directory: ${{ github.workspace }}/languages/python + before-script-linux: | + # workaround 'No module named pip' with newer images + ln -s /usr/local/bin/python3.6 /usr/local/bin/python3 - name: Upload wheels uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From 00819d0ae118218c17d7697dbc55a486a2d3c9b6 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Thu, 7 Dec 2023 05:58:02 -0800 Subject: [PATCH 097/108] update package name --- languages/python/pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/languages/python/pyproject.toml b/languages/python/pyproject.toml index 9418a689f..28bb22507 100644 --- a/languages/python/pyproject.toml +++ b/languages/python/pyproject.toml @@ -14,7 +14,7 @@ classifiers = [ ] dependencies = ["dateutils >= 0.6.6"] description = "A Bitwarden Client for python" -name = "BitwardenClient" +name = "bitwarden_sdk" readme = "README.md" requires-python = ">=3.0" version = "0.1.0" @@ -23,7 +23,7 @@ version = "0.1.0" bindings = "pyo3" compatibility = "2_28" include = [ - { path = "BitwardenClient/*.py", format = ["sdist", "wheel"] } + { path = "bitwarden_sdk/*.py", format = ["sdist", "wheel"] } ] manifest-path = "../../crates/bitwarden-py/Cargo.toml" -python-packages = ["BitwardenClient"] +python-packages = ["bitwarden_sdk"] From 89aeffa5bbb549fd8249a32e305facec2066778b Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Thu, 7 Dec 2023 06:05:26 -0800 Subject: [PATCH 098/108] Revert "try workaround for python3" This reverts commit 85490df47b8b01e5c78030dc6cb1b311a5d2d134. --- .github/workflows/build-python-wheels.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 73abdcfcf..49b537967 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -114,13 +114,10 @@ jobs: with: target: ${{ matrix.settings.target }} args: --release --find-interpreter --sdist - # container: quay.io/pypa/manylinux_2_28_x86_64:2023-11-20-745eb52 + container: quay.io/pypa/manylinux_2_28_x86_64:2023-11-20-745eb52 sccache: "true" manylinux: "2_28" # https://github.com/pola-rs/polars/pull/12211 working-directory: ${{ github.workspace }}/languages/python - before-script-linux: | - # workaround 'No module named pip' with newer images - ln -s /usr/local/bin/python3.6 /usr/local/bin/python3 - name: Upload wheels uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 From c7829d81b086fe73b2605894eaf624857b774184 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Thu, 7 Dec 2023 12:44:04 -0800 Subject: [PATCH 099/108] update package path --- .github/workflows/build-python-wheels.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 49b537967..f5e193b91 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -89,7 +89,7 @@ jobs: uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: schemas.py - path: ${{ github.workspace }}/languages/python/BitwardenClient/ + path: ${{ github.workspace }}/languages/python/bitwarden_sdk/ # - name: Setup Windows ARM64 # if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} @@ -122,12 +122,12 @@ jobs: - name: Upload wheels uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: - name: BitwardenClient-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} - path: ${{ github.workspace }}/target/wheels/BitwardenClient*.whl + name: bitwarden_sdk-${{ env._PACKAGE_VERSION }}-${{ matrix.settings.target }} + path: ${{ github.workspace }}/target/wheels/bitwarden_sdk*.whl - name: Upload sdists if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} # we only need one sdist uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: - name: BitwardenClient-${{ env._PACKAGE_VERSION }}-sdist - path: ${{ github.workspace }}/target/wheels/BitwardenClient-*.tar.gz + name: bitwarden_sdk-${{ env._PACKAGE_VERSION }}-sdist + path: ${{ github.workspace }}/target/wheels/bitwarden_sdk-*.tar.gz From bfe4d7aae268963a63ff356505e4005d0a230898 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 13 Dec 2023 09:58:17 -0800 Subject: [PATCH 100/108] update branch trigger to `main` --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index f5e193b91..21ebca2be 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -5,7 +5,7 @@ on: pull_request: push: branches: - - "master" + - "main" - "rc" - "hotfix-rc" workflow_dispatch: From 4d3bbd9b7b7dea97d8ea8ea4451e9f9b61bba7e3 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:00:50 -0800 Subject: [PATCH 101/108] troubleshoot schema path --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 21ebca2be..80b95e11c 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -89,7 +89,7 @@ jobs: uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: schemas.py - path: ${{ github.workspace }}/languages/python/bitwarden_sdk/ + path: ${{ github.workspace }}/languages/python/bitwarden_sdk/schemas.py # - name: Setup Windows ARM64 # if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} From db772a242a01171a12b61badda5c8b8e4e0fbba3 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:04:03 -0800 Subject: [PATCH 102/108] Revert "troubleshoot schema path" This reverts commit 4d3bbd9b7b7dea97d8ea8ea4451e9f9b61bba7e3. --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 80b95e11c..21ebca2be 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -89,7 +89,7 @@ jobs: uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: schemas.py - path: ${{ github.workspace }}/languages/python/bitwarden_sdk/schemas.py + path: ${{ github.workspace }}/languages/python/bitwarden_sdk/ # - name: Setup Windows ARM64 # if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} From a91037ea85bb2ebf16537c722474e78448ed11ec Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:43:15 -0800 Subject: [PATCH 103/108] troubleshoot schema path --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index 21ebca2be..fa3f770f0 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -89,7 +89,7 @@ jobs: uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: schemas.py - path: ${{ github.workspace }}/languages/python/bitwarden_sdk/ + path: ${{ github.workspace }}/languages/python/bitwarden_sdk # - name: Setup Windows ARM64 # if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} From d954658218c0bebd28f37ffaf78254cea9a58f3f Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:43:47 -0800 Subject: [PATCH 104/108] update download-artifact to 4.1.0 --- .github/workflows/build-python-wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index fa3f770f0..ffe10d864 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -86,7 +86,7 @@ jobs: key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.os }} - name: Retrieve schemas - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110 # v4.1.0 with: name: schemas.py path: ${{ github.workspace }}/languages/python/bitwarden_sdk From 03f95fcf1903cddf5b391c228302adee647644e7 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 8 Jan 2024 11:42:18 -0800 Subject: [PATCH 105/108] update var names --- languages/python/example.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/languages/python/example.py b/languages/python/example.py index 5fc43ed01..10420acf0 100755 --- a/languages/python/example.py +++ b/languages/python/example.py @@ -5,19 +5,23 @@ from bitwarden_sdk import BitwardenClient, DeviceType, client_settings_from_dict # Create the BitwardenClient, which is used to interact with the SDK -client = BitwardenClient(client_settings_from_dict({ - "apiUrl": "http://localhost:4000", - "deviceType": DeviceType.SDK, - "identityUrl": "http://localhost:33656", - "userAgent": "Python", -})) +client = BitwardenClient( + client_settings_from_dict( + { + "apiUrl": os.getenv("API_URL", "http://localhost:4000"), + "deviceType": DeviceType.SDK, + "identityUrl": os.getenv("IDENTITY_URL", "http://localhost:33656"), + "userAgent": "Python", + } + ) +) # Add some logging & set the org id logging.basicConfig(level=logging.DEBUG) -organization_id = os.getenv("BWS_ORG_ID") +organization_id = os.getenv("ORGANIZATION_ID") # Attempt to authenticate with the Secrets Manager Access Token -client.access_token_login(os.getenv("BWS_ACCESS_TOKEN")) +client.access_token_login(os.getenv("ACCESS_TOKEN")) # -- Example Project Commands -- From 23d7896c3b82bcdaecce9b6455faeab62e4e903e Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 8 Jan 2024 11:42:41 -0800 Subject: [PATCH 106/108] format --- languages/python/example.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/languages/python/example.py b/languages/python/example.py index 10420acf0..16367a0c5 100755 --- a/languages/python/example.py +++ b/languages/python/example.py @@ -27,7 +27,9 @@ project = client.projects().create("ProjectName", organization_id) project2 = client.projects().create("Project - Don't Delete Me!", organization_id) -updated_project = client.projects().update(project.data.id, "Cool New Project Name", organization_id) +updated_project = client.projects().update( + project.data.id, "Cool New Project Name", organization_id +) get_that_project = client.projects().get(project.data.id) input("Press Enter to delete the project...") @@ -38,13 +40,27 @@ # -- Example Secret Commands -- secret = client.secrets().create( - "TEST_SECRET", "This is a test secret", organization_id, "Secret1234!", [project2.data.id]) + "TEST_SECRET", + "This is a test secret", + organization_id, + "Secret1234!", + [project2.data.id], +) secret2 = client.secrets().create( - "Secret - Don't Delete Me!", "This is a test secret that will stay", organization_id, "Secret1234!", - [project2.data.id]) + "Secret - Don't Delete Me!", + "This is a test secret that will stay", + organization_id, + "Secret1234!", + [project2.data.id], +) secret_updated = client.secrets().update( - secret.data.id, "TEST_SECRET_UPDATED", "This as an updated test secret", organization_id, "Secret1234!_updated", - [project2.data.id]) + secret.data.id, + "TEST_SECRET_UPDATED", + "This as an updated test secret", + organization_id, + "Secret1234!_updated", + [project2.data.id], +) secret_retrieved = client.secrets().get(secret.data.id) input("Press Enter to delete the secret...") From aa4bbdc66852fa90e1afb9d64cc61790cd4325fb Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 8 Jan 2024 14:26:14 -0800 Subject: [PATCH 107/108] use new var names --- languages/python/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/python/README.md b/languages/python/README.md index 00babf86a..e77e7a8eb 100644 --- a/languages/python/README.md +++ b/languages/python/README.md @@ -25,7 +25,7 @@ pip install BitwardenClient # Run -Set the `BWS_ORG_ID` and `BWS_ACCESS_TOKEN` environment variables to your organization ID and access token, respectively. +Set the `ORGANIZATION_ID` and `ACCESS_TOKEN` environment variables to your organization ID and access token, respectively. ```bash python3 ./example.py From df2e6295f8af88d5fabf183842e23281b0cfd14f Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 10 Jan 2024 09:25:34 -0800 Subject: [PATCH 108/108] remove Windows ARM comments --- .github/workflows/build-python-wheels.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/build-python-wheels.yml b/.github/workflows/build-python-wheels.yml index ffe10d864..e69f3eec1 100644 --- a/.github/workflows/build-python-wheels.yml +++ b/.github/workflows/build-python-wheels.yml @@ -55,10 +55,6 @@ jobs: - os: windows-2022 target: x86_64-pc-windows-msvc - # # Win ARM builds fail: https://github.com/bitwarden/sdk/actions/runs/6960684148/job/18940738400#step:9:175 - # - os: windows-2022 - # target: aarch64-pc-windows-msvc - - os: ubuntu-22.04 target: x86_64-unknown-linux-gnu @@ -91,13 +87,6 @@ jobs: name: schemas.py path: ${{ github.workspace }}/languages/python/bitwarden_sdk - # - name: Setup Windows ARM64 - # if: ${{ matrix.settings.target == 'aarch64-pc-windows-msvc' }} - # shell: pwsh - # run: | - # # ring crate: add Visual Studio Build Tools "VS 2022 C++ ARM64 build tools" and "clang" components - # $env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" - - name: Build wheels if: ${{ matrix.settings.target != 'x86_64-unknown-linux-gnu' }} uses: PyO3/maturin-action@b9e8f88fd4448fdecf5095864cdc7e39a544aa9f # v1.40.7