Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add run_command_async #993

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
520a958
Add `run_command_async`
justindbaur Aug 23, 2024
a913189
Remove Logs
justindbaur Aug 23, 2024
497979e
Formatting
justindbaur Aug 23, 2024
c5c8d17
Formatting
justindbaur Aug 23, 2024
2d2801b
Free String On Rust Side
justindbaur Aug 23, 2024
adb445f
Formatting
justindbaur Aug 25, 2024
60bf783
Merge remote-tracking branch 'origin/main' into add-run-command-async
justindbaur Sep 3, 2024
a58121a
Migrate All C# Clients to Async
justindbaur Sep 4, 2024
bb1bc1e
Support Cancellation
justindbaur Sep 4, 2024
9ed29b7
Remove Comment
justindbaur Sep 4, 2024
6014b51
Cleanup
justindbaur Sep 4, 2024
cb73715
Formatting
justindbaur Sep 4, 2024
c1dc017
More Formatting
justindbaur Sep 4, 2024
5787db5
Use More Local Import
justindbaur Sep 4, 2024
d28a9e2
Remove Unnecessary async
justindbaur Sep 4, 2024
3709f6d
Format
justindbaur Sep 4, 2024
d101914
Format Again...
justindbaur Sep 4, 2024
5c433eb
Try A Thing
justindbaur Sep 5, 2024
ec3004d
Pass `CancellationToken` to `SetCancelled`
justindbaur Sep 5, 2024
447d6e7
Update crates/bitwarden-c/src/c.rs
justindbaur Sep 10, 2024
7bcd6d7
Update languages/csharp/Bitwarden.Sdk.Tests/GlobalUsings.cs
justindbaur Sep 10, 2024
8b16ece
Move Debug Stuff To bitwarden-json
justindbaur Sep 10, 2024
9d3a052
Merge branch 'add-run-command-async' of github.com:bitwarden/sdk intoโ€ฆ
justindbaur Sep 10, 2024
78a1ad6
Reorder Deps
justindbaur Sep 10, 2024
38c7cc5
Format
justindbaur Sep 10, 2024
0c8566b
Add Sample Tests
justindbaur Sep 18, 2024
aaff4f5
Merge branch 'main' into add-run-command-async
justindbaur Oct 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion crates/bitwarden-c/src/c.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::{ffi::CStr, os::raw::c_char, str};
use std::{
ffi::{CStr, CString},
os::raw::c_char,
str
};

use bitwarden_json::client::Client;

Expand Down Expand Up @@ -28,6 +32,37 @@
}
}

type OnCompletedCallback = unsafe extern "C" fn(result: *mut c_char) -> ();

#[no_mangle]
pub extern "C" fn run_command_async(
c_str_ptr: *const c_char,
client_ptr: *const CClient,
on_completed_callback: OnCompletedCallback,
) -> () {
let client = unsafe { ffi_ref!(client_ptr) };
let input_str = str::from_utf8(unsafe { CStr::from_ptr(c_str_ptr) }.to_bytes())
.expect("Input should be a valid string")
// Languages may assume that the string is collectable as soon as this method exits
// but it's not since the request will be run in the background
// so we need to make our own copy.
.to_owned();

client.runtime.spawn(async move {
let result = client.client.run_command(input_str.as_str()).await;
let str_result = match std::ffi::CString::new(result) {
Ok(cstr) => cstr.into_raw(),
Err(_) => panic!("failed to return comment result: null encountered"),

Check warning on line 55 in crates/bitwarden-c/src/c.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-c/src/c.rs#L38-L55

Added lines #L38 - L55 were not covered by tests
};

// run completed function
unsafe {
on_completed_callback(str_result);
let _ = CString::from_raw(str_result);
}
});
}

Check warning on line 64 in crates/bitwarden-c/src/c.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-c/src/c.rs#L59-L64

Added lines #L59 - L64 were not covered by tests

// Init client, potential leak! You need to call free_mem after this!
#[no_mangle]
pub extern "C" fn init(c_str_ptr: *const c_char) -> *mut CClient {
Expand Down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll let @bitwarden/team-secrets-manager-dev decide if they want to accept net 8 as the new target.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
4 changes: 2 additions & 2 deletions languages/csharp/Bitwarden.Sdk.Samples/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
๏ปฟusing Bitwarden.Sdk;
using Bitwarden.Sdk;

// Configure secrets
var accessToken = Environment.GetEnvironmentVariable("ACCESS_TOKEN")!;
Expand All @@ -9,7 +9,7 @@
using var bitwardenClient = new BitwardenClient();

// Authenticate
bitwardenClient.AccessTokenLogin(accessToken);
await bitwardenClient.AccessTokenLoginAsync(accessToken);

// Project operations
var projectResponse = bitwardenClient.Projects.Create(organizationId, "NewTestProject");
Expand Down
6 changes: 3 additions & 3 deletions languages/csharp/Bitwarden.Sdk/Bitwarden.Sdk.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
Hinton marked this conversation as resolved.
Show resolved Hide resolved
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Bitwarden.Sdk</RootNamespace>

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Hinton marked this conversation as resolved.
Show resolved Hide resolved
<Title>Bitwarden Secrets Manager SDK</Title>
<Authors>Bitwarden Inc.</Authors>
<Description>.NET bindings for interacting with the Bitwarden Secrets Manager</Description>
Expand Down Expand Up @@ -74,4 +74,4 @@
<PackagePath>runtimes/win-x64/native</PackagePath>
</Content>
</ItemGroup>
</Project>
</Project>
6 changes: 3 additions & 3 deletions languages/csharp/Bitwarden.Sdk/BitwardenClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public BitwardenClient(BitwardenSettings? settings = null)
Secrets = new SecretsClient(_commandRunner);
}

public void AccessTokenLogin(string accessToken)
public async Task AccessTokenLoginAsync(string accessToken)
{
var command = new Command { AccessTokenLogin = new AccessTokenLoginRequest { AccessToken = accessToken } };
var response = _commandRunner.RunCommand<ResponseForApiKeyLoginResponse>(command);
var command = new Command { LoginAccessToken = new AccessTokenLoginRequest { AccessToken = accessToken } };
var response = await _commandRunner.RunCommandAsync<ResponseForApiKeyLoginResponse>(command);
if (response is not { Success: true })
{
throw new BitwardenAuthException(response != null ? response.ErrorMessage : "Login failed");
Expand Down
41 changes: 34 additions & 7 deletions languages/csharp/Bitwarden.Sdk/BitwardenLibrary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,47 @@

namespace Bitwarden.Sdk;

internal static class BitwardenLibrary
internal static partial class BitwardenLibrary
{
[DllImport("bitwarden_c", CallingConvention = CallingConvention.Cdecl)]
private static extern BitwardenSafeHandle init(string settings);
[LibraryImport("bitwarden_c", StringMarshalling = StringMarshalling.Utf8)]
private static partial BitwardenSafeHandle init(string settings);

[DllImport("bitwarden_c", CallingConvention = CallingConvention.Cdecl)]
private static extern void free_mem(IntPtr handle);
[LibraryImport("bitwarden_c", StringMarshalling = StringMarshalling.Utf8)]
private static partial void free_mem(IntPtr handle);

[DllImport("bitwarden_c", CallingConvention = CallingConvention.Cdecl)]
private static extern string run_command(string json, BitwardenSafeHandle handle);
[LibraryImport("bitwarden_c", StringMarshalling = StringMarshalling.Utf8)]
private static partial string run_command(string json, BitwardenSafeHandle handle);

internal delegate void OnCompleteCallback(IntPtr json);

[LibraryImport("bitwarden_c", StringMarshalling = StringMarshalling.Utf8)]
private static partial void run_command_async(string json, BitwardenSafeHandle handle, OnCompleteCallback on_completed_callback);

internal static BitwardenSafeHandle Init(string settings) => init(settings);

internal static void FreeMemory(IntPtr handle) => free_mem(handle);

internal static string RunCommand(string json, BitwardenSafeHandle handle) => run_command(json, handle);

internal static Task<string> RunCommandAsync(string json, BitwardenSafeHandle handle, CancellationToken token = default)
{
var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);

try
{
run_command_async(json, handle, (resultPointer) =>
{
var stringResult = Marshal.PtrToStringUTF8(resultPointer);
tcs.SetResult(stringResult);
});
}
catch (Exception ex)
{
tcs.SetException(ex);
}

// TODO: Register cancellation on token
justindbaur marked this conversation as resolved.
Show resolved Hide resolved

return tcs.Task;
}
}
7 changes: 7 additions & 0 deletions languages/csharp/Bitwarden.Sdk/CommandRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,11 @@ internal CommandRunner(BitwardenSafeHandle handle)
var result = BitwardenLibrary.RunCommand(req, _handle);
return JsonSerializer.Deserialize<T>(result, Converter.Settings);
}

internal async Task<T?> RunCommandAsync<T>(Command command)
{
var req = JsonSerializer.Serialize(command, Converter.Settings);
var result = await BitwardenLibrary.RunCommandAsync(req, _handle);
return JsonSerializer.Deserialize<T>(result, Converter.Settings);
}
}
Loading