Skip to content

Commit

Permalink
Merge f6bb326 into 11ca5dc
Browse files Browse the repository at this point in the history
  • Loading branch information
carrala committed May 7, 2021
2 parents 11ca5dc + f6bb326 commit a0b1804
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 15 deletions.
79 changes: 69 additions & 10 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import (
const (
DefaultStorageURL = "https://api.e3db.com"
DefaultEncryptedFileName = "encrypted"
DefaultDownloadedFileName = "downloaded"
SecretUUID = "38bb737a-4ce0-5ead-8585-e13ea23b09a6"
SecretWriterUsernameMetadataKey = "username"
SecretSharedMetadataKey = "shared"
Expand Down Expand Up @@ -1446,7 +1447,12 @@ func (c *ToznySDKV3) CreateSecret(ctx context.Context, secret CreateSecretOption
}
var createdRecord *pdsClient.Record
if secret.SecretType == "File" {
createdRecord, err = c.WriteFile(ctx, recordType, plain, secret.FileName)
writeFileRequest := WriteFileOptions{
RecordType: recordType,
Plain: plain,
FileName: secret.FileName,
}
createdRecord, err = c.WriteFile(ctx, writeFileRequest)
if err != nil {
return nil, err
}
Expand All @@ -1465,43 +1471,49 @@ func (c *ToznySDKV3) CreateSecret(ctx context.Context, secret CreateSecretOption
return createdSecret, nil
}

type WriteFileOptions struct {
RecordType string
Plain map[string]string
FileName string
}

// WriteFile encrypts the file with specified fileName and uploads it, creating a new record in E3DB
func (c *ToznySDKV3) WriteFile(ctx context.Context, recordType string, plain map[string]string, fileName string) (*pdsClient.Record, error) {
func (c *ToznySDKV3) WriteFile(ctx context.Context, options WriteFileOptions) (*pdsClient.Record, error) {
keyRequest := pdsClient.GetOrCreateAccessKeyRequest{
WriterID: c.E3dbPDSClient.ClientID,
UserID: c.E3dbPDSClient.ClientID,
ReaderID: c.E3dbPDSClient.ClientID,
RecordType: recordType,
RecordType: options.RecordType,
}
ak, err := c.E3dbPDSClient.GetOrCreateAccessKey(ctx, keyRequest)
if err != nil {
return nil, err
}
// Encrypt the file
size, checksum, err := e3dbClients.EncryptFile(fileName, DefaultEncryptedFileName, ak)
size, checksum, err := e3dbClients.EncryptFile(options.FileName, DefaultEncryptedFileName, ak)
if err != nil {
return nil, err
}
defer func() {
err := os.Remove(DefaultEncryptedFileName)
if err != nil {
fmt.Println("CreateSecret: error deleting encrypted file")
fmt.Printf("CreatedSecret: Could not delete %s: %+v", DefaultEncryptedFileName, err)
}
}()
plain[SecretFilenameMetadataKey] = fileName
options.Plain[SecretFilenameMetadataKey] = options.FileName
sizeKB := size / 1024
if sizeKB >= 1 {
plain[SecretFileSizeMetadataKey] = fmt.Sprintf("%d", sizeKB)
options.Plain[SecretFileSizeMetadataKey] = fmt.Sprintf("%d", sizeKB)
} else {
plain[SecretFileSizeMetadataKey] = "< 1"
options.Plain[SecretFileSizeMetadataKey] = "< 1"
}
// Write the whole file
recordToWrite := storageClient.Record{
Metadata: storageClient.Meta{
Type: recordType,
Type: options.RecordType,
WriterID: uuid.MustParse(c.StorageClient.ClientID),
UserID: uuid.MustParse(c.StorageClient.ClientID),
Plain: plain,
Plain: options.Plain,
FileMeta: &storageClient.FileMeta{
Size: int64(size),
Checksum: checksum,
Expand Down Expand Up @@ -1547,6 +1559,53 @@ func (c *ToznySDKV3) WriteFile(ctx context.Context, recordType string, plain map
return fileRecord, nil
}

type ReadFileOptions struct {
RecordID string
DownloadFileName string
}

// ReadFile downloads and decrypts the file from the record
func (c *ToznySDKV3) ReadFile(ctx context.Context, options ReadFileOptions) error {
secretUUID, err := uuid.Parse(options.RecordID)
if err != nil {
return err
}
fileResp, err := c.E3dbPDSClient.GetFileRecord(ctx, secretUUID)
if err != nil {
return err
}
fileURL := fileResp.Metadata.FileMeta.FileURL
downloadRequest := file.DownloadRequest{
URL: fileURL,
EncryptedFileName: DefaultDownloadedFileName,
}
downloadResponse, err := file.DownloadFile(downloadRequest)
if err != nil || downloadResponse != "" {
return fmt.Errorf("ReadFile: Err: %+v Resp: %+v", err, downloadResponse)
}
defer func() {
err := os.Remove(DefaultDownloadedFileName)
if err != nil {
fmt.Printf("ReadFile: Could not delete %s: %+v", DefaultDownloadedFileName, err)
}
}()
keyRequest := pdsClient.GetOrCreateAccessKeyRequest{
WriterID: c.E3dbPDSClient.ClientID,
UserID: c.E3dbPDSClient.ClientID,
ReaderID: c.E3dbPDSClient.ClientID,
RecordType: fileResp.Metadata.Type,
}
ak, err := c.E3dbPDSClient.GetOrCreateAccessKey(ctx, keyRequest)
if err != nil {
return err
}
err = e3dbClients.DecryptFile(DefaultDownloadedFileName, options.DownloadFileName, ak)
if err != nil {
return err
}
return nil
}

// WriteRecord encrypts the data for the record and creates a new record in E3DB
func (c *ToznySDKV3) WriteRecord(ctx context.Context, data map[string]string, recordType string, plain map[string]string) (*pdsClient.Record, error) {
recordToWrite := pdsClient.WriteRecordRequest{
Expand Down
39 changes: 34 additions & 5 deletions secrets_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package e3db

import (
"bytes"
"context"
"fmt"
"io/ioutil"
"os"
"testing"

Expand All @@ -17,6 +19,7 @@ var (
baseURL = os.Getenv("TEST_IDENTITY_API_URL")
testCtx = context.Background()
plaintextFileName = "plainfile"
decryptedFileName = "decrypted"
)

func TestCreateAndListSecrets(t *testing.T) {
Expand Down Expand Up @@ -172,18 +175,18 @@ func TestCreateAndViewSecretSucceeds(t *testing.T) {
t.Fatalf("Could not create secret: Req: %+v Err: %+v", secretReq, err)
}
viewOptions := ViewSecretOptions{
SecretID: secretCreated.Record.Metadata.RecordID,
SecretID: secretCreated.SecretID,
}
secretView, err := sdk.ViewSecret(testCtx, viewOptions)
if err != nil {
t.Fatalf("Could not view secret: Err: %+v", err)
}
if secretReq.SecretValue != secretView.Record.Data["secretValue"] {
if secretReq.SecretValue != secretView.SecretValue {
t.Fatalf("SecretValue doesn't match. Created: %s Viewed: %s", secretCreated.Record.Data["secretValue"], secretView.Record.Data["secretValue"])
}
}

func TestCreateAndViewFileSecretSucceeds(t *testing.T) {
func TestCreateAndReadFileSecretSucceeds(t *testing.T) {
request := TozIDLoginRequest{
Username: username,
Password: password,
Expand Down Expand Up @@ -213,15 +216,41 @@ func TestCreateAndViewFileSecretSucceeds(t *testing.T) {
secretReq := CreateSecretOptions{
SecretName: fmt.Sprintf("client-%s", uuid.New().String()),
SecretType: "File",
SecretValue: "",
Description: "a file test",
FileName: plaintextFileName,
RealmName: realmName,
}
_, err = sdk.CreateSecret(testCtx, secretReq)
createdSecret, err := sdk.CreateSecret(testCtx, secretReq)
if err != nil {
t.Fatalf("Could not create secret: Req: %+v Err: %+v", secretReq, err)
}
readFileOptions := ReadFileOptions{
RecordID: createdSecret.SecretID,
DownloadFileName: decryptedFileName,
}
err = sdk.ReadFile(testCtx, readFileOptions)
if err != nil {
t.Fatalf("Could not read file: Err: %+v", err)
}
defer func() {
err := os.Remove(decryptedFileName)
if err != nil {
t.Logf("Could not delete %s: %+v", decryptedFileName, err)
}
}()
// Compare plaintext and decrypted file contents
plaintext, err := ioutil.ReadFile(plaintextFileName)
if err != nil {
t.Fatalf("Could not read %s file: %+v", plaintextFileName, err)
}
decrypted, err := ioutil.ReadFile(decryptedFileName)
if err != nil {
t.Fatalf("Could not read %s file: %+v", decryptedFileName, err)
}
compare := bytes.Equal(plaintext, decrypted)
if !compare {
t.Fatalf("%s and %s files do not match", plaintextFileName, decryptedFileName)
}
}

func mfaHandler(sessionResponse *IdentitySessionIntermediateResponse) (LoginActionData, error) {
Expand Down

0 comments on commit a0b1804

Please sign in to comment.