From 662a92dab241e754f6243727b2ab8d87174b9dd5 Mon Sep 17 00:00:00 2001 From: Boris Bujak Date: Thu, 21 Sep 2023 20:32:07 +0200 Subject: [PATCH] .NET wrapper for SDK (#193) Co-authored-by: Boris Bujak Co-authored-by: Oscar Hinton --- .github/workflows/build-dotnet.yml | 78 +++++ .../workflows/build-rust-cross-platform.yml | 48 +++ .github/workflows/generate_schemas.yml | 2 +- .github/workflows/publish-dotnet.yml | 69 ++++ .gitignore | 2 +- .vscode/launch.json | 2 +- .vscode/settings.json | 1 + .vscode/tasks.json | 2 +- languages/csharp/.editorconfig | 125 ++++++++ .../Bitwarden.Sdk.Samples.csproj | 14 + .../csharp/Bitwarden.Sdk.Samples/Program.cs | 30 ++ .../csharp/Bitwarden.Sdk/Bitwarden.Sdk.csproj | 73 +++++ .../Bitwarden.Sdk/BitwardenAuthException.cs | 13 + .../csharp/Bitwarden.Sdk/BitwardenClient.cs | 39 +++ .../Bitwarden.Sdk/BitwardenException.cs | 13 + .../csharp/Bitwarden.Sdk/BitwardenLibrary.cs | 31 ++ .../Bitwarden.Sdk/BitwardenSafeHandle.cs | 17 + .../csharp/Bitwarden.Sdk/BitwardenSettings.cs | 15 + .../csharp/Bitwarden.Sdk/CommandRunner.cs | 20 ++ .../csharp/Bitwarden.Sdk/ProjectsClient.cs | 94 ++++++ .../csharp/Bitwarden.Sdk/SecretsClient.cs | 113 +++++++ languages/csharp/Bitwarden.Sdk/bitwarden.png | Bin 0 -> 878 bytes languages/csharp/Bitwarden.sln | 22 ++ languages/csharp/BitwardenSdk.cs | 75 ----- languages/csharp/LICENSE.txt | 295 ++++++++++++++++++ languages/csharp/Program.cs | 6 - languages/csharp/README.md | 71 ++++- languages/csharp/bitwardenSdk.csproj | 42 --- languages/csharp/global.json | 6 + support/scripts/schemas.ts | 2 +- 30 files changed, 1183 insertions(+), 137 deletions(-) create mode 100644 .github/workflows/build-dotnet.yml create mode 100644 .github/workflows/build-rust-cross-platform.yml create mode 100644 .github/workflows/publish-dotnet.yml create mode 100644 languages/csharp/.editorconfig create mode 100644 languages/csharp/Bitwarden.Sdk.Samples/Bitwarden.Sdk.Samples.csproj create mode 100644 languages/csharp/Bitwarden.Sdk.Samples/Program.cs create mode 100644 languages/csharp/Bitwarden.Sdk/Bitwarden.Sdk.csproj create mode 100644 languages/csharp/Bitwarden.Sdk/BitwardenAuthException.cs create mode 100644 languages/csharp/Bitwarden.Sdk/BitwardenClient.cs create mode 100644 languages/csharp/Bitwarden.Sdk/BitwardenException.cs create mode 100644 languages/csharp/Bitwarden.Sdk/BitwardenLibrary.cs create mode 100644 languages/csharp/Bitwarden.Sdk/BitwardenSafeHandle.cs create mode 100644 languages/csharp/Bitwarden.Sdk/BitwardenSettings.cs create mode 100644 languages/csharp/Bitwarden.Sdk/CommandRunner.cs create mode 100644 languages/csharp/Bitwarden.Sdk/ProjectsClient.cs create mode 100644 languages/csharp/Bitwarden.Sdk/SecretsClient.cs create mode 100644 languages/csharp/Bitwarden.Sdk/bitwarden.png create mode 100644 languages/csharp/Bitwarden.sln delete mode 100644 languages/csharp/BitwardenSdk.cs create mode 100644 languages/csharp/LICENSE.txt delete mode 100644 languages/csharp/Program.cs delete mode 100644 languages/csharp/bitwardenSdk.csproj create mode 100644 languages/csharp/global.json diff --git a/.github/workflows/build-dotnet.yml b/.github/workflows/build-dotnet.yml new file mode 100644 index 000000000..9d0ab1dce --- /dev/null +++ b/.github/workflows/build-dotnet.yml @@ -0,0 +1,78 @@ +name: Build .NET SDK + +on: + pull_request: + branches: + - master + +jobs: + generate_schemas: + uses: ./.github/workflows/generate_schemas.yml + + build_rust: + uses: ./.github/workflows/build-rust-cross-platform.yml + + build_dotnet: + name: Build .NET + runs-on: ubuntu-22.04 + needs: + - generate_schemas + - build_rust + + steps: + - name: Checkout Repository + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + + - name: Download C# schemas artifact + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: schemas.cs + path: languages/csharp/Bitwarden.Sdk + + - name: Set up .NET Core + uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0 + with: + global-json-file: languages/csharp/global.json + + - name: Download x86_64-apple-darwin files + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: libbitwarden_c_files-x86_64-apple-darwin + path: languages/csharp/Bitwarden.Sdk/macos-x64 + + - name: Download aarch64-apple-darwin files + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: libbitwarden_c_files-aarch64-apple-darwin + path: languages/csharp/Bitwarden.Sdk/macos-arm64 + + - name: Download x86_64-unknown-linux-gnu files + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: libbitwarden_c_files-x86_64-unknown-linux-gnu + path: languages/csharp/Bitwarden.Sdk/ubuntu-x64 + + - name: Download x86_64-pc-windows-msvc files + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: libbitwarden_c_files-x86_64-pc-windows-msvc + path: languages/csharp/Bitwarden.Sdk/windows-x64 + + - name: Build .NET 6 Project + working-directory: languages/csharp/Bitwarden.Sdk + run: | + dotnet restore + dotnet build --configuration Release + + - name: Pack NuGet Package + env: + VERSION: 0.0.1 + run: dotnet pack --configuration Release -p:PackageID=Bitwarden.Sdk -p:Version=${VERSION} --output ./nuget-output /nologo /v:n + working-directory: languages/csharp/Bitwarden.Sdk + + - name: Upload NuGet package + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + with: + name: Bitwarden.Sdk.0.0.1.nupkg + path: | + ./languages/csharp/Bitwarden.Sdk/nuget-output/*.nupkg diff --git a/.github/workflows/build-rust-cross-platform.yml b/.github/workflows/build-rust-cross-platform.yml new file mode 100644 index 000000000..d287cf061 --- /dev/null +++ b/.github/workflows/build-rust-cross-platform.yml @@ -0,0 +1,48 @@ +name: Build Rust Cross Platform + +on: + workflow_call: + +jobs: + build_rust: + name: Build for ${{ matrix.settings.os }} ${{ matrix.settings.target }} + runs-on: ${{ matrix.settings.os }} + strategy: + fail-fast: false + matrix: + settings: + - os: macos-12 + target: x86_64-apple-darwin + - os: macos-12 + target: aarch64-apple-darwin + - os: windows-2022 + target: x86_64-pc-windows-msvc + - os: ubuntu-22.04 + target: x86_64-unknown-linux-gnu + + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + + - name: Install rust + uses: dtolnay/rust-toolchain@f361669954a8ecfc00a3443f35f9ac8e610ffc06 # stable + with: + toolchain: stable + + - name: Cache cargo registry + uses: Swatinem/rust-cache@e207df5d269b42b69c8bc5101da26f7d31feddb4 # v2.6.2 + + - name: Add build architecture + run: rustup target add ${{ matrix.settings.target }} + + - name: Build Rust + env: + RUSTFLAGS: "-D warnings" + run: cargo build --target ${{ matrix.settings.target }} --release + + - name: Upload Artifact + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + with: + name: libbitwarden_c_files-${{ matrix.settings.target }} + path: | + target/${{ matrix.settings.target }}/release/*bitwarden_c* diff --git a/.github/workflows/generate_schemas.yml b/.github/workflows/generate_schemas.yml index 1f75ee483..ee30a10fe 100644 --- a/.github/workflows/generate_schemas.yml +++ b/.github/workflows/generate_schemas.yml @@ -47,7 +47,7 @@ jobs: uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: name: schemas.cs - path: ${{ github.workspace }}/languages/csharp/schemas.cs + path: ${{ github.workspace }}/languages/csharp/Bitwarden.Sdk/schemas.cs if-no-files-found: error - name: Upload python schemas artifact diff --git a/.github/workflows/publish-dotnet.yml b/.github/workflows/publish-dotnet.yml new file mode 100644 index 000000000..a37266f69 --- /dev/null +++ b/.github/workflows/publish-dotnet.yml @@ -0,0 +1,69 @@ +name: Deploy NuGet Package + +on: + workflow_dispatch: + version_number: + description: "New Version" + required: true + +jobs: + generate_schemas: + uses: ./.github/workflows/generate_schemas.yml + + build_rust: + uses: ./.github/workflows/build-rust-cross-platform.yml + + deploy: + name: Deploy + runs-on: ubuntu-22.04 + needs: + - generate_schemas + - build_rust + + steps: + - name: Checkout Repository + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + + - name: Download C# schemas artifact + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: schemas.cs + path: languages/csharp/Bitwarden.Sdk + + - name: Set up .NET Core + uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0 + with: + global-json-file: languages/csharp/global.json + + - name: Download x86_64-apple-darwin files + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: libbitwarden_c_files-x86_64-apple-darwin + path: languages/csharp/Bitwarden.Sdk/macos-x64 + + - name: Download aarch64-apple-darwin files + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: libbitwarden_c_files-aarch64-apple-darwin + path: languages/csharp/Bitwarden.Sdk/macos-arm64 + + - name: Download x86_64-unknown-linux-gnu files + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: libbitwarden_c_files-x86_64-unknown-linux-gnu + path: languages/csharp/Bitwarden.Sdk/ubuntu-x64 + + - name: Download x86_64-pc-windows-msvc files + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: libbitwarden_c_files-x86_64-pc-windows-msvc + path: languages/csharp/Bitwarden.Sdk/windows-x64 + + - name: Pack NuGet Package + env: + VERSION: ${{ github.event.inputs.version_number }} + run: dotnet pack --configuration Release -p:PackageID=Bitwarden.Sdk -p:Version=${VERSION} --output ./nuget-output /nologo /v:n + working-directory: languages/csharp/Bitwarden.Sdk + + - name: Publish NuGet Package + run: dotnet nuget push ./languages/csharp/Bitwarden.Sdk/nuget-output/*.nupkg -k ${{ secrets.NUGET_API_KEY }} -s https://api.nuget.org/v3/index.json diff --git a/.gitignore b/.gitignore index 9e450f9ab..3f459493b 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,6 @@ languages/kotlin/sdk/src/main/java/com/bitwarden/core/bitwarden.kt # Schemas support/schemas crates/bitwarden-napi/src-ts/bitwarden_client/schemas.ts -languages/csharp/schemas.cs +languages/csharp/Bitwarden.Sdk/schemas.cs languages/js_webassembly/bitwarden_client/schemas.ts languages/python/BitwardenClient/schemas.py diff --git a/.vscode/launch.json b/.vscode/launch.json index cb99bc8e0..7da474a22 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "buildCsharp", - "program": "${workspaceFolder}/languages/csharp/bin/Debug/net6.0/bitwardenSdk.dll", + "program": "${workspaceFolder}/languages/csharp/Bitwarden.Sdk/bin/Debug/net6.0/BitwardenSdk.dll", "args": [], "env": { "RUST_LOG": "debug" diff --git a/.vscode/settings.json b/.vscode/settings.json index fcf022457..e75498e9c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "cSpell.words": [ "bindgen", + "Bitwarden", "Cdecl", "chrono", "cloc", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 491d770c9..55dc10eb2 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -30,7 +30,7 @@ "type": "process", "args": [ "build", - "${workspaceFolder}/languages/csharp/bitwardenSdk.csproj", + "${workspaceFolder}/languages/csharp/Bitwarden.Sdk/Bitwarden.Sdk.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], diff --git a/languages/csharp/.editorconfig b/languages/csharp/.editorconfig new file mode 100644 index 000000000..21d7ac4a3 --- /dev/null +++ b/languages/csharp/.editorconfig @@ -0,0 +1,125 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Don't use tabs for indentation. +[*] +indent_style = space +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +guidelines = 120 +# (Please don't specify an indent_size here; that has too many unintended consequences.) + +# Code files +[*.{cs,csx,vb,vbx}] +indent_size = 4 +charset = utf-8-bom + +# Xml project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +indent_size = 2 + +# Xml config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_size = 2 + +# JSON files +[*.json] +indent_size = 2 + +# Dotnet code style settings: +[*.{cs,vb}] +# Sort using and Import directives with System.* appearing first +dotnet_sort_system_directives_first = true +# Avoid "this." and "Me." if not necessary +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion + +# Use language keywords instead of framework type names for type references +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +# Suggest more modern language features when available +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion + +# Prefix private members with underscore +dotnet_naming_rule.private_members_with_underscore.symbols = private_fields +dotnet_naming_rule.private_members_with_underscore.style = prefix_underscore +dotnet_naming_rule.private_members_with_underscore.severity = suggestion + +dotnet_naming_symbols.private_fields.applicable_kinds = field +dotnet_naming_symbols.private_fields.applicable_accessibilities = private + +dotnet_naming_style.prefix_underscore.capitalization = camel_case +dotnet_naming_style.prefix_underscore.required_prefix = _ + +# Async methods should have "Async" suffix +dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods +dotnet_naming_rule.async_methods_end_in_async.style = end_in_async +dotnet_naming_rule.async_methods_end_in_async.severity = suggestion + +dotnet_naming_symbols.any_async_methods.applicable_kinds = method +dotnet_naming_symbols.any_async_methods.applicable_accessibilities = * +dotnet_naming_symbols.any_async_methods.required_modifiers = async + +dotnet_naming_style.end_in_async.required_prefix = +dotnet_naming_style.end_in_async.required_suffix = Async +dotnet_naming_style.end_in_async.capitalization = pascal_case +dotnet_naming_style.end_in_async.word_separator = + +# Obsolete warnings, this should be removed or changed to warning once we address some of the obsolete items. +dotnet_diagnostic.CS0618.severity = suggestion + +# Obsolete warnings, this should be removed or changed to warning once we address some of the obsolete items. +dotnet_diagnostic.CS0612.severity = suggestion + +# Remove unnecessary using directives https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005 +dotnet_diagnostic.IDE0005.severity = warning + +# CSharp code style settings: +[*.cs] +# Prefer "var" everywhere +csharp_style_var_for_built_in_types = true:suggestion +csharp_style_var_when_type_is_apparent = true:suggestion +csharp_style_var_elsewhere = true:suggestion + +# Prefer method-like constructs to have a expression-body +csharp_style_expression_bodied_methods = true:none +csharp_style_expression_bodied_constructors = true:none +csharp_style_expression_bodied_operators = true:none + +# Prefer property-like constructs to have an expression-body +csharp_style_expression_bodied_properties = true:none +csharp_style_expression_bodied_indexers = true:none +csharp_style_expression_bodied_accessors = true:none + +# Suggest more modern language features when available +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + +# Newline settings +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true + +# Namespace settings +csharp_style_namespace_declarations = file_scoped:warning + +# Switch expression +dotnet_diagnostic.CS8509.severity = error # missing switch case for named enum value +dotnet_diagnostic.CS8524.severity = none # missing switch case for unnamed enum value diff --git a/languages/csharp/Bitwarden.Sdk.Samples/Bitwarden.Sdk.Samples.csproj b/languages/csharp/Bitwarden.Sdk.Samples/Bitwarden.Sdk.Samples.csproj new file mode 100644 index 000000000..5b189d8ca --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk.Samples/Bitwarden.Sdk.Samples.csproj @@ -0,0 +1,14 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + diff --git a/languages/csharp/Bitwarden.Sdk.Samples/Program.cs b/languages/csharp/Bitwarden.Sdk.Samples/Program.cs new file mode 100644 index 000000000..ee6834979 --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk.Samples/Program.cs @@ -0,0 +1,30 @@ +using Bitwarden.Sdk; + +// Configure secrets +var accessToken = Environment.GetEnvironmentVariable("ACCESS_TOKEN")!; +var organizationIdString = Environment.GetEnvironmentVariable("ORGANIZATION_ID")!; +var organizationId = Guid.Parse(organizationIdString); + +// Create SDK Client +using var bitwardenClient = new BitwardenClient(); + +// Authenticate +bitwardenClient.AccessTokenLogin(accessToken); + +// Project operations +var projectResponse = bitwardenClient.Projects.Create(organizationId, "NewTestProject"); +var projectsResponse = bitwardenClient.Projects.List(organizationId); +var projectId = projectResponse.Id; +projectResponse = bitwardenClient.Projects.Get(projectId); +projectResponse = bitwardenClient.Projects.Update(projectId, organizationId, "NewTestProject2"); + +// Secret operations +var secretResponse = + bitwardenClient.Secrets.Create("key", "value", "note", organizationId, new[] { projectId }); +var secretId = secretResponse.Id; +var secretIdentifiersResponse = bitwardenClient.Secrets.List(organizationId); +secretResponse = bitwardenClient.Secrets.Get(secretId); +secretResponse = bitwardenClient.Secrets + .Update(secretId, "key2", "value2", "note2", organizationId, new[] { projectId }); +bitwardenClient.Secrets.Delete(new[] { secretId }); +bitwardenClient.Projects.Delete(new[] { projectId }); diff --git a/languages/csharp/Bitwarden.Sdk/Bitwarden.Sdk.csproj b/languages/csharp/Bitwarden.Sdk/Bitwarden.Sdk.csproj new file mode 100644 index 000000000..97f850211 --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk/Bitwarden.Sdk.csproj @@ -0,0 +1,73 @@ + + + + net6.0 + README.md + enable + enable + Bitwarden.Sdk + Bitwarden Secrets Manager SDK + Bitwarden Inc. + .NET bindings for interacting with the Bitwarden Secrets Manager + Bitwarden Inc. + https://github.com/bitwarden/sdk/tree/master/languages/csharp + Bitwarden;Sdk;.NET + SDK + bitwarden.png + Git + Bitwarden.Sdk + https://bitwarden.com/products/secrets-manager/ + https://github.com/bitwarden/sdk/blob/master/LICENSE + + + + + + + + + + + + + + + 4 + + + + Always + true + + + Always + true + + + Always + true + + + + + Always + true + runtimes/osx-x64/native + + + Always + true + runtimes/osx-arm64/native + + + Always + true + runtimes/linux-x64/native + + + Always + true + runtimes/win-x64/native + + + diff --git a/languages/csharp/Bitwarden.Sdk/BitwardenAuthException.cs b/languages/csharp/Bitwarden.Sdk/BitwardenAuthException.cs new file mode 100644 index 000000000..8a2b480de --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk/BitwardenAuthException.cs @@ -0,0 +1,13 @@ +namespace Bitwarden.Sdk; + +public class BitwardenAuthException : Exception +{ + public BitwardenAuthException(string message) : base(message) + { + } + + public BitwardenAuthException(string message, System.Exception innerException) + : base(message, innerException) + { + } +} diff --git a/languages/csharp/Bitwarden.Sdk/BitwardenClient.cs b/languages/csharp/Bitwarden.Sdk/BitwardenClient.cs new file mode 100644 index 000000000..617a3d00b --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk/BitwardenClient.cs @@ -0,0 +1,39 @@ +namespace Bitwarden.Sdk; + +public sealed class BitwardenClient : IDisposable +{ + private readonly CommandRunner _commandRunner; + private readonly BitwardenSafeHandle _handle; + + public BitwardenClient(BitwardenSettings? settings = null) + { + var clientSettings = new ClientSettings + { + ApiUrl = settings?.ApiUrl!, IdentityUrl = settings?.IdentityUrl!, UserAgent = "Bitwarden DOTNET-SDK" + }; + + _handle = BitwardenLibrary.Init(clientSettings.ToJson()); + _commandRunner = new CommandRunner(_handle); + Projects = new ProjectsClient(_commandRunner); + Secrets = new SecretsClient(_commandRunner); + } + + public void AccessTokenLogin(string accessToken) + { + var command = new Command() { AccessTokenLogin = new AccessTokenLoginRequest { AccessToken = accessToken } }; + var response = _commandRunner.RunCommand(command); + if (response is not { Success: true }) + { + throw new BitwardenAuthException(response != null ? response.ErrorMessage : "Login failed"); + } + } + + public ProjectsClient Projects { get; } + + public SecretsClient Secrets { get; } + + public void Dispose() + { + _handle.Dispose(); + } +} diff --git a/languages/csharp/Bitwarden.Sdk/BitwardenException.cs b/languages/csharp/Bitwarden.Sdk/BitwardenException.cs new file mode 100644 index 000000000..539656bf4 --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk/BitwardenException.cs @@ -0,0 +1,13 @@ +namespace Bitwarden.Sdk; + +public class BitwardenException : Exception +{ + public BitwardenException(string message) : base(message) + { + } + + public BitwardenException(string message, System.Exception innerException) + : base(message, innerException) + { + } +} diff --git a/languages/csharp/Bitwarden.Sdk/BitwardenLibrary.cs b/languages/csharp/Bitwarden.Sdk/BitwardenLibrary.cs new file mode 100644 index 000000000..76a35ed5b --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk/BitwardenLibrary.cs @@ -0,0 +1,31 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Bitwarden.Sdk; + +internal static class BitwardenLibrary +{ + [DllImport("bitwarden_c", CallingConvention = CallingConvention.Cdecl)] + private static extern BitwardenSafeHandle init(string settings); + + [DllImport("bitwarden_c", CallingConvention = CallingConvention.Cdecl)] + private static extern void free_mem(IntPtr handle); + + [DllImport("bitwarden_c", CallingConvention = CallingConvention.Cdecl)] + private static extern string run_command(string json, BitwardenSafeHandle handle); + + internal static BitwardenSafeHandle Init(string settings) + { + return init(settings); + } + + internal static void FreeMemory(IntPtr handle) + { + free_mem(handle); + } + + internal static string RunCommand(string json, BitwardenSafeHandle handle) + { + return run_command(json, handle); + } +} diff --git a/languages/csharp/Bitwarden.Sdk/BitwardenSafeHandle.cs b/languages/csharp/Bitwarden.Sdk/BitwardenSafeHandle.cs new file mode 100644 index 000000000..7939aab67 --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk/BitwardenSafeHandle.cs @@ -0,0 +1,17 @@ +using Microsoft.Win32.SafeHandles; + +namespace Bitwarden.Sdk; + +internal class BitwardenSafeHandle : SafeHandleZeroOrMinusOneIsInvalid +{ + public BitwardenSafeHandle() : base(true) + { + SetHandle(handle); + } + + protected override bool ReleaseHandle() + { + BitwardenLibrary.FreeMemory(handle); + return true; + } +} diff --git a/languages/csharp/Bitwarden.Sdk/BitwardenSettings.cs b/languages/csharp/Bitwarden.Sdk/BitwardenSettings.cs new file mode 100644 index 000000000..a96c5932f --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk/BitwardenSettings.cs @@ -0,0 +1,15 @@ +namespace Bitwarden.Sdk; + +public class BitwardenSettings +{ + /// + /// The api url of the targeted Bitwarden instance. Defaults to `https://api.bitwarden.com` + /// + public string? ApiUrl { get; set; } + + /// + /// The identity url of the targeted Bitwarden instance. Defaults to + /// `https://identity.bitwarden.com` + /// + public string? IdentityUrl { get; set; } +} diff --git a/languages/csharp/Bitwarden.Sdk/CommandRunner.cs b/languages/csharp/Bitwarden.Sdk/CommandRunner.cs new file mode 100644 index 000000000..d797e9ece --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk/CommandRunner.cs @@ -0,0 +1,20 @@ +namespace Bitwarden.Sdk; +using System.Text.Json; + +internal class CommandRunner +{ + + private readonly BitwardenSafeHandle _handle; + + internal CommandRunner(BitwardenSafeHandle handle) + { + _handle = handle; + } + + internal T? RunCommand(Command command) + { + var req = JsonSerializer.Serialize(command, Converter.Settings); + var result = BitwardenLibrary.RunCommand(req, _handle); + return JsonSerializer.Deserialize(result, Converter.Settings); + } +} diff --git a/languages/csharp/Bitwarden.Sdk/ProjectsClient.cs b/languages/csharp/Bitwarden.Sdk/ProjectsClient.cs new file mode 100644 index 000000000..da22e2d7f --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk/ProjectsClient.cs @@ -0,0 +1,94 @@ +namespace Bitwarden.Sdk; + +public class ProjectsClient +{ + private readonly CommandRunner _commandRunner; + + internal ProjectsClient(CommandRunner commandRunner) + { + _commandRunner = commandRunner; + } + + public ProjectResponse Get(Guid id) + { + var command = new Command() { Projects = new ProjectsCommand { Get = new ProjectGetRequest { Id = id } } }; + var result = _commandRunner.RunCommand(command); + + if (result is { Success: true }) + { + return result.Data; + } + + throw new BitwardenException(result != null ? result.ErrorMessage : "Project not found"); + } + + public ProjectResponse Create(Guid organizationId, string name) + { + var command = new Command() + { + Projects = new ProjectsCommand + { + Create = new ProjectCreateRequest { OrganizationId = organizationId, Name = name } + } + }; + var result = _commandRunner.RunCommand(command); + + if (result is { Success: true }) + { + return result.Data; + } + + throw new BitwardenException(result != null ? result.ErrorMessage : "Project create failed"); + } + + public ProjectResponse Update(Guid id, Guid organizationId, string name) + { + var command = new Command() + { + Projects = new ProjectsCommand + { + Update = new ProjectPutRequest { Id = id, OrganizationId = organizationId, Name = name } + } + }; + var result = _commandRunner.RunCommand(command); + + if (result is { Success: true }) + { + return result.Data; + } + + throw new BitwardenException(result != null ? result.ErrorMessage : "Project update failed"); + } + + public ProjectsDeleteResponse Delete(Guid[] ids) + { + var command = new Command() + { + Projects = new ProjectsCommand { Delete = new ProjectsDeleteRequest { Ids = ids } } + }; + var result = _commandRunner.RunCommand(command); + + if (result is { Success: true }) + { + return result.Data; + } + + throw new BitwardenException(result != null ? result.ErrorMessage : "Project delete failed"); + } + + public ProjectsResponse List(Guid organizationId) + { + var command = new Command() + { + Projects = new ProjectsCommand { List = new ProjectsListRequest { OrganizationId = organizationId } } + }; + var result = _commandRunner.RunCommand(command); + + if (result is { Success: true }) + { + return result.Data; + } + + throw new BitwardenException(result != null ? result.ErrorMessage : "No projects for given organization"); + } +} diff --git a/languages/csharp/Bitwarden.Sdk/SecretsClient.cs b/languages/csharp/Bitwarden.Sdk/SecretsClient.cs new file mode 100644 index 000000000..cf6cd36b1 --- /dev/null +++ b/languages/csharp/Bitwarden.Sdk/SecretsClient.cs @@ -0,0 +1,113 @@ +namespace Bitwarden.Sdk; + +public class SecretsClient +{ + private readonly CommandRunner _commandRunner; + + internal SecretsClient(CommandRunner commandRunner) + { + _commandRunner = commandRunner; + } + + public SecretResponse Get(Guid id) + { + var command = new Command() { Secrets = new SecretsCommand { Get = new SecretGetRequest { Id = id } } }; + var result = _commandRunner.RunCommand(command); + + if (result is { Success: true }) + { + return result.Data; + } + + throw new BitwardenException(result != null ? result.ErrorMessage : "Secret not found"); + } + + public SecretResponse Create(string key, string value, string note, Guid organizationId, + Guid[] projectIds) + { + var command = new Command() + { + Secrets = new SecretsCommand + { + Create = new SecretCreateRequest + { + Key = key, + Value = value, + Note = note, + OrganizationId = organizationId, + ProjectIds = projectIds + } + } + }; + + var result = _commandRunner.RunCommand(command); + + if (result is { Success: true }) + { + return result.Data; + } + + throw new BitwardenException(result != null ? result.ErrorMessage : "Secret create failed"); + } + + public SecretResponse Update(Guid id, string key, string value, string note, Guid organizationId, + Guid[] projectIds) + { + var command = new Command() + { + Secrets = new SecretsCommand + { + Update = new SecretPutRequest + { + Id = id, + Key = key, + Value = value, + Note = note, + OrganizationId = organizationId, + ProjectIds = projectIds + } + } + }; + + var result = _commandRunner.RunCommand(command); + + if (result is { Success: true }) + { + return result.Data; + } + + throw new BitwardenException(result != null ? result.ErrorMessage : "Secret update failed"); + } + + public SecretsDeleteResponse Delete(Guid[] ids) + { + var command = new Command() + { + Secrets = new SecretsCommand { Delete = new SecretsDeleteRequest { Ids = ids } } + }; + var result = _commandRunner.RunCommand(command); + + if (result is { Success: true }) + { + return result.Data; + } + + throw new BitwardenException(result != null ? result.ErrorMessage : "Secrets delete failed"); + } + + public SecretIdentifiersResponse List(Guid organizationId) + { + var command = new Command() + { + Secrets = new SecretsCommand { List = new SecretIdentifiersRequest { OrganizationId = organizationId } } + }; + var result = _commandRunner.RunCommand(command); + + if (result is { Success: true }) + { + return result.Data; + } + + throw new BitwardenException(result != null ? result.ErrorMessage : "No secrets for given organization"); + } +} diff --git a/languages/csharp/Bitwarden.Sdk/bitwarden.png b/languages/csharp/Bitwarden.Sdk/bitwarden.png new file mode 100644 index 0000000000000000000000000000000000000000..5b9d09d51d999275473c8f210437a424ea96d84d GIT binary patch literal 878 zcmV-!1CjiRP)}b0K@`U)%ZbFGQ8}Xs zClM_aEkwJZkYJ%HW0OKGy>=B+i4y$4Dqyxf3qi3+V@gdS9w^rZuQ-W?U@#zl1TSYu zqM*_F-_6Rg?(N;|%zh;E9xMyDEc@PX-q+r~>0&;z_tLw5ezN&7$d40jV@sJIMSeJ+ zA03|eUhMKQ{vJPFVVhGXIfSde0Jz~h`RT)gyB|Z}`|05! z3IPH@00;m9AOHk_01yBIKmZ5;0U!VbfB+Bx0zd!=00A%pKrWk!AHet3->CsGaI{;C zj#2YH zKp8+yC=dmNv60>EfxWM-@ioO~E58e%@z4nYO%7IlY-CqJOWrWPq9FveybS4rfFaE1 zcXENVKRS)q`ZfrK&R$;#l^ESbhat>XF7GBhJfos9`C?f5kIvZbnmb@RmA^%p%rHb8B&`QwQ*xC9q!z zAVyC&vj5bp<=71uQpR7a#Uud0;Dn5BmLjr}!^{=O65B~94KyCRNax+UbdxnU6PhAr zcMEMDfY?SlWC(<^u(eSIyjP9gJnezd&kWf<|5tzk0ALb5Vs4E8{{R3007*qoM6N<$ Eg66e@TL1t6 literal 0 HcmV?d00001 diff --git a/languages/csharp/Bitwarden.sln b/languages/csharp/Bitwarden.sln new file mode 100644 index 000000000..4cf8d147f --- /dev/null +++ b/languages/csharp/Bitwarden.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bitwarden.Sdk", "Bitwarden.Sdk\Bitwarden.Sdk.csproj", "{DADE59E5-E573-430A-8EB2-BC21D8E8C1D3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bitwarden.Sdk.Samples", "Bitwarden.Sdk.Samples\Bitwarden.Sdk.Samples.csproj", "{CA9F8EDC-643F-4624-AC00-F741E1F30CA4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DADE59E5-E573-430A-8EB2-BC21D8E8C1D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DADE59E5-E573-430A-8EB2-BC21D8E8C1D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DADE59E5-E573-430A-8EB2-BC21D8E8C1D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DADE59E5-E573-430A-8EB2-BC21D8E8C1D3}.Release|Any CPU.Build.0 = Release|Any CPU + {CA9F8EDC-643F-4624-AC00-F741E1F30CA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CA9F8EDC-643F-4624-AC00-F741E1F30CA4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CA9F8EDC-643F-4624-AC00-F741E1F30CA4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CA9F8EDC-643F-4624-AC00-F741E1F30CA4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/languages/csharp/BitwardenSdk.cs b/languages/csharp/BitwardenSdk.cs deleted file mode 100644 index 388b7977f..000000000 --- a/languages/csharp/BitwardenSdk.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Bitwarden.Sdk -{ - internal class BitwardenSdk : IDisposable - { - [DllImport("bitwarden_c", CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr init(string settings); - [DllImport("bitwarden_c", CallingConvention = CallingConvention.Cdecl)] - private static extern void free_mem(IntPtr clientPtr); - - [DllImport("bitwarden_c", CallingConvention = CallingConvention.Cdecl)] - private static extern string run_command(string loginRequest, IntPtr clientPtr); - - private readonly IntPtr _ptr; - private bool disposedValue; - - public BitwardenSdk(ClientSettings? settings = null) - { - _ptr = init(settings?.ToJson()); - } - - public ResponseForPasswordLoginResponse? PasswordLogin(string email, string password) => RunCommand(new Command - { - PasswordLogin = new PasswordLoginRequest { - Email = email, - Password = password - }, - }, ResponseForPasswordLoginResponse.FromJson); - - public ResponseForUserApiKeyResponse? UserApiKey(string password) => RunCommand(new Command - { - GetUserApiKey = new SecretVerificationRequest { - MasterPassword = password - }, - }, ResponseForUserApiKeyResponse.FromJson); - - private TReturn? RunCommand(Command input, Func deserializer) - { - var req = input.ToJson(); - - var json_result = run_command(req, _ptr); - Console.WriteLine(json_result); - return deserializer(json_result); - } - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // TODO: dispose managed state (managed objects) - } - - free_mem(_ptr); - disposedValue = true; - } - } - - - ~BitwardenSdk() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: false); - } - - public void Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: true); - GC.SuppressFinalize(this); - } - } -} diff --git a/languages/csharp/LICENSE.txt b/languages/csharp/LICENSE.txt new file mode 100644 index 000000000..e9d496ff7 --- /dev/null +++ b/languages/csharp/LICENSE.txt @@ -0,0 +1,295 @@ +BITWARDEN SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT +Version 1, 17 March 2023 + +1. Introduction + +1.1 The Bitwarden Software Development Kit (referred to in the License Agreement +as the "SDK" and available for download at the following URL +https://github.com/bitwarden/sdk) is licensed to you subject to the terms of +this License Agreement. The License Agreement forms a legally binding contract +between you and the Company in relation to your use of the SDK. + +1.2 "Bitwarden" means the Bitwarden software made available by the Company, +available for download at the following URL, as updated from time to time. + +1.3 A "Compatible Application" means any software program or service that (i) +connects to and interoperates with a current version of the Bitwarden server +products distributed by the Company; and (ii) complies with the Company’s +acceptable use policy available at the following URL: +https://bitwarden.com/terms/#acceptable_use. + +1.4 "Company" means Bitwarden Inc., organized under the laws of the State of +Delaware. + +2. Accepting this License Agreement + +2.1 In order to access or use the SDK, you must first agree to the License +Agreement. You may not access or use the SDK if you do not accept the License +Agreement. + +2.2 By clicking to accept and/or accessing or using the SDK, you hereby agree to +the terms of the License Agreement. + +2.3 You may not access or use the SDK and may not accept the License Agreement +if you are a person barred from receiving the SDK under the laws of the United +States or other countries, including the country in which you are resident or +from which you access or use the SDK. + +2.4 If you are agreeing to be bound by the License Agreement on behalf of your +employer or any other entity, you represent and warrant that you have full legal +authority to bind your employer or such other entity to the License Agreement. +If you do not have the requisite authority, you may not accept the License +Agreement or you may not access or use the SDK on behalf of your employer or +other entity. + +3. SDK License from Bitwarden + +3.1 Subject to the terms of this License Agreement, Bitwarden grants you a +limited, worldwide, royalty-free, non-assignable, non-exclusive, and +non-sublicensable license to use the SDK solely (a) to develop, test, and +demonstrate a Compatible Application; (b) to develop, test, and run a Compatible +Application for personal use by your family; or (c) to to develop, test, and run +a Compatible Application for the internal business operations of your +organization in connection with a paid license for a Bitwarden server product, +provided that in no case above may the Compatible Application be offered, +licensed, or sold to a third party. + +3.2 You agree that Bitwarden or third parties own all legal right, title and +interest in and to the SDK, including any Intellectual Property Rights that +subsist in the SDK. "Intellectual Property Rights" means any and all rights +under patent law, copyright law, trade secret law, trademark law, and any and +all other proprietary rights. Bitwarden reserves all rights not expressly +granted to you. + +3.3 You may not use this SDK to develop applications for use with software other +than Bitwarden (including non-compatible implementations of Bitwarden) or to +develop another SDK. + +3.4 You may not use the SDK for any purpose not expressly permitted by the +License Agreement. Except for contributions to Bitwarden pursuant to the +Contribution License Agreement available at this URL: +https://cla-assistant.io/bitwarden/clients, or to the extent required by +applicable third party licenses, you may not copy modify, adapt, redistribute, +decompile, reverse engineer, disassemble, or create derivative works of the SDK +or any part of the SDK. + +3.5 Use, reproduction, and distribution of a component of the SDK licensed under +an open source software license are governed solely by the terms of that open +source software license and not the License Agreement. + +3.6 You agree that the form and nature of the SDK that the Company provides may +change without prior notice to you and that future versions of the SDK may be +incompatible with applications developed on previous versions of the SDK. You +agree that the Company may stop (permanently or temporarily) providing the SDK +or any features within the SDK to you or to users generally at the Company’s +sole discretion, without prior notice to you. + +3.7 Nothing in the License Agreement gives you a right to use any of the +Company’s trade names, trademarks, service marks, logos, domain names, or other +distinctive brand features. + +3.8 You agree that you will not remove, obscure, or alter any proprietary rights +notices (including copyright and trademark notices) that may be affixed to or +contained within the SDK. + +4. Use of the SDK by You + +4.1 The Company agrees that it obtains no right, title, or interest from you (or +your licensors) under the License Agreement in or to any software applications +that you develop using the SDK, including any Intellectual Property Rights that +subsist in those applications. + +4.2 You agree to use the SDK and write applications only for purposes that are +permitted by (a) the License Agreement and (b) any applicable law, regulation or +generally accepted practices or guidelines in the relevant jurisdictions +(including any laws regarding the export of data or software to and from the +United States or other relevant countries). + +4.3 You agree that if you use the SDK to develop applications for other users, +you will protect the privacy and legal rights of those users. If the users +provide you with user names, passwords, or other login information or personal +information, you must make the users aware that the information will be +available to your application, and you must provide legally adequate privacy +notice and protection for those users. If your application stores personal or +sensitive information provided by users, it must do so securely. If the user +provides your application with Bitwarden Account information, your application +may only use that information to access the user's Bitwarden Account when, and +for the limited purposes for which, the user has given you permission to do so. + +4.4 You agree that you will not engage in any activity with the SDK, including +the development or distribution of an application, that interferes with, +disrupts, damages, or accesses in an unauthorized manner the servers, networks, +or other properties or services of any third party including, but not limited +to, the Company, or any mobile communications carrier or public cloud service. + +4.5 If you use the SDK to retrieve a user's data from Bitwarden, you acknowledge +and agree that you shall retrieve data only with the user's explicit consent and +only when, and for the limited purposes for which, the user has given you +permission to do so. + +4.6 You agree that you are solely responsible for, and that the Company has no +responsibility to you or to any third party for, any data, content, or resources +that you create, transmit or display through Bitwarden and/or applications for +Bitwarden, and for the consequences of your actions (including any loss or +damage which Bitwarden may suffer) by doing so. + +4.7 You agree that you are solely responsible for, and that the Company has no +responsibility to you or to any third party for, any breach of your obligations +under the License Agreement, any applicable third party contract or Terms of +Service, or any applicable law or regulation, and for the consequences +(including any loss or damage which the Company or any third party may suffer) +of any such breach. + +5. Third Party Applications + +5.1 If you use the SDK to integrate or run applications developed by a third +party or that access data, content or resources provided by a third party, you +agree that the Company is not responsible for those applications, data, content, +or resources. You understand that all data, content or resources which you may +access through such third party applications are the sole responsibility of the +person from which they originated and that the Company is not liable for any +loss or damage that you may experience as a result of the use or access of any +of those third party applications, data, content, or resources. + +5.2 You should be aware that the data, content, and resources presented to you +through such a third party application may be protected by intellectual property +rights which are owned by the providers (or by other persons or companies on +their behalf). You acknowledge that your use of such third party applications, +data, content, or resources may be subject to separate terms between you and the +relevant third party. In that case, the License Agreement does not affect your +legal relationship with these third parties. + +6. Use of Bitwarden Server + +You acknowledge and agree that the Bitwarden server products to which any +Compatible Application must connect is protected by intellectual property rights +which are owned by the Company and your use of the Bitwarden server products is +subject to additional terms not set forth in this License Agreement. + +7. Terminating this License Agreement + +7.1 The License Agreement will continue to apply until terminated by either you +or the Company as set out below. + +7.2 If you want to terminate the License Agreement, you may do so by ceasing +your use of the SDK and any relevant developer credentials. + +7.3 The Company may at any time, terminate the License Agreement with you if: + +(a) you have breached any provision of the License Agreement; or + +(b) the Company is required to do so by law; or + +(c) a third party with whom the Company offered certain parts of the SDK to you +has terminated its relationship with the Company or ceased to offer certain +parts of the SDK to either the Company or to you; or + +(d) the Company decides to no longer provide the SDK or certain parts of the SDK +to users in the country in which you are resident or from which you use the +service, or the provision of the SDK or certain SDK services to you by the +Company is, in the Company’'s sole discretion, no longer commercially viable or +technically practicable. + +7.4 When the License Agreement comes to an end, all of the legal rights, +obligations and liabilities that you and the Company have benefited from, been +subject to (or which have accrued over time whilst the License Agreement has +been in force) or which are expressed to continue indefinitely, shall be +unaffected by this cessation, and the provisions of paragraph 12.8 shall +continue to apply to such rights, obligations and liabilities indefinitely. + +8. NO SUPPORT + +The Company is not obligated under this License Agreement to provide you any +support services for the SDK. Any support provided is at the Company’s sole +discretion and provided on an "as is" basis and without warranty of any kind. + +9. DISCLAIMER OF WARRANTIES + +9.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE SDK IS AT YOUR SOLE +RISK AND THAT THE SDK IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF +ANY KIND FROM Bitwarden. + +9.2 YOUR USE OF THE SDK AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED +THROUGH THE USE OF THE SDK IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY +RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF +DATA THAT RESULTS FROM SUCH USE. + +9.3 THE COMPANY FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY +KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED +WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE +AND NON-INFRINGEMENT. + +10. LIMITATION OF LIABILITY + +YOU EXPRESSLY UNDERSTAND AND AGREE THAT THE COMPANY, ITS SUBSIDIARIES AND +AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF +LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, +STATUTORY, OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS +OF DATA, WHETHER OR NOT THE COMPANY OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF +OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING. + +11. Indemnification + +To the maximum extent permitted by law, you agree to defend, indemnify and hold +harmless the Company, its affiliates and their respective directors, officers, +employees and agents from and against any and all claims, actions, suits or +proceedings, as well as any and all losses, liabilities, damages, costs and +expenses (including reasonable attorneys fees) arising out of or accruing from +(a) your use of the SDK, (b) any application you develop on the SDK that +infringes any copyright, trademark, trade secret, trade dress, patent or other +intellectual property right of any person or defames any person or violates +their rights of publicity or privacy, and (c) any non-compliance by you with the +License Agreement. + +12. General Legal Terms + +12.1 The Company may make changes to the License Agreement as it distributes new +versions of the SDK. When these changes are made, the Company will make a new +version of the License Agreement available on the website where the SDK is made +available. + +12.2 The License Agreement constitutes the whole legal agreement between you and +the Company and governs your use of the SDK (excluding any services or software +which the Company may provide to you under a separate written agreement), and +completely replaces any prior agreements between you and the Company in relation +to the SDK. + +12.3 You agree that if the Company does not exercise or enforce any legal right +or remedy which is contained in the License Agreement (or which the Company has +the benefit of under any applicable law), this will not be taken to be a formal +waiver of the Company's rights and that those rights or remedies will still be +available to the Company. + +12.4 If any court of law, having the jurisdiction to decide on this matter, +rules that any provision of the License Agreement is invalid, then that +provision will be removed from the License Agreement without affecting the rest +of the License Agreement. The remaining provisions of the License Agreement will +continue to be valid and enforceable. + +12.5 You acknowledge and agree that each member of the group of companies of +which the Company is the parent shall be third party beneficiaries to the +License Agreement and that such other companies shall be entitled to directly +enforce, and rely upon, any provision of the License Agreement that confers a +benefit on them or rights in favor of them. Other than this, no other person or +company shall be third party beneficiaries to the License Agreement. + +12.6 EXPORT RESTRICTIONS. THE SDK IS SUBJECT TO UNITED STATES EXPORT LAWS AND +REGULATIONS. YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND +REGULATIONS THAT APPLY TO THE SDK. THESE LAWS INCLUDE RESTRICTIONS ON +DESTINATIONS, END USERS, AND END USE. + +12.7 The rights granted in the License Agreement may not be assigned or +transferred by either you or the Company without the prior written approval of +the other party, provided that the Company may assign this License Agreement +upon notice to you in connection with an acquisition, merger, sale of assets, or +similar corporate change in control for the Company or the Intellectual Property +Rights in the SDK. + +12.8 The License Agreement, and any dispute relating to or arising out of this +License Agreement, shall be governed by the laws of the State of California +without regard to its conflict of laws provisions. You and the Company agree to +submit to the exclusive jurisdiction of the courts located within the county of +Los Angeles, California to resolve any dispute or legal matter arising from the +License Agreement. Notwithstanding this, you agree that the Company shall be +allowed to apply for injunctive remedies, or any equivalent type of urgent legal +relief, in any forum or jurisdiction. diff --git a/languages/csharp/Program.cs b/languages/csharp/Program.cs deleted file mode 100644 index d2e047bfb..000000000 --- a/languages/csharp/Program.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Bitwarden.Sdk; - -var sdk = new BitwardenSdk(); -sdk.PasswordLogin("test@bitwarden.com", "asdfasdf"); -var apiKey = sdk.UserApiKey("asdfasdf"); -Console.WriteLine(apiKey?.Data?.ApiKey ?? "api key was null"); diff --git a/languages/csharp/README.md b/languages/csharp/README.md index e390a1ca1..dea2d1d22 100644 --- a/languages/csharp/README.md +++ b/languages/csharp/README.md @@ -1,17 +1,70 @@ -# Requirements +# Bitwarden Secrets Manager SDK -- Dotnet +.NET bindings for interacting with the [Bitwarden Secrets Manager]. This is a beta release and might be missing some functionality. -# Installation +## Create access token -From the `languages/csharp/` directory, +Review the help documentation on [Access Tokens] -```bash -dotnet restore +## Usage code snippets + +### Create new Bitwarden client + +```csharp +const string accessToken = ""; +using var bitwardenClient = new BitwardenClient(); +bitwardenClient.AccessTokenLogin(accessToken); +``` + +### Create new project + +```csharp +var organizationId = Guid.Parse(""); +var projectResponse = bitwardenClient.Projects().Create(organizationId, "TestProject"); +``` + +### List all projects + +```csharp +var response = bitwardenClient.Projects.List(organizationId); +``` + +### Update project + +```csharp +var projectId = projectResponse.Id; +projectResponse = bitwardenClient.Projects.Get(projectId); +projectResponse = bitwardenClient.Projects.Update(projectId, organizationId, "TestProjectUpdated"); +``` + +### Add new secret + +```csharp +var key = "key"; +var value = "value"; +var note = "note"; +var secretResponse = bitwardenClient.Secrets.Create(key, value, note, organizationId, new[] { projectId }); +var secretId = secretResponse.Id; +``` + +### Update secret +```csharp +secretResponse = bitwardenClient.Secrets + .Update(secretId, "key2", "value2", "note2", organizationId, new[] { projectId }); ``` -# Run +### List secrets -```bash -dotnet run +```csharp +var secretIdentifiersResponse = bitwardenClient.Secrets.List(organizationId); ``` + +# Delete secret or project + +```csharp +bitwardenClient.Secrets.Delete(new [] { secretId }); +bitwardenClient.Projects.Delete(new [] { projectId }); +``` + +[Access Tokens]: https://bitwarden.com/help/access-tokens/ +[Bitwarden Secrets Manager]: https://bitwarden.com/products/secrets-manager/ diff --git a/languages/csharp/bitwardenSdk.csproj b/languages/csharp/bitwardenSdk.csproj deleted file mode 100644 index 315bdca9f..000000000 --- a/languages/csharp/bitwardenSdk.csproj +++ /dev/null @@ -1,42 +0,0 @@ - - - - Exe - net6.0 - enable - enable - Bitwarden.Sdk - - - - - - - - - - - - - Always - - - Always - - - Always - - - - - - Always - - - Always - - - Always - - - diff --git a/languages/csharp/global.json b/languages/csharp/global.json new file mode 100644 index 000000000..527fd31d3 --- /dev/null +++ b/languages/csharp/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "6.0.413", + "rollForward": "latestFeature" + } +} diff --git a/support/scripts/schemas.ts b/support/scripts/schemas.ts index e08661017..148b089e6 100644 --- a/support/scripts/schemas.ts +++ b/support/scripts/schemas.ts @@ -62,7 +62,7 @@ async function main() { }, }); - writeToFile("./languages/csharp/schemas.cs", csharp.lines); + writeToFile("./languages/csharp/Bitwarden.Sdk/schemas.cs", csharp.lines); } main();