Skip to content

Commit

Permalink
add client and wrap secrets handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
hooksie1 committed Jul 4, 2024
1 parent 1871d0d commit 69b0dc3
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 5 deletions.
29 changes: 28 additions & 1 deletion cmd/database.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package cmd

import (
"encoding/json"
"fmt"
"time"

"github.com/hooksie1/piggybank/service"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// databaseCmd represents the database command
var databaseCmd = &cobra.Command{
Use: "database",
Short: "Interact with the piggybank db, valid args are init, lock, unlock",
Expand All @@ -29,6 +30,7 @@ func database(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
key := viper.GetString("key")

switch args[0] {
case "init":
Expand All @@ -39,6 +41,31 @@ func database(cmd *cobra.Command, args []string) error {

fmt.Println(string(msg.Data))
return nil
case "unlock":
if key == "" {
return fmt.Errorf("database key required")
}

req := service.DatabaseKey{DBKey: key}

data, err := json.Marshal(req)
if err != nil {
return err
}
msg, err := nc.Request("piggybank.database.unlock", data, 1*time.Second)
if err != nil {
return err
}

fmt.Println(string(msg.Data))

case "lock":
msg, err := nc.Request("piggybank.database.lock", nil, 1*time.Second)
if err != nil {
return err
}

fmt.Println(string(msg.Data))
}

return nil
Expand Down
73 changes: 73 additions & 0 deletions cmd/secrets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package cmd

import (
"fmt"
"strings"
"time"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var secretsCmd = &cobra.Command{
Use: "secrets",
Short: "Interact with piggybank secrets",
RunE: secrets,
Args: cobra.MatchAll(cobra.MinimumNArgs(1), cobra.OnlyValidArgs),
ValidArgs: []string{"add", "get", "delete"},
SilenceUsage: true,
}

func init() {
clientCmd.AddCommand(secretsCmd)
secretsCmd.Flags().StringP("id", "i", "", "Secret ID")
viper.BindPFlag("id", secretsCmd.Flags().Lookup("id"))
secretsCmd.MarkFlagRequired("id")
secretsCmd.Flags().StringP("value", "v", "", "Secret value")
viper.BindPFlag("value", secretsCmd.Flags().Lookup("value"))
}

func getSubject(verb string, id string) string {
return fmt.Sprintf("piggybank.secrets.%s.%s", strings.ToUpper(verb), id)
}

func secrets(cmd *cobra.Command, args []string) error {
nc, err := newNatsConnection("piggy-client")
if err != nil {
return err
}
id := viper.GetString("id")

switch args[0] {
case "get":
subject := fmt.Sprintf("piggybank.secrets.GET.%s", id)
msg, err := nc.Request(subject, nil, 1*time.Second)
if err != nil {
return err
}

fmt.Println(string(msg.Data))
case "add":
val := viper.GetString("value")
if val == "" {
return fmt.Errorf("value flag is required to add a secret")
}
subject := fmt.Sprintf("piggybank.secrets.POST.%s", id)
msg, err := nc.Request(subject, []byte(val), 1*time.Second)
if err != nil {
return err
}

fmt.Println(string(msg.Data))
case "delete":
subject := fmt.Sprintf("piggybank.secrets.DELETE.%s", id)
msg, err := nc.Request(subject, nil, 1*time.Second)
if err != nil {
return err
}

fmt.Println(string(msg.Data))
}

return nil
}
18 changes: 14 additions & 4 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func start(cmd *cobra.Command, args []string) error {
//}

// uncomment to enable logging over NATS
//logger.SetOutput(cwnats.NewNatsLogger("prime.logs.piggybank", nc))
//logger.SetOutput(cwnats.NewNatsLogger("logs.piggybank", nc))

svc, err := micro.AddService(nc, config)
if err != nil {
Expand All @@ -77,6 +77,16 @@ func start(cmd *cobra.Command, args []string) error {
}),
micro.WithEndpointSubject("initialize"),
)
dbGroup.AddEndpoint("status",
service.AppHandler(logger, service.SecretHandler(service.Status), appCtx),
micro.WithEndpointMetadata(map[string]string{
"description": "returns the status of the database",
"format": "application/json",
"request_schema": "",
"response_schema": schemaString(&service.ResponseMessage{}),
}),
micro.WithEndpointSubject("status"),
)
dbGroup.AddEndpoint("lock",
service.AppHandler(logger, service.Lock, appCtx),
micro.WithEndpointMetadata(map[string]string{
Expand All @@ -99,7 +109,7 @@ func start(cmd *cobra.Command, args []string) error {

appGroup := svc.AddGroup("piggybank.secrets", micro.WithGroupQueueGroup("app"))
appGroup.AddEndpoint("GET",
service.AppHandler(logger, service.GetRecord, appCtx),
service.AppHandler(logger, service.SecretHandler(service.GetRecord), appCtx),
micro.WithEndpointMetadata(map[string]string{
"description": "Gets a secret",
"format": "application/json",
Expand All @@ -109,7 +119,7 @@ func start(cmd *cobra.Command, args []string) error {
micro.WithEndpointSubject("GET.>"),
)
appGroup.AddEndpoint("POST",
service.AppHandler(logger, service.AddRecord, appCtx),
service.AppHandler(logger, service.SecretHandler(service.AddRecord), appCtx),
micro.WithEndpointMetadata(map[string]string{
"description": "Adds a secret",
"format": "application/json",
Expand All @@ -119,7 +129,7 @@ func start(cmd *cobra.Command, args []string) error {
micro.WithEndpointSubject("POST.>"),
)
appGroup.AddEndpoint("DELETE",
service.AppHandler(logger, service.DeleteRecord, appCtx),
service.AppHandler(logger, service.SecretHandler(service.DeleteRecord), appCtx),
micro.WithEndpointMetadata(map[string]string{
"description": "Deletes a secret",
"format": "application/json",
Expand Down
16 changes: 16 additions & 0 deletions service/nats.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ type ResponseMessage struct {
Details string `json:"details,omitempty"`
}

// SecretHandler wraps any secret handlers to check if database is currently locked
func SecretHandler(a AppHandlerFunc) AppHandlerFunc {
return func(r micro.Request, app AppContext) error {
if databaseKey == nil {
return NewClientError(fmt.Errorf("database locked"), 403)
}
return a(r, app)
}

}

func Lock(r micro.Request, app AppContext) error {
databaseKey = nil
return r.RespondJSON(ResponseMessage{Details: "database locked"})
Expand Down Expand Up @@ -65,6 +76,11 @@ func Unlock(r micro.Request, app AppContext) error {
return r.RespondJSON(ResponseMessage{Details: "database successfully unlocked"})
}

// Wrap Status in secret handler so it will catch locked requests
func Status(r micro.Request, app AppContext) error {
return r.RespondJSON(ResponseMessage{Details: "database unlocked"})
}

func GetRecord(r micro.Request, app AppContext) error {
record := NewJSRecord().SetBucket(piggyBucket).SetSanitizedKey(r.Subject())
decrypted, err := app.getRecord(record)
Expand Down

0 comments on commit 69b0dc3

Please sign in to comment.