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 support for document data source #161

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 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
13 changes: 13 additions & 0 deletions onepassword/cli/op.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,19 @@ func (op *OP) GetItemByTitle(ctx context.Context, title string, vaultUuid string
return op.GetItem(ctx, title, vaultUuid)
}

func (op *OP) GetFileContent(ctx context.Context, file *onepassword.File, itemUuid, vaultUuid string) ([]byte, error) {
versionErr := op.checkCliVersion(ctx)
if versionErr != nil {
return nil, versionErr
}
ref := fmt.Sprintf("op://%s/%s/%s", vaultUuid, itemUuid, file.ID)
res, err := op.execRaw(ctx, nil, p("read"), p(ref))
if err != nil {
return nil, err
}
return res, nil
}

func (op *OP) CreateItem(ctx context.Context, item *onepassword.Item, vaultUuid string) (*onepassword.Item, error) {
versionErr := op.checkCliVersion(ctx)
if versionErr != nil {
Expand Down
4 changes: 4 additions & 0 deletions onepassword/connectctx/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ func (w *Wrapper) DeleteItem(_ context.Context, item *onepassword.Item, vaultUui
return w.client.DeleteItem(item, vaultUuid)
}

func (w *Wrapper) GetFileContent(_ context.Context, file *onepassword.File, itemUUID, vaultUUID string) ([]byte, error) {
return w.client.GetFileContent(file)
}

func Wrap(client connect.Client) *Wrapper {
return &Wrapper{client: client}
}
50 changes: 50 additions & 0 deletions onepassword/data_source_onepassword_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package onepassword

import (
"context"
"encoding/base64"
"errors"
"fmt"
"strings"
Expand Down Expand Up @@ -154,6 +155,39 @@ func dataSourceOnepasswordItem() *schema.Resource {
},
},
},
"file": {
Description: sectionFilesDescription,
Type: schema.TypeList,
Computed: true,
MinItems: 0,
Elem: &schema.Resource{
Description: fileDescription,
Schema: map[string]*schema.Schema{
"id": {
Description: fileIDDescription,
Type: schema.TypeString,
Computed: true,
},
"name": {
Description: fileNameDescription,
Type: schema.TypeString,
Computed: true,
},
"content": {
Description: fileContentDescription,
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
"content_base64": {
Description: fileContentBase64Description,
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
},
},
},
},
}
}
Expand All @@ -177,6 +211,22 @@ func dataSourceOnepasswordItemRead(ctx context.Context, data *schema.ResourceDat
}
}

dataFiles := []interface{}{}
sdahlbac marked this conversation as resolved.
Show resolved Hide resolved
for _, f := range item.Files {
file := map[string]interface{}{}
file["name"] = f.Name
file["id"] = f.ID
data, err := client.GetFileContent(ctx, f, item.ID, item.Vault.ID)
if err != nil {
return diag.FromErr(err)
}
file["content"] = string(data)
file["content_base64"] = base64.StdEncoding.EncodeToString(data)

dataFiles = append(dataFiles, file)
}
data.Set("file", dataFiles)

data.Set("tags", item.Tags)
data.Set("category", strings.ToLower(string(item.Category)))

Expand Down
47 changes: 47 additions & 0 deletions onepassword/data_source_onepassword_item_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,34 @@ func TestDataSourceOnePasswordItemRead(t *testing.T) {
compareItemToSource(t, dataSourceData, expectedItem)
}

func TestDataSourceOnePasswordItemDocumentRead(t *testing.T) {
expectedItem := generateItem()
expectedItem.Category = "DOCUMENT"
expectedItem.Files = []*onepassword.File{
{
Name: "test_file",
},
}
expectedItem.Files[0].SetContent([]byte("test_content"))
meta := &testClient{
GetItemFunc: func(uuid string, vaultUUID string) (*onepassword.Item, error) {
return expectedItem, nil
},
GetFileFunc: func(file *onepassword.File, itemUUID, vaultUUID string) ([]byte, error) {
return []byte("test_content"), nil
},
}

dataSourceData := generateDataSource(t, expectedItem)
dataSourceData.Set("uuid", expectedItem.ID)

err := dataSourceOnepasswordItemRead(context.Background(), dataSourceData, meta)
if err != nil {
t.Errorf("Unexpected error occured")
}
compareItemToSource(t, dataSourceData, expectedItem)
}

func TestDataSourceOnePasswordItemReadByTitle(t *testing.T) {
expectedItem := generateItem()
meta := &testClient{
Expand Down Expand Up @@ -126,6 +154,25 @@ func compareItemToSource(t *testing.T, dataSourceData *schema.ResourceData, item
t.Errorf("Expected field %v to be %v got %v", f.Label, f.Value, dataSourceData.Get(path))
}
}
if files := dataSourceData.Get("file"); files != nil && len(item.Files) != len(files.([]interface{})) {
got := len(files.([]interface{}))
t.Errorf("Expected %v files got %v", len(item.Files), got)
}
for i, file := range item.Files {
if dataSourceData.Get(fmt.Sprintf("file.%s", file.Name)) == nil {
t.Errorf("Expected file %v to be present", file.Name)
}
want, err := file.Content()
if err != nil {
t.Errorf("Unexpected error occured")
}
if dataSourceData.Get(fmt.Sprintf("file.%d.content", i)).(string) != string(want) {
t.Errorf("Expected file %v to have content %v, got %v", file.Name, string(want), dataSourceData.Get(fmt.Sprintf("file.%d.content", i)))
}
}
if len(item.Files) == 2 {
t.Errorf("dafuq")
}
sdahlbac marked this conversation as resolved.
Show resolved Hide resolved
}

func generateDataSource(t *testing.T, item *onepassword.Item) *schema.ResourceData {
Expand Down
5 changes: 5 additions & 0 deletions onepassword/mock_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type testClient struct {
CreateItemFunc func(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
UpdateItemFunc func(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error)
DeleteItemFunc func(item *onepassword.Item, vaultUUID string) error
GetFileFunc func(file *onepassword.File, itemUUID, vaultUUID string) ([]byte, error)
}

var _ Client = (*testClient)(nil)
Expand Down Expand Up @@ -45,3 +46,7 @@ func (m *testClient) DeleteItem(_ context.Context, item *onepassword.Item, vault
func (m *testClient) UpdateItem(_ context.Context, item *onepassword.Item, vaultUUID string) (*onepassword.Item, error) {
return m.UpdateItemFunc(item, vaultUUID)
}

func (m *testClient) GetFileContent(_ context.Context, file *onepassword.File, itemUUID, vaultUUID string) ([]byte, error) {
return m.GetFileFunc(file, itemUUID, vaultUUID)
}
1 change: 1 addition & 0 deletions onepassword/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,5 @@ type Client interface {
CreateItem(ctx context.Context, item *onepassword.Item, vaultUuid string) (*onepassword.Item, error)
UpdateItem(ctx context.Context, item *onepassword.Item, vaultUuid string) (*onepassword.Item, error)
DeleteItem(ctx context.Context, item *onepassword.Item, vaultUuid string) error
GetFileContent(ctx context.Context, file *onepassword.File, itemUUid, vaultUuid string) ([]byte, error)
}
10 changes: 9 additions & 1 deletion onepassword/resource_onepassword_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,21 @@ const (
sectionLabelDescription = "The label for the section."
sectionFieldsDescription = "A list of custom fields in the section."

sectionFilesDescription = "A list of files in an item."
sdahlbac marked this conversation as resolved.
Show resolved Hide resolved

fieldDescription = "A custom field."
fieldIDDescription = "A unique identifier for the field."
fieldLabelDescription = "The label for the field."
fieldPurposeDescription = "Purpose indicates this is a special field: a username, password, or notes field."
fieldTypeDescription = "The type of value stored in the field."
fieldValueDescription = "The value of the field."

fileDescription = "A file attached to the item."
fileIDDescription = "A UUID for the file."
fileNameDescription = "The name of the file."
fileContentDescription = "The content of the file."
fileContentBase64Description = "The content of the file in base64 encoding. (Use this for binary files.)"

passwordRecipeDescription = "The recipe used to generate a new value for a password."
passwordElementDescription = "The kinds of characters to include in the password."
passwordLengthDescription = "The length of the password to be generated."
Expand All @@ -55,7 +63,7 @@ const (
enumDescription = "%s One of %q"
)

var categories = []string{"login", "password", "database"}
var categories = []string{"login", "password", "database", "document"}
var dbTypes = []string{"db2", "filemaker", "msaccess", "mssql", "mysql", "oracle", "postgresql", "sqlite", "other"}
var fieldPurposes = []string{"USERNAME", "PASSWORD", "NOTES"}
var fieldTypes = []string{"STRING", "EMAIL", "CONCEALED", "URL", "OTP", "DATE", "MONTH_YEAR", "MENU"}
Expand Down