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",