Skip to content

Commit

Permalink
Improve api (#21)
Browse files Browse the repository at this point in the history
* improve most commands

* fixes for move

* utilize tre's err not nil

* found another occurance

* changed log
  • Loading branch information
Joey Roosing authored Jun 25, 2020
1 parent 048907d commit 4e6d3bd
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 76 deletions.
7 changes: 1 addition & 6 deletions cmd/kiya/cmd_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ import (
"log"

cloudstore "cloud.google.com/go/storage"
"github.com/emicklei/tre"
"google.golang.org/api/cloudkms/v1"

"github.com/kramphub/kiya"
)

// commandDelete deletes a stored key
func commandDelete(kmsService *cloudkms.Service, storageService *cloudstore.Client, target kiya.Profile, key string) {
_, err := kiya.GetValueByKey(kmsService, storageService, key, target)
if err != nil {
log.Fatal(tre.New(err, "delete failed", "key", key, "err", err))
}
if promptForYes(fmt.Sprintf("Are you sure to delete [%s] from [%s] (y/N)? ", key, target.Label)) {
if err := kiya.DeleteSecret(storageService, target, key); err != nil {
if err := kiya.DeleteSecret(kmsService, storageService, target, key); err != nil {
fmt.Printf("failed to delete [%s] from [%s] because [%v]\n", key, target.Label, err)
} else {
fmt.Printf("Successfully deleted [%s] from [%s]\n", key, target.Label)
Expand Down
26 changes: 9 additions & 17 deletions cmd/kiya/cmd_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,29 @@ import (
"time"

cloudstore "cloud.google.com/go/storage"
"github.com/emicklei/tre"
"github.com/olekukonko/tablewriter"
"golang.org/x/net/context"
"google.golang.org/api/iterator"

"github.com/kramphub/kiya"
)

// commandList lists keys in a specific profile
func commandList(storageService *cloudstore.Client, target kiya.Profile, filter string) {
ctx := context.Background()
bucket := storageService.Bucket(target.Bucket)
query := &cloudstore.Query{}
it := bucket.Objects(ctx, query)
data := [][]string{}
keys, err := kiya.List(storageService, target)
if err != nil {
log.Fatal(err)
}

var data [][]string
filteredCount := 0

for {
next, err := it.Next()
if err == iterator.Done {
break
} else if err != nil {
log.Fatal(tre.New(err, "list failed"))
}
for _, k := range keys {
if len(filter) > 0 {
if !caseInsensitiveContains(next.Name, filter) {
if !caseInsensitiveContains(k.Name, filter) {
filteredCount++
continue
}
}
data = append(data, []string{fmt.Sprintf("kiya %s copy %s", target.Label, next.Name), next.Created.Format(time.RFC822), next.Owner})
data = append(data, []string{fmt.Sprintf("kiya %s copy %s", target.Label, k.Name), k.CreatedAt.Format(time.RFC822), k.Owner})
}

if len(filter) > 0 {
Expand Down
17 changes: 7 additions & 10 deletions cmd/kiya/cmd_move.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"log"

cloudstore "cloud.google.com/go/storage"
"github.com/emicklei/tre"
"google.golang.org/api/cloudkms/v1"

"github.com/kramphub/kiya"
Expand All @@ -20,14 +19,12 @@ func commandMove(
target kiya.Profile,
targetKey string) {

// fetch value for key from source
sourceValue, err := kiya.GetValueByKey(kmsService, storageService, sourceKey, source)
if err != nil {
log.Fatal(tre.New(err, "get source key failed", "key", sourceKey))
if promptForYes(fmt.Sprintf("Are you sure you want to move [%s] from [%s] (y/N)", sourceKey, target.Label)) {
if err := kiya.Move(kmsService, storageService, source, sourceKey, target, targetKey); err != nil {
log.Fatal(err)
}
fmt.Printf("Successfully moved [%s] to [%s]\n", sourceKey, target.Label)
} else {
log.Fatalln("delete aborted")
}
// store value for key to target
commandPutPasteGenerate(kmsService, storageService, target, "put", targetKey, sourceValue, true)
fmt.Printf("Successfully copied [%s] to [%s]\n", sourceKey, target.Label)
// delete key from source
commandDelete(kmsService, storageService, source, sourceKey)
}
14 changes: 4 additions & 10 deletions cmd/kiya/cmd_put_paste_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"log"

cloudstore "cloud.google.com/go/storage"
"github.com/emicklei/tre"
"google.golang.org/api/cloudkms/v1"

"github.com/kramphub/kiya"
Expand All @@ -14,19 +13,14 @@ import (
// commandPutPasteGenerate ...
func commandPutPasteGenerate(kmsService *cloudkms.Service, storageService *cloudstore.Client,
target kiya.Profile, command, key, value string, mustPrompt bool) {
// check for exists
_, err := kiya.LoadSecret(storageService, target, key)
if err == nil {

if kiya.CheckSecretExists(storageService, target, key) {
if mustPrompt && !promptForYes(fmt.Sprintf("Are you sure to overwrite [%s] from [%s] (y/N)? ", key, target.Label)) {
log.Fatalln(command + " aborted")
return
}
}
encryptedValue, err := kiya.GetEncryptedValue(kmsService, target, value)
if err != nil {
log.Fatal(tre.New(err, command+" failed", "key", key))
}
if err := kiya.StoreSecret(storageService, target, key, encryptedValue); err != nil {
log.Fatal(tre.New(err, command+" failed", "key", key, "encryptedValue", encryptedValue))
if err := kiya.PutSecret(kmsService, storageService, target, key, value); err != nil {
log.Fatal(err)
}
}
12 changes: 0 additions & 12 deletions gcp_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,6 @@ func StoreSecret(storageService *cloudstore.Client, target Profile, key, encrypt
return tre.New(err, "writing encrypted value failed", "encryptedValue", encryptedValue)
}

// DeleteSecret removes a key from the bucket
func DeleteSecret(storageService *cloudstore.Client, target Profile, key string) error {
bucket := storageService.Bucket(target.Bucket)
if _, err := bucket.Attrs(context.Background()); err != nil {
tre.New(err, "bucket does not exist", "bucket", target.Bucket)
}
if err := bucket.Object(key).Delete(context.Background()); err != nil {
return tre.New(err, "failed to delete secret", "key", key)
}
return nil
}

// LoadSecret gets a secret from the bucket
func LoadSecret(storageService *cloudstore.Client, target Profile, key string) (string, error) {
bucket := storageService.Bucket(target.Bucket)
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ require (
cloud.google.com/go v0.16.0
github.com/atotto/clipboard v0.0.0-20160219034421-bb272b845f11
github.com/emicklei/tre v0.0.0-20170203105728-6532a4213209
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
github.com/golang/protobuf v0.0.0-20171113180720-1e59b77b52bf // indirect
github.com/google/go-cmp v0.5.0 // indirect
github.com/googleapis/gax-go v2.0.0+incompatible // indirect
github.com/mattn/go-runewidth v0.0.2 // indirect
github.com/olekukonko/tablewriter v0.0.0-20170925234030-a7a4c189eb47
golang.org/x/net v0.0.0-20171115151908-9dfe39835686
golang.org/x/oauth2 v0.0.0-20171106152852-9ff8ebcc8e24
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a // indirect
golang.org/x/text v0.1.1-0.20171102192421-88f656faf3f3 // indirect
google.golang.org/api v0.0.0-20171110222743-a0c31fb0028e
google.golang.org/appengine v1.0.0 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ github.com/atotto/clipboard v0.0.0-20160219034421-bb272b845f11 h1:Gmm0NreNeu4FgE
github.com/atotto/clipboard v0.0.0-20160219034421-bb272b845f11/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/emicklei/tre v0.0.0-20170203105728-6532a4213209 h1:uVKDszIb7eKEiD5Rxa1xuDLJDmV8OI1rJ16+6mjRoJY=
github.com/emicklei/tre v0.0.0-20170203105728-6532a4213209/go.mod h1:QITyLYm0EScbfskFNk1wgRL1dVWz0M6f7ArRoU3OLTU=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/protobuf v0.0.0-20171113180720-1e59b77b52bf h1:pFr/u+m8QUBMW/itAczltF3guNRAL7XDs5tD3f6nSD0=
github.com/golang/protobuf v0.0.0-20171113180720-1e59b77b52bf/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o=
Expand All @@ -16,8 +20,12 @@ golang.org/x/net v0.0.0-20171115151908-9dfe39835686 h1:fxZ+mPcFhowcPZdlXrTF3GFhW
golang.org/x/net v0.0.0-20171115151908-9dfe39835686/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20171106152852-9ff8ebcc8e24 h1:nP0LlV1P7+z/qtbjHygz+Bba7QsbB4MqdhGJmAyicuI=
golang.org/x/oauth2 v0.0.0-20171106152852-9ff8ebcc8e24/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/text v0.1.1-0.20171102192421-88f656faf3f3 h1:OxMYHd6bm+jH+TI7NBCb/CaYk6pMJnBC8GIzIi68Hk4=
golang.org/x/text v0.1.1-0.20171102192421-88f656faf3f3/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20171110222743-a0c31fb0028e h1:JqsdgDldV2QUAQJSr6xQynaJxTec77/Ij9QLf+Degpg=
google.golang.org/api v0.0.0-20171110222743-a0c31fb0028e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/appengine v1.0.0 h1:dN4LljjBKVChsv0XCSI+zbyzdqrkEwX5LQFUMRSGqOc=
Expand Down
101 changes: 101 additions & 0 deletions kiya.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package kiya

import (
"context"
"time"

cloudstore "cloud.google.com/go/storage"
"github.com/emicklei/tre"
"google.golang.org/api/cloudkms/v1"
"google.golang.org/api/iterator"
)

type Key struct {
Name string
CreatedAt time.Time
Owner string
}

func List(storageService *cloudstore.Client, target Profile) ([]Key, error) {
ctx := context.Background()
bucket := storageService.Bucket(target.Bucket)
query := &cloudstore.Query{}
it := bucket.Objects(ctx, query)
var keys []Key

for {
next, err := it.Next()
if err == iterator.Done {
break
} else if err != nil {
return nil, tre.New(err, "list failed")
}
keys = append(keys, Key{
Name: next.Name,
CreatedAt: next.Created,
Owner: next.Owner,
})
}
return keys, nil
}

func Move(kmsService *cloudkms.Service,
storageService *cloudstore.Client,
source Profile,
sourceKey string,
target Profile,
targetKey string) error {

// fetch value for key from source
sourceValue, err := GetValueByKey(kmsService, storageService, sourceKey, source)
if err != nil {
return tre.New(err, "get source key failed", "key", sourceKey)
}

if err := PutSecret(kmsService, storageService, target, targetKey, sourceValue); err != nil {
return tre.New(err, "save key failed", targetKey)
}
// delete key from source
err = DeleteSecret(kmsService, storageService, source, sourceKey)
return tre.New(err, "could not delete key", targetKey)
}

func CheckSecretExists(storageService *cloudstore.Client, target Profile, key string) bool {
_, err := LoadSecret(storageService, target, key)
if err == nil {
return true
}
return false
}

// PutSecret encrypts the given value and stores it
func PutSecret(kmsService *cloudkms.Service,
storageService *cloudstore.Client,
target Profile,
key,
value string) error {

encryptedValue, err := GetEncryptedValue(kmsService, target, value)
if err != nil {
return tre.New(err, "failed to fetch encrypted value", "key", key)
}
err = StoreSecret(storageService, target, key, encryptedValue)
return tre.New(err, "store secret failed", "key", key, "encryptedValue", encryptedValue)
}

// DeleteSecret removes a key from the bucket
func DeleteSecret(kmsService *cloudkms.Service, storageService *cloudstore.Client, target Profile, key string) error {
_, err := GetValueByKey(kmsService, storageService, key, target)
if err != nil {
return tre.New(err, "delete failed", "key", key, "err", err)
}

bucket := storageService.Bucket(target.Bucket)
if _, err := bucket.Attrs(context.Background()); err != nil {
return tre.New(err, "bucket does not exist", "bucket", target.Bucket)
}
err = bucket.Object(key).Delete(context.Background())
return tre.New(err, "failed to delete secret", "key", key)
}


21 changes: 0 additions & 21 deletions utils.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package kiya

import (
"crypto/rand"
"log"
"math/big"

cloudstore "cloud.google.com/go/storage"
"github.com/emicklei/tre"
Expand All @@ -22,24 +20,5 @@ func GetValueByKey(kmsService *cloudkms.Service, storageService *cloudstore.Clie
log.Fatal(tre.New(err, "get failed", "cipherText", encryptedValue))
return "", err
}

return decryptedValue, nil
}

// Generate_secret generates a random key
func Generate_secret(length int, chars string) (string, error) {
if len(chars) == 0 {
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*()_+`-={}|[]\\:\"<>?,./"
}

randomString := make([]byte, length)
for i := 0; i < length; i++ {
n, err := rand.Int(rand.Reader, big.NewInt(int64(len(chars))))
if err != nil {
return "", err
}
randomString[i] = chars[n.Int64()]
}

return string(randomString), nil
}

0 comments on commit 4e6d3bd

Please sign in to comment.