Skip to content

Commit

Permalink
Java wrapper for SDK (#179)
Browse files Browse the repository at this point in the history
## Type of change

```
- [ ] Bug fix
- [x] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other
```

## Objective

Added a Maven-based Java project that wraps native C library for the SDK
and exposed its commands through BitwardenClient class.

## Code changes

- Updated schemas.ts to generate Java classes for the API - difference
with current generators is that it creates multiple files
- Added BitWardenClient class as a wrapper for the native SDK library
- BitwardenLibrary inteface uses JNA to link to the native lib
- AutoCloseable inteface implemented to deal with freeing memory, client
can be used with try-with-resources or close() can be called explicitly
(finalize() method is deprecated in newer Java versions)

---------

Co-authored-by: Vince Grassia <[email protected]>
Co-authored-by: Daniel García <[email protected]>
Co-authored-by: Oscar Hinton <[email protected]>
  • Loading branch information
4 people authored Nov 28, 2023
1 parent f18020d commit 31c005f
Show file tree
Hide file tree
Showing 22 changed files with 1,088 additions and 1 deletion.
68 changes: 68 additions & 0 deletions .github/workflows/build-java.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Build Java 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_java:
name: Build Java
runs-on: ubuntu-22.04
needs:
- generate_schemas
- build_rust

steps:
- name: Checkout Repository
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0

- name: Download Java schemas artifact
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
with:
name: sdk-schemas-java
path: languages/java/src/main/java/bit/sdk/schema/

- name: Setup Java
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
with:
distribution: temurin
java-version: 17

- 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/java/src/main/resources/darwin-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/java/src/main/resources/darwin-aarch64

- 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/java/src/main/resources/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/java/src/main/resources/windows-x64

- name: Publish Maven
uses: gradle/gradle-build-action@b5126f31dbc19dd434c3269bf8c28c315e121da2 # v2.8.1
with:
arguments: publish
build-root-directory: languages/java
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7 changes: 7 additions & 0 deletions .github/workflows/generate_schemas.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,10 @@ jobs:
name: sdk-schemas-json
path: ${{ github.workspace }}/support/schemas/*
if-no-files-found: error

- name: Upload java schemas artifact
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: sdk-schemas-java
path: ${{ github.workspace }}/languages/java/src/main/java/com/bitwarden/sdk/schema/*
if-no-files-found: error
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +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
11 changes: 11 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@
"options": {
"cwd": "${workspaceFolder}/languages/python"
}
},
{
"label": "buildJava",
"type": "shell",
"command": "gradle",
"args": ["build"],
"dependsOrder": "sequence",
"dependsOn": ["rust: bitwarden-c build"],
"options": {
"cwd": "${workspaceFolder}/languages/java"
}
}
]
}
3 changes: 3 additions & 0 deletions languages/java/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target
.gradle
src/main/resources
73 changes: 73 additions & 0 deletions languages/java/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Bitwarden Secrets Manager SDK

Java 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

### Create new Bitwarden client

```java
BitwardenSettings bitwardenSettings = new BitwardenSettings();
bitwardenSettings.setApiUrl("https://api.bitwarden.com");
bitwardenSettings.setIdentityUrl("https://identity.bitwarden.com");
BitwardenClient bitwardenClient = new BitwardenClient(bitwardenSettings);
bitwardenClient.accessTokenLogin("<access-token>");
```

### Create new project

```java
UUID organizationId = UUID.fromString("<organization-id>");
var projectResponse = bitwardenClient.projects().create(organizationId, "TestProject");
```

### List all projects

```java
var projectsResponse = bitwardenClient.projects().list(organizationId);
```

### Update project

```java
UUID projectId = projectResponse.getID();
projectResponse = bitwardenClient.projects().get(projectId);
projectResponse = bitwardenClient.projects.update(projectId, organizationId, "TestProjectUpdated");
```

### Add new secret

```java
String key = "key";
String value = "value";
String note = "note";
var secretResponse = bitwardenClient.secrets().create(key, value, note, organizationId, new UUID[]{projectId});
UUID secretId = secretResponse.getID();
```

### Update secret

```java
bitwardenClient.secrets().update(secretId, key2, value2, note2, organizationId, new UUID[]{projectId});
```

### List secrets

```java
var secretIdentifiersResponse secretIdentifiersResponse = bitwardenClient.secrets().list(organizationId);
```

# Delete secret or project

```java
bitwardenClient.secrets().delete(new UUID[]{secretId});
bitwardenClient.projects().delete(new UUID[]{projectId});
```

[Access Tokens]: https://bitwarden.com/help/access-tokens/
[Bitwarden Secrets Manager]: https://bitwarden.com/products/secrets-manager/
90 changes: 90 additions & 0 deletions languages/java/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* This file was generated by the Gradle 'init' task.
*/

plugins {
id 'java-library'
id 'maven-publish'
}

repositories {
mavenLocal()
maven {
url = uri('https://repo.maven.apache.org/maven2/')
}

dependencies {
api 'com.fasterxml.jackson.core:jackson-core:2.9.10'
api 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.10'
api 'net.java.dev.jna:jna-platform:5.12.1'
}

description = 'BitwardenSDK'
java.sourceCompatibility = JavaVersion.VERSION_1_8

publishing {
publications {
maven(MavenPublication) {
groupId = 'com.bitwarden'
artifactId = 'sdk'

// Determine the version from the git history.
//
// PRs: use the branch name.
// Master: Grab it from `crates/bitwarden/Cargo.toml`

def branchName = "git branch --show-current".execute().text.trim()

if (branchName == "master") {
def content = ['grep', '-o', '^version = ".*"', '../../crates/bitwarden/Cargo.toml'].execute().text.trim()
def match = ~/version = "(.*)"/
def matcher = match.matcher(content)
matcher.find()

version = "${matcher.group(1)}-SNAPSHOT"
} else {
// branchName-SNAPSHOT
version = "${branchName.replaceAll('/', '-')}-SNAPSHOT"
}

afterEvaluate {
from components.java
}
}
}
repositories {
maven {
name = "GitHubPackages"
url = "https://maven.pkg.github.com/bitwarden/sdk"
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
}
}
}

tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}

tasks.withType(Javadoc) {
options.encoding = 'UTF-8'
}

// Gradle build requires GitHub workflow to copy native library to resources
// Uncomment copyNativeLib and jar tasks to use the local build (modify architecture if needed)
//tasks.register('copyNativeLib', Copy) {
// delete 'src/main/resources/darwin-aarch64'
// from '../../target/debug'
// include '*libbitwarden_c*.dylib'
// include '*libbitwarden_c*.so'
// include '*bitwarden_c*.dll'
// into 'src/main/resources/darwin-aarch64'
//}
//
//jar {
// dependsOn tasks.named("copyNativeLib").get()
// from 'src/main/resources'
//}
Binary file added languages/java/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
7 changes: 7 additions & 0 deletions languages/java/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 31c005f

Please sign in to comment.