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

move and rename models #157

Merged
merged 2 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:

services:
vaultwarden:
image: vaultwarden/server:latest
image: vaultwarden/server:1.32.0
env:
ADMIN_TOKEN: test1234
I_REALLY_WANT_VOLATILE_STORAGE: "true"
Expand Down
34 changes: 0 additions & 34 deletions internal/bitwarden/bw/client_options.go

This file was deleted.

15 changes: 0 additions & 15 deletions internal/bitwarden/bw/filter.go

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package bw
package bwcli

import (
"context"
Expand All @@ -7,31 +7,33 @@ import (
"fmt"
"os"

"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden"
"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden/models"
"github.com/maxlaverse/terraform-provider-bitwarden/internal/command"
)

type Client interface {
CreateAttachment(ctx context.Context, itemId, filePath string) (*Object, error)
CreateObject(context.Context, Object) (*Object, error)
EditObject(context.Context, Object) (*Object, error)
type CLIClient interface {
CreateAttachment(ctx context.Context, itemId, filePath string) (*models.Object, error)
CreateObject(context.Context, models.Object) (*models.Object, error)
EditObject(context.Context, models.Object) (*models.Object, error)
GetAttachment(ctx context.Context, itemId, attachmentId string) ([]byte, error)
GetObject(context.Context, Object) (*Object, error)
GetObject(context.Context, models.Object) (*models.Object, error)
GetSessionKey() string
HasSessionKey() bool
ListObjects(ctx context.Context, objType string, options ...ListObjectsOption) ([]Object, error)
ListObjects(ctx context.Context, objType models.ObjectType, options ...bitwarden.ListObjectsOption) ([]models.Object, error)
LoginWithAPIKey(ctx context.Context, password, clientId, clientSecret string) error
LoginWithPassword(ctx context.Context, username, password string) error
Logout(context.Context) error
DeleteAttachment(ctx context.Context, itemId, attachmentId string) error
DeleteObject(context.Context, Object) error
DeleteObject(context.Context, models.Object) error
SetServer(context.Context, string) error
SetSessionKey(string)
Status(context.Context) (*Status, error)
Sync(context.Context) error
Unlock(ctx context.Context, password string) error
}

func NewClient(execPath string, opts ...Options) Client {
func NewClient(execPath string, opts ...Options) CLIClient {
c := &client{
execPath: execPath,
}
Expand All @@ -55,33 +57,34 @@ type client struct {
sessionKey string
}

type Options func(c Client)
type Options func(c bitwarden.Client)

func WithAppDataDir(appDataDir string) Options {
return func(c Client) {
return func(c bitwarden.Client) {
c.(*client).appDataDir = appDataDir
}
}

func WithExtraCACertsPath(extraCACertsPath string) Options {
return func(c Client) {
return func(c bitwarden.Client) {
c.(*client).extraCACertsPath = extraCACertsPath
}
}

func DisableSync() Options {
return func(c Client) {
return func(c bitwarden.Client) {
c.(*client).disableSync = true
}
}

func DisableRetryBackoff() Options {
return func(c Client) {
return func(c bitwarden.Client) {
c.(*client).disableRetryBackoff = true
}
}

func (c *client) CreateObject(ctx context.Context, obj Object) (*Object, error) {
func (c *client) CreateObject(ctx context.Context, obj models.Object) (*models.Object, error) {
obj.Groups = []interface{}{}
objEncoded, err := c.encode(obj)
if err != nil {
return nil, err
Expand All @@ -93,7 +96,7 @@ func (c *client) CreateObject(ctx context.Context, obj Object) (*Object, error)
objEncoded,
}

if obj.Object == ObjectTypeOrgCollection {
if obj.Object == models.ObjectTypeOrgCollection {
args = append(args, "--organizationid", obj.OrganizationID)
}

Expand All @@ -111,13 +114,13 @@ func (c *client) CreateObject(ctx context.Context, obj Object) (*Object, error)
return &obj, nil
}

func (c *client) CreateAttachment(ctx context.Context, itemId string, filePath string) (*Object, error) {
out, err := c.cmdWithSession("create", string(ObjectTypeAttachment), "--itemid", itemId, "--file", filePath).Run(ctx)
func (c *client) CreateAttachment(ctx context.Context, itemId string, filePath string) (*models.Object, error) {
out, err := c.cmdWithSession("create", string(models.ObjectTypeAttachment), "--itemid", itemId, "--file", filePath).Run(ctx)
if err != nil {
return nil, err
}

var obj Object
var obj models.Object
err = json.Unmarshal(out, &obj)
if err != nil {
return nil, err
Expand All @@ -128,7 +131,7 @@ func (c *client) CreateAttachment(ctx context.Context, itemId string, filePath s
return &obj, nil
}

func (c *client) EditObject(ctx context.Context, obj Object) (*Object, error) {
func (c *client) EditObject(ctx context.Context, obj models.Object) (*models.Object, error) {
objEncoded, err := c.encode(obj)
if err != nil {
return nil, err
Expand Down Expand Up @@ -157,14 +160,14 @@ func (c *client) EditObject(ctx context.Context, obj Object) (*Object, error) {
return &obj, nil
}

func (c *client) GetObject(ctx context.Context, obj Object) (*Object, error) {
func (c *client) GetObject(ctx context.Context, obj models.Object) (*models.Object, error) {
args := []string{
"get",
string(obj.Object),
obj.ID,
}

if obj.Object == ObjectTypeOrgCollection {
if obj.Object == models.ObjectTypeOrgCollection {
args = append(args, "--organizationid", obj.OrganizationID)
}

Expand All @@ -182,7 +185,7 @@ func (c *client) GetObject(ctx context.Context, obj Object) (*Object, error) {
}

func (c *client) GetAttachment(ctx context.Context, itemId, attachmentId string) ([]byte, error) {
out, err := c.cmdWithSession("get", string(ObjectTypeAttachment), attachmentId, "--itemid", itemId, "--raw").Run(ctx)
out, err := c.cmdWithSession("get", string(models.ObjectTypeAttachment), attachmentId, "--itemid", itemId, "--raw").Run(ctx)
if err != nil {
return nil, remapError(err)
}
Expand All @@ -195,22 +198,20 @@ func (c *client) GetSessionKey() string {
}

// ListObjects returns objects of a given type matching given filters.
func (c *client) ListObjects(ctx context.Context, objType string, options ...ListObjectsOption) ([]Object, error) {
func (c *client) ListObjects(ctx context.Context, objType models.ObjectType, options ...bitwarden.ListObjectsOption) ([]models.Object, error) {
args := []string{
"list",
objType,
fmt.Sprintf("%ss", objType),
}

for _, applyOption := range options {
applyOption(&args)
}
applyFiltersToArgs(&args, options...)

out, err := c.cmdWithSession(args...).Run(ctx)
if err != nil {
return nil, remapError(err)
}

var obj []Object
var obj []models.Object
err = json.Unmarshal(out, &obj)
if err != nil {
return nil, newUnmarshallError(err, args[0:2], out)
Expand Down Expand Up @@ -245,14 +246,14 @@ func (c *client) Logout(ctx context.Context) error {
return err
}

func (c *client) DeleteObject(ctx context.Context, obj Object) error {
func (c *client) DeleteObject(ctx context.Context, obj models.Object) error {
args := []string{
"delete",
string(obj.Object),
obj.ID,
}

if obj.Object == ObjectTypeOrgCollection {
if obj.Object == models.ObjectTypeOrgCollection {
args = append(args, "--organizationid", obj.OrganizationID)
}

Expand All @@ -261,7 +262,7 @@ func (c *client) DeleteObject(ctx context.Context, obj Object) error {
}

func (c *client) DeleteAttachment(ctx context.Context, itemId, attachmentId string) error {
_, err := c.cmdWithSession("delete", string(ObjectTypeAttachment), attachmentId, "--itemid", itemId).Run(ctx)
_, err := c.cmdWithSession("delete", string(models.ObjectTypeAttachment), attachmentId, "--itemid", itemId).Run(ctx)
return err
}

Expand Down Expand Up @@ -331,10 +332,29 @@ func (c *client) env() []string {
return defaultEnv
}

func (c *client) encode(item Object) (string, error) {
func (c *client) encode(item models.Object) (string, error) {
newOut, err := json.Marshal(item)
if err != nil {
return "", fmt.Errorf("marshalling error: %v, %v", err, string(newOut))
}
return base64.RawStdEncoding.EncodeToString(newOut), nil
}

func applyFiltersToArgs(args *[]string, options ...bitwarden.ListObjectsOption) {
filters := bitwarden.ListObjectsOptionsToFilterOptions(options...)
if filters.OrganizationFilter != "" {
*args = append(*args, "--organizationid", filters.OrganizationFilter)
}
if filters.FolderFilter != "" {
*args = append(*args, "--folderid", filters.FolderFilter)
}
if filters.CollectionFilter != "" {
*args = append(*args, "--collectionid", filters.CollectionFilter)
}
if filters.SearchFilter != "" {
*args = append(*args, "--search", filters.SearchFilter)
}
if filters.UrlFilter != "" {
*args = append(*args, "--url", filters.UrlFilter)
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
package bw
package bwcli

import (
"context"
"testing"

"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden"
"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden/models"
test_command "github.com/maxlaverse/terraform-provider-bitwarden/internal/command/test"
"github.com/stretchr/testify/assert"
)

func TestCreateObjectEncoding(t *testing.T) {
removeMocks, commandsExecuted := test_command.MockCommands(t, map[string]string{
"create item eyJncm91cHMiOm51bGwsImxvZ2luIjp7fSwib2JqZWN0IjoiaXRlbSIsInNlY3VyZU5vdGUiOnt9LCJ0eXBlIjoxLCJmaWVsZHMiOlt7Im5hbWUiOiJ0ZXN0IiwidmFsdWUiOiJwYXNzZWQiLCJ0eXBlIjowLCJsaW5rZWRJZCI6bnVsbH1dfQ": `{}`,
"create item eyJncm91cHMiOltdLCJsb2dpbiI6e30sIm9iamVjdCI6Iml0ZW0iLCJzZWN1cmVOb3RlIjp7fSwidHlwZSI6MSwiZmllbGRzIjpbeyJuYW1lIjoidGVzdCIsInZhbHVlIjoicGFzc2VkIiwidHlwZSI6MCwibGlua2VkSWQiOm51bGx9XX0": `{}`,
})
defer removeMocks(t)

b := NewClient("dummy")
_, err := b.CreateObject(context.Background(), Object{
Type: ItemTypeLogin,
Object: ObjectTypeItem,
Fields: []Field{
_, err := b.CreateObject(context.Background(), models.Object{
Type: models.ItemTypeLogin,
Object: models.ObjectTypeItem,
Fields: []models.Field{
{
Name: "test",
Value: "passed",
Expand All @@ -29,22 +31,22 @@ func TestCreateObjectEncoding(t *testing.T) {

assert.NoError(t, err)
if assert.Len(t, commandsExecuted(), 1) {
assert.Equal(t, "create item eyJncm91cHMiOm51bGwsImxvZ2luIjp7fSwib2JqZWN0IjoiaXRlbSIsInNlY3VyZU5vdGUiOnt9LCJ0eXBlIjoxLCJmaWVsZHMiOlt7Im5hbWUiOiJ0ZXN0IiwidmFsdWUiOiJwYXNzZWQiLCJ0eXBlIjowLCJsaW5rZWRJZCI6bnVsbH1dfQ", commandsExecuted()[0])
assert.Equal(t, "create item eyJncm91cHMiOltdLCJsb2dpbiI6e30sIm9iamVjdCI6Iml0ZW0iLCJzZWN1cmVOb3RlIjp7fSwidHlwZSI6MSwiZmllbGRzIjpbeyJuYW1lIjoidGVzdCIsInZhbHVlIjoicGFzc2VkIiwidHlwZSI6MCwibGlua2VkSWQiOm51bGx9XX0", commandsExecuted()[0])
}
}

func TestListObjects(t *testing.T) {
removeMocks, commandsExecuted := test_command.MockCommands(t, map[string]string{
"list item --folderid folder-id --collectionid collection-id --search search": `[]`,
"list items --folderid folder-id --collectionid collection-id --search search": `[]`,
})
defer removeMocks(t)

b := NewClient("dummy")
_, err := b.ListObjects(context.Background(), "item", WithFolderID("folder-id"), WithCollectionID("collection-id"), WithSearch("search"))
_, err := b.ListObjects(context.Background(), models.ObjectTypeItem, bitwarden.WithFolderID("folder-id"), bitwarden.WithCollectionID("collection-id"), bitwarden.WithSearch("search"))

assert.NoError(t, err)
if assert.Len(t, commandsExecuted(), 1) {
assert.Equal(t, "list item --folderid folder-id --collectionid collection-id --search search", commandsExecuted()[0])
assert.Equal(t, "list items --folderid folder-id --collectionid collection-id --search search", commandsExecuted()[0])
}
}

Expand All @@ -55,7 +57,7 @@ func TestGetItem(t *testing.T) {
defer removeMocks(t)

b := NewClient("dummy")
_, err := b.GetObject(context.Background(), Object{ID: "object-id", Object: ObjectTypeItem, Type: ItemTypeLogin})
_, err := b.GetObject(context.Background(), models.Object{ID: "object-id", Object: models.ObjectTypeItem, Type: models.ItemTypeLogin})

assert.NoError(t, err)
if assert.Len(t, commandsExecuted(), 1) {
Expand All @@ -70,7 +72,7 @@ func TestGetOrgCollection(t *testing.T) {
defer removeMocks(t)

b := NewClient("dummy")
_, err := b.GetObject(context.Background(), Object{ID: "object-id", Object: ObjectTypeOrgCollection, OrganizationID: "org-id"})
_, err := b.GetObject(context.Background(), models.Object{ID: "object-id", Object: models.ObjectTypeOrgCollection, OrganizationID: "org-id"})

assert.NoError(t, err)
if assert.Len(t, commandsExecuted(), 1) {
Expand All @@ -80,14 +82,14 @@ func TestGetOrgCollection(t *testing.T) {

func TestErrorContainsCommand(t *testing.T) {
removeMocks, _ := test_command.MockCommands(t, map[string]string{
"list org-collection --search search": ``,
"list org-collections --search search": ``,
})
defer removeMocks(t)

b := NewClient("dummy")
_, err := b.ListObjects(context.Background(), "org-collection", WithSearch("search"))
_, err := b.ListObjects(context.Background(), models.ObjectTypeOrgCollection, bitwarden.WithSearch("search"))

if assert.Error(t, err) {
assert.ErrorContains(t, err, "unable to parse result of 'list org-collection', error: 'unexpected end of JSON input', output: ''")
assert.ErrorContains(t, err, "unable to parse result of 'list org-collections', error: 'unexpected end of JSON input', output: ''")
}
}
Loading
Loading