diff --git a/.github/workflows/generate_schemas.yml b/.github/workflows/generate_schemas.yml index d367d0e48..48cd57bf6 100644 --- a/.github/workflows/generate_schemas.yml +++ b/.github/workflows/generate_schemas.yml @@ -69,4 +69,4 @@ jobs: with: name: sdk-schemas-java path: ${{ github.workspace }}/languages/java/src/main/java/bit/sdk/schema/* - if-no-files-found: error \ No newline at end of file + if-no-files-found: error diff --git a/.gitignore b/.gitignore index 908917e10..38b074349 100644 --- a/.gitignore +++ b/.gitignore @@ -49,4 +49,4 @@ crates/bitwarden-napi/src-ts/bitwarden_client/schemas.ts languages/csharp/Bitwarden.Sdk/schemas.cs languages/js_webassembly/bitwarden_client/schemas.ts languages/python/BitwardenClient/schemas.py -languages/java/src/main/java/com/bitwarden/sdk/schema \ No newline at end of file +languages/java/src/main/java/com/bitwarden/sdk/schema diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 6616022c4..31edf637b 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -53,7 +53,10 @@ "command": "gradle", "args": ["build"], "dependsOrder": "sequence", - "dependsOn": ["rust: bitwarden-c build"] - } + "dependsOn": ["rust: bitwarden-c build"], + "options": { + "cwd": "${workspaceFolder}/languages/java" + } + } ] } diff --git a/languages/java/.gitignore b/languages/java/.gitignore index eea31218b..b5b6c5697 100644 --- a/languages/java/.gitignore +++ b/languages/java/.gitignore @@ -1,5 +1,3 @@ target -.idea -build .gradle src/main/resources diff --git a/languages/java/README.md b/languages/java/README.md index aabf67a99..93010b510 100644 --- a/languages/java/README.md +++ b/languages/java/README.md @@ -71,4 +71,4 @@ bitwardenClient.projects().delete(new UUID[]{projectId}); [Access Tokens]: https://bitwarden.com/help/access-tokens/ -[Bitwarden Secrets Manager]: https://bitwarden.com/products/secrets-manager/ +[Bitwarden Secrets Manager]: https://bitwarden.com/products/secrets-manager/ \ No newline at end of file diff --git a/languages/java/src/main/java/com/bitwarden/sdk/BitwardenClient.java b/languages/java/src/main/java/com/bitwarden/sdk/BitwardenClient.java index 889fa0734..9e1948184 100644 --- a/languages/java/src/main/java/com/bitwarden/sdk/BitwardenClient.java +++ b/languages/java/src/main/java/com/bitwarden/sdk/BitwardenClient.java @@ -9,28 +9,17 @@ public class BitwardenClient implements AutoCloseable { - static Function throwingFunctionWrapper(ThrowingFunction throwingFunction) { - - return i -> { - try { - return throwingFunction.accept(i); - } catch (Exception ex) { - throw new BitwardenClientException("Response deserialization failed"); - } - }; - } - - private Pointer client; + private final Pointer client; - private BitwardenLibrary library; + private final BitwardenLibrary library; - private CommandRunner commandRunner; + private final CommandRunner commandRunner; private boolean isClientOpen; - private ProjectsClient projects; + private final ProjectsClient projects; - private SecretsClient secrets; + private final SecretsClient secrets; public BitwardenClient(BitwardenSettings bitwardenSettings) { ClientSettings clientSettings = new ClientSettings(); @@ -38,28 +27,45 @@ public BitwardenClient(BitwardenSettings bitwardenSettings) { clientSettings.setIdentityURL(bitwardenSettings.getIdentityUrl()); clientSettings.setDeviceType(DeviceType.SDK); clientSettings.setUserAgent("Bitwarden JAVA-SDK"); + library = Native.load("bitwarden_c", BitwardenLibrary.class); + try { client = library.init(Converter.ClientSettingsToJsonString(clientSettings)); } catch (JsonProcessingException e) { throw new BitwardenClientException("Error while processing client settings"); } + commandRunner = new CommandRunner(library, client); projects = new ProjectsClient(commandRunner); secrets = new SecretsClient(commandRunner); isClientOpen = true; } + static Function throwingFunctionWrapper(ThrowingFunction throwingFunction) { + + return i -> { + try { + return throwingFunction.accept(i); + } catch (Exception ex) { + throw new BitwardenClientException("Response deserialization failed"); + } + }; + } + public APIKeyLoginResponse accessTokenLogin(String accessToken) { Command command = new Command(); AccessTokenLoginRequest accessTokenLoginRequest = new AccessTokenLoginRequest(); accessTokenLoginRequest.setAccessToken(accessToken); command.setAccessTokenLogin(accessTokenLoginRequest); + ResponseForAPIKeyLoginResponse response = commandRunner.runCommand(command, throwingFunctionWrapper(Converter::ResponseForAPIKeyLoginResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "Login failed"); } + return response.getData(); } diff --git a/languages/java/src/main/java/com/bitwarden/sdk/CommandRunner.java b/languages/java/src/main/java/com/bitwarden/sdk/CommandRunner.java index 6b903d9b2..11a100814 100644 --- a/languages/java/src/main/java/com/bitwarden/sdk/CommandRunner.java +++ b/languages/java/src/main/java/com/bitwarden/sdk/CommandRunner.java @@ -5,14 +5,15 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.sun.jna.Pointer; + import java.io.IOException; import java.util.function.Function; class CommandRunner { - private BitwardenLibrary library; + private final BitwardenLibrary library; - private Pointer client; + private final Pointer client; CommandRunner(BitwardenLibrary library, Pointer client) { this.library = library; @@ -21,11 +22,13 @@ class CommandRunner { T runCommand(Command command, Function deserializer) { String response = null; + try { response = library.run_command(commandToString(command), client); } catch (IOException e) { throw new RuntimeException(e); } + return deserializer.apply(response); } diff --git a/languages/java/src/main/java/com/bitwarden/sdk/ProjectsClient.java b/languages/java/src/main/java/com/bitwarden/sdk/ProjectsClient.java index e212052db..73b87440c 100644 --- a/languages/java/src/main/java/com/bitwarden/sdk/ProjectsClient.java +++ b/languages/java/src/main/java/com/bitwarden/sdk/ProjectsClient.java @@ -6,7 +6,7 @@ public class ProjectsClient { - private CommandRunner commandRunner; + private final CommandRunner commandRunner; ProjectsClient(CommandRunner commandRunner) { this.commandRunner = commandRunner; @@ -19,11 +19,14 @@ public ProjectResponse get(UUID id) { projectGetRequest.setID(id); projectsCommand.setGet(projectGetRequest); command.setProjects(projectsCommand); + ResponseForProjectResponse response = commandRunner.runCommand(command, BitwardenClient.throwingFunctionWrapper(Converter::ResponseForProjectResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "Project not found"); } + return response.getData(); } @@ -35,11 +38,14 @@ public ProjectResponse create(UUID organizationId, String name) { projectCreateRequest.setName(name); projectsCommand.setCreate(projectCreateRequest); command.setProjects(projectsCommand); + ResponseForProjectResponse response = commandRunner.runCommand(command, BitwardenClient.throwingFunctionWrapper(Converter::ResponseForProjectResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "Project create failed"); } + return response.getData(); } @@ -52,11 +58,14 @@ public ProjectResponse update(UUID id, UUID organizationId, String name) { projectPutRequest.setName(name); projectsCommand.setUpdate(projectPutRequest); command.setProjects(projectsCommand); + ResponseForProjectResponse response = commandRunner.runCommand(command, BitwardenClient.throwingFunctionWrapper(Converter::ResponseForProjectResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "Project update failed"); } + return response.getData(); } @@ -67,12 +76,15 @@ public ProjectsDeleteResponse delete(UUID[] ids) { projectsDeleteRequest.setIDS(ids); projectsCommand.setDelete(projectsDeleteRequest); command.setProjects(projectsCommand); + ResponseForProjectsDeleteResponse response = commandRunner.runCommand(command, BitwardenClient.throwingFunctionWrapper(Converter::ResponseForProjectsDeleteResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "Projects update failed"); } + return response.getData(); } @@ -83,12 +95,15 @@ public ProjectsResponse list(UUID organizationId) { projectsListRequest.setOrganizationID(organizationId); projectsCommand.setList(projectsListRequest); command.setProjects(projectsCommand); + ResponseForProjectsResponse response = commandRunner.runCommand(command, BitwardenClient.throwingFunctionWrapper(Converter::ResponseForProjectsResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "No projects for given organization"); } + return response.getData(); } } diff --git a/languages/java/src/main/java/com/bitwarden/sdk/SecretsClient.java b/languages/java/src/main/java/com/bitwarden/sdk/SecretsClient.java index e857f56a4..f1a97fdc7 100644 --- a/languages/java/src/main/java/com/bitwarden/sdk/SecretsClient.java +++ b/languages/java/src/main/java/com/bitwarden/sdk/SecretsClient.java @@ -6,7 +6,7 @@ public class SecretsClient { - private CommandRunner commandRunner; + private final CommandRunner commandRunner; SecretsClient(CommandRunner commandRunner) { this.commandRunner = commandRunner; @@ -19,16 +19,18 @@ public SecretResponse get(UUID id) { secretGetRequest.setID(id); secretsCommand.setGet(secretGetRequest); command.setSecrets(secretsCommand); + ResponseForSecretResponse response = commandRunner.runCommand(command, BitwardenClient.throwingFunctionWrapper(Converter::ResponseForSecretResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "Secret not found"); } + return response.getData(); } - public SecretResponse create(String key, String value, String note, UUID organizationId, - UUID[] projectIds) { + public SecretResponse create(String key, String value, String note, UUID organizationId, UUID[] projectIds) { Command command = new Command(); SecretsCommand secretsCommand = new SecretsCommand(); SecretCreateRequest secretCreateRequest = new SecretCreateRequest(); @@ -39,11 +41,14 @@ public SecretResponse create(String key, String value, String note, UUID organiz secretCreateRequest.setProjectIDS(projectIds); secretsCommand.setCreate(secretCreateRequest); command.setSecrets(secretsCommand); + ResponseForSecretResponse response = commandRunner.runCommand(command, BitwardenClient.throwingFunctionWrapper(Converter::ResponseForSecretResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "Secret create failed"); } + return response.getData(); } @@ -60,11 +65,14 @@ public SecretResponse update(UUID id, String key, String value, String note, UUI secretPutRequest.setProjectIDS(projectIds); secretsCommand.setUpdate(secretPutRequest); command.setSecrets(secretsCommand); + ResponseForSecretResponse response = commandRunner.runCommand(command, BitwardenClient.throwingFunctionWrapper(Converter::ResponseForSecretResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "Secret update failed"); } + return response.getData(); } @@ -75,11 +83,14 @@ public SecretsDeleteResponse delete(UUID[] ids) { secretsDeleteRequest.setIDS(ids); secretsCommand.setDelete(secretsDeleteRequest); command.setSecrets(secretsCommand); + ResponseForSecretsDeleteResponse response = commandRunner.runCommand(command, BitwardenClient.throwingFunctionWrapper(Converter::ResponseForSecretsDeleteResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "Secrets delete failed"); } + return response.getData(); } @@ -90,12 +101,15 @@ public SecretIdentifiersResponse list(UUID organizationId) { secretIdentifiersRequest.setOrganizationID(organizationId); secretsCommand.setList(secretIdentifiersRequest); command.setSecrets(secretsCommand); + ResponseForSecretIdentifiersResponse response = commandRunner.runCommand(command, BitwardenClient.throwingFunctionWrapper(Converter::ResponseForSecretIdentifiersResponseFromJsonString)); + if (response == null || !response.getSuccess()) { throw new BitwardenClientException(response != null ? response.getErrorMessage() : "No secrets for given organization"); } + return response.getData(); } }