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

Golang SDK #218

Merged
merged 41 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
770f95c
initial
cvele Sep 4, 2023
c058c7f
Merge branch 'master' into golang-sdk
cvele Sep 4, 2023
9c5c1f1
Adding basic readme
cvele Sep 4, 2023
7061221
Renaming go package
cvele Sep 5, 2023
8ba4987
Merge branch 'master' into golang-sdk
cvele Sep 5, 2023
a277dfd
ignoring auto-generated schema
cvele Sep 6, 2023
5260304
Merge branch 'golang-sdk' of github.com:cvele/sdk into golang-sdk
cvele Sep 6, 2023
4742e1c
ignoring auto-generated schema
cvele Sep 6, 2023
c19b5ed
Do not expose Impl to consumers
cvele Oct 2, 2023
64dbda5
Clearly denote file as example
cvele Oct 2, 2023
4f30dac
modify package name from main to sdk
cvele Oct 2, 2023
35f1601
Moving c interface to internal package
cvele Oct 2, 2023
537e10b
Exclude unsafe internal impl from examples
cvele Oct 2, 2023
12f295c
Merge branch 'master' into golang-sdk
cvele Oct 2, 2023
af0b153
lower version requirement
cvele Oct 2, 2023
8c8bc29
WIP - initial github release action
cvele Oct 2, 2023
3da0798
fix spelling
cvele Oct 26, 2023
e7e6a3c
Fix package name in schemas
cvele Oct 26, 2023
93eadd1
Update example, remove hard dependency on schemas
cvele Oct 26, 2023
9b4359a
initialize example main module
cvele Oct 26, 2023
f8342c2
Be friendly to IDE - add .work
cvele Oct 26, 2023
574a832
Unwrap the responses
cvele Oct 26, 2023
18cdf6c
Unwrap the responses
cvele Oct 26, 2023
29a86e6
Unwrap responses and return native error types
cvele Oct 26, 2023
4dc0fd6
Merge branch 'master' into golang-sdk
cvele Oct 26, 2023
2f5bd02
address PR comments
Oct 30, 2023
4e98474
address PR comments
Oct 31, 2023
00ca7a3
address PR comments
Oct 31, 2023
b9060c4
address PR comments
Oct 31, 2023
5ce40b4
remove go.work
Nov 2, 2023
afa2813
address PR comments
Nov 2, 2023
b7ef4b8
remove build.sh and custom lib
Nov 14, 2023
6a04b18
Merge branch 'master' into golang-sdk
bbujak Nov 22, 2023
d48f419
Merge branch 'master' into golang-sdk
bbujak Nov 24, 2023
302729a
Merge branch 'master' into golang-sdk
bbujak Nov 27, 2023
4c9f6db
remove some comments
Nov 27, 2023
3640a1f
Merge branch 'master' into golang-sdk
bbujak Nov 28, 2023
9257c20
run prettier
Nov 28, 2023
21669a4
Merge remote-tracking branch 'origin/golang-sdk' into golang-sdk
Nov 28, 2023
1dc8a3b
Merge branch 'master' into golang-sdk
bbujak Nov 30, 2023
5c14d95
merged main
Nov 30, 2023
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
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 Go schemas artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: schemas.go
path: ${{ github.workspace }}/languages/go/schema.go
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/schemas.cs
languages/js_webassembly/bitwarden_client/schemas.ts
languages/python/BitwardenClient/schemas.py
languages/go/schema.go
116 changes: 116 additions & 0 deletions languages/go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# 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.
Hinton marked this conversation as resolved.
Show resolved Hide resolved

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

settings := ClientSettings{
// Your settings here
}
lib := BitwardenLibraryImpl{}
client := NewBitwardenClient(settings, lib)
cvele marked this conversation as resolved.
Show resolved Hide resolved
```

---

### Login

To login using an access token:

```go
response := client.AccessTokenLogin("your_access_token_here")
```

---

### Projects

#### Create a Project

```go
response, err := client.Projects.Create("organization_id", "project_name")
Hinton marked this conversation as resolved.
Show resolved Hide resolved
```

#### List Projects

```go
response, err := client.Projects.List("organization_id")
```

#### Update a Project

```go
response, err := client.Projects.Update("project_id", "organization_id", "new_project_name")
```

#### Delete Projects

```go
response, err := client.Projects.Delete([]string{"project_id_1", "project_id_2"})
```

---

### Secrets

#### Create a Secret

```go
response, err := client.Secrets.Create("key", "value", "note", "organization_id", []string{"project_id"})
```

#### List Secrets

```go
response, err := client.Secrets.List("organization_id")
```

#### Update a Secret

```go
response, err := client.Secrets.Update("secret_id", "new_key", "new_value", "new_note", "organization_id", []string{"project_id"})
```

#### Delete Secrets

```go
response, err := client.Secrets.Delete([]string{"secret_id_1", "secret_id_2"})
```

---

### Close Client

To free up resources:

```go
client.Close()
```

---

For more detailed information, refer to the code comments and method signatures.
50 changes: 50 additions & 0 deletions languages/go/bitwarden_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import "encoding/json"

type BitwardenClient struct {
client ClientPointer
lib BitwardenLibrary
commandRunner CommandRunnerInterface
Projects ProjectsInterface
Secrets SecretsInterface
}

func NewBitwardenClient(settings ClientSettings, lib BitwardenLibrary) *BitwardenClient {
settingsJSON, err := json.Marshal(settings)
if err != nil {
panic(err)
}

client, err := lib.Init(string(settingsJSON))
if err != nil {
panic(err)
}
runner := NewCommandRunner(client, lib)

return &BitwardenClient{
lib: lib,
client: client,
commandRunner: runner,
Projects: NewProjects(runner),
Secrets: NewSecrets(runner),
}
}

func (c *BitwardenClient) AccessTokenLogin(accessToken string) ResponseForAPIKeyLoginResponse {
req := AccessTokenLoginRequest{AccessToken: accessToken}
command := Command{AccessTokenLogin: &req}

responseStr := c.commandRunner.RunCommand(command)

var response ResponseForAPIKeyLoginResponse
if err := json.Unmarshal([]byte(responseStr), &response); err != nil {
panic(err)
}
Hinton marked this conversation as resolved.
Show resolved Hide resolved

return response
}

func (c *BitwardenClient) Close() {
c.lib.FreeMem(c.client)
}
54 changes: 54 additions & 0 deletions languages/go/bitwarden_libary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//go:build !custom
// +build !custom

package main

import (
"fmt"
"unsafe"
)

/*
#cgo LDFLAGS: -lbitwarden_c
#cgo linux LDFLAGS: -L/usr/local/lib -L/usr/lib
#cgo darwin LDFLAGS: -L/usr/local/lib -L/usr/lib
#include <stdlib.h>
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 (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
}
54 changes: 54 additions & 0 deletions languages/go/bitwarden_libary_custom.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//go:build custom
// +build custom

package main

import (
"fmt"
"unsafe"
)

/*
#cgo LDFLAGS: -lbitwarden_c
#cgo linux LDFLAGS: -L/usr/local/lib -L/usr/lib
#cgo darwin LDFLAGS: -L/usr/local/lib -L/usr/lib
#include <stdlib.h>
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 (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
}
8 changes: 8 additions & 0 deletions languages/go/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

if [ -n "$BITWARDEN_LIB_PATH" ]; then
sed "s/{{.LibPath}}/$BITWARDEN_LIB_PATH/g" bitwarden_library.go > bitwarden_library.go
go build -tags custom
else
go build
fi
35 changes: 35 additions & 0 deletions languages/go/command_runner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"encoding/json"
)

type CommandRunnerInterface interface {
RunCommand(command Command) string
}

type CommandRunner struct {
client ClientPointer
lib BitwardenLibrary
}

func NewCommandRunner(client ClientPointer, lib BitwardenLibrary) *CommandRunner {
return &CommandRunner{
client: client,
lib: lib,
}
}

func (c *CommandRunner) RunCommand(command Command) string {
commandJSON, err := json.Marshal(command)
if err != nil {
panic(err)
}

responseStr, err := c.lib.RunCommand(string(commandJSON), c.client)
if err != nil {
panic(err)
}

return responseStr
}
5 changes: 5 additions & 0 deletions languages/go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/bitwarden/sdk/languages/go

go 1.20

require github.com/gofrs/uuid v4.4.0+incompatible
2 changes: 2 additions & 0 deletions languages/go/go.sum
Original file line number Diff line number Diff line change
@@ -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=
Loading