diff --git a/core/common/ccprovider/metadata/validators.go b/core/common/ccprovider/metadata/validators.go index 06dea70385b..92cc684fe51 100644 --- a/core/common/ccprovider/metadata/validators.go +++ b/core/common/ccprovider/metadata/validators.go @@ -8,9 +8,9 @@ package metadata import ( "encoding/json" - "errors" "fmt" "io/ioutil" + "path/filepath" "reflect" "strings" @@ -36,18 +36,28 @@ func (e *UnhandledDirectoryError) Error() string { return e.err } -// InvalidFileError is returned for invalid metadata files -type InvalidFileError struct { +// BadExtensionError is returned for metadata files with extension other than .json +type BadExtensionError struct { err string } -func (e *InvalidFileError) Error() string { +func (e *BadExtensionError) Error() string { + return e.err +} + +// InvalidIndexContentError is returned for metadata files with invalid content +type InvalidIndexContentError struct { + err string +} + +func (e *InvalidIndexContentError) Error() string { return e.err } // ValidateMetadataFile checks that metadata files are valid // according to the validation rules of the metadata directory (metadataType) func ValidateMetadataFile(srcPath, metadataType string) error { + // Get the validator handler for the metadata directory fileValidator, ok := fileValidators[metadataType] @@ -56,10 +66,10 @@ func ValidateMetadataFile(srcPath, metadataType string) error { return &UnhandledDirectoryError{fmt.Sprintf("Metadata not supported in directory: %s", metadataType)} } - // If the file is not valid for the given metadata directory, return InvalidFileError + // If the file is not valid for the given metadata directory, return an error err := fileValidator(srcPath) if err != nil { - return &InvalidFileError{fmt.Sprintf("Metadata file [%s] failed validation: %s", srcPath, err)} + return err } // file is valid, return nil error @@ -68,6 +78,14 @@ func ValidateMetadataFile(srcPath, metadataType string) error { // couchdbIndexFileValidator implements fileValidator func couchdbIndexFileValidator(srcPath string) error { + + ext := filepath.Ext(srcPath) + + // if the file does not have a .json extension, then return as error + if ext != ".json" { + return &BadExtensionError{fmt.Sprintf("Index metadata file [%s] does not have a .json extension", srcPath)} + } + fileBytes, err := ioutil.ReadFile(srcPath) if err != nil { return err @@ -76,11 +94,16 @@ func couchdbIndexFileValidator(srcPath string) error { // if the content does not validate as JSON, return err to invalidate the file boolIsJSON, indexDefinition := isJSON(fileBytes) if !boolIsJSON { - return errors.New("File is not valid JSON") + return &InvalidIndexContentError{fmt.Sprintf("Index metadata file [%s] is not a valid JSON", srcPath)} } // validate the index definition - return validateIndexJSON(indexDefinition) + err = validateIndexJSON(indexDefinition) + if err != nil { + return &InvalidIndexContentError{fmt.Sprintf("Index metadata file [%s] is not a valid index definition: %s", srcPath, err)} + } + + return nil } diff --git a/core/common/ccprovider/metadata/validators_test.go b/core/common/ccprovider/metadata/validators_test.go index f38fe8f92fa..fcf4b08f287 100644 --- a/core/common/ccprovider/metadata/validators_test.go +++ b/core/common/ccprovider/metadata/validators_test.go @@ -45,11 +45,11 @@ func TestBadIndexJSON(t *testing.T) { err = ValidateMetadataFile(filename, "META-INF/statedb/couchdb/indexes") - assert.Error(t, err, "Should have received an InvalidFileError") + assert.Error(t, err, "Should have received an InvalidIndexContentError") - // Type assertion on InvalidFileError - _, ok := err.(*InvalidFileError) - assert.True(t, ok, "Should have received an InvalidFileError") + // Type assertion on InvalidIndexContentError + _, ok := err.(*InvalidIndexContentError) + assert.True(t, ok, "Should have received an InvalidIndexContentError") t.Log("SAMPLE ERROR STRING:", err.Error()) } @@ -108,6 +108,27 @@ func TestCantReadFile(t *testing.T) { err := ValidateMetadataFile(filename, "META-INF/statedb/couchdb/indexes") assert.Error(t, err, "Should have received error reading file") + +} + +func TestBadMetadataExtension(t *testing.T) { + testDir := filepath.Join(packageTestDir, "BadMetadataExtension") + cleanupDir(testDir) + defer cleanupDir(testDir) + + filename := filepath.Join(testDir, "META-INF/statedb/couchdb/indexes", "myIndex.go") + filebytes := []byte(`{"index":{"fields":["data.docType","data.owner"]},"name":"indexOwner","type":"json"}`) + + err := writeToFile(filename, filebytes) + assert.NoError(t, err, "Error writing to file") + + err = ValidateMetadataFile(filename, "META-INF/statedb/couchdb/indexes") + assert.Error(t, err, "Should have received an BadExtensionError") + + // Type assertion on BadExtensionError + _, ok := err.(*BadExtensionError) + assert.True(t, ok, "Should have received an BadExtensionError") + } func TestIndexValidation(t *testing.T) {