Skip to content

Commit

Permalink
Fix file backend so that it properly removes nested secrets.
Browse files Browse the repository at this point in the history
This patch makes file backend properly remove nested secrets, without leaving
empty directory artifacts, no matter how nested directories were.
  • Loading branch information
vespian committed Oct 4, 2016
1 parent d13c10f commit 3156098
Showing 1 changed file with 35 additions and 30 deletions.
65 changes: 35 additions & 30 deletions physical/file.go
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"os"
"path/filepath"
"strings"
"sync"

log "github.com/mgutz/logxi/v1"
Expand Down Expand Up @@ -39,48 +40,52 @@ func newFileBackend(conf map[string]string, logger log.Logger) (Backend, error)
}, nil
}

func (b *FileBackend) Delete(k string) error {
func (b *FileBackend) Delete(path string) error {
b.l.Lock()
defer b.l.Unlock()

path, key := b.path(k)
fullPath := filepath.Join(path, key)
basePath, key := b.path(path)
fullPath := filepath.Join(basePath, key)

// If the path doesn't exist return success; this is in line with Vault's
// expected behavior and we don't want to check for an empty directory if
// we couldn't even find the path in the first place.
err := os.Remove(fullPath)
if err != nil {
if os.IsNotExist(err) {
return nil
} else {
return err
}
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("Failed to remove `%s`: %v", fullPath, err)
}

// Check for the directory being empty and remove if so, with another
// additional guard for the path not existing
dir, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
return nil
} else {
return err
}
}
err = b.cleanupLogicalPath(path)

list, err := dir.Readdir(1)
dir.Close()
if err != nil && err != io.EOF {
return err
}
return err
}

// If we have no entries, it's an empty directory; remove it
if err == io.EOF || list == nil || len(list) == 0 {
err = os.Remove(path)
// cleanupLogicalPath is used to remove all empty nodes, begining with deepest
// one, aborting on first non-empty one, up to top-level node.
func (b *FileBackend) cleanupLogicalPath(path string) error {
nodes := strings.Split(path, "/")
for i := len(nodes) - 1; i > 0; i-- {
fullPath := b.Path + "/" + strings.Join(nodes[:i], "/")

dir, err := os.Open(fullPath)
if err != nil {
if os.IsNotExist(err) {
return nil
} else {
return err
}
}

list, err := dir.Readdir(1)
dir.Close()
if err != nil && err != io.EOF {
return err
}

// If we have no entries, it's an empty directory; remove it
if err == io.EOF || list == nil || len(list) == 0 {
err = os.Remove(fullPath)
if err != nil {
return err
}
}
}

return nil
Expand Down

0 comments on commit 3156098

Please sign in to comment.