mirror of https://github.com/docker/docs.git
320 lines
8.6 KiB
Go
320 lines
8.6 KiB
Go
package trustmanager
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
"github.com/stretchr/testify/require"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"testing"
|
|
)
|
|
|
|
func TestAddFile(t *testing.T) {
|
|
testData := []byte("This test data should be part of the file.")
|
|
testName := "docker.com/notary/certificate"
|
|
testExt := ".crt"
|
|
perms := os.FileMode(0755)
|
|
|
|
// Temporary directory where test files will be created
|
|
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tempBaseDir)
|
|
|
|
// Since we're generating this manually we need to add the extension '.'
|
|
expectedFilePath := filepath.Join(tempBaseDir, testName+testExt)
|
|
|
|
// Create our SimpleFileStore
|
|
store := &SimpleFileStore{
|
|
baseDir: tempBaseDir,
|
|
fileExt: testExt,
|
|
perms: perms,
|
|
}
|
|
|
|
// Call the Add function
|
|
err = store.Add(testName, testData)
|
|
require.NoError(t, err)
|
|
|
|
// Check to see if file exists
|
|
b, err := ioutil.ReadFile(expectedFilePath)
|
|
require.NoError(t, err)
|
|
require.Equal(t, testData, b, "unexpected content in the file: %s", expectedFilePath)
|
|
}
|
|
|
|
func TestRemoveFile(t *testing.T) {
|
|
testName := "docker.com/notary/certificate"
|
|
testExt := ".crt"
|
|
perms := os.FileMode(0755)
|
|
|
|
// Temporary directory where test files will be created
|
|
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tempBaseDir)
|
|
|
|
// Since we're generating this manually we need to add the extension '.'
|
|
expectedFilePath := filepath.Join(tempBaseDir, testName+testExt)
|
|
|
|
_, err = generateRandomFile(expectedFilePath, perms)
|
|
require.NoError(t, err)
|
|
|
|
// Create our SimpleFileStore
|
|
store := &SimpleFileStore{
|
|
baseDir: tempBaseDir,
|
|
fileExt: testExt,
|
|
perms: perms,
|
|
}
|
|
|
|
// Call the Remove function
|
|
err = store.Remove(testName)
|
|
require.NoError(t, err)
|
|
|
|
// Check to see if file exists
|
|
_, err = os.Stat(expectedFilePath)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestListFiles(t *testing.T) {
|
|
testName := "docker.com/notary/certificate"
|
|
testExt := "crt"
|
|
perms := os.FileMode(0755)
|
|
|
|
// Temporary directory where test files will be created
|
|
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tempBaseDir)
|
|
|
|
var expectedFilePath string
|
|
// Create 10 randomfiles
|
|
for i := 1; i <= 10; i++ {
|
|
// Since we're generating this manually we need to add the extension '.'
|
|
expectedFilename := testName + strconv.Itoa(i) + "." + testExt
|
|
expectedFilePath = filepath.Join(tempBaseDir, expectedFilename)
|
|
_, err = generateRandomFile(expectedFilePath, perms)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// Create our SimpleFileStore
|
|
store := &SimpleFileStore{
|
|
baseDir: tempBaseDir,
|
|
fileExt: testExt,
|
|
perms: perms,
|
|
}
|
|
|
|
// Call the List function. Expect 10 files
|
|
files := store.ListFiles()
|
|
require.Len(t, files, 10)
|
|
}
|
|
|
|
func TestGetPath(t *testing.T) {
|
|
testExt := ".crt"
|
|
perms := os.FileMode(0755)
|
|
|
|
// Create our SimpleFileStore
|
|
store := &SimpleFileStore{
|
|
baseDir: "",
|
|
fileExt: testExt,
|
|
perms: perms,
|
|
}
|
|
|
|
firstPath := "diogomonica.com/openvpn/0xdeadbeef.crt"
|
|
secondPath := "/docker.io/testing-dashes/@#$%^&().crt"
|
|
|
|
result, err := store.GetPath("diogomonica.com/openvpn/0xdeadbeef")
|
|
require.Equal(t, firstPath, result, "unexpected error from GetPath: %v", err)
|
|
|
|
result, err = store.GetPath("/docker.io/testing-dashes/@#$%^&()")
|
|
require.Equal(t, secondPath, result, "unexpected error from GetPath: %v", err)
|
|
}
|
|
|
|
func TestGetPathProtection(t *testing.T) {
|
|
testExt := ".crt"
|
|
perms := os.FileMode(0755)
|
|
|
|
// Create our SimpleFileStore
|
|
store := &SimpleFileStore{
|
|
baseDir: "/path/to/filestore/",
|
|
fileExt: testExt,
|
|
perms: perms,
|
|
}
|
|
|
|
// Should deny requests for paths outside the filestore
|
|
_, err := store.GetPath("../../etc/passwd")
|
|
require.Error(t, err)
|
|
require.Equal(t, ErrPathOutsideStore, err)
|
|
|
|
_, err = store.GetPath("private/../../../etc/passwd")
|
|
require.Error(t, err)
|
|
require.Equal(t, ErrPathOutsideStore, err)
|
|
|
|
// Convoluted paths should work as long as they end up inside the store
|
|
expected := "/path/to/filestore/filename.crt"
|
|
result, err := store.GetPath("private/../../filestore/./filename")
|
|
require.NoError(t, err)
|
|
require.Equal(t, expected, result)
|
|
|
|
// Repeat tests with a relative baseDir
|
|
relStore := &SimpleFileStore{
|
|
baseDir: "relative/file/path",
|
|
fileExt: testExt,
|
|
perms: perms,
|
|
}
|
|
|
|
// Should deny requests for paths outside the filestore
|
|
_, err = relStore.GetPath("../../etc/passwd")
|
|
require.Error(t, err)
|
|
require.Equal(t, ErrPathOutsideStore, err)
|
|
_, err = relStore.GetPath("private/../../../etc/passwd")
|
|
require.Error(t, err)
|
|
require.Equal(t, ErrPathOutsideStore, err)
|
|
|
|
// Convoluted paths should work as long as they end up inside the store
|
|
expected = "relative/file/path/filename.crt"
|
|
result, err = relStore.GetPath("private/../../path/./filename")
|
|
require.NoError(t, err)
|
|
require.Equal(t, expected, result)
|
|
}
|
|
|
|
func TestGetData(t *testing.T) {
|
|
testName := "docker.com/notary/certificate"
|
|
testExt := ".crt"
|
|
perms := os.FileMode(0755)
|
|
|
|
// Temporary directory where test files will be created
|
|
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tempBaseDir)
|
|
|
|
// Since we're generating this manually we need to add the extension '.'
|
|
expectedFilePath := filepath.Join(tempBaseDir, testName+testExt)
|
|
|
|
expectedData, err := generateRandomFile(expectedFilePath, perms)
|
|
require.NoError(t, err)
|
|
|
|
// Create our SimpleFileStore
|
|
store := &SimpleFileStore{
|
|
baseDir: tempBaseDir,
|
|
fileExt: testExt,
|
|
perms: perms,
|
|
}
|
|
testData, err := store.Get(testName)
|
|
require.NoError(t, err, "failed to get data from: %s", testName)
|
|
require.Equal(t, expectedData, testData, "unexpected content for the file: %s", expectedFilePath)
|
|
}
|
|
|
|
func TestCreateDirectory(t *testing.T) {
|
|
testDir := "fake/path/to/directory"
|
|
|
|
// Temporary directory where test files will be created
|
|
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tempBaseDir)
|
|
|
|
dirPath := filepath.Join(tempBaseDir, testDir)
|
|
|
|
// Call createDirectory
|
|
createDirectory(dirPath, visible)
|
|
|
|
// Check to see if file exists
|
|
fi, err := os.Stat(dirPath)
|
|
require.NoError(t, err)
|
|
|
|
// Check to see if it is a directory
|
|
require.True(t, fi.IsDir(), "expected to be directory: %s", dirPath)
|
|
|
|
// Check to see if the permissions match
|
|
require.Equal(t, "drwxr-xr-x", fi.Mode().String(), "permissions are wrong for: %s. Got: %s", dirPath, fi.Mode().String())
|
|
}
|
|
|
|
func TestCreatePrivateDirectory(t *testing.T) {
|
|
testDir := "fake/path/to/private/directory"
|
|
|
|
// Temporary directory where test files will be created
|
|
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tempBaseDir)
|
|
|
|
dirPath := filepath.Join(tempBaseDir, testDir)
|
|
|
|
// Call createDirectory
|
|
createDirectory(dirPath, private)
|
|
|
|
// Check to see if file exists
|
|
fi, err := os.Stat(dirPath)
|
|
require.NoError(t, err)
|
|
|
|
// Check to see if it is a directory
|
|
require.True(t, fi.IsDir(), "expected to be directory: %s", dirPath)
|
|
|
|
// Check to see if the permissions match
|
|
require.Equal(t, "drwx------", fi.Mode().String(), "permissions are wrong for: %s. Got: %s", dirPath, fi.Mode().String())
|
|
}
|
|
|
|
func generateRandomFile(filePath string, perms os.FileMode) ([]byte, error) {
|
|
rndBytes := make([]byte, 10)
|
|
_, err := rand.Read(rndBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
os.MkdirAll(filepath.Dir(filePath), perms)
|
|
if err = ioutil.WriteFile(filePath, rndBytes, perms); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return rndBytes, nil
|
|
}
|
|
|
|
func TestFileStoreConsistency(t *testing.T) {
|
|
// Temporary directory where test files will be created
|
|
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tempBaseDir)
|
|
|
|
tempBaseDir2, err := ioutil.TempDir("", "notary-test-")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tempBaseDir2)
|
|
|
|
s, err := NewPrivateSimpleFileStore(tempBaseDir, "txt")
|
|
require.NoError(t, err)
|
|
|
|
s2, err := NewPrivateSimpleFileStore(tempBaseDir2, ".txt")
|
|
require.NoError(t, err)
|
|
|
|
file1Data := make([]byte, 20)
|
|
_, err = rand.Read(file1Data)
|
|
require.NoError(t, err)
|
|
|
|
file2Data := make([]byte, 20)
|
|
_, err = rand.Read(file2Data)
|
|
require.NoError(t, err)
|
|
|
|
file3Data := make([]byte, 20)
|
|
_, err = rand.Read(file3Data)
|
|
require.NoError(t, err)
|
|
|
|
file1Path := "file1"
|
|
file2Path := "path/file2"
|
|
file3Path := "long/path/file3"
|
|
|
|
for _, s := range []Storage{s, s2} {
|
|
s.Add(file1Path, file1Data)
|
|
s.Add(file2Path, file2Data)
|
|
s.Add(file3Path, file3Data)
|
|
|
|
paths := map[string][]byte{
|
|
file1Path: file1Data,
|
|
file2Path: file2Data,
|
|
file3Path: file3Data,
|
|
}
|
|
for _, p := range s.ListFiles() {
|
|
_, ok := paths[p]
|
|
require.True(t, ok, fmt.Sprintf("returned path not found: %s", p))
|
|
d, err := s.Get(p)
|
|
require.NoError(t, err)
|
|
require.Equal(t, paths[p], d)
|
|
}
|
|
}
|
|
|
|
}
|